gauge.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright 2017 Zack Guo <zack.y.guo@gmail.com>. All rights reserved.
  2. // Use of this source code is governed by a MIT license that can
  3. // be found in the LICENSE file.
  4. package termui
  5. import (
  6. "strconv"
  7. "strings"
  8. )
  9. // Gauge is a progress bar like widget.
  10. // A simple example:
  11. /*
  12. g := termui.NewGauge()
  13. g.Percent = 40
  14. g.Width = 50
  15. g.Height = 3
  16. g.BorderLabel = "Slim Gauge"
  17. g.BarColor = termui.ColorRed
  18. g.PercentColor = termui.ColorBlue
  19. */
  20. const ColorUndef Attribute = Attribute(^uint16(0))
  21. type Gauge struct {
  22. Block
  23. Percent int
  24. BarColor Attribute
  25. PercentColor Attribute
  26. PercentColorHighlighted Attribute
  27. Label string
  28. LabelAlign Align
  29. }
  30. // NewGauge return a new gauge with current theme.
  31. func NewGauge() *Gauge {
  32. g := &Gauge{
  33. Block: *NewBlock(),
  34. PercentColor: ThemeAttr("gauge.percent.fg"),
  35. BarColor: ThemeAttr("gauge.bar.bg"),
  36. Label: "{{percent}}%",
  37. LabelAlign: AlignCenter,
  38. PercentColorHighlighted: ColorUndef,
  39. }
  40. g.Width = 12
  41. g.Height = 5
  42. return g
  43. }
  44. // Buffer implements Bufferer interface.
  45. func (g *Gauge) Buffer() Buffer {
  46. buf := g.Block.Buffer()
  47. // plot bar
  48. w := g.Percent * g.innerArea.Dx() / 100
  49. for i := 0; i < g.innerArea.Dy(); i++ {
  50. for j := 0; j < w; j++ {
  51. c := Cell{}
  52. c.Ch = ' '
  53. c.Bg = g.BarColor
  54. if c.Bg == ColorDefault {
  55. c.Bg |= AttrReverse
  56. }
  57. buf.Set(g.innerArea.Min.X+j, g.innerArea.Min.Y+i, c)
  58. }
  59. }
  60. // plot percentage
  61. s := strings.Replace(g.Label, "{{percent}}", strconv.Itoa(g.Percent), -1)
  62. pry := g.innerArea.Min.Y + g.innerArea.Dy()/2
  63. rs := str2runes(s)
  64. var pos int
  65. switch g.LabelAlign {
  66. case AlignLeft:
  67. pos = 0
  68. case AlignCenter:
  69. pos = (g.innerArea.Dx() - strWidth(s)) / 2
  70. case AlignRight:
  71. pos = g.innerArea.Dx() - strWidth(s) - 1
  72. }
  73. pos += g.innerArea.Min.X
  74. for i, v := range rs {
  75. c := Cell{
  76. Ch: v,
  77. Fg: g.PercentColor,
  78. }
  79. if w+g.innerArea.Min.X > pos+i {
  80. c.Bg = g.BarColor
  81. if c.Bg == ColorDefault {
  82. c.Bg |= AttrReverse
  83. }
  84. if g.PercentColorHighlighted != ColorUndef {
  85. c.Fg = g.PercentColorHighlighted
  86. }
  87. } else {
  88. c.Bg = g.Block.Bg
  89. }
  90. buf.Set(1+pos+i, pry, c)
  91. }
  92. return buf
  93. }