Files
gio/widget/float.go
T
Elias Naur d42dae73f0 widget: [API] separate Float state update; remove min, max, invert parameters
This change allows users of Float to determine its state before Layout
by calling Update.

While here, remove the value transformation represented by the min, max,
invert parameters; they're too many arguments for a computation that
may as well be done by the user.

Remove Float.Pos; it is better to compute its value from the dimensions
returned by Float.Layout.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2023-10-06 20:04:32 -05:00

68 lines
1.6 KiB
Go

// SPDX-License-Identifier: Unlicense OR MIT
package widget
import (
"image"
"gioui.org/gesture"
"gioui.org/io/pointer"
"gioui.org/layout"
"gioui.org/op/clip"
"gioui.org/unit"
)
// Float is for selecting a value in a range.
type Float struct {
// Value is the value of the Float, in the [0; 1] range.
Value float32
drag gesture.Drag
axis layout.Axis
length float32
}
// Dragging returns whether the value is being interacted with.
func (f *Float) Dragging() bool { return f.drag.Dragging() }
func (f *Float) Layout(gtx layout.Context, axis layout.Axis, pointerMargin unit.Dp) layout.Dimensions {
f.Update(gtx)
size := gtx.Constraints.Min
f.length = float32(axis.Convert(size).X)
f.axis = axis
margin := axis.Convert(image.Pt(gtx.Dp(pointerMargin), 0))
rect := image.Rectangle{
Min: margin.Mul(-1),
Max: size.Add(margin),
}
defer clip.Rect(rect).Push(gtx.Ops).Pop()
f.drag.Add(gtx.Ops)
return layout.Dimensions{Size: size}
}
// Update the Value according to drag events along the f's main axis.
// The return value reports whether the value was changed.
//
// The range of f is set by the minimum constraints main axis value.
func (f *Float) Update(gtx layout.Context) bool {
changed := false
for _, e := range f.drag.Events(gtx.Metric, gtx, gesture.Axis(f.axis)) {
if f.length > 0 && (e.Kind == pointer.Press || e.Kind == pointer.Drag) {
pos := e.Position.X
if f.axis == layout.Vertical {
pos = f.length - e.Position.Y
}
f.Value = pos / f.length
if f.Value < 0 {
f.Value = 0
} else if f.Value > 1 {
f.Value = 1
}
changed = true
}
}
return changed
}