forked from joejulian/gio
fd2cb4a7a1
Before this change, the widget.Button.Layout method assumed the caller had set up the pointer hit area before. Further, the very common rectangular hit areas needed both an AreaOp and a widget.Button.Layout call. Make widget.Button less subtle and more useful by setting up a pointer hit area given by the incoming minimum constraints. Drop a pointer.AreaOp made redundant by the change. Signed-off-by: Elias Naur <mail@eliasnaur.com>
77 lines
1.4 KiB
Go
77 lines
1.4 KiB
Go
// SPDX-License-Identifier: Unlicense OR MIT
|
|
|
|
package widget
|
|
|
|
import (
|
|
"image"
|
|
"time"
|
|
|
|
"gioui.org/f32"
|
|
"gioui.org/gesture"
|
|
"gioui.org/io/pointer"
|
|
"gioui.org/layout"
|
|
"gioui.org/op"
|
|
)
|
|
|
|
type Button struct {
|
|
click gesture.Click
|
|
// clicks tracks the number of unreported clicks.
|
|
clicks int
|
|
history []Click
|
|
}
|
|
|
|
// Click represents a past click.
|
|
type Click struct {
|
|
Position f32.Point
|
|
Time time.Time
|
|
}
|
|
|
|
func (b *Button) Clicked(gtx *layout.Context) bool {
|
|
b.processEvents(gtx)
|
|
if b.clicks > 0 {
|
|
b.clicks--
|
|
if b.clicks > 0 {
|
|
// Ensure timely delivery of remaining clicks.
|
|
op.InvalidateOp{}.Add(gtx.Ops)
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (b *Button) History() []Click {
|
|
return b.history
|
|
}
|
|
|
|
func (b *Button) Layout(gtx *layout.Context) {
|
|
// Flush clicks from before the previous frame.
|
|
b.processEvents(gtx)
|
|
var st op.StackOp
|
|
st.Push(gtx.Ops)
|
|
pointer.Rect(image.Rectangle{Max: gtx.Constraints.Min()}).Add(gtx.Ops)
|
|
b.click.Add(gtx.Ops)
|
|
st.Pop()
|
|
for len(b.history) > 0 {
|
|
c := b.history[0]
|
|
if gtx.Now().Sub(c.Time) < 1*time.Second {
|
|
break
|
|
}
|
|
copy(b.history, b.history[1:])
|
|
b.history = b.history[:len(b.history)-1]
|
|
}
|
|
}
|
|
|
|
func (b *Button) processEvents(gtx *layout.Context) {
|
|
for _, e := range b.click.Events(gtx) {
|
|
switch e.Type {
|
|
case gesture.TypeClick:
|
|
b.clicks++
|
|
case gesture.TypePress:
|
|
b.history = append(b.history, Click{
|
|
Position: e.Position,
|
|
Time: gtx.Now(),
|
|
})
|
|
}
|
|
}
|
|
}
|