decorations.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package widget
  2. import (
  3. "fmt"
  4. "math/bits"
  5. "gioui.org/io/system"
  6. "gioui.org/layout"
  7. "gioui.org/op/clip"
  8. )
  9. // Decorations handles the states of window decorations.
  10. type Decorations struct {
  11. // Maximized controls the look and behaviour of the maximize
  12. // button. It is the user's responsibility to set Maximized
  13. // according to the window state reported through [app.ConfigEvent].
  14. Maximized bool
  15. clicks map[int]*Clickable
  16. }
  17. // LayoutMove lays out the widget that makes a window movable.
  18. func (d *Decorations) LayoutMove(gtx layout.Context, w layout.Widget) layout.Dimensions {
  19. dims := w(gtx)
  20. defer clip.Rect{Max: dims.Size}.Push(gtx.Ops).Pop()
  21. system.ActionInputOp(system.ActionMove).Add(gtx.Ops)
  22. return dims
  23. }
  24. // Clickable returns the clickable for the given single action.
  25. func (d *Decorations) Clickable(action system.Action) *Clickable {
  26. if bits.OnesCount(uint(action)) != 1 {
  27. panic(fmt.Errorf("not a single action"))
  28. }
  29. idx := bits.TrailingZeros(uint(action))
  30. click, found := d.clicks[idx]
  31. if !found {
  32. click = new(Clickable)
  33. if d.clicks == nil {
  34. d.clicks = make(map[int]*Clickable)
  35. }
  36. d.clicks[idx] = click
  37. }
  38. return click
  39. }
  40. // Update the state and return the set of actions activated by the user.
  41. func (d *Decorations) Update(gtx layout.Context) system.Action {
  42. var actions system.Action
  43. for idx, clk := range d.clicks {
  44. if !clk.Clicked(gtx) {
  45. continue
  46. }
  47. action := system.Action(1 << idx)
  48. switch {
  49. case action == system.ActionMaximize && d.Maximized:
  50. action = system.ActionUnmaximize
  51. case action == system.ActionUnmaximize && !d.Maximized:
  52. action = system.ActionMaximize
  53. }
  54. actions |= action
  55. }
  56. return actions
  57. }