Work on supporting mouse interactions via simple hyperlinks

This commit is contained in:
Kovid Goyal
2024-05-04 09:45:57 +05:30
parent ffed63a048
commit 0b743464fb
3 changed files with 83 additions and 0 deletions

View File

@@ -70,6 +70,7 @@ func main() (rc int, err error) {
lp.SetCursorVisible(true)
return ``
}
lp.OnMouseEvent = h.on_mouse_event
lp.OnResize = func(_, _ loop.ScreenSize) error {
return h.draw_screen()
}

View File

@@ -5,6 +5,7 @@ import (
"strings"
"sync"
"kitty/tools/tui"
"kitty/tools/tui/loop"
"kitty/tools/tui/readline"
"kitty/tools/utils"
@@ -30,6 +31,7 @@ type handler struct {
state State
err_mutex sync.Mutex
err_in_worker_thread error
mouse_state tui.MouseState
// Listing
rl *readline.Readline
@@ -278,6 +280,10 @@ func (h *handler) on_wakeup() (err error) {
return h.draw_screen()
}
func (h *handler) on_mouse_event(event *loop.MouseEvent) (err error) {
return h.mouse_state.UpdateState(event)
}
func (h *handler) on_key_event(event *loop.KeyEvent) (err error) {
if event.MatchesPressOrRepeat("ctrl+c") {
event.Handled = true

View File

@@ -201,3 +201,79 @@ func (ms *MouseSelection) DragScroll(ev *loop.MouseEvent, lp *loop.Loop, callbac
}
ms.drag_scroll.mouse_event = *ev
}
type CellRegion struct {
TopLeft, BottomRight struct{ X, Y int }
Hovered bool
Id string
OnClick []func(id string) error
}
func (c CellRegion) Contains(x, y int) bool { // 0-based
if c.TopLeft.Y > y || c.BottomRight.Y < y {
return false
}
return (y > c.TopLeft.Y || (y == c.TopLeft.Y && x >= c.TopLeft.X)) && (y < c.BottomRight.Y || (y == c.BottomRight.Y && x <= c.BottomRight.X))
}
type MouseState struct {
Cell, Pixel struct{ X, Y int }
Pressed struct{ Left, Right, Middle, Fourth, Fifth, Sixth, Seventh bool }
regions []*CellRegion
}
func (m *MouseState) AddCellRegion(id string, start_x, start_y, end_x, end_y int, on_click ...func(id string) error) *CellRegion {
cr := CellRegion{TopLeft: struct{ X, Y int }{start_x, start_y}, BottomRight: struct{ X, Y int }{end_x, end_y}, Id: id, OnClick: on_click}
m.regions = append(m.regions, &cr)
cr.Hovered = cr.Contains(m.Cell.X, m.Cell.Y)
return &cr
}
func (m *MouseState) ClearCellRegions() {
m.regions = nil
}
func (m *MouseState) UpdateState(ev *loop.MouseEvent) error {
m.Cell = ev.Cell
m.Pixel = ev.Pixel
if ev.Event_type == loop.MOUSE_PRESS || ev.Event_type == loop.MOUSE_RELEASE {
pressed := ev.Event_type == loop.MOUSE_PRESS
if ev.Buttons&loop.LEFT_MOUSE_BUTTON != 0 {
m.Pressed.Left = pressed
}
if ev.Buttons&loop.RIGHT_MOUSE_BUTTON != 0 {
m.Pressed.Right = pressed
}
if ev.Buttons&loop.MIDDLE_MOUSE_BUTTON != 0 {
m.Pressed.Middle = pressed
}
if ev.Buttons&loop.FOURTH_MOUSE_BUTTON != 0 {
m.Pressed.Fourth = pressed
}
if ev.Buttons&loop.FIFTH_MOUSE_BUTTON != 0 {
m.Pressed.Fifth = pressed
}
if ev.Buttons&loop.SIXTH_MOUSE_BUTTON != 0 {
m.Pressed.Sixth = pressed
}
if ev.Buttons&loop.SEVENTH_MOUSE_BUTTON != 0 {
m.Pressed.Seventh = pressed
}
}
for _, r := range m.regions {
if r.Contains(m.Cell.X, m.Cell.Y) {
r.Hovered = true
if ev.Event_type == loop.MOUSE_CLICK {
for _, f := range r.OnClick {
if err := f(r.Id); err != nil {
return err
}
}
}
} else {
r.Hovered = false
}
}
return nil
}