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) style.Layout(gtx)
// Update the window based on the actions on the decorations. // 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. // Offset to place the frame content below the decorations.
decoHeight := gtx.Dp(w.decorations.Config.decoHeight) decoHeight := gtx.Dp(w.decorations.Config.decoHeight)
if w.decorations.currentHeight != decoHeight { if w.decorations.currentHeight != decoHeight {
+29 -23
View File
@@ -12,12 +12,11 @@ import (
// Decorations handles the states of window decorations. // Decorations handles the states of window decorations.
type Decorations struct { type Decorations struct {
clicks []Clickable clicks map[int]*Clickable
resize [8]struct { resize [8]struct {
gesture.Hover gesture.Hover
gesture.Drag gesture.Drag
} }
actions system.Action
maximized bool 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. // 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 { if bits.OnesCount(uint(action)) != 1 {
panic(fmt.Errorf("not a single action")) panic(fmt.Errorf("not a single action"))
} }
idx := bits.TrailingZeros(uint(action)) idx := bits.TrailingZeros(uint(action))
if n := idx - len(d.clicks); n >= 0 { click, found := d.clicks[idx]
d.clicks = append(d.clicks, make([]Clickable, n+1)...) if !found {
} click = new(Clickable)
click := &d.clicks[idx] if d.clicks == nil {
if click.Clicked(gtx) { d.clicks = make(map[int]*Clickable)
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
} }
d.clicks[idx] = click
} }
return click return click
} }
@@ -66,11 +56,27 @@ func (d *Decorations) Perform(actions system.Action) {
} }
} }
// Actions returns the set of actions activated by the user. // Update the state and return the set of actions activated by the user.
func (d *Decorations) Actions() system.Action { func (d *Decorations) Update(gtx layout.Context) system.Action {
a := d.actions var actions system.Action
d.actions = 0 for idx, clk := range d.clicks {
return a 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. // 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: default:
continue continue
} }
cl := d.Decorations.Clickable(gtx, a) cl := d.Decorations.Clickable(a)
dims := cl.Layout(gtx, func(gtx layout.Context) layout.Dimensions { dims := cl.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
semantic.Button.Add(gtx.Ops) semantic.Button.Add(gtx.Ops)
return layout.Stack{Alignment: layout.Center}.Layout(gtx, return layout.Stack{Alignment: layout.Center}.Layout(gtx,