...
1 package cview
2
3 import (
4 "math"
5 "sync"
6
7 "github.com/gdamore/tcell/v2"
8 )
9
10
11 type ProgressBar struct {
12 *Box
13
14
15 emptyRune rune
16
17
18 emptyColor tcell.Color
19
20
21 filledRune rune
22
23
24 filledColor tcell.Color
25
26
27
28 vertical bool
29
30
31 progress int
32
33
34 max int
35
36 sync.RWMutex
37 }
38
39
40 func NewProgressBar() *ProgressBar {
41 p := &ProgressBar{
42 Box: NewBox(),
43 emptyRune: tcell.RuneBlock,
44 emptyColor: Styles.PrimitiveBackgroundColor,
45 filledRune: tcell.RuneBlock,
46 filledColor: Styles.PrimaryTextColor,
47 max: 100,
48 }
49 p.SetBackgroundColor(Styles.PrimitiveBackgroundColor)
50 return p
51 }
52
53
54 func (p *ProgressBar) SetEmptyRune(empty rune) {
55 p.Lock()
56 defer p.Unlock()
57
58 p.emptyRune = empty
59 }
60
61
62 func (p *ProgressBar) SetEmptyColor(empty tcell.Color) {
63 p.Lock()
64 defer p.Unlock()
65
66 p.emptyColor = empty
67 }
68
69
70 func (p *ProgressBar) SetFilledRune(filled rune) {
71 p.Lock()
72 defer p.Unlock()
73
74 p.filledRune = filled
75 }
76
77
78 func (p *ProgressBar) SetFilledColor(filled tcell.Color) {
79 p.Lock()
80 defer p.Unlock()
81
82 p.filledColor = filled
83 }
84
85
86 func (p *ProgressBar) SetVertical(vertical bool) {
87 p.Lock()
88 defer p.Unlock()
89
90 p.vertical = vertical
91 }
92
93
94 func (p *ProgressBar) SetMax(max int) {
95 p.Lock()
96 defer p.Unlock()
97
98 p.max = max
99 }
100
101
102 func (p *ProgressBar) GetMax() int {
103 p.RLock()
104 defer p.RUnlock()
105
106 return p.max
107 }
108
109
110 func (p *ProgressBar) AddProgress(progress int) {
111 p.Lock()
112 defer p.Unlock()
113
114 p.progress += progress
115 if p.progress < 0 {
116 p.progress = 0
117 } else if p.progress > p.max {
118 p.progress = p.max
119 }
120 }
121
122
123 func (p *ProgressBar) SetProgress(progress int) {
124 p.Lock()
125 defer p.Unlock()
126
127 p.progress = progress
128 if p.progress < 0 {
129 p.progress = 0
130 } else if p.progress > p.max {
131 p.progress = p.max
132 }
133 }
134
135
136 func (p *ProgressBar) GetProgress() int {
137 p.RLock()
138 defer p.RUnlock()
139
140 return p.progress
141 }
142
143
144 func (p *ProgressBar) Complete() bool {
145 p.RLock()
146 defer p.RUnlock()
147
148 return p.progress >= p.max
149 }
150
151
152 func (p *ProgressBar) Draw(screen tcell.Screen) {
153 if !p.GetVisible() {
154 return
155 }
156
157 p.Box.Draw(screen)
158
159 p.Lock()
160 defer p.Unlock()
161
162 x, y, width, height := p.GetInnerRect()
163
164 barSize := height
165 maxLength := width
166 if p.vertical {
167 barSize = width
168 maxLength = height
169 }
170
171 barLength := int(math.RoundToEven(float64(maxLength) * (float64(p.progress) / float64(p.max))))
172 if barLength > maxLength {
173 barLength = maxLength
174 }
175
176 for i := 0; i < barSize; i++ {
177 for j := 0; j < barLength; j++ {
178 if p.vertical {
179 screen.SetContent(x+i, y+(height-1-j), p.filledRune, nil, tcell.StyleDefault.Foreground(p.filledColor).Background(p.backgroundColor))
180 } else {
181 screen.SetContent(x+j, y+i, p.filledRune, nil, tcell.StyleDefault.Foreground(p.filledColor).Background(p.backgroundColor))
182 }
183 }
184 for j := barLength; j < maxLength; j++ {
185 if p.vertical {
186 screen.SetContent(x+i, y+(height-1-j), p.emptyRune, nil, tcell.StyleDefault.Foreground(p.emptyColor).Background(p.backgroundColor))
187 } else {
188 screen.SetContent(x+j, y+i, p.emptyRune, nil, tcell.StyleDefault.Foreground(p.emptyColor).Background(p.backgroundColor))
189 }
190 }
191 }
192 }
193
View as plain text