widget,widget/material: remove disabled drawing modes

Determining the enabled state of a widget from whether its Clicked method has
been called only works for button-like widgets. For example, it's not clear a
Clicked method is appropriate for a CheckBox.

Remove the feature for now, and let's find a better design in the future.

As a nice side effect, we can now process events in Layout methods, so that
buttons react to user input even when Clicked is not called.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-11-02 12:27:56 +01:00
parent 06aa0da2a2
commit 4107485902
4 changed files with 60 additions and 61 deletions
+10 -16
View File
@@ -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)
+43 -35
View File
@@ -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]
}
}
+7 -3
View File
@@ -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) {
-7
View File
@@ -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