mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 18:35:34 +00:00
io/pointer: add InputOp.Types to specify which types of events to receive
Signed-off-by: Gordon Klaus <gordon.klaus@gmail.com>
This commit is contained in:
Vendored
+4
-1
@@ -124,7 +124,10 @@ func (w *quarterWidget) Layout(gtx layout.Context) layout.Dimensions {
|
|||||||
pointer.Rect(image.Rectangle{
|
pointer.Rect(image.Rectangle{
|
||||||
Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y),
|
Max: image.Pt(gtx.Constraints.Max.X, gtx.Constraints.Max.Y),
|
||||||
}).Add(gtx.Ops)
|
}).Add(gtx.Ops)
|
||||||
pointer.InputOp{Tag: w}.Add(gtx.Ops)
|
pointer.InputOp{
|
||||||
|
Tag: w,
|
||||||
|
Types: pointer.Press,
|
||||||
|
}.Add(gtx.Ops)
|
||||||
|
|
||||||
for _, e := range gtx.Events(w) {
|
for _, e := range gtx.Events(w) {
|
||||||
if e, ok := e.(pointer.Event); ok && e.Type == pointer.Press {
|
if e, ok := e.(pointer.Event); ok && e.Type == pointer.Press {
|
||||||
|
|||||||
+9
-2
@@ -112,7 +112,10 @@ var touchSlop = unit.Dp(3)
|
|||||||
|
|
||||||
// Add the handler to the operation list to receive click events.
|
// Add the handler to the operation list to receive click events.
|
||||||
func (c *Click) Add(ops *op.Ops) {
|
func (c *Click) Add(ops *op.Ops) {
|
||||||
op := pointer.InputOp{Tag: c}
|
op := pointer.InputOp{
|
||||||
|
Tag: c,
|
||||||
|
Types: pointer.Press | pointer.Release | pointer.Enter | pointer.Leave,
|
||||||
|
}
|
||||||
op.Add(ops)
|
op.Add(ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +171,11 @@ func (c *Click) Events(q event.Queue) []ClickEvent {
|
|||||||
|
|
||||||
// Add the handler to the operation list to receive scroll events.
|
// Add the handler to the operation list to receive scroll events.
|
||||||
func (s *Scroll) Add(ops *op.Ops) {
|
func (s *Scroll) Add(ops *op.Ops) {
|
||||||
oph := pointer.InputOp{Tag: s, Grab: s.grab}
|
oph := pointer.InputOp{
|
||||||
|
Tag: s,
|
||||||
|
Grab: s.grab,
|
||||||
|
Types: pointer.Press | pointer.Move | pointer.Release | pointer.Scroll,
|
||||||
|
}
|
||||||
oph.Add(ops)
|
oph.Add(ops)
|
||||||
if s.flinger.Active() {
|
if s.flinger.Active() {
|
||||||
op.InvalidateOp{}.Add(ops)
|
op.InvalidateOp{}.Add(ops)
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const (
|
|||||||
TypePaintLen = 1 + 4*4
|
TypePaintLen = 1 + 4*4
|
||||||
TypeColorLen = 1 + 4
|
TypeColorLen = 1 + 4
|
||||||
TypeAreaLen = 1 + 1 + 4*4
|
TypeAreaLen = 1 + 1 + 4*4
|
||||||
TypePointerInputLen = 1 + 1
|
TypePointerInputLen = 1 + 1 + 1
|
||||||
TypePassLen = 1 + 1
|
TypePassLen = 1 + 1
|
||||||
TypeKeyInputLen = 1 + 1
|
TypeKeyInputLen = 1 + 1
|
||||||
TypeHideInputLen = 1
|
TypeHideInputLen = 1
|
||||||
|
|||||||
+17
-3
@@ -8,6 +8,23 @@ object such as a finger.
|
|||||||
The InputOp operation is used to declare a handler ready for pointer
|
The InputOp operation is used to declare a handler ready for pointer
|
||||||
events. Use an event.Queue to receive events.
|
events. Use an event.Queue to receive events.
|
||||||
|
|
||||||
|
Types
|
||||||
|
|
||||||
|
Only events that match a specified list of types are delivered to a handler.
|
||||||
|
|
||||||
|
For example, to receive Press, Move, and Release events (but not Enter,
|
||||||
|
Leave, or Scroll):
|
||||||
|
|
||||||
|
var ops op.Ops
|
||||||
|
var h *Handler = ...
|
||||||
|
|
||||||
|
pointer.InputOp{
|
||||||
|
Tag: h,
|
||||||
|
Types: pointer.Press | pointer.Move | pointer.Release,
|
||||||
|
}.Add(ops)
|
||||||
|
|
||||||
|
Cancel events are always delivered.
|
||||||
|
|
||||||
Areas
|
Areas
|
||||||
|
|
||||||
The area operations are used for specifying the area where
|
The area operations are used for specifying the area where
|
||||||
@@ -15,9 +32,6 @@ subsequent InputOp are active.
|
|||||||
|
|
||||||
For example, to set up a rectangular hit area:
|
For example, to set up a rectangular hit area:
|
||||||
|
|
||||||
var ops op.Ops
|
|
||||||
var h *Handler = ...
|
|
||||||
|
|
||||||
r := image.Rectangle{...}
|
r := image.Rectangle{...}
|
||||||
pointer.Rect(r).Add(ops)
|
pointer.Rect(r).Add(ops)
|
||||||
pointer.InputOp{Tag: h}.Add(ops)
|
pointer.InputOp{Tag: h}.Add(ops)
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ type InputOp struct {
|
|||||||
// Grab, if set, request that the handler get
|
// Grab, if set, request that the handler get
|
||||||
// Grabbed priority.
|
// Grabbed priority.
|
||||||
Grab bool
|
Grab bool
|
||||||
|
// Types is a bitwise-or of event types to receive.
|
||||||
|
Types Type
|
||||||
}
|
}
|
||||||
|
|
||||||
// PassOp sets the pass-through mode.
|
// PassOp sets the pass-through mode.
|
||||||
@@ -83,7 +85,7 @@ type areaKind uint8
|
|||||||
const (
|
const (
|
||||||
// A Cancel event is generated when the current gesture is
|
// A Cancel event is generated when the current gesture is
|
||||||
// interrupted by other handlers or the system.
|
// interrupted by other handlers or the system.
|
||||||
Cancel Type = iota
|
Cancel Type = (1 << iota) >> 1
|
||||||
// Press of a pointer.
|
// Press of a pointer.
|
||||||
Press
|
Press
|
||||||
// Release of a pointer.
|
// Release of a pointer.
|
||||||
@@ -157,6 +159,7 @@ func (h InputOp) Add(o *op.Ops) {
|
|||||||
if h.Grab {
|
if h.Grab {
|
||||||
data[1] = 1
|
data[1] = 1
|
||||||
}
|
}
|
||||||
|
data[2] = byte(h.Types)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (op PassOp) Add(o *op.Ops) {
|
func (op PassOp) Add(o *op.Ops) {
|
||||||
|
|||||||
+14
-5
@@ -46,6 +46,7 @@ type pointerHandler struct {
|
|||||||
active bool
|
active bool
|
||||||
transform op.TransformOp
|
transform op.TransformOp
|
||||||
wantsGrab bool
|
wantsGrab bool
|
||||||
|
types pointer.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
type areaOp struct {
|
type areaOp struct {
|
||||||
@@ -109,6 +110,7 @@ func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t o
|
|||||||
h.area = area
|
h.area = area
|
||||||
h.transform = t
|
h.transform = t
|
||||||
h.wantsGrab = op.Grab
|
h.wantsGrab = op.Grab
|
||||||
|
h.types = op.Types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -264,7 +266,7 @@ func (q *pointerQueue) deliverEvent(p *pointerInfo, events *handlerEvents, e poi
|
|||||||
}
|
}
|
||||||
e.Position = h.transform.Invert().Transform(e.Position)
|
e.Position = h.transform.Invert().Transform(e.Position)
|
||||||
|
|
||||||
events.Add(k, e)
|
addPointerEvent(events, k, e, h.types)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,15 +295,21 @@ func (q *pointerQueue) deliverEnterLeaveEvents(p *pointerInfo, events *handlerEv
|
|||||||
case !hit && entered != -1:
|
case !hit && entered != -1:
|
||||||
p.entered = append(p.entered[:entered], p.entered[entered+1:]...)
|
p.entered = append(p.entered[:entered], p.entered[entered+1:]...)
|
||||||
e.Type = pointer.Leave
|
e.Type = pointer.Leave
|
||||||
events.Add(k, e)
|
addPointerEvent(events, k, e, h.types)
|
||||||
case hit && entered == -1:
|
case hit && entered == -1:
|
||||||
p.entered = append(p.entered, k)
|
p.entered = append(p.entered, k)
|
||||||
e.Type = pointer.Enter
|
e.Type = pointer.Enter
|
||||||
events.Add(k, e)
|
addPointerEvent(events, k, e, h.types)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addPointerEvent(events *handlerEvents, k event.Tag, e pointer.Event, types pointer.Type) {
|
||||||
|
if e.Type&types == e.Type {
|
||||||
|
events.Add(k, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (op *areaOp) Decode(d []byte) {
|
func (op *areaOp) Decode(d []byte) {
|
||||||
if opconst.OpType(d[0]) != opconst.TypeArea {
|
if opconst.OpType(d[0]) != opconst.TypeArea {
|
||||||
panic("invalid op")
|
panic("invalid op")
|
||||||
@@ -352,8 +360,9 @@ func decodePointerInputOp(d []byte, refs []interface{}) pointer.InputOp {
|
|||||||
panic("invalid op")
|
panic("invalid op")
|
||||||
}
|
}
|
||||||
return pointer.InputOp{
|
return pointer.InputOp{
|
||||||
Tag: refs[0].(event.Tag),
|
Tag: refs[0].(event.Tag),
|
||||||
Grab: d[1] != 0,
|
Grab: d[1] != 0,
|
||||||
|
Types: pointer.Type(d[2]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,12 +47,14 @@ func TestPointerMove(t *testing.T) {
|
|||||||
handler2 := new(int)
|
handler2 := new(int)
|
||||||
var ops op.Ops
|
var ops op.Ops
|
||||||
|
|
||||||
|
types := pointer.Move | pointer.Enter | pointer.Leave
|
||||||
|
|
||||||
// Handler 1 area: (0, 0) - (100, 100)
|
// Handler 1 area: (0, 0) - (100, 100)
|
||||||
pointer.Rect(image.Rect(0, 0, 100, 100)).Add(&ops)
|
pointer.Rect(image.Rect(0, 0, 100, 100)).Add(&ops)
|
||||||
pointer.InputOp{Tag: handler1}.Add(&ops)
|
pointer.InputOp{Tag: handler1, Types: types}.Add(&ops)
|
||||||
// Handler 2 area: (50, 50) - (100, 100) (areas intersect).
|
// Handler 2 area: (50, 50) - (100, 100) (areas intersect).
|
||||||
pointer.Rect(image.Rect(50, 50, 200, 200)).Add(&ops)
|
pointer.Rect(image.Rect(50, 50, 200, 200)).Add(&ops)
|
||||||
pointer.InputOp{Tag: handler2}.Add(&ops)
|
pointer.InputOp{Tag: handler2, Types: types}.Add(&ops)
|
||||||
|
|
||||||
var r Router
|
var r Router
|
||||||
r.Frame(&ops)
|
r.Frame(&ops)
|
||||||
@@ -86,6 +88,43 @@ func TestPointerMove(t *testing.T) {
|
|||||||
assertEventSequence(t, r.Events(handler2), pointer.Cancel, pointer.Enter, pointer.Move, pointer.Leave)
|
assertEventSequence(t, r.Events(handler2), pointer.Cancel, pointer.Enter, pointer.Move, pointer.Leave)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPointerTypes(t *testing.T) {
|
||||||
|
handler := new(int)
|
||||||
|
var ops op.Ops
|
||||||
|
pointer.Rect(image.Rect(0, 0, 100, 100)).Add(&ops)
|
||||||
|
pointer.InputOp{
|
||||||
|
Tag: handler,
|
||||||
|
Types: pointer.Press | pointer.Release,
|
||||||
|
}.Add(&ops)
|
||||||
|
|
||||||
|
var r Router
|
||||||
|
r.Frame(&ops)
|
||||||
|
r.Add(
|
||||||
|
pointer.Event{
|
||||||
|
Type: pointer.Press,
|
||||||
|
Position: f32.Point{
|
||||||
|
X: 50,
|
||||||
|
Y: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pointer.Event{
|
||||||
|
Type: pointer.Move,
|
||||||
|
Position: f32.Point{
|
||||||
|
X: 150,
|
||||||
|
Y: 150,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pointer.Event{
|
||||||
|
Type: pointer.Release,
|
||||||
|
Position: f32.Point{
|
||||||
|
X: 150,
|
||||||
|
Y: 150,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assertEventSequence(t, r.Events(handler), pointer.Cancel, pointer.Press, pointer.Release)
|
||||||
|
}
|
||||||
|
|
||||||
func TestPointerEnterLeave(t *testing.T) {
|
func TestPointerEnterLeave(t *testing.T) {
|
||||||
handler1 := new(int)
|
handler1 := new(int)
|
||||||
handler2 := new(int)
|
handler2 := new(int)
|
||||||
@@ -190,13 +229,15 @@ func TestPointerEnterLeaveNested(t *testing.T) {
|
|||||||
handler2 := new(int)
|
handler2 := new(int)
|
||||||
var ops op.Ops
|
var ops op.Ops
|
||||||
|
|
||||||
|
types := pointer.Press | pointer.Move | pointer.Release | pointer.Enter | pointer.Leave
|
||||||
|
|
||||||
// Handler 1 area: (0, 0) - (100, 100)
|
// Handler 1 area: (0, 0) - (100, 100)
|
||||||
pointer.Rect(image.Rect(0, 0, 100, 100)).Add(&ops)
|
pointer.Rect(image.Rect(0, 0, 100, 100)).Add(&ops)
|
||||||
pointer.InputOp{Tag: handler1}.Add(&ops)
|
pointer.InputOp{Tag: handler1, Types: types}.Add(&ops)
|
||||||
|
|
||||||
// Handler 2 area: (25, 25) - (75, 75) (nested within first).
|
// Handler 2 area: (25, 25) - (75, 75) (nested within first).
|
||||||
pointer.Rect(image.Rect(25, 25, 75, 75)).Add(&ops)
|
pointer.Rect(image.Rect(25, 25, 75, 75)).Add(&ops)
|
||||||
pointer.InputOp{Tag: handler2}.Add(&ops)
|
pointer.InputOp{Tag: handler2, Types: types}.Add(&ops)
|
||||||
|
|
||||||
var r Router
|
var r Router
|
||||||
r.Frame(&ops)
|
r.Frame(&ops)
|
||||||
@@ -360,7 +401,10 @@ func TestMultitouch(t *testing.T) {
|
|||||||
func addPointerHandler(ops *op.Ops, tag event.Tag, area image.Rectangle) {
|
func addPointerHandler(ops *op.Ops, tag event.Tag, area image.Rectangle) {
|
||||||
defer op.Push(ops).Pop()
|
defer op.Push(ops).Pop()
|
||||||
pointer.Rect(area).Add(ops)
|
pointer.Rect(area).Add(ops)
|
||||||
pointer.InputOp{Tag: tag}.Add(ops)
|
pointer.InputOp{
|
||||||
|
Tag: tag,
|
||||||
|
Types: pointer.Press | pointer.Move | pointer.Release | pointer.Enter | pointer.Leave,
|
||||||
|
}.Add(ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pointerTypes converts a sequence of event.Event to their pointer.Types. It assumes
|
// pointerTypes converts a sequence of event.Event to their pointer.Types. It assumes
|
||||||
@@ -411,7 +455,10 @@ func BenchmarkRouterAdd(b *testing.B) {
|
|||||||
Y: 100,
|
Y: 100,
|
||||||
},
|
},
|
||||||
}).Add(&ops)
|
}).Add(&ops)
|
||||||
pointer.InputOp{Tag: handlers[i]}.Add(&ops)
|
pointer.InputOp{
|
||||||
|
Tag: handlers[i],
|
||||||
|
Types: pointer.Move,
|
||||||
|
}.Add(&ops)
|
||||||
}
|
}
|
||||||
var r Router
|
var r Router
|
||||||
r.Frame(&ops)
|
r.Frame(&ops)
|
||||||
|
|||||||
Reference in New Issue
Block a user