diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2025-06-17 11:43:34 -0500 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-08-20 15:57:21 +0200 |
| commit | 4206d7fe5cf450fbc1f9a16e8d57b85c08df3dab (patch) | |
| tree | c0dd008bcb47fe6e7af49e5b79ba928ace002cc7 /go/ui/collection.go | |
| parent | ab08e0b7c7ebc50549392e6de3908dfa61f1e973 (diff) | |
| download | muhqs-game-4206d7fe5cf450fbc1f9a16e8d57b85c08df3dab.tar.gz muhqs-game-4206d7fe5cf450fbc1f9a16e8d57b85c08df3dab.zip | |
make input events consumable
Having a input queue of consumable input events allow widgets to prevent
the further handling of the same event by different collections by
consuming the event.
Diffstat (limited to 'go/ui/collection.go')
| -rw-r--r-- | go/ui/collection.go | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/go/ui/collection.go b/go/ui/collection.go index bb7a4d53..9ccaa176 100644 --- a/go/ui/collection.go +++ b/go/ui/collection.go @@ -4,7 +4,6 @@ import ( "log" "github.com/hajimehoshi/ebiten/v2" - "github.com/hajimehoshi/ebiten/v2/inpututil" "golang.org/x/exp/slices" ) @@ -18,6 +17,16 @@ type Collection struct { focused Widget } +type CollectionInterface interface { + Widget + Widgets() []Widget + Clear() + AddWidget(Widget) + FindWidget(Widget) int + RemoveWidget(Widget) + RemoveWidgetAt(int) +} + func (c *Collection) Layout() (int, int) { return c.Width, c.Height } @@ -125,12 +134,18 @@ func (c *Collection) switchFocus(fcsbl Widget) { } func (c *Collection) handleTouchInputs() error { - for _, tap := range TouchManager.Taps { + for i := len(TouchManager.Taps) - 1; i >= 0; i-- { + tap := TouchManager.Taps[i] for i := len(c.widgets) - 1; i >= 0; i-- { w := c.widgets[i] if !w.Contains(tap.X, tap.Y) { continue } + // Skip collections their widgets will receive left over input + // during the following updateWidgets call, + if _, ok := w.(CollectionInterface); ok { + continue + } if w.IsClickable() { w.Click(tap.X, tap.Y) } @@ -139,6 +154,8 @@ func (c *Collection) handleTouchInputs() error { } else if c.focused != nil { c.switchFocus(nil) } + log.Printf("consume Tap for %T %v\n", w, w) + TouchManager.consumeTap(i) break } } @@ -157,12 +174,8 @@ func (c *Collection) handleTouchInputs() error { return nil } -func passInput(textInput *TextInput) { - var input []rune - input = ebiten.AppendInputChars(input) - if len(input) > 0 { - textInput.AddInput(input) - } +func passInput(ev InputEvent, textInput *TextInput) { + textInput.AddInput(ev.ctx.(TextCtx).in) textInput.HandleKey() } @@ -170,7 +183,7 @@ func (c *Collection) IsUpdatable() bool { return true } -func (c *Collection) Update() error { +func (c *Collection) updateWidgets() error { // Update all updatables for _, w := range c.widgets { if w.IsUpdatable() { @@ -179,43 +192,51 @@ func (c *Collection) Update() error { } } } + return nil +} + +func (c *Collection) Update() error { + defer c.updateWidgets() if err := c.handleTouchInputs(); err != nil { return err } - x, y := ebiten.CursorPosition() - - activeWidget := c.FindWidgetAt(x, y) - - c.hoverDetector.update(c, x, y, activeWidget) - - if activeWidget == nil { - if txt, ok := c.focused.(*TextInput); ok { - if ebiten.IsKeyPressed(ebiten.KeyA) { - txt.AddInput([]rune{'a'}) + for i := len(Input) - 1; i >= 0; i-- { + ev := Input[i] + w := c.FindWidgetAt(ev.x, ev.y) + if w != nil { + switch ev.kind { + case Click: + if w.IsClickable() && ev.ctx.(ClickCtx).btn == ebiten.MouseButtonLeft { + w.Click(ev.x, ev.y) + consumeInput(i) + } + // TODO: switch focus + case Scroll: + if w.IsScrollable() { + s := ev.ctx.(ScrollCtx) + w.Scroll(s.scrollX, s.scrollY) + consumeInput(i) + } + case Text: + if txt, ok := w.(*TextInput); ok { + passInput(ev, txt) + consumeInput(i) + } + } + // handle focused text input + } else if ev.kind == Text { + if txt, ok := c.focused.(*TextInput); ok { + passInput(ev, txt) + consumeInput(i) } - passInput(txt) - } - return nil - } - - scrollX, scrollY := ebiten.Wheel() - if scrollX != 0 || scrollY != 0 { - if activeWidget.IsScrollable() { - activeWidget.Scroll(int(scrollX), int(scrollY)) } } - if textInput, ok := activeWidget.(*TextInput); ok { - passInput(textInput) - } - - if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) { - if activeWidget.IsClickable() { - activeWidget.Click(x, y) - } - } + x, y := ebiten.CursorPosition() + activeWidget := c.FindWidgetAt(x, y) + c.hoverDetector.update(c, x, y, activeWidget) return nil } |
