diff --git a/widget/button.go b/widget/button.go index 7a488cf4..c43f7792 100644 --- a/widget/button.go +++ b/widget/button.go @@ -8,6 +8,7 @@ import ( "gioui.org/f32" "gioui.org/gesture" + "gioui.org/io/key" "gioui.org/io/pointer" "gioui.org/layout" "gioui.org/op" @@ -15,10 +16,18 @@ import ( // Clickable represents a clickable area. type Clickable struct { - click gesture.Click - // clicks tracks the number of unreported clicks. - clicks int - history []Press + click gesture.Click + clicks []Click + // prevClicks is the index into clicks that marks the clicks + // from the most recent Layout call. prevClicks is used to keep + // clicks bounded. + prevClicks int + history []Press +} + +// Click represents a click. +type Click struct { + Modifiers key.Modifiers } // Press represents a past pointer press. @@ -27,14 +36,26 @@ type Press struct { Time time.Time } -// Clicked and reports whether the button was clicked since the last -// call to Clicked. Clicked returns true once per click. +// Clicked reports whether there are pending clicks as would be +// reported by Clicks. If so, Clicked removes the earliest click. func (b *Clickable) Clicked() bool { - if b.clicks > 0 { - b.clicks-- - return true + if len(b.clicks) == 0 { + return false } - return false + n := copy(b.clicks, b.clicks[1:]) + b.clicks = b.clicks[:n] + if b.prevClicks > 0 { + b.prevClicks-- + } + return true +} + +// Clicks returns and clear the clicks since the last call to Clicks. +func (b Clickable) Clicks() []Click { + clicks := b.clicks + b.clicks = nil + b.prevClicks = 0 + return clicks } // History is the past pointer presses useful for drawing markers. @@ -63,10 +84,17 @@ func (b *Clickable) Layout(gtx layout.Context) layout.Dimensions { // update the button state by processing events. func (b *Clickable) update(gtx layout.Context) { + // Flush clicks from before the last update. + n := copy(b.clicks, b.clicks[b.prevClicks:]) + b.clicks = b.clicks[:n] + b.prevClicks = n + for _, e := range b.click.Events(gtx) { switch e.Type { case gesture.TypeClick: - b.clicks++ + b.clicks = append(b.clicks, Click{ + Modifiers: e.Modifiers, + }) case gesture.TypePress: b.history = append(b.history, Press{ Position: e.Position,