From 75314fcee2be42dd1b843a07c64f10df202cd312 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 25 Nov 2023 14:36:00 -0600 Subject: [PATCH] all: use a single tag per widget for event handling With the introduction of filters, it is now possible to have one tag per widget by convention. Note that gestures still have their own tags, for disambiguation. Signed-off-by: Elias Naur --- widget/button.go | 9 ++++----- widget/dnd.go | 13 ++++++------- widget/dnd_test.go | 11 ++++++----- widget/editor.go | 15 +++++++-------- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/widget/button.go b/widget/button.go index d955d693..5b1454f0 100644 --- a/widget/button.go +++ b/widget/button.go @@ -21,7 +21,6 @@ type Clickable struct { click gesture.Click history []Press - keyTag struct{} requestClicks int focused bool pressedKey key.Name @@ -69,7 +68,7 @@ func (b *Clickable) Pressed() bool { // Focus requests the input focus for the element. func (b *Clickable) Focus(gtx layout.Context) { - gtx.Execute(key.FocusCmd{Tag: &b.keyTag}) + gtx.Execute(key.FocusCmd{Tag: b}) } // Focused reports whether b has focus. @@ -97,7 +96,7 @@ func (b *Clickable) Layout(gtx layout.Context, w layout.Widget) layout.Dimension defer clip.Rect(image.Rectangle{Max: dims.Size}).Push(gtx.Ops).Pop() semantic.EnabledOp(gtx.Enabled()).Add(gtx.Ops) b.click.Add(gtx.Ops) - event.InputOp(gtx.Ops, &b.keyTag) + event.InputOp(gtx.Ops, b) c.Add(gtx.Ops) return dims } @@ -141,7 +140,7 @@ func (b *Clickable) Update(gtx layout.Context) (Click, bool) { } case gesture.KindPress: if e.Source == pointer.Mouse { - gtx.Execute(key.FocusCmd{Tag: &b.keyTag}) + gtx.Execute(key.FocusCmd{Tag: b}) } b.history = append(b.history, Press{ Position: e.Position, @@ -156,7 +155,7 @@ func (b *Clickable) Update(gtx layout.Context) (Click, bool) { filters = append(filters, key.Filter{Name: key.NameReturn}, key.Filter{Name: key.NameSpace}) } for { - e, ok := gtx.Event(&b.keyTag, filters...) + e, ok := gtx.Event(b, filters...) if !ok { break } diff --git a/widget/dnd.go b/widget/dnd.go index 4a905dd4..4d62f2fa 100644 --- a/widget/dnd.go +++ b/widget/dnd.go @@ -18,10 +18,9 @@ type Draggable struct { // Type contains the MIME type and matches transfer.SourceOp. Type string - handle struct{} - drag gesture.Drag - click f32.Point - pos f32.Point + drag gesture.Drag + click f32.Point + pos f32.Point } func (d *Draggable) Layout(gtx layout.Context, w, drag layout.Widget) layout.Dimensions { @@ -32,7 +31,7 @@ func (d *Draggable) Layout(gtx layout.Context, w, drag layout.Widget) layout.Dim stack := clip.Rect{Max: dims.Size}.Push(gtx.Ops) d.drag.Add(gtx.Ops) - event.InputOp(gtx.Ops, &d.handle) + event.InputOp(gtx.Ops, d) stack.Pop() if drag != nil && d.drag.Pressed() { @@ -66,7 +65,7 @@ func (d *Draggable) Update(gtx layout.Context) (mime string, requested bool) { d.pos = pos for { - e, ok := gtx.Event(&d.handle, transfer.SourceFilter{Type: d.Type}) + e, ok := gtx.Event(d, transfer.SourceFilter{Type: d.Type}) if !ok { break } @@ -80,7 +79,7 @@ func (d *Draggable) Update(gtx layout.Context) (mime string, requested bool) { // Offer the data ready for a drop. Must be called after being Requested. // The mime must be one in the requested list. func (d *Draggable) Offer(gtx layout.Context, mime string, data io.ReadCloser) { - gtx.Execute(transfer.OfferCmd{Tag: &d.handle, Type: mime, Data: data}) + gtx.Execute(transfer.OfferCmd{Tag: d, Type: mime, Data: data}) } // Pos returns the drag position relative to its initial click position. diff --git a/widget/dnd_test.go b/widget/dnd_test.go index d5ec9c90..705cec4c 100644 --- a/widget/dnd_test.go +++ b/widget/dnd_test.go @@ -25,16 +25,17 @@ func TestDraggable(t *testing.T) { drag := &Draggable{ Type: "file", } + tgt := new(int) defer pointer.PassOp{}.Push(gtx.Ops).Pop() dims := drag.Layout(gtx, func(gtx layout.Context) layout.Dimensions { return layout.Dimensions{Size: gtx.Constraints.Min} }, nil) stack := clip.Rect{Max: dims.Size}.Push(gtx.Ops) - event.InputOp(gtx.Ops, drag) + event.InputOp(gtx.Ops, tgt) stack.Pop() drag.Update(gtx) - r.Event(drag, transfer.TargetFilter{Type: drag.Type}) + r.Event(tgt, transfer.TargetFilter{Type: drag.Type}) r.Frame(gtx.Ops) r.Queue( pointer.Event{ @@ -52,10 +53,10 @@ func TestDraggable(t *testing.T) { ) ofr := &offer{data: "hello"} drag.Update(gtx) - r.Event(drag, transfer.TargetFilter{Type: drag.Type}) + r.Event(tgt, transfer.TargetFilter{Type: drag.Type}) drag.Offer(gtx, "file", ofr) - e, ok := r.Event(drag, transfer.TargetFilter{Type: drag.Type}) + e, ok := r.Event(tgt, transfer.TargetFilter{Type: drag.Type}) if !ok { t.Fatalf("expected event") } @@ -66,7 +67,7 @@ func TestDraggable(t *testing.T) { if ofr.closed { t.Error("offer closed prematurely") } - e, ok = r.Event(drag, transfer.TargetFilter{Type: drag.Type}) + e, ok = r.Event(tgt, transfer.TargetFilter{Type: drag.Type}) if !ok { t.Fatalf("expected event") } diff --git a/widget/editor.go b/widget/editor.go index 46175f05..86a5a88b 100644 --- a/widget/editor.go +++ b/widget/editor.go @@ -71,7 +71,6 @@ type Editor struct { // scratch is a byte buffer that is reused to efficiently read portions of text // from the textView. scratch []byte - eventKey int blinkStart time.Time focused bool @@ -381,7 +380,7 @@ func (e *Editor) processKey(gtx layout.Context) { // adjust keeps track of runes dropped because of MaxLen. var adjust int for { - ke, ok := gtx.Event(&e.eventKey, filters...) + ke, ok := gtx.Event(e, filters...) if !ok { break } @@ -479,7 +478,7 @@ func (e *Editor) command(gtx layout.Context, k key.Event) { // half is in Editor.processKey() under clipboard.Event. case "V": if !e.ReadOnly { - gtx.Execute(clipboard.ReadCmd{Tag: &e.eventKey}) + gtx.Execute(clipboard.ReadCmd{Tag: e}) } // Copy or Cut selection -- ignored if nothing selected. case "C", "X": @@ -560,7 +559,7 @@ func (e *Editor) command(gtx layout.Context, k key.Event) { // Focus requests the input focus for the Editor. func (e *Editor) Focus(gtx layout.Context) { - gtx.Execute(key.FocusCmd{Tag: &e.eventKey}) + gtx.Execute(key.FocusCmd{Tag: e}) gtx.Execute(key.SoftKeyboardCmd{Show: true}) } @@ -605,7 +604,7 @@ func (e *Editor) Update(gtx layout.Context) { } if newSel != e.ime.selection { e.ime.selection = newSel - gtx.Execute(key.SelectionCmd{Tag: &e.eventKey, Range: newSel.rng, Caret: newSel.caret}) + gtx.Execute(key.SelectionCmd{Tag: e, Range: newSel.rng, Caret: newSel.caret}) } e.updateSnippet(gtx, e.ime.start, e.ime.end) @@ -662,7 +661,7 @@ func (e *Editor) updateSnippet(gtx layout.Context, start, end int) { return } e.ime.snippet = newSnip - gtx.Execute(key.SnippetCmd{Tag: &e.eventKey, Snippet: newSnip}) + gtx.Execute(key.SnippetCmd{Tag: e, Snippet: newSnip}) } func (e *Editor) layout(gtx layout.Context, textMaterial, selectMaterial op.CallOp) layout.Dimensions { @@ -677,8 +676,8 @@ func (e *Editor) layout(gtx layout.Context, textMaterial, selectMaterial op.Call defer clip.Rect(image.Rectangle{Max: visibleDims.Size}).Push(gtx.Ops).Pop() pointer.CursorText.Add(gtx.Ops) - event.InputOp(gtx.Ops, &e.eventKey) - key.InputHintOp{Tag: &e.eventKey, Hint: e.InputHint}.Add(gtx.Ops) + event.InputOp(gtx.Ops, e) + key.InputHintOp{Tag: e, Hint: e.InputHint}.Add(gtx.Ops) e.scroller.Add(gtx.Ops)