io/router: support cursor changes on Frame events

Add support to Router so that the cursor can be changed with CursorNameOp without any mouse movement.
Enter and Leave events are also delivered as areas change.

Signed-off-by: pierre <pierre.curto@gmail.com>
This commit is contained in:
pierre
2021-01-27 19:56:47 +01:00
committed by Elias Naur
parent c3346680f4
commit 1100e03c1e
3 changed files with 47 additions and 5 deletions
+9 -4
View File
@@ -409,6 +409,7 @@ func (w *Window) run(opts *window.Options) {
w.destroy(err) w.destroy(err)
return return
} }
w.updateCursor()
case *system.CommandEvent: case *system.CommandEvent:
w.out <- e w.out <- e
w.waitAck() w.waitAck()
@@ -424,10 +425,7 @@ func (w *Window) run(opts *window.Options) {
w.setNextFrame(time.Time{}) w.setNextFrame(time.Time{})
w.updateAnimation() w.updateAnimation()
} }
if c := w.queue.q.Cursor(); c != w.cursor { w.updateCursor()
w.cursor = c
w.SetCursorName(c)
}
w.out <- e w.out <- e
} }
w.ack <- struct{}{} w.ack <- struct{}{}
@@ -435,6 +433,13 @@ func (w *Window) run(opts *window.Options) {
} }
} }
func (w *Window) updateCursor() {
if c := w.queue.q.Cursor(); c != w.cursor {
w.cursor = c
w.SetCursorName(c)
}
}
func (q *queue) Events(k event.Tag) []event.Event { func (q *queue) Events(k event.Tag) []event.Event {
return q.q.Events(k) return q.q.Events(k)
} }
+8
View File
@@ -47,6 +47,9 @@ type pointerInfo struct {
id pointer.ID id pointer.ID
pressed bool pressed bool
handlers []event.Tag handlers []event.Tag
// last tracks the last pointer event received,
// used while processing frame events.
last pointer.Event
// entered tracks the tags that contain the pointer. // entered tracks the tags that contain the pointer.
entered []event.Tag entered []event.Tag
@@ -247,6 +250,10 @@ func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) {
} }
} }
} }
for i := range q.pointers {
p := &q.pointers[i]
q.deliverEnterLeaveEvents(p, events, p.last)
}
} }
func cancelHandlers(events *handlerEvents, tags ...event.Tag) { func cancelHandlers(events *handlerEvents, tags ...event.Tag) {
@@ -295,6 +302,7 @@ func (q *pointerQueue) Push(e pointer.Event, events *handlerEvents) {
pidx = len(q.pointers) - 1 pidx = len(q.pointers) - 1
} }
p := &q.pointers[pidx] p := &q.pointers[pidx]
p.last = e
if e.Type == pointer.Move && p.pressed { if e.Type == pointer.Move && p.pressed {
e.Type = pointer.Drag e.Type = pointer.Drag
+30 -1
View File
@@ -443,7 +443,7 @@ func TestMultitouch(t *testing.T) {
func TestCursorNameOp(t *testing.T) { func TestCursorNameOp(t *testing.T) {
ops := new(op.Ops) ops := new(op.Ops)
var r Router var r Router
var h int var h, h2 int
var widget2 func() var widget2 func()
widget := func() { widget := func() {
// This is the area where the cursor is changed to CursorPointer. // This is the area where the cursor is changed to CursorPointer.
@@ -502,6 +502,35 @@ func TestCursorNameOp(t *testing.T) {
}, },
want: pointer.CursorDefault, want: pointer.CursorDefault,
}, },
{label: "add new input on top while inside",
event: func() []event.Event {
widget2 = func() {
pointer.InputOp{Tag: &h2}.Add(ops)
pointer.CursorNameOp{Name: pointer.CursorCrossHair}.Add(ops)
}
return []event.Event{
_at(50, 50),
key.Event{
Name: "A",
State: key.Press,
},
}
},
want: pointer.CursorCrossHair,
},
{label: "remove input on top while inside",
event: func() []event.Event {
widget2 = nil
return []event.Event{
_at(50, 50),
key.Event{
Name: "A",
State: key.Press,
},
}
},
want: pointer.CursorPointer,
},
} { } {
t.Run(tc.label, func(t *testing.T) { t.Run(tc.label, func(t *testing.T) {
ops.Reset() ops.Reset()