From d7044c48b15cbe98027eb1a3c8e2c436c4cc373a Mon Sep 17 00:00:00 2001 From: aditya-K2 Date: Mon, 29 Aug 2022 17:36:36 +0530 Subject: [PATCH] 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) --- ui/app.go | 7 +-- ui/progressBar.go | 133 ++++++++++++++++++++++++---------------------- utils/utils.go | 10 ---- 3 files changed, 73 insertions(+), 77 deletions(-) diff --git a/ui/app.go b/ui/app.go index dcc7d45..4d31ddc 100644 --- a/ui/app.go +++ b/ui/app.go @@ -17,13 +17,14 @@ type Application struct { ExpandedView *tview.Table Navbar *tview.Table SearchBar *tview.InputField - ProgressBar *progressBar + ProgressBar *ProgressBar Pages *tview.Pages } func NewApplication() *Application { - var pBar *progressBar = newProgressBar() + pBar := NewProgressBar() + pBar.SetProgressFunc(progressFunction) expandedView := tview.NewTable() Navbar := tview.NewTable() searchBar := tview.NewInputField() @@ -67,7 +68,7 @@ func NewApplication() *Application { MainFlex := tview.NewFlex().SetDirection(tview.FlexRow). 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.SetSelectable(true, false) diff --git a/ui/progressBar.go b/ui/progressBar.go index 103db80..1905bba 100644 --- a/ui/progressBar.go +++ b/ui/progressBar.go @@ -3,17 +3,17 @@ package ui import ( "fmt" "strconv" + "strings" "github.com/fhs/gompd/mpd" + "github.com/gdamore/tcell/v2" "github.com/aditya-K2/gomp/utils" - "github.com/aditya-K2/tview" - "github.com/gdamore/tcell/v2" ) var ( - CurrentSong string + CurrentSong string = "" CONN *mpd.Client RENDERER interface{ Send(string) } ) @@ -26,48 +26,63 @@ func ConnectRenderer(r interface{ Send(string) }) { RENDERER = r } -// The progressBar is just a string which is separated by the color formatting String -// for e.g -// "[:#fbff00:]******************`innerText`[-:-:-] " -// the above string shows represents the progress until [-:-:-] -// [-:-:-] this string represents resetting colors so the substring before it would be with a -// colored background. this is done by calculating the innerRect of the table and taking that length as -// 100% and then representing the rest of the information in relation to it -type progressBar struct { - t *tview.Table +type ProgressBar struct { + *tview.Box + BarTitle string + BarText string + BarTopTitle string + progressFunc func() (string, string, string, float64) } -// This Function returns a progressBar with a table of two rows -// the First row will contain information about the current Song -// and the Second one will contain the progressBar -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 (self *ProgressBar) SetProgressFunc(pfunc func() (string, string, string, float64)) *ProgressBar { + self.progressFunc = pfunc + return self } -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() + var song, top, text string + var percentage float64 if err == nil { - song := "[green::bi]" + _currentAttributes["Title"] + "[-:-:-] - " + "[blue::b]" + _currentAttributes["Artist"] + "\n" - s.t.GetCell(0, 0).Text = song + song = "[green::bi]" + + _currentAttributes["Title"] + "[-:-:-] - " + "[blue::b]" + + _currentAttributes["Artist"] + "\n" if len(_currentAttributes) == 0 && CurrentSong != "" { CurrentSong = "" RENDERER.Send("stop") @@ -75,39 +90,29 @@ func (s *progressBar) updateTitle() { RENDERER.Send(_currentAttributes["file"]) CurrentSong = song } + } else { + utils.Print("RED", "Error Retrieving Current Song\n") + panic(err) } -} - -func (s *progressBar) updateProgress() { _status, err := CONN.Status() - _, _, _width, _ := s.t.GetInnerRect() el, err1 := strconv.ParseFloat(_status["elapsed"], 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 { - percentage := el / du * 100 + percentage = el / du * 100 if err == nil && err1 == nil { - s.t.SetTitle(fmt.Sprintf("[[::i] %s [-:-:-]Shuffle: %s Repeat: %s Volume: %s ]", - utils.FormatString(_status["state"]), - 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)+"%"+")") + text = utils.StrTime(el) + "/" + utils.StrTime(du) + + "(" + strconv.FormatFloat(percentage, 'f', 2, 32) + "%" + ")" } else { - s.t.SetTitle(fmt.Sprintf("[[::i] %s [-:-:-]Shuffle: %s Repeat: %s]", - utils.FormatString(_status["state"]), - utils.FormatString(_status["random"]), - utils.FormatString(_status["repeat"]))). - SetTitleAlign(tview.AlignRight) - s.t.GetCell(2, 0).Text = "" + text = "" } } else { - s.t.SetTitle(fmt.Sprintf("[[::i] %s [-:-:-]Shuffle: %s Repeat: %s Volume: %s ]", - utils.FormatString(_status["state"]), - utils.FormatString(_status["random"]), - utils.FormatString(_status["repeat"]), - _status["volume"])). - SetTitleAlign(tview.AlignRight) - s.t.GetCell(2, 0).Text = utils.GetText(float64(_width), 0, " ---:---") + text = " ---:---" + percentage = 0 } + return song, top, text, percentage } diff --git a/utils/utils.go b/utils/utils.go index 1bf3f30..95db7bf 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -58,16 +58,6 @@ func InsertAt(inputString, stringTobeInserted string, index int) string { 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 { var p []string for k2, v := range ArtistTree {