diff options
Diffstat (limited to 'widgets/spinner.go')
-rw-r--r-- | widgets/spinner.go | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/widgets/spinner.go b/widgets/spinner.go new file mode 100644 index 0000000..2e7e367 --- /dev/null +++ b/widgets/spinner.go @@ -0,0 +1,80 @@ +package widgets + +import ( + "time" + + "github.com/gdamore/tcell" + + "git.sr.ht/~sircmpwn/aerc2/lib/ui" +) + +var ( + frames = []string{ + "[..] ", + " [..] ", + " [..] ", + " [..] ", + " [..]", + " [..] ", + " [..] ", + " [..] ", + } +) + +type Spinner struct { + frame int + onInvalidate func(d ui.Drawable) + stop chan interface{} +} + +func NewSpinner() *Spinner { + spinner := Spinner{ + stop: make(chan interface{}), + frame: -1, + } + return &spinner +} + +func (s *Spinner) Start() { + s.frame = 0 + go func() { + for { + select { + case <-s.stop: + return + case <-time.After(200 * time.Millisecond): + s.frame++ + if s.frame >= len(frames) { + s.frame = 0 + } + s.Invalidate() + } + } + }() +} + +func (s *Spinner) Stop() { + s.stop <- nil + s.frame = -1 + s.Invalidate() +} + +func (s *Spinner) IsRunning() bool { + return s.frame != -1 +} + +func (s *Spinner) Draw(ctx *ui.Context) { + ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', tcell.StyleDefault) + col := ctx.Width()/2 - len(frames[0])/2 + 1 + ctx.Printf(col, 0, tcell.StyleDefault, "%s", frames[s.frame]) +} + +func (s *Spinner) OnInvalidate(onInvalidate func(d ui.Drawable)) { + s.onInvalidate = onInvalidate +} + +func (s *Spinner) Invalidate() { + if s.onInvalidate != nil { + s.onInvalidate(s) + } +} |