1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- // 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, ok := f.drag.Update(gtx.Metric, gtx.Source, gesture.Axis(f.axis))
- if !ok {
- break
- }
- 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
- }
|