ProgressIndicator.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package giu
  2. import (
  3. "image"
  4. "math"
  5. "time"
  6. "github.com/AllenDang/imgui-go"
  7. )
  8. var _ Disposable = &progressIndicatorState{}
  9. type progressIndicatorState struct {
  10. angle float64
  11. stop bool
  12. }
  13. func (ps *progressIndicatorState) update() {
  14. ticker := time.NewTicker(time.Second / 60)
  15. for !ps.stop {
  16. if ps.angle > 6.2 {
  17. ps.angle = 0
  18. }
  19. ps.angle += 0.1
  20. Update()
  21. <-ticker.C
  22. }
  23. ticker.Stop()
  24. }
  25. // Dispose implements Disposable interface.
  26. func (ps *progressIndicatorState) Dispose() {
  27. ps.stop = true
  28. }
  29. // static check to ensure if ProgressIndicatorWidget implements Widget interface.
  30. var _ Widget = &ProgressIndicatorWidget{}
  31. // ProgressIndicatorWidget represents progress indicator widget
  32. // see examples/extrawidgets/.
  33. type ProgressIndicatorWidget struct {
  34. internalID string
  35. width float32
  36. height float32
  37. radius float32
  38. label string
  39. }
  40. // ProgressIndicator creates a new ProgressIndicatorWidget.
  41. func ProgressIndicator(label string, width, height, radius float32) *ProgressIndicatorWidget {
  42. return &ProgressIndicatorWidget{
  43. internalID: "###giu-progress-indicator",
  44. width: width,
  45. height: height,
  46. radius: radius,
  47. label: label,
  48. }
  49. }
  50. // Build implements Widget interface.
  51. func (p *ProgressIndicatorWidget) Build() {
  52. // State exists
  53. if s := Context.GetState(p.internalID); s == nil {
  54. // Register state and start go routine
  55. ps := progressIndicatorState{angle: 0.0, stop: false}
  56. Context.SetState(p.internalID, &ps)
  57. go ps.update()
  58. } else {
  59. var isOk bool
  60. state, isOk := s.(*progressIndicatorState)
  61. Assert(isOk, "ProgressIndicatorWidget", "Build", "got unexpected type of widget's sate")
  62. child := Child().Border(false).Size(p.width, p.height).Layout(Layout{
  63. Custom(func() {
  64. // Process width and height
  65. width, height := GetAvailableRegion()
  66. canvas := GetCanvas()
  67. pos := GetCursorScreenPos()
  68. centerPt := pos.Add(image.Pt(int(width/2), int(height/2)))
  69. centerPt2 := image.Pt(
  70. int(float64(p.radius)*math.Sin(state.angle)+float64(centerPt.X)),
  71. int(float64(p.radius)*math.Cos(state.angle)+float64(centerPt.Y)),
  72. )
  73. color := imgui.CurrentStyle().GetColor(imgui.StyleColorText)
  74. rgba := Vec4ToRGBA(color)
  75. canvas.AddCircle(centerPt, p.radius, rgba, int(p.radius), p.radius/20.0)
  76. canvas.AddCircleFilled(centerPt2, p.radius/5, rgba)
  77. // Draw text
  78. if len(p.label) > 0 {
  79. labelWidth, _ := CalcTextSize(tStr(p.label))
  80. labelPos := centerPt.Add(image.Pt(-1*int(labelWidth/2), int(p.radius+p.radius/5+8)))
  81. canvas.AddText(labelPos, rgba, p.label)
  82. }
  83. }),
  84. })
  85. child.Build()
  86. }
  87. }