diff --git a/example/kitchen/kitchen.go b/example/kitchen/kitchen.go index 4143b482..8c7cc640 100644 --- a/example/kitchen/kitchen.go +++ b/example/kitchen/kitchen.go @@ -62,13 +62,13 @@ var ( SingleLine: true, Submit: true, } - button = new(widget.Button) - disabledButton = new(widget.Button) - iconButton = new(widget.Button) - list = &layout.List{ + button = new(widget.Button) + greenButton = new(widget.Button) + iconButton = new(widget.Button) + list = &layout.List{ Axis: layout.Vertical, } - enabled bool + green = true topLabel = "Hello, Gio" icon *material.Icon ) @@ -98,15 +98,13 @@ func kitchen(gtx *layout.Context, th *material.Theme) { in := layout.UniformInset(unit.Dp(8)) b1 := buttons.Rigid(gtx, func() { in.Layout(gtx, func() { - for iconButton.Clicked(gtx) { - } th.IconButton(icon).Layout(gtx, iconButton) }) }) b2 := buttons.Rigid(gtx, func() { in.Layout(gtx, func() { for button.Clicked(gtx) { - enabled = !enabled + green = !green } th.Button("Click me!").Layout(gtx, button) }) @@ -114,15 +112,11 @@ func kitchen(gtx *layout.Context, th *material.Theme) { b3 := buttons.Rigid(gtx, func() { in.Layout(gtx, func() { var btn material.Button - if enabled { - for disabledButton.Clicked(gtx) { - } - btn = th.Button("Enabled") - } else { - btn = th.Button("Disabled") + btn = th.Button("Green button") + if green { + btn.Background = color.RGBA{A: 0xff, R: 0x9e, G: 0x9d, B: 0x24} } - btn.Background = color.RGBA{A: 0xff, R: 0x9e, G: 0x9d, B: 0x24} - btn.Layout(gtx, disabledButton) + btn.Layout(gtx, greenButton) }) }) buttons.Layout(gtx, b1, b2, b3) diff --git a/widget/button.go b/widget/button.go index 7beecef4..24cc8d11 100644 --- a/widget/button.go +++ b/widget/button.go @@ -12,9 +12,13 @@ import ( ) type Button struct { - click gesture.Click - clicks int - history []Click + click gesture.Click + // clicks tracks the number of unreported clicks. + clicks int + // prevClicks tracks the number of unreported clicks + // that belong to the previous frame. + prevClicks int + history []Click } // Click represents a historic click. @@ -24,6 +28,42 @@ type Click struct { } func (b *Button) Clicked(gtx *layout.Context) bool { + b.processEvents(gtx) + if b.clicks > 0 { + b.clicks-- + if b.prevClicks > 0 { + b.prevClicks-- + } + 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.clicks -= b.prevClicks + b.prevClicks = 0 + b.processEvents(gtx) + b.click.Add(gtx.Ops) + 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: @@ -35,36 +75,4 @@ func (b *Button) Clicked(gtx *layout.Context) bool { }) } } - 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) Active() bool { - return b.click.Active() -} - -func (b *Button) History() []Click { - return b.history -} - -func (b *Button) Layout(gtx *layout.Context) { - b.click.Add(gtx.Ops) - if !b.Active() { - b.clicks = 0 - } - 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] - } } diff --git a/widget/editor.go b/widget/editor.go index b9038257..d061816a 100644 --- a/widget/editor.go +++ b/widget/editor.go @@ -60,6 +60,8 @@ type Editor struct { // events is the list of events not yet processed. events []EditorEvent + // prevEvents is the number of events from the previous frame. + prevEvents int } type EditorEvent interface { @@ -90,6 +92,7 @@ func (e *Editor) Events(gtx *layout.Context) []EditorEvent { e.processEvents(gtx) events := e.events e.events = nil + e.prevEvents = 0 return events } @@ -177,15 +180,16 @@ func (e *Editor) Focus() { // Layout lays out the editor. func (e *Editor) Layout(gtx *layout.Context, sh *text.Shaper, font text.Font) { + // Flush events from before the previous frame. + copy(e.events, e.events[e.prevEvents:]) + e.events = e.events[:len(e.events)-e.prevEvents] + e.prevEvents = len(e.events) if e.font != font { e.invalidate() e.font = font } e.processEvents(gtx) e.layout(gtx, sh) - if !e.clicker.Active() { - e.events = nil - } } func (e *Editor) layout(gtx *layout.Context, sh *text.Shaper) { diff --git a/widget/material/button.go b/widget/material/button.go index 13335df7..30fbc323 100644 --- a/widget/material/button.go +++ b/widget/material/button.go @@ -78,10 +78,6 @@ func (t *Theme) IconButton(icon *Icon) IconButton { func (b Button) Layout(gtx *layout.Context, button *widget.Button) { col := b.Color bgcol := b.Background - if !button.Active() { - col = rgb(0x888888) - bgcol = rgb(0xcccccc) - } st := layout.Stack{Alignment: layout.Center} hmin := gtx.Constraints.Width.Min vmin := gtx.Constraints.Height.Min @@ -128,9 +124,6 @@ func (b IconButton) Layout(gtx *layout.Context, button *widget.Button) { button.Layout(gtx) }) bgcol := b.Background - if !button.Active() { - bgcol = rgb(0xcccccc) - } bg := st.Expand(gtx, func() { size := float32(gtx.Constraints.Width.Min) rr := float32(size) * .5