forked from joejulian/gio
3f38e67ce0
The app.Window.Perform(ActionMove) is the wrong abstraction for initiating a move gesture: Windows needs to know the move gesture area at pointer move, and macOS needs to know the pointer button down event that triggers the move gesture. This change replaces Perform(ActionMove) with a new system.ActionInputOp that marks an area movable. 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(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
|
|
}
|