github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/gio/widget/button.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 package widget 4 5 import ( 6 "time" 7 8 "github.com/gop9/olt/gio/f32" 9 "github.com/gop9/olt/gio/gesture" 10 "github.com/gop9/olt/gio/layout" 11 "github.com/gop9/olt/gio/op" 12 ) 13 14 type Button struct { 15 click gesture.Click 16 // clicks tracks the number of unreported clicks. 17 clicks int 18 // prevClicks tracks the number of unreported clicks 19 // that belong to the previous frame. 20 prevClicks int 21 history []Click 22 } 23 24 // Click represents a historic click. 25 type Click struct { 26 Position f32.Point 27 Time time.Time 28 } 29 30 func (b *Button) Clicked(gtx *layout.Context) bool { 31 b.processEvents(gtx) 32 if b.clicks > 0 { 33 b.clicks-- 34 if b.prevClicks > 0 { 35 b.prevClicks-- 36 } 37 if b.clicks > 0 { 38 // Ensure timely delivery of remaining clicks. 39 op.InvalidateOp{}.Add(gtx.Ops) 40 } 41 return true 42 } 43 return false 44 } 45 46 func (b *Button) History() []Click { 47 return b.history 48 } 49 50 func (b *Button) Layout(gtx *layout.Context) { 51 // Flush clicks from before the previous frame. 52 b.clicks -= b.prevClicks 53 b.prevClicks = 0 54 b.processEvents(gtx) 55 b.click.Add(gtx.Ops) 56 for len(b.history) > 0 { 57 c := b.history[0] 58 if gtx.Now().Sub(c.Time) < 1*time.Second { 59 break 60 } 61 copy(b.history, b.history[1:]) 62 b.history = b.history[:len(b.history)-1] 63 } 64 } 65 66 func (b *Button) processEvents(gtx *layout.Context) { 67 for _, e := range b.click.Events(gtx) { 68 switch e.Type { 69 case gesture.TypeClick: 70 b.clicks++ 71 case gesture.TypePress: 72 b.history = append(b.history, Click{ 73 Position: e.Position, 74 Time: gtx.Now(), 75 }) 76 } 77 } 78 }