~eliasnaur/gio

33a87ac61c387c39a2b53f1d25dfae5ff9a8986a — Gordon Klaus a month ago 9d2a6c4
io/router: deliver scroll events only to the foremost scroll handler

Signed-off-by: Gordon Klaus <gordon.klaus@gmail.com>
3 files changed, 50 insertions(+), 0 deletions(-)

M io/pointer/doc.go
M io/router/pointer.go
M io/router/pointer_test.go
M io/pointer/doc.go => io/pointer/doc.go +2 -0
@@ 23,6 23,8 @@ Leave, or Scroll):
		Types: pointer.Press | pointer.Move | pointer.Release,
	}.Add(ops)

Scroll events are only delivered to the foremost scroll handler.

Cancel events are always delivered.

Areas

M io/router/pointer.go => io/router/pointer.go +5 -0
@@ 267,6 267,11 @@ func (q *pointerQueue) deliverEvent(p *pointerInfo, events *handlerEvents, e poi
		e.Position = h.transform.Invert().Transform(e.Position)

		addPointerEvent(events, k, e, h.types)

		// Only deliver scroll events to the foremost handler.
		if e.Type == pointer.Scroll && e.Type&h.types != 0 {
			return
		}
	}
}


M io/router/pointer_test.go => io/router/pointer_test.go +43 -0
@@ 125,6 125,49 @@ func TestPointerTypes(t *testing.T) {
	assertEventSequence(t, r.Events(handler), pointer.Cancel, pointer.Press, pointer.Release)
}

func TestPointerScroll(t *testing.T) {
	handler1 := new(int)
	handler2 := new(int)
	var ops op.Ops

	pointer.Rect(image.Rect(0, 0, 100, 100)).Add(&ops)
	pointer.InputOp{Tag: handler1, Types: pointer.Scroll}.Add(&ops)

	pointer.Rect(image.Rect(0, 0, 100, 50)).Add(&ops)
	pointer.InputOp{Tag: handler2, Types: pointer.Scroll}.Add(&ops)

	var r Router
	r.Frame(&ops)
	r.Add(
		// Hit handler 2.
		pointer.Event{
			Type: pointer.Scroll,
			Position: f32.Point{
				X: 50,
				Y: 25,
			},
		},
		// Hit handler 1.
		pointer.Event{
			Type: pointer.Scroll,
			Position: f32.Point{
				X: 50,
				Y: 75,
			},
		},
		// Hit no handlers.
		pointer.Event{
			Type: pointer.Scroll,
			Position: f32.Point{
				X: 50,
				Y: 125,
			},
		},
	)
	assertEventSequence(t, r.Events(handler1), pointer.Cancel, pointer.Scroll)
	assertEventSequence(t, r.Events(handler2), pointer.Cancel, pointer.Scroll)
}

func TestPointerEnterLeave(t *testing.T) {
	handler1 := new(int)
	handler2 := new(int)