mirror of
https://github.com/navidys/tvxwidgets.git
synced 2025-04-26 13:48:49 +08:00
Add spinner widget.
Signed-off-by: Andreas Krennmair <ak@synflood.at>
This commit is contained in:
parent
02e3c8f9d9
commit
f1d2fee386
@ -56,3 +56,4 @@ func main() {
|
||||
* percentage mode gauge
|
||||
* utilisation mode gauge
|
||||
* message dialog (info and error)
|
||||
* spinner
|
||||
|
1
demos/spinner/README.md
Normal file
1
demos/spinner/README.md
Normal file
@ -0,0 +1 @@
|
||||

|
67
demos/spinner/main.go
Normal file
67
demos/spinner/main.go
Normal file
@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/navidys/tvxwidgets"
|
||||
"github.com/rivo/tview"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := tview.NewApplication()
|
||||
grid := tview.NewGrid()
|
||||
grid.SetBorder(true).SetTitle("Spinners")
|
||||
|
||||
spinners := [][]*tvxwidgets.Spinner{
|
||||
{
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerDotsCircling),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerDotsUpDown),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerBounce),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerLine),
|
||||
},
|
||||
{
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerCircleQuarters),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerSquareCorners),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerCircleHalves),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerCorners),
|
||||
},
|
||||
{
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerArrows),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerHamburger),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerStack),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerStar),
|
||||
},
|
||||
{
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerGrowHorizontal),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerGrowVertical),
|
||||
tvxwidgets.NewSpinner().SetStyle(tvxwidgets.SpinnerBoxBounce),
|
||||
tvxwidgets.NewSpinner().SetCustomStyle([]rune{'🕛', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚'}),
|
||||
},
|
||||
}
|
||||
|
||||
for rowIdx, row := range spinners {
|
||||
for colIdx, spinner := range row {
|
||||
grid.AddItem(spinner, rowIdx, colIdx, 1, 1, 1, 1, false)
|
||||
}
|
||||
}
|
||||
|
||||
update := func() {
|
||||
tick := time.NewTicker(100 * time.Millisecond)
|
||||
for {
|
||||
select {
|
||||
case <-tick.C:
|
||||
for _, row := range spinners {
|
||||
for _, spinner := range row {
|
||||
spinner.Pulse()
|
||||
}
|
||||
}
|
||||
app.Draw()
|
||||
}
|
||||
}
|
||||
}
|
||||
go update()
|
||||
|
||||
if err := app.SetRoot(grid, false).EnableMouse(true).Run(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
BIN
demos/spinner/screenshot.png
Normal file
BIN
demos/spinner/screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
101
spinner.go
Normal file
101
spinner.go
Normal file
@ -0,0 +1,101 @@
|
||||
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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user