io/router: fix default cursor in Router

Do not update the cursor was reset upon receiving Cancel events. Added more tests.

Signed-off-by: pierre <pierre.curto@gmail.com>
This commit is contained in:
pierre
2021-01-25 16:33:05 +01:00
committed by Elias Naur
parent f88a8216e9
commit b11fd6ee8e
2 changed files with 73 additions and 33 deletions
+1 -2
View File
@@ -209,7 +209,6 @@ func (q *pointerQueue) reset() {
if q.handlers == nil { if q.handlers == nil {
q.handlers = make(map[event.Tag]*pointerHandler) q.handlers = make(map[event.Tag]*pointerHandler)
} }
q.cursor = pointer.CursorDefault
} }
func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) { func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) {
@@ -331,6 +330,7 @@ func (q *pointerQueue) Push(e pointer.Event, events *handlerEvents) {
q.pointers = append(q.pointers[:pidx], q.pointers[pidx+1:]...) q.pointers = append(q.pointers[:pidx], q.pointers[pidx+1:]...)
} }
q.cursor = pointer.CursorDefault
for _, k := range p.entered { for _, k := range p.entered {
h := q.handlers[k] h := q.handlers[k]
q.hitCursor(h.area) q.hitCursor(h.area)
@@ -395,7 +395,6 @@ func (q *pointerQueue) hitCursor(want int) {
for _, c := range q.cursors { for _, c := range q.cursors {
if c.area == want { if c.area == want {
q.cursor = c.name q.cursor = c.name
return
} }
} }
} }
+72 -31
View File
@@ -10,8 +10,8 @@ import (
"gioui.org/f32" "gioui.org/f32"
"gioui.org/io/event" "gioui.org/io/event"
"gioui.org/io/key"
"gioui.org/io/pointer" "gioui.org/io/pointer"
"gioui.org/layout"
"gioui.org/op" "gioui.org/op"
) )
@@ -441,45 +441,86 @@ func TestMultitouch(t *testing.T) {
} }
func TestCursorNameOp(t *testing.T) { func TestCursorNameOp(t *testing.T) {
ops := new(op.Ops)
var r Router
var h int
var widget2 func()
widget := func() {
// This is the area where the cursor is changed to CursorPointer.
pointer.Rect(image.Rectangle{Max: image.Pt(100, 100)}).Add(ops)
// The cursor is checked and changed upon cursor movement.
pointer.InputOp{Tag: &h}.Add(ops)
pointer.CursorNameOp{Name: pointer.CursorPointer}.Add(ops)
if widget2 != nil {
widget2()
}
}
// Register the handlers.
widget()
// No cursor change as the mouse has not moved yet.
if got, want := r.Cursor(), pointer.CursorDefault; got != want {
t.Errorf("got %q; want %q", got, want)
}
_at := func(x, y float32) pointer.Event {
return pointer.Event{
Type: pointer.Move,
Source: pointer.Mouse,
Buttons: pointer.ButtonLeft,
Position: f32.Pt(x, y),
}
}
for _, tc := range []struct { for _, tc := range []struct {
label string label string
pt image.Point event interface{}
want pointer.CursorName want pointer.CursorName
}{ }{
{label: "inside", pt: image.Pt(50, 50), want: pointer.CursorPointer}, {label: "move inside",
{label: "outside", pt: image.Pt(200, 200), want: pointer.CursorDefault}, event: _at(50, 50),
want: pointer.CursorPointer,
},
{label: "move outside",
event: _at(200, 200),
want: pointer.CursorDefault,
},
{label: "move back inside",
event: _at(50, 50),
want: pointer.CursorPointer,
},
{label: "send key events while inside",
event: []event.Event{
key.Event{Name: "A", State: key.Press},
key.Event{Name: "A", State: key.Release},
},
want: pointer.CursorPointer,
},
{label: "send key events while outside",
event: []event.Event{
_at(200, 200),
key.Event{Name: "A", State: key.Press},
key.Event{Name: "A", State: key.Release},
},
want: pointer.CursorDefault,
},
} { } {
t.Run(tc.label, func(t *testing.T) { t.Run(tc.label, func(t *testing.T) {
ops := new(op.Ops) ops.Reset()
var r Router
var h int
widget := func() {
// This is the area where the cursor is changed to CursorPointer.
pointer.Rect(image.Rectangle{Max: image.Pt(100, 100)}).Add(ops)
// The cursor is checked and changed upon cursor movement.
pointer.InputOp{
Tag: &h,
Types: pointer.Move,
}.Add(ops)
pointer.CursorNameOp{Name: pointer.CursorPointer}.Add(ops)
}
// Register the handlers.
widget() widget()
// No cursor change as the mouse has not moved yet.
if got, want := r.Cursor(), pointer.CursorDefault; got != want {
t.Errorf("got %q; want %q", got, want)
}
// Add a mouse move event.
r.Frame(ops) r.Frame(ops)
r.Queue( switch ev := tc.event.(type) {
pointer.Event{ case event.Event:
Source: pointer.Mouse, r.Queue(ev)
Type: pointer.Move, case []event.Event:
Position: layout.FPt(tc.pt), r.Queue(ev...)
}, case func() event.Event:
) r.Queue(ev())
// Make the widget process the new event. case func() []event.Event:
r.Queue(ev()...)
default:
panic(fmt.Sprintf("unkown event %T", ev))
}
widget() widget()
r.Frame(ops)
// The cursor should now have been changed if the mouse moved over the declared area. // The cursor should now have been changed if the mouse moved over the declared area.
if got, want := r.Cursor(), tc.want; got != want { if got, want := r.Cursor(), tc.want; got != want {
t.Errorf("got %q; want %q", got, want) t.Errorf("got %q; want %q", got, want)