github.com/Seikaijyu/gio@v0.0.1/widget/decorations.go (about) 1 package widget 2 3 import ( 4 "fmt" 5 "math/bits" 6 7 "github.com/Seikaijyu/gio/gesture" 8 "github.com/Seikaijyu/gio/io/system" 9 "github.com/Seikaijyu/gio/layout" 10 "github.com/Seikaijyu/gio/op/clip" 11 ) 12 13 // Decorations handles the states of window decorations. 14 type Decorations struct { 15 clicks map[int]*Clickable 16 resize [8]struct { 17 gesture.Hover 18 gesture.Drag 19 } 20 maximized bool 21 } 22 23 // LayoutMove lays out the widget that makes a window movable. 24 func (d *Decorations) LayoutMove(gtx layout.Context, w layout.Widget) layout.Dimensions { 25 dims := w(gtx) 26 defer clip.Rect{Max: dims.Size}.Push(gtx.Ops).Pop() 27 system.ActionInputOp(system.ActionMove).Add(gtx.Ops) 28 return dims 29 } 30 31 // Clickable returns the clickable for the given single action. 32 func (d *Decorations) Clickable(action system.Action) *Clickable { 33 if bits.OnesCount(uint(action)) != 1 { 34 panic(fmt.Errorf("not a single action")) 35 } 36 idx := bits.TrailingZeros(uint(action)) 37 click, found := d.clicks[idx] 38 if !found { 39 click = new(Clickable) 40 if d.clicks == nil { 41 d.clicks = make(map[int]*Clickable) 42 } 43 d.clicks[idx] = click 44 } 45 return click 46 } 47 48 // Perform updates the decorations as if the specified actions were 49 // performed by the user. 50 func (d *Decorations) Perform(actions system.Action) { 51 if actions&system.ActionMaximize != 0 { 52 d.maximized = true 53 } 54 if actions&(system.ActionUnmaximize|system.ActionMinimize|system.ActionFullscreen) != 0 { 55 d.maximized = false 56 } 57 } 58 59 // Update the state and return the set of actions activated by the user. 60 func (d *Decorations) Update(gtx layout.Context) system.Action { 61 var actions system.Action 62 for idx, clk := range d.clicks { 63 if !clk.Clicked(gtx) { 64 continue 65 } 66 action := system.Action(1 << idx) 67 switch { 68 case action == system.ActionMaximize && d.maximized: 69 action = system.ActionUnmaximize 70 case action == system.ActionUnmaximize && !d.maximized: 71 action = system.ActionMaximize 72 } 73 switch action { 74 case system.ActionMaximize, system.ActionUnmaximize: 75 d.maximized = !d.maximized 76 } 77 actions |= action 78 } 79 return actions 80 } 81 82 // Maximized returns whether the window is maximized. 83 func (d *Decorations) Maximized() bool { 84 return d.maximized 85 }