cview/progressbar.go

177 lines
3.9 KiB
Go
Raw Normal View History

2020-01-17 00:53:51 +00:00
package cview
import (
"math"
"sync"
"github.com/gdamore/tcell"
)
// ProgressBar indicates the progress of an operation.
type ProgressBar struct {
*Box
// Rune to use when rendering the empty area of the progress bar.
2020-03-26 15:54:12 +00:00
emptyRune rune
2020-01-17 00:53:51 +00:00
// Color of the empty area of the progress bar.
2020-03-26 15:54:12 +00:00
emptyColor tcell.Color
2020-01-17 00:53:51 +00:00
// Rune to use when rendering the filled area of the progress bar.
2020-03-26 15:54:12 +00:00
filledRune rune
2020-01-17 00:53:51 +00:00
// Color of the filled area of the progress bar.
2020-03-26 15:54:12 +00:00
filledColor tcell.Color
2020-01-17 00:53:51 +00:00
// If set to true, instead of filling from left to right, the bar is filled
// from bottom to top.
2020-03-26 15:54:12 +00:00
vertical bool
2020-01-17 00:53:51 +00:00
2020-03-26 15:54:12 +00:00
// Current progress.
2020-01-17 00:53:51 +00:00
progress int
2020-03-25 14:32:57 +00:00
2020-03-26 15:54:12 +00:00
// Progress required to fill the bar.
max int
sync.RWMutex
2020-01-17 00:53:51 +00:00
}
// NewProgressBar returns a new progress bar.
func NewProgressBar() *ProgressBar {
return &ProgressBar{
2020-02-22 18:14:57 +00:00
Box: NewBox().SetBackgroundColor(Styles.PrimitiveBackgroundColor),
2020-03-26 15:54:12 +00:00
emptyRune: ' ',
emptyColor: Styles.PrimitiveBackgroundColor,
filledRune: tcell.RuneBlock,
filledColor: Styles.PrimaryTextColor,
2020-01-17 00:53:51 +00:00
max: 100,
}
}
2020-03-26 15:54:12 +00:00
// SetEmptyRune sets the rune used for the empty area of the progress bar.
func (p *ProgressBar) SetEmptyRune(empty rune) {
p.Lock()
defer p.Unlock()
p.emptyRune = empty
}
// SetEmptyColor sets the color of the empty area of the progress bar.
func (p *ProgressBar) SetEmptyColor(empty tcell.Color) {
p.Lock()
defer p.Unlock()
p.emptyColor = empty
}
// SetFilledRune sets the rune used for the filled area of the progress bar.
func (p *ProgressBar) SetFilledRune(filled rune) {
p.Lock()
defer p.Unlock()
p.filledRune = filled
}
// SetFilledColor sets the color of the filled area of the progress bar.
func (p *ProgressBar) SetFilledColor(filled tcell.Color) {
p.Lock()
defer p.Unlock()
p.filledColor = filled
}
// SetVertical sets the direction of the progress bar.
func (p *ProgressBar) SetVertical(vertical bool) {
p.Lock()
defer p.Unlock()
p.vertical = vertical
}
2020-01-17 00:53:51 +00:00
// SetMax sets the progress required to fill the bar.
func (p *ProgressBar) SetMax(max int) {
p.Lock()
defer p.Unlock()
p.max = max
}
// GetMax returns the progress required to fill the bar.
func (p *ProgressBar) GetMax() int {
p.RLock()
defer p.RUnlock()
2020-01-17 00:53:51 +00:00
return p.max
}
// AddProgress adds to the current progress.
func (p *ProgressBar) AddProgress(progress int) {
p.Lock()
defer p.Unlock()
p.progress += progress
}
// SetProgress sets the current progress.
func (p *ProgressBar) SetProgress(progress int) {
p.Lock()
defer p.Unlock()
p.progress = progress
}
// GetProgress gets the current progress.
func (p *ProgressBar) GetProgress() int {
p.RLock()
defer p.RUnlock()
2020-01-17 00:53:51 +00:00
return p.progress
}
// Complete returns whether the progress bar has been filled.
func (p *ProgressBar) Complete() bool {
p.RLock()
defer p.RUnlock()
2020-01-17 00:53:51 +00:00
return p.progress >= p.max
}
// Draw draws this primitive onto the screen.
func (p *ProgressBar) Draw(screen tcell.Screen) {
2020-03-25 14:32:57 +00:00
p.Box.Draw(screen)
2020-01-17 00:53:51 +00:00
p.Lock()
defer p.Unlock()
x, y, width, height := p.GetInnerRect()
barSize := height
maxLength := width
2020-03-26 15:54:12 +00:00
if p.vertical {
2020-01-17 00:53:51 +00:00
barSize = width
maxLength = height
}
barLength := int(math.RoundToEven(float64(maxLength) * (float64(p.progress) / float64(p.max))))
if barLength > maxLength {
barLength = maxLength
}
for i := 0; i < barSize; i++ {
for j := 0; j < barLength; j++ {
2020-03-26 15:54:12 +00:00
if p.vertical {
screen.SetContent(x+i, y+(height-1-j), p.filledRune, nil, tcell.StyleDefault.Foreground(p.filledColor).Background(p.backgroundColor))
2020-01-17 00:53:51 +00:00
} else {
2020-03-26 15:54:12 +00:00
screen.SetContent(x+j, y+i, p.filledRune, nil, tcell.StyleDefault.Foreground(p.filledColor).Background(p.backgroundColor))
2020-01-17 00:53:51 +00:00
}
}
for j := barLength; j < maxLength; j++ {
2020-03-26 15:54:12 +00:00
if p.vertical {
screen.SetContent(x+i, y+(height-1-j), p.emptyRune, nil, tcell.StyleDefault.Foreground(p.emptyColor).Background(p.backgroundColor))
2020-01-17 00:53:51 +00:00
} else {
2020-03-26 15:54:12 +00:00
screen.SetContent(x+j, y+i, p.emptyRune, nil, tcell.StyleDefault.Foreground(p.emptyColor).Background(p.backgroundColor))
2020-01-17 00:53:51 +00:00
}
}
}
}