-
Notifications
You must be signed in to change notification settings - Fork 12
/
spinner.go
103 lines (87 loc) · 2.67 KB
/
spinner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package tvxwidgets
import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
)
// Spinner represents a spinner widget.
type Spinner struct {
*tview.Box
counter int
currentStyle SpinnerStyle
styles map[SpinnerStyle][]rune
}
type SpinnerStyle int
const (
SpinnerDotsCircling SpinnerStyle = iota
SpinnerDotsUpDown
SpinnerBounce
SpinnerLine
SpinnerCircleQuarters
SpinnerSquareCorners
SpinnerCircleHalves
SpinnerCorners
SpinnerArrows
SpinnerHamburger
SpinnerStack
SpinnerGrowHorizontal
SpinnerGrowVertical
SpinnerStar
SpinnerBoxBounce
spinnerCustom // non-public constant to indicate that a custom style has been set by the user.
)
// NewSpinner returns a new spinner widget.
func NewSpinner() *Spinner {
return &Spinner{
Box: tview.NewBox(),
currentStyle: SpinnerDotsCircling,
styles: map[SpinnerStyle][]rune{
SpinnerDotsCircling: []rune(`⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏`),
SpinnerDotsUpDown: []rune(`⠋⠙⠚⠞⠖⠦⠴⠲⠳⠓`),
SpinnerBounce: []rune(`⠄⠆⠇⠋⠙⠸⠰⠠⠰⠸⠙⠋⠇⠆`),
SpinnerLine: []rune(`|/-\`),
SpinnerCircleQuarters: []rune(`◴◷◶◵`),
SpinnerSquareCorners: []rune(`◰◳◲◱`),
SpinnerCircleHalves: []rune(`◐◓◑◒`),
SpinnerCorners: []rune(`⌜⌝⌟⌞`),
SpinnerArrows: []rune(`⇑⇗⇒⇘⇓⇙⇐⇖`),
SpinnerHamburger: []rune(`☰☱☳☷☶☴`),
SpinnerStack: []rune(`䷀䷪䷡䷊䷒䷗䷁䷖䷓䷋䷠䷫`),
SpinnerGrowHorizontal: []rune(`▉▊▋▌▍▎▏▎▍▌▋▊▉`),
SpinnerGrowVertical: []rune(`▁▃▄▅▆▇▆▅▄▃`),
SpinnerStar: []rune(`✶✸✹✺✹✷`),
SpinnerBoxBounce: []rune(`▌▀▐▄`),
},
}
}
// Draw draws this primitive onto the screen.
func (s *Spinner) Draw(screen tcell.Screen) {
s.Box.DrawForSubclass(screen, s)
x, y, width, _ := s.Box.GetInnerRect()
tview.Print(screen, s.getCurrentFrame(), x, y, width, tview.AlignLeft, tcell.ColorDefault)
}
// Pulse updates the spinner to the next frame.
func (s *Spinner) Pulse() {
s.counter++
}
// Reset sets the frame counter to 0.
func (s *Spinner) Reset() {
s.counter = 0
}
// SetStyle sets the spinner style.
func (s *Spinner) SetStyle(style SpinnerStyle) *Spinner {
s.currentStyle = style
return s
}
func (s *Spinner) getCurrentFrame() string {
frames := s.styles[s.currentStyle]
if len(frames) == 0 {
return ""
}
return string(frames[s.counter%len(frames)])
}
// SetCustomStyle sets a list of runes as custom frames to show as the spinner.
func (s *Spinner) SetCustomStyle(frames []rune) *Spinner {
s.styles[spinnerCustom] = frames
s.currentStyle = spinnerCustom
return s
}