mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-08 19:05:35 +00:00
io/router: add tests for Enter/Leave pointer events
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This commit is contained in:
@@ -130,3 +130,172 @@ func countPointerEvents(typ pointer.Type, events []event.Event) int {
|
|||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPointerEnterLeave(t *testing.T) {
|
||||||
|
handler1 := new(int)
|
||||||
|
handler2 := new(int)
|
||||||
|
var ops op.Ops
|
||||||
|
|
||||||
|
// Handler 1 area: (0, 0) - (100, 100)
|
||||||
|
pointer.Rect(image.Rectangle{
|
||||||
|
Max: image.Point{
|
||||||
|
X: 100,
|
||||||
|
Y: 100,
|
||||||
|
},
|
||||||
|
}).Add(&ops)
|
||||||
|
pointer.InputOp{Key: handler1}.Add(&ops)
|
||||||
|
// Handler 2 area: (50, 50) - (100, 100) (areas intersect).
|
||||||
|
pointer.Rect(image.Rectangle{
|
||||||
|
Min: image.Point{
|
||||||
|
X: 50,
|
||||||
|
Y: 50,
|
||||||
|
},
|
||||||
|
Max: image.Point{
|
||||||
|
X: 200,
|
||||||
|
Y: 200,
|
||||||
|
},
|
||||||
|
}).Add(&ops)
|
||||||
|
pointer.InputOp{Key: handler2}.Add(&ops)
|
||||||
|
|
||||||
|
var r Router
|
||||||
|
r.Frame(&ops)
|
||||||
|
// Hit both handlers.
|
||||||
|
r.Add(
|
||||||
|
pointer.Event{
|
||||||
|
Type: pointer.Move,
|
||||||
|
Position: f32.Point{
|
||||||
|
X: 50,
|
||||||
|
Y: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
// First event for a handler is always a Cancel.
|
||||||
|
assertEventSequence(t, r.Events(handler1), pointer.Cancel, pointer.Enter, pointer.Move)
|
||||||
|
assertEventSequence(t, r.Events(handler2), pointer.Cancel, pointer.Enter, pointer.Move)
|
||||||
|
|
||||||
|
// Leave the second area by moving into the first.
|
||||||
|
r.Add(
|
||||||
|
pointer.Event{
|
||||||
|
Type: pointer.Move,
|
||||||
|
Position: f32.Point{
|
||||||
|
X: 45,
|
||||||
|
Y: 45,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assertEventSequence(t, r.Events(handler1), pointer.Move)
|
||||||
|
assertEventSequence(t, r.Events(handler2), pointer.Leave)
|
||||||
|
|
||||||
|
// Move, but stay within the same hit area.
|
||||||
|
r.Add(
|
||||||
|
pointer.Event{
|
||||||
|
Type: pointer.Move,
|
||||||
|
Position: f32.Point{
|
||||||
|
X: 40,
|
||||||
|
Y: 40,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assertEventSequence(t, r.Events(handler1), pointer.Move)
|
||||||
|
assertEventSequence(t, r.Events(handler2))
|
||||||
|
|
||||||
|
// Move outside of both inputs.
|
||||||
|
r.Add(
|
||||||
|
pointer.Event{
|
||||||
|
Type: pointer.Move,
|
||||||
|
Position: f32.Point{
|
||||||
|
X: 300,
|
||||||
|
Y: 300,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assertEventSequence(t, r.Events(handler1), pointer.Leave)
|
||||||
|
assertEventSequence(t, r.Events(handler2))
|
||||||
|
|
||||||
|
// Check that a Press event generates Enter Events.
|
||||||
|
r.Add(
|
||||||
|
pointer.Event{
|
||||||
|
Type: pointer.Press,
|
||||||
|
Position: f32.Point{
|
||||||
|
X: 125,
|
||||||
|
Y: 125,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assertEventSequence(t, r.Events(handler1))
|
||||||
|
assertEventSequence(t, r.Events(handler2), pointer.Enter, pointer.Press)
|
||||||
|
|
||||||
|
// Check that a Release event generates Enter/Leave Events.
|
||||||
|
r.Add(
|
||||||
|
pointer.Event{
|
||||||
|
Type: pointer.Release,
|
||||||
|
Position: f32.Point{
|
||||||
|
// Move out of the second hit area and into the first.
|
||||||
|
X: 25,
|
||||||
|
Y: 25,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assertEventSequence(t, r.Events(handler1), pointer.Enter, pointer.Release)
|
||||||
|
assertEventSequence(t, r.Events(handler2), pointer.Leave)
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertEventSequence ensures that the provided actualEvents match the expected event types
|
||||||
|
// in the provided order
|
||||||
|
func assertEventSequence(t *testing.T, actualEvents []event.Event, expected ...pointer.Type) {
|
||||||
|
for i, event := range actualEvents {
|
||||||
|
pointerEvent, ok := event.(pointer.Event)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("actualEvents[%d] is not a pointer event, type %T", i, event)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(expected) <= i {
|
||||||
|
t.Errorf("actualEvents is longer than expected, has len %d, expected len %d", len(actualEvents), len(expected))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if pointerEvent.Type != expected[i] {
|
||||||
|
t.Errorf("actualEvents[%d] has type %s, expected %s", i, pointerEvent.Type.String(), expected[i].String())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkRouterAdd(b *testing.B) {
|
||||||
|
// Set this to the number of overlapping handlers that you want to
|
||||||
|
// evaluate performance for. Typical values for the example applications
|
||||||
|
// are 1-3, though checking highers values helps evaluate performance for
|
||||||
|
// more complex applications.
|
||||||
|
const handlerCount = 3
|
||||||
|
handlers := make([]event.Key, handlerCount)
|
||||||
|
for i := 0; i < handlerCount; i++ {
|
||||||
|
h := new(int)
|
||||||
|
*h = i
|
||||||
|
handlers[i] = h
|
||||||
|
}
|
||||||
|
var ops op.Ops
|
||||||
|
|
||||||
|
for i := range handlers {
|
||||||
|
pointer.Rect(image.Rectangle{
|
||||||
|
Max: image.Point{
|
||||||
|
X: 100,
|
||||||
|
Y: 100,
|
||||||
|
},
|
||||||
|
}).Add(&ops)
|
||||||
|
pointer.InputOp{Key: handlers[i]}.Add(&ops)
|
||||||
|
}
|
||||||
|
var r Router
|
||||||
|
r.Frame(&ops)
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
r.Add(
|
||||||
|
pointer.Event{
|
||||||
|
Type: pointer.Move,
|
||||||
|
Position: f32.Point{
|
||||||
|
X: 50,
|
||||||
|
Y: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user