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  }