progressbar.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // SPDX-License-Identifier: Unlicense OR MIT
  2. package material
  3. import (
  4. "image"
  5. "image/color"
  6. "gioui.org/internal/f32color"
  7. "gioui.org/layout"
  8. "gioui.org/op/clip"
  9. "gioui.org/op/paint"
  10. "gioui.org/unit"
  11. )
  12. type ProgressBarStyle struct {
  13. Color color.NRGBA
  14. Height unit.Dp
  15. Radius unit.Dp
  16. TrackColor color.NRGBA
  17. Progress float32
  18. }
  19. func ProgressBar(th *Theme, progress float32) ProgressBarStyle {
  20. return ProgressBarStyle{
  21. Progress: progress,
  22. Height: unit.Dp(4),
  23. Radius: unit.Dp(2),
  24. Color: th.Palette.ContrastBg,
  25. TrackColor: f32color.MulAlpha(th.Palette.Fg, 0x88),
  26. }
  27. }
  28. func (p ProgressBarStyle) Layout(gtx layout.Context) layout.Dimensions {
  29. shader := func(width int, color color.NRGBA) layout.Dimensions {
  30. d := image.Point{X: width, Y: gtx.Dp(p.Height)}
  31. rr := gtx.Dp(p.Radius)
  32. defer clip.UniformRRect(image.Rectangle{Max: image.Pt(width, d.Y)}, rr).Push(gtx.Ops).Pop()
  33. paint.ColorOp{Color: color}.Add(gtx.Ops)
  34. paint.PaintOp{}.Add(gtx.Ops)
  35. return layout.Dimensions{Size: d}
  36. }
  37. progressBarWidth := gtx.Constraints.Max.X
  38. return layout.Stack{Alignment: layout.W}.Layout(gtx,
  39. layout.Stacked(func(gtx layout.Context) layout.Dimensions {
  40. return shader(progressBarWidth, p.TrackColor)
  41. }),
  42. layout.Stacked(func(gtx layout.Context) layout.Dimensions {
  43. fillWidth := int(float32(progressBarWidth) * clamp1(p.Progress))
  44. fillColor := p.Color
  45. if !gtx.Enabled() {
  46. fillColor = f32color.Disabled(fillColor)
  47. }
  48. if fillWidth < int(p.Radius*2) {
  49. fillWidth = int(p.Radius * 2)
  50. }
  51. return shader(fillWidth, fillColor)
  52. }),
  53. )
  54. }
  55. // clamp1 limits v to range [0..1].
  56. func clamp1(v float32) float32 {
  57. if v >= 1 {
  58. return 1
  59. } else if v <= 0 {
  60. return 0
  61. } else {
  62. return v
  63. }
  64. }