New progressBar Primitive

Previous Implementation of progressBar wasn't clean and for a long time
I wanted to make progressBar a Primitive. Which also makes it project
agnostic.

Following changes have been made:

1. Moved `utils.GetText` to `ui.GetProgressGlyph` (As it had no use other
   than for the progressBar
2. Removed the old Implementation of progressBar

How progressBar works as of right now:

All the Values for the progressBar are provided through the
ProgressFunction()

The ProgressFunction should return
Title (Bar's Title), TopText (Box's Title), BarText (The Text Inside the
progressBar), Percentage(Float64 representing the progress Percentage)
This commit is contained in:
aditya-K2 2022-08-29 17:36:36 +05:30
parent 429db5b1e7
commit d7044c48b1
3 changed files with 73 additions and 77 deletions

View File

@ -17,13 +17,14 @@ type Application struct {
ExpandedView *tview.Table ExpandedView *tview.Table
Navbar *tview.Table Navbar *tview.Table
SearchBar *tview.InputField SearchBar *tview.InputField
ProgressBar *progressBar ProgressBar *ProgressBar
Pages *tview.Pages Pages *tview.Pages
} }
func NewApplication() *Application { func NewApplication() *Application {
var pBar *progressBar = newProgressBar() pBar := NewProgressBar()
pBar.SetProgressFunc(progressFunction)
expandedView := tview.NewTable() expandedView := tview.NewTable()
Navbar := tview.NewTable() Navbar := tview.NewTable()
searchBar := tview.NewInputField() searchBar := tview.NewInputField()
@ -67,7 +68,7 @@ func NewApplication() *Application {
MainFlex := tview.NewFlex().SetDirection(tview.FlexRow). MainFlex := tview.NewFlex().SetDirection(tview.FlexRow).
AddItem(searchBarFlex, 0, 8, false). AddItem(searchBarFlex, 0, 8, false).
AddItem(pBar.t, 5, 1, false) AddItem(pBar, 5, 1, false)
expandedView.SetBorderPadding(1, 1, 1, 1).SetBorder(true) expandedView.SetBorderPadding(1, 1, 1, 1).SetBorder(true)
expandedView.SetSelectable(true, false) expandedView.SetSelectable(true, false)

View File

@ -3,17 +3,17 @@ package ui
import ( import (
"fmt" "fmt"
"strconv" "strconv"
"strings"
"github.com/fhs/gompd/mpd" "github.com/fhs/gompd/mpd"
"github.com/gdamore/tcell/v2"
"github.com/aditya-K2/gomp/utils" "github.com/aditya-K2/gomp/utils"
"github.com/aditya-K2/tview" "github.com/aditya-K2/tview"
"github.com/gdamore/tcell/v2"
) )
var ( var (
CurrentSong string CurrentSong string = ""
CONN *mpd.Client CONN *mpd.Client
RENDERER interface{ Send(string) } RENDERER interface{ Send(string) }
) )
@ -26,48 +26,63 @@ func ConnectRenderer(r interface{ Send(string) }) {
RENDERER = r RENDERER = r
} }
// The progressBar is just a string which is separated by the color formatting String type ProgressBar struct {
// for e.g *tview.Box
// "[:#fbff00:]******************`innerText`[-:-:-] " BarTitle string
// the above string shows represents the progress until [-:-:-] BarText string
// [-:-:-] this string represents resetting colors so the substring before it would be with a BarTopTitle string
// colored background. this is done by calculating the innerRect of the table and taking that length as progressFunc func() (string, string, string, float64)
// 100% and then representing the rest of the information in relation to it
type progressBar struct {
t *tview.Table
} }
// This Function returns a progressBar with a table of two rows func (self *ProgressBar) SetProgressFunc(pfunc func() (string, string, string, float64)) *ProgressBar {
// the First row will contain information about the current Song self.progressFunc = pfunc
// and the Second one will contain the progressBar return self
func newProgressBar() *progressBar {
p := progressBar{}
a := tview.NewTable().
SetCell(0, 0, tview.NewTableCell("")).
SetCell(1, 0, tview.NewTableCell("")).
SetCell(2, 0, tview.NewTableCell(""))
a.SetBackgroundColor(tcell.ColorDefault)
a.SetBorder(true)
a.SetDrawFunc(func(s tcell.Screen, x, y, width, height int) (int, int, int, int) {
p.updateTitle()
p.updateProgress()
return p.t.GetInnerRect()
})
CurrentSong = ""
p = progressBar{a}
return &p
} }
func (s *progressBar) updateTitle() { func NewProgressBar() *ProgressBar {
return &ProgressBar{
Box: tview.NewBox(),
}
}
func GetProgressGlyph(width, percentage float64, btext string) string {
q := "[black:white:b]"
var a string
a += strings.Repeat(" ", int(width)-len(btext))
a = utils.InsertAt(a, btext, int(width/2)-10)
a = utils.InsertAt(a, "[-:-:-]", int(width*percentage/100))
q += a
return q
}
func (self *ProgressBar) Draw(screen tcell.Screen) {
var (
OFFSET int = 1
)
self.Box.SetBorder(true)
self.Box.SetBackgroundColor(tcell.ColorDefault)
var percentage float64
self.BarTitle, self.BarTopTitle, self.BarText, percentage = self.progressFunc()
self.DrawForSubclass(screen, self.Box)
self.Box.SetTitle(self.BarTopTitle)
self.Box.SetTitleAlign(tview.AlignRight)
x, y, _width, _ := self.Box.GetInnerRect()
tview.Print(screen, self.BarTitle, x+OFFSET, y, _width, tview.AlignLeft, tcell.ColorWhite)
tview.Print(screen,
GetProgressGlyph(float64(_width-OFFSET-1),
percentage,
self.BarText),
x, y+2, _width-OFFSET, tview.AlignRight, tcell.ColorWhite)
}
func progressFunction() (string, string, string, float64) {
_currentAttributes, err := CONN.CurrentSong() _currentAttributes, err := CONN.CurrentSong()
var song, top, text string
var percentage float64
if err == nil { if err == nil {
song := "[green::bi]" + _currentAttributes["Title"] + "[-:-:-] - " + "[blue::b]" + _currentAttributes["Artist"] + "\n" song = "[green::bi]" +
s.t.GetCell(0, 0).Text = song _currentAttributes["Title"] + "[-:-:-] - " + "[blue::b]" +
_currentAttributes["Artist"] + "\n"
if len(_currentAttributes) == 0 && CurrentSong != "" { if len(_currentAttributes) == 0 && CurrentSong != "" {
CurrentSong = "" CurrentSong = ""
RENDERER.Send("stop") RENDERER.Send("stop")
@ -75,39 +90,29 @@ func (s *progressBar) updateTitle() {
RENDERER.Send(_currentAttributes["file"]) RENDERER.Send(_currentAttributes["file"])
CurrentSong = song CurrentSong = song
} }
} else {
utils.Print("RED", "Error Retrieving Current Song\n")
panic(err)
} }
}
func (s *progressBar) updateProgress() {
_status, err := CONN.Status() _status, err := CONN.Status()
_, _, _width, _ := s.t.GetInnerRect()
el, err1 := strconv.ParseFloat(_status["elapsed"], 8) el, err1 := strconv.ParseFloat(_status["elapsed"], 8)
du, err := strconv.ParseFloat(_status["duration"], 8) du, err := strconv.ParseFloat(_status["duration"], 8)
top = fmt.Sprintf("[[::i] %s [-:-:-]Shuffle: %s Repeat: %s Volume: %s ]",
utils.FormatString(_status["state"]),
utils.FormatString(_status["random"]),
utils.FormatString(_status["repeat"]),
_status["volume"])
if du != 0 { if du != 0 {
percentage := el / du * 100 percentage = el / du * 100
if err == nil && err1 == nil { if err == nil && err1 == nil {
s.t.SetTitle(fmt.Sprintf("[[::i] %s [-:-:-]Shuffle: %s Repeat: %s Volume: %s ]", text = utils.StrTime(el) + "/" + utils.StrTime(du) +
utils.FormatString(_status["state"]), "(" + strconv.FormatFloat(percentage, 'f', 2, 32) + "%" + ")"
utils.FormatString(_status["random"]),
utils.FormatString(_status["repeat"]),
_status["volume"])).
SetTitleAlign(tview.AlignRight)
s.t.GetCell(2, 0).Text = utils.GetText(float64(_width), percentage, utils.StrTime(el)+"/"+utils.StrTime(du)+"("+strconv.FormatFloat(percentage, 'f', 2, 32)+"%"+")")
} else { } else {
s.t.SetTitle(fmt.Sprintf("[[::i] %s [-:-:-]Shuffle: %s Repeat: %s]", text = ""
utils.FormatString(_status["state"]),
utils.FormatString(_status["random"]),
utils.FormatString(_status["repeat"]))).
SetTitleAlign(tview.AlignRight)
s.t.GetCell(2, 0).Text = ""
} }
} else { } else {
s.t.SetTitle(fmt.Sprintf("[[::i] %s [-:-:-]Shuffle: %s Repeat: %s Volume: %s ]", text = " ---:---"
utils.FormatString(_status["state"]), percentage = 0
utils.FormatString(_status["random"]),
utils.FormatString(_status["repeat"]),
_status["volume"])).
SetTitleAlign(tview.AlignRight)
s.t.GetCell(2, 0).Text = utils.GetText(float64(_width), 0, " ---:---")
} }
return song, top, text, percentage
} }

View File

@ -58,16 +58,6 @@ func InsertAt(inputString, stringTobeInserted string, index int) string {
return s return s
} }
func GetText(width, percentage float64, eta string) string {
q := "[black:white:b]"
var a string
a += strings.Repeat(" ", int(width)-len(eta))
a = InsertAt(a, eta, int(width/2)-10)
a = InsertAt(a, "[-:-:-]", int(width*percentage/100))
q += a
return q
}
func ConvertToArray(ArtistTree map[string]map[string]map[string]string) []string { func ConvertToArray(ArtistTree map[string]map[string]map[string]string) []string {
var p []string var p []string
for k2, v := range ArtistTree { for k2, v := range ArtistTree {