From 96f8dbbbeb34b1d9713624f44ee4400fafe75559 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 7 May 2024 12:05:28 +0530 Subject: [PATCH] Get clicking on family names functional --- kittens/choose_fonts/family_list.go | 3 ++- kittens/choose_fonts/ui.go | 25 ++++++++++++++++---- tools/tui/mouse.go | 36 +++++++++++++++++++++-------- tools/utils/set.go | 16 +++++++++++++ 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/kittens/choose_fonts/family_list.go b/kittens/choose_fonts/family_list.go index 6d52abd3e..64d559930 100644 --- a/kittens/choose_fonts/family_list.go +++ b/kittens/choose_fonts/family_list.go @@ -96,7 +96,8 @@ func apply_search(families []string, expression string, marks ...string) (matche } func make_family_names_clickable(family string) string { - return tui.InternalHyperlink(family, "family-chosen:"+family) + id := wcswidth.StripEscapeCodes(family) + return tui.InternalHyperlink(family, "family-chosen:"+id) } func (self *FamilyList) UpdateFamilies(families []string) { diff --git a/kittens/choose_fonts/ui.go b/kittens/choose_fonts/ui.go index d4b1ec477..99b5a7d2c 100644 --- a/kittens/choose_fonts/ui.go +++ b/kittens/choose_fonts/ui.go @@ -30,6 +30,7 @@ type handler struct { err_mutex sync.Mutex err_in_worker_thread error mouse_state tui.MouseState + render_count uint render_lines tui.RenderLines // Listing @@ -271,10 +272,13 @@ func (h *handler) finalize() { } func (h *handler) draw_screen() (err error) { + h.render_count++ h.lp.StartAtomicUpdate() - defer h.mouse_state.UpdateHoveredIds() - defer h.mouse_state.ApplyHoverStyles(h.lp) - defer h.lp.EndAtomicUpdate() + defer func() { + h.mouse_state.UpdateHoveredIds() + h.mouse_state.ApplyHoverStyles(h.lp) + h.lp.EndAtomicUpdate() + }() h.lp.ClearScreen() h.lp.AllowLineWrapping(false) h.mouse_state.ClearCellRegions() @@ -301,8 +305,19 @@ func (h *handler) on_wakeup() (err error) { } func (h *handler) on_mouse_event(event *loop.MouseEvent) (err error) { - err = h.mouse_state.UpdateState(event) - h.mouse_state.ApplyHoverStyles(h.lp) + rc := h.render_count + redraw_needed := false + if h.mouse_state.UpdateState(event) { + redraw_needed = true + } + if event.Event_type == loop.MOUSE_CLICK && event.Buttons&loop.LEFT_MOUSE_BUTTON != 0 { + if err = h.mouse_state.ClickHoveredRegions(); err != nil { + return + } + } + if redraw_needed && rc == h.render_count { + err = h.draw_screen() + } return } diff --git a/tools/tui/mouse.go b/tools/tui/mouse.go index 6d1d22f19..eb1a56b6d 100644 --- a/tools/tui/mouse.go +++ b/tools/tui/mouse.go @@ -248,17 +248,16 @@ func (m *MouseState) ClearCellRegions() { m.hovered_ids = nil } -func (m *MouseState) UpdateHoveredIds() { - if m.hovered_ids == nil { - m.hovered_ids = utils.NewSet[string]() - } else { - m.hovered_ids.Clear() - } +func (m *MouseState) UpdateHoveredIds() (changed bool) { + h := utils.NewSet[string]() for _, r := range m.regions { if r.Contains(m.Cell.X, m.Cell.Y) { - m.hovered_ids.Add(r.Id) + h.Add(r.Id) } } + changed = !h.Equal(m.hovered_ids) + m.hovered_ids = h + return } func (m *MouseState) ApplyHoverStyles(lp *loop.Loop, style ...string) { @@ -297,7 +296,25 @@ func (m *MouseState) ApplyHoverStyles(lp *loop.Loop, style ...string) { } } -func (m *MouseState) UpdateState(ev *loop.MouseEvent) error { +func (m *MouseState) ClickHoveredRegions() error { + seen := utils.NewSet[string]() + for id := range m.hovered_ids.Iterable() { + for _, r := range m.region_id_map[id] { + if seen.Has(r.Id) { + continue + } + seen.Add(r.Id) + for _, f := range r.OnClick { + if err := f(r.Id); err != nil { + return err + } + } + } + } + return nil +} + +func (m *MouseState) UpdateState(ev *loop.MouseEvent) (hovered_ids_changed bool) { m.Cell = ev.Cell m.Pixel = ev.Pixel if ev.Event_type == loop.MOUSE_PRESS || ev.Event_type == loop.MOUSE_RELEASE { @@ -324,6 +341,5 @@ func (m *MouseState) UpdateState(ev *loop.MouseEvent) error { m.Pressed.Seventh = pressed } } - m.UpdateHoveredIds() - return nil + return m.UpdateHoveredIds() } diff --git a/tools/utils/set.go b/tools/utils/set.go index 6618e22da..e36ee218c 100644 --- a/tools/utils/set.go +++ b/tools/utils/set.go @@ -121,6 +121,22 @@ func (self *Set[T]) IsSubsetOf(other *Set[T]) bool { return true } +func (self *Set[T]) Equal(other *Set[T]) bool { + l := self.Len() + if other == nil { + return l == 0 + } + if l != other.Len() { + return false + } + for x := range self.items { + if !other.Has(x) { + return false + } + } + return true +} + func NewSet[T comparable](capacity ...int) (ans *Set[T]) { if len(capacity) == 0 { ans = &Set[T]{items: make(map[T]struct{}, 8)}