aboutsummaryrefslogtreecommitdiff
path: root/gui/internal/ui/highlight.go
diff options
context:
space:
mode:
Diffstat (limited to 'gui/internal/ui/highlight.go')
-rw-r--r--gui/internal/ui/highlight.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/gui/internal/ui/highlight.go b/gui/internal/ui/highlight.go
new file mode 100644
index 0000000..8a4acd4
--- /dev/null
+++ b/gui/internal/ui/highlight.go
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package ui
+
+import (
+ "github.com/diamondburned/gotk4/pkg/gtk/v4"
+
+ "krino/gui/internal/model"
+)
+
+// The colours a configuration is painted in. They are chosen to read on a
+// light and a dark theme alike, since the window follows whatever GTK theme
+// is in use (his request, 2026-09-16).
+var spanColours = map[model.SpanKind]string{
+ model.SpanComment: "#8b8b8b",
+ model.SpanString: "#2e8b57",
+ model.SpanHead: "#3584e4",
+ model.SpanAction: "#c06014",
+ model.SpanParen: "#9a9a9a",
+}
+
+// highlighter paints a configuration in a TextView.
+type highlighter struct {
+ buf *gtk.TextBuffer
+ tags map[model.SpanKind]*gtk.TextTag
+ on bool
+}
+
+// newHighlighter registers one tag per kind, once per buffer.
+func newHighlighter(buf *gtk.TextBuffer) *highlighter {
+ h := &highlighter{buf: buf, tags: map[model.SpanKind]*gtk.TextTag{}, on: true}
+ table := buf.TagTable()
+ names := map[model.SpanKind]string{
+ model.SpanComment: "krino-comment",
+ model.SpanString: "krino-string",
+ model.SpanHead: "krino-head",
+ model.SpanAction: "krino-action",
+ model.SpanParen: "krino-paren",
+ }
+ for kind, name := range names {
+ t := gtk.NewTextTag(name)
+ t.SetObjectProperty("foreground", spanColours[kind])
+ if kind == model.SpanComment {
+ t.SetObjectProperty("style", 2) // PANGO_STYLE_ITALIC
+ }
+ table.Add(t)
+ h.tags[kind] = t
+ }
+ return h
+}
+
+// setEnabled turns the colours on or off.
+func (h *highlighter) setEnabled(on bool) {
+ h.on = on
+ if !on {
+ h.clear()
+ }
+}
+
+// clear takes every colour off the buffer.
+func (h *highlighter) clear() {
+ start, end := h.buf.Bounds()
+ h.buf.RemoveAllTags(start, end)
+}
+
+// paint colours the text now in the buffer.
+func (h *highlighter) paint(text string) {
+ h.clear()
+ if !h.on {
+ return
+ }
+ for _, s := range model.Spans(text) {
+ if tag, ok := h.tags[s.Kind]; ok {
+ h.buf.ApplyTag(tag, h.buf.IterAtOffset(s.From), h.buf.IterAtOffset(s.To))
+ }
+ }
+}