forked from joejulian/gio
b53cdfef8d
Allowing clients to initiate resize gestures is a waste: macOS doesn't support them, and the only reason we added them was to implement client-side decorations for Wayland. Now all desktop platforms implement resize gestures as needed, and we no longer need the system.Action actions. Signed-off-by: Elias Naur <mail@eliasnaur.com>
86 lines
1.9 KiB
Go
86 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 {
|
|
move gesture.Drag
|
|
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)
|
|
d.move.Events(gtx.Metric, gtx, gesture.Both)
|
|
st := clip.Rect{Max: dims.Size}.Push(gtx.Ops)
|
|
d.move.Add(gtx.Ops)
|
|
if d.move.Pressed() {
|
|
d.actions |= system.ActionMove
|
|
}
|
|
st.Pop()
|
|
return dims
|
|
}
|
|
|
|
// Clickable returns the clickable for the given single action.
|
|
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() {
|
|
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
|
|
}
|