Files
gio-patched/widget/decorations.go
T
Elias Naur 3f38e67ce0 io/system: add ActionInputOp to register window move gesture areas
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>
2022-06-25 19:40:46 +02:00

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
}