float.go 1.6 KB

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