github.com/Seikaijyu/gio@v0.0.1/widget/float.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  package widget
     4  
     5  import (
     6  	"image"
     7  
     8  	"github.com/Seikaijyu/gio/gesture"
     9  	"github.com/Seikaijyu/gio/io/pointer"
    10  	"github.com/Seikaijyu/gio/layout"
    11  	"github.com/Seikaijyu/gio/op/clip"
    12  	"github.com/Seikaijyu/gio/unit"
    13  )
    14  
    15  // Float is for selecting a value in a range.
    16  type Float struct {
    17  	// Value is the value of the Float, in the [0; 1] range.
    18  	Value float32
    19  
    20  	drag   gesture.Drag
    21  	axis   layout.Axis
    22  	length float32
    23  }
    24  
    25  // Dragging returns whether the value is being interacted with.
    26  func (f *Float) Dragging() bool { return f.drag.Dragging() }
    27  
    28  func (f *Float) Layout(gtx layout.Context, axis layout.Axis, pointerMargin unit.Dp) layout.Dimensions {
    29  	f.Update(gtx)
    30  	size := gtx.Constraints.Min
    31  	f.length = float32(axis.Convert(size).X)
    32  	f.axis = axis
    33  
    34  	margin := axis.Convert(image.Pt(gtx.Dp(pointerMargin), 0))
    35  	rect := image.Rectangle{
    36  		Min: margin.Mul(-1),
    37  		Max: size.Add(margin),
    38  	}
    39  	defer clip.Rect(rect).Push(gtx.Ops).Pop()
    40  	f.drag.Add(gtx.Ops)
    41  
    42  	return layout.Dimensions{Size: size}
    43  }
    44  
    45  // Update the Value according to drag events along the f's main axis.
    46  // The return value reports whether the value was changed.
    47  //
    48  // The range of f is set by the minimum constraints main axis value.
    49  func (f *Float) Update(gtx layout.Context) bool {
    50  	changed := false
    51  	for _, e := range f.drag.Update(gtx.Metric, gtx, gesture.Axis(f.axis)) {
    52  		if f.length > 0 && (e.Kind == pointer.Press || e.Kind == pointer.Drag) {
    53  			pos := e.Position.X
    54  			if f.axis == layout.Vertical {
    55  				pos = f.length - e.Position.Y
    56  			}
    57  			f.Value = pos / f.length
    58  			if f.Value < 0 {
    59  				f.Value = 0
    60  			} else if f.Value > 1 {
    61  				f.Value = 1
    62  			}
    63  			changed = true
    64  		}
    65  	}
    66  	return changed
    67  }