Allow more sophisticated event tracking for hover regions

This commit is contained in:
Kovid Goyal
2025-07-05 13:04:43 +05:30
parent fdf0a13687
commit 0a9d83e11b
2 changed files with 38 additions and 6 deletions

View File

@@ -413,11 +413,9 @@ func (h *Handler) OnKeyEvent(ev *loop.KeyEvent) (err error) {
func (h *Handler) OnMouseEvent(event *loop.MouseEvent) (err error) { func (h *Handler) OnMouseEvent(event *loop.MouseEvent) (err error) {
h.state.redraw_needed = h.state.mouse_state.UpdateState(event) h.state.redraw_needed = h.state.mouse_state.UpdateState(event)
if event.Event_type == loop.MOUSE_CLICK && event.Buttons&loop.LEFT_MOUSE_BUTTON != 0 { if err = h.state.mouse_state.DispatchEventToHoveredRegions(event); err != nil {
if err = h.state.mouse_state.ClickHoveredRegions(); err != nil {
return return
} }
}
if h.state.redraw_needed { if h.state.redraw_needed {
err = h.draw_screen() err = h.draw_screen()
} }

View File

@@ -210,10 +210,15 @@ type Point struct {
X, Y int X, Y int
} }
func (p Point) Sub(other Point) Point {
return Point{X: p.X - other.X, Y: p.Y - other.Y}
}
type CellRegion struct { type CellRegion struct {
TopLeft, BottomRight Point TopLeft, BottomRight Point
Id string Id string
OnClick []func(id string) error OnClick []func(id string) error // simple left click ignoring modifiers
OnClickEvent func(id string, ev *loop.MouseEvent, cell_offset Point) error // any click event
PointerShape loop.PointerShape PointerShape loop.PointerShape
HoverStyle string // set to "default" for the global hover style HoverStyle string // set to "default" for the global hover style
} }
@@ -226,7 +231,7 @@ func (c CellRegion) Contains(x, y int) bool { // 0-based
} }
type MouseState struct { type MouseState struct {
Cell, Pixel struct{ X, Y int } Cell, Pixel Point
Pressed struct{ Left, Right, Middle, Fourth, Fifth, Sixth, Seventh bool } Pressed struct{ Left, Right, Middle, Fourth, Fifth, Sixth, Seventh bool }
regions []*CellRegion regions []*CellRegion
@@ -325,6 +330,35 @@ func (m *MouseState) ApplyHoverStyles(lp *loop.Loop, style ...string) {
} }
} }
func (m *MouseState) DispatchEventToHoveredRegions(ev *loop.MouseEvent) error {
if ev.Event_type != loop.MOUSE_CLICK {
return nil
}
is_simple_click := ev.Buttons&loop.LEFT_MOUSE_BUTTON != 0
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)
if is_simple_click {
for _, f := range r.OnClick {
if err := f(r.Id); err != nil {
return err
}
}
}
if r.OnClickEvent != nil {
if err := r.OnClickEvent(r.Id, ev, m.Cell.Sub(r.TopLeft)); err != nil {
return err
}
}
}
}
return nil
}
func (m *MouseState) ClickHoveredRegions() error { func (m *MouseState) ClickHoveredRegions() error {
seen := utils.NewSet[string]() seen := utils.NewSet[string]()
for id := range m.hovered_ids.Iterable() { for id := range m.hovered_ids.Iterable() {