Files
gio/widget/float.go
T
Elias Naur d331dd2de8 op: rename StackOp/Push/Pop to StateOp/Save/Load
The semantics were relaxed in a previous commit; this change renames
to operations accordingly.

API change. Use gofmt to adjust your code accordingly:

gofmt -r 'op.Push(a).Pop() -> op.Save(a).Load()'
gofmt -r 'op.Push(a) -> op.Save(a)'
gofmt -r 'v.Pop() -> v.Load()'
gofmt -r 'op.StackOp -> op.StateOp'

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2021-01-12 21:28:59 +01:00

92 lines
1.8 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"
)
// Float is for selecting a value in a range.
type Float struct {
Value float32
drag gesture.Drag
pos float32 // position normalized to [0, 1]
length float32
changed bool
}
// Dragging returns whether the value is being interacted with.
func (f *Float) Dragging() bool { return f.drag.Dragging() }
// Layout processes events.
func (f *Float) Layout(gtx layout.Context, pointerMargin int, min, max float32) layout.Dimensions {
size := gtx.Constraints.Min
f.length = float32(size.X)
var de *pointer.Event
for _, e := range f.drag.Events(gtx.Metric, gtx, gesture.Horizontal) {
if e.Type == pointer.Press || e.Type == pointer.Drag {
de = &e
}
}
value := f.Value
if de != nil {
f.pos = de.Position.X / f.length
value = min + (max-min)*f.pos
} else if min != max {
f.pos = value/(max-min) - min
}
// Unconditionally call setValue in case min, max, or value changed.
f.setValue(value, min, max)
if f.pos < 0 {
f.pos = 0
} else if f.pos > 1 {
f.pos = 1
}
defer op.Save(gtx.Ops).Load()
rect := image.Rectangle{Max: size}
rect.Min.X -= pointerMargin
rect.Max.X += pointerMargin
pointer.Rect(rect).Add(gtx.Ops)
f.drag.Add(gtx.Ops)
return layout.Dimensions{Size: size}
}
func (f *Float) setValue(value, min, max float32) {
if min > max {
min, max = max, min
}
if value < min {
value = min
} else if value > max {
value = max
}
if f.Value != value {
f.Value = value
f.changed = true
}
}
// Pos reports the selected position.
func (f *Float) Pos() float32 {
return f.pos * f.length
}
// Changed reports whether the value has changed since
// the last call to Changed.
func (f *Float) Changed() bool {
changed := f.changed
f.changed = false
return changed
}