widget: [API] move Decorations state update to Actions

Similar to a previous change for Clickable and Bool this change separates
state changes from Decorations.Layout to Actions so that access may
happen before Layout.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2023-10-02 17:22:12 -05:00
parent dc97871122
commit b9837def5c
3 changed files with 31 additions and 25 deletions
+1 -1
View File
@@ -1024,7 +1024,7 @@ func (w *Window) decorate(d driver, e system.FrameEvent, o *op.Ops) (size, offse
}
style.Layout(gtx)
// Update the window based on the actions on the decorations.
w.Perform(deco.Actions())
w.Perform(deco.Update(gtx))
// Offset to place the frame content below the decorations.
decoHeight := gtx.Dp(w.decorations.Config.decoHeight)
if w.decorations.currentHeight != decoHeight {
+29 -23
View File
@@ -12,12 +12,11 @@ import (
// Decorations handles the states of window decorations.
type Decorations struct {
clicks []Clickable
clicks map[int]*Clickable
resize [8]struct {
gesture.Hover
gesture.Drag
}
actions system.Action
maximized bool
}
@@ -30,27 +29,18 @@ func (d *Decorations) LayoutMove(gtx layout.Context, w layout.Widget) layout.Dim
}
// Clickable returns the clickable for the given single action.
func (d *Decorations) Clickable(gtx layout.Context, action system.Action) *Clickable {
func (d *Decorations) Clickable(action system.Action) *Clickable {
if bits.OnesCount(uint(action)) != 1 {
panic(fmt.Errorf("not a single action"))
}
idx := bits.TrailingZeros(uint(action))
if n := idx - len(d.clicks); n >= 0 {
d.clicks = append(d.clicks, make([]Clickable, n+1)...)
}
click := &d.clicks[idx]
if click.Clicked(gtx) {
if action == system.ActionMaximize {
if d.maximized {
d.maximized = false
d.actions |= system.ActionUnmaximize
} else {
d.maximized = true
d.actions |= system.ActionMaximize
}
} else {
d.actions |= action
click, found := d.clicks[idx]
if !found {
click = new(Clickable)
if d.clicks == nil {
d.clicks = make(map[int]*Clickable)
}
d.clicks[idx] = click
}
return click
}
@@ -66,11 +56,27 @@ func (d *Decorations) Perform(actions system.Action) {
}
}
// Actions returns the set of actions activated by the user.
func (d *Decorations) Actions() system.Action {
a := d.actions
d.actions = 0
return a
// Update the state and return the set of actions activated by the user.
func (d *Decorations) Update(gtx layout.Context) system.Action {
var actions system.Action
for idx, clk := range d.clicks {
if !clk.Clicked(gtx) {
continue
}
action := system.Action(1 << idx)
switch {
case action == system.ActionMaximize && d.maximized:
action = system.ActionUnmaximize
case action == system.ActionUnmaximize && !d.maximized:
action = system.ActionMaximize
}
switch action {
case system.ActionMaximize, system.ActionUnmaximize:
d.maximized = !d.maximized
}
actions |= action
}
return actions
}
// Maximized returns whether the window is maximized.
+1 -1
View File
@@ -85,7 +85,7 @@ func (d DecorationsStyle) layoutDecorations(gtx layout.Context) layout.Dimension
default:
continue
}
cl := d.Decorations.Clickable(gtx, a)
cl := d.Decorations.Clickable(a)
dims := cl.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
semantic.Button.Add(gtx.Ops)
return layout.Stack{Alignment: layout.Center}.Layout(gtx,