mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-01 07:35:40 +00:00
4a4fe5a69b
Before this change, Clickable state updates would happen in Layout. However, that is too late in cases where clicks affects layout that contiains the Clickable. This change removes state changes from Layout and moves them to Clicks, to allow users pre-layout access. Note that Layout itself processes events, which means users can no longer access clicks after Layout. Signed-off-by: Elias Naur <mail@eliasnaur.com>
80 lines
1.9 KiB
Go
80 lines
1.9 KiB
Go
package widget
|
|
|
|
import (
|
|
"fmt"
|
|
"math/bits"
|
|
|
|
"gioui.org/gesture"
|
|
"gioui.org/io/system"
|
|
"gioui.org/layout"
|
|
"gioui.org/op/clip"
|
|
)
|
|
|
|
// Decorations handles the states of window decorations.
|
|
type Decorations struct {
|
|
clicks []Clickable
|
|
resize [8]struct {
|
|
gesture.Hover
|
|
gesture.Drag
|
|
}
|
|
actions system.Action
|
|
maximized bool
|
|
}
|
|
|
|
// LayoutMove lays out the widget that makes a window movable.
|
|
func (d *Decorations) LayoutMove(gtx layout.Context, w layout.Widget) layout.Dimensions {
|
|
dims := w(gtx)
|
|
defer clip.Rect{Max: dims.Size}.Push(gtx.Ops).Pop()
|
|
system.ActionInputOp(system.ActionMove).Add(gtx.Ops)
|
|
return dims
|
|
}
|
|
|
|
// Clickable returns the clickable for the given single action.
|
|
func (d *Decorations) Clickable(gtx layout.Context, 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
|
|
}
|
|
}
|
|
return click
|
|
}
|
|
|
|
// Perform updates the decorations as if the specified actions were
|
|
// performed by the user.
|
|
func (d *Decorations) Perform(actions system.Action) {
|
|
if actions&system.ActionMaximize != 0 {
|
|
d.maximized = true
|
|
}
|
|
if actions&(system.ActionUnmaximize|system.ActionMinimize|system.ActionFullscreen) != 0 {
|
|
d.maximized = false
|
|
}
|
|
}
|
|
|
|
// Actions returns the set of actions activated by the user.
|
|
func (d *Decorations) Actions() system.Action {
|
|
a := d.actions
|
|
d.actions = 0
|
|
return a
|
|
}
|
|
|
|
// Maximized returns whether the window is maximized.
|
|
func (d *Decorations) Maximized() bool {
|
|
return d.maximized
|
|
}
|