widget: add Button.Clicks for retrieving clicks

An earlier change unexported the Button.Update method that exposed raw pointer
input not available from the boolean Button.Clicked method. Introduce Click
and Button.Clicks to replace it, and implement Clicked in terms of it.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-05-24 12:41:13 +02:00
parent 8d838e89f5
commit 4898e1a691
+39 -11
View File
@@ -8,6 +8,7 @@ import (
"gioui.org/f32" "gioui.org/f32"
"gioui.org/gesture" "gioui.org/gesture"
"gioui.org/io/key"
"gioui.org/io/pointer" "gioui.org/io/pointer"
"gioui.org/layout" "gioui.org/layout"
"gioui.org/op" "gioui.org/op"
@@ -15,10 +16,18 @@ import (
// Clickable represents a clickable area. // Clickable represents a clickable area.
type Clickable struct { type Clickable struct {
click gesture.Click click gesture.Click
// clicks tracks the number of unreported clicks. clicks []Click
clicks int // prevClicks is the index into clicks that marks the clicks
history []Press // 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. // Press represents a past pointer press.
@@ -27,14 +36,26 @@ type Press struct {
Time time.Time Time time.Time
} }
// Clicked and reports whether the button was clicked since the last // Clicked reports whether there are pending clicks as would be
// call to Clicked. Clicked returns true once per click. // reported by Clicks. If so, Clicked removes the earliest click.
func (b *Clickable) Clicked() bool { func (b *Clickable) Clicked() bool {
if b.clicks > 0 { if len(b.clicks) == 0 {
b.clicks-- return false
return true
} }
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. // 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. // update the button state by processing events.
func (b *Clickable) update(gtx layout.Context) { 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) { for _, e := range b.click.Events(gtx) {
switch e.Type { switch e.Type {
case gesture.TypeClick: case gesture.TypeClick:
b.clicks++ b.clicks = append(b.clicks, Click{
Modifiers: e.Modifiers,
})
case gesture.TypePress: case gesture.TypePress:
b.history = append(b.history, Press{ b.history = append(b.history, Press{
Position: e.Position, Position: e.Position,