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 }