diff --git a/ui/util/util.go b/ui/util/util.go index ced227d..4178b91 100644 --- a/ui/util/util.go +++ b/ui/util/util.go @@ -23,6 +23,37 @@ func SecondsToTimeString(s float64) string { return fmt.Sprintf("%d:%02d", min, sec) } +func BytesToSizeString(bytes int64) string { + var num float64 + var suffix string + switch b := float64(bytes); { + case b > 1000000000: + suffix = "GB" + num = b / 1000000000 + case b > 1000000: + suffix = "MB" + num = b / 1000000 + case b > 1000: + suffix = "KB" + num = b / 1000 + default: + suffix = "B" + num = b + } + return fmt.Sprintf(fmtStringForThreeSigFigs(num)+" %s", num, suffix) +} + +func fmtStringForThreeSigFigs(num float64) string { + switch { + case num >= 100: + return "%0.0f" + case num >= 10: + return "%0.1f" + default: + return "%0.2f" + } +} + func ImageAspect(im image.Image) float32 { b := im.Bounds() return float32(b.Max.X-b.Min.X) / float32(b.Max.Y-b.Min.Y) diff --git a/ui/widgets/tracklist.go b/ui/widgets/tracklist.go index 744988f..7e7130d 100644 --- a/ui/widgets/tracklist.go +++ b/ui/widgets/tracklist.go @@ -27,6 +27,7 @@ const ( ColumnFavorite = "Favorite" ColumnPlays = "Plays" ColumnBitrate = "Bitrate" + ColumnSize = "Size" ) type Tracklist struct { @@ -71,12 +72,12 @@ type Tracklist struct { } func NewTracklist(tracks []*subsonic.Child) *Tracklist { - t := &Tracklist{Tracks: tracks, nowPlayingIdx: -1, visibleColumns: make([]bool, 9)} + t := &Tracklist{Tracks: tracks, nowPlayingIdx: -1, visibleColumns: make([]bool, 10)} t.ExtendBaseWidget(t) t.selectionMgr = util.NewListSelectionManager(func() int { return len(t.Tracks) }) - // #, Title, Artist, Album, Time, Year, Favorite, Plays, Bitrate - t.colLayout = layouts.NewColumnsLayout([]float32{35, -1, -1, -1, 60, 60, 47, 65, 75}) + // #, Title, Artist, Album, Time, Year, Favorite, Plays, Bitrate, Size + t.colLayout = layouts.NewColumnsLayout([]float32{35, -1, -1, -1, 60, 60, 47, 65, 75, 70}) t.buildHeader() t.hdr.OnColumnVisibilityChanged = t.setColumnVisible t.hdr.OnColumnVisibilityMenuShown = func(pop *widget.PopUp) { @@ -118,7 +119,8 @@ func (t *Tracklist) buildHeader() { {Text: "Year", AlignTrailing: true, CanToggleVisible: true}, {Text: "Fav.", AlignTrailing: false, CanToggleVisible: true}, {Text: "Plays", AlignTrailing: true, CanToggleVisible: true}, - {Text: "Bitrate", AlignTrailing: true, CanToggleVisible: true}}, + {Text: "Bitrate", AlignTrailing: true, CanToggleVisible: true}, + {Text: "Size", AlignTrailing: true, CanToggleVisible: true}}, t.colLayout) } @@ -322,6 +324,8 @@ func ColNumber(colName string) int { return 7 case ColumnBitrate: return 8 + case ColumnSize: + return 9 default: log.Printf("error: Tracklist: invalid column name %s", colName) return -100 @@ -345,6 +349,8 @@ func colName(i int) string { return ColumnPlays case 8: return ColumnBitrate + case 9: + return ColumnSize default: return "" } @@ -373,6 +379,7 @@ type TrackRow struct { favorite *fyne.Container bitrate *widget.RichText plays *widget.RichText + size *widget.RichText OnTappedSecondary func(e *fyne.PointEvent, trackIdx int) @@ -401,9 +408,11 @@ func NewTrackRow(tracklist *Tracklist, playingIcon fyne.CanvasObject) *TrackRow t.plays.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignTrailing t.bitrate = widget.NewRichTextWithText("") t.bitrate.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignTrailing + t.size = widget.NewRichTextWithText("") + t.size.Segments[0].(*widget.TextSegment).Style.Alignment = fyne.TextAlignTrailing t.Content = container.New(tracklist.colLayout, - t.num, t.name, t.artist, t.album, t.dur, t.year, t.favorite, t.plays, t.bitrate) + t.num, t.name, t.artist, t.album, t.dur, t.year, t.favorite, t.plays, t.bitrate, t.size) return t } @@ -426,6 +435,7 @@ func (t *TrackRow) Update(tr *subsonic.Child, isPlaying bool, rowNum int) { t.year.Segments[0].(*widget.TextSegment).Text = strconv.Itoa(tr.Year) t.plays.Segments[0].(*widget.TextSegment).Text = strconv.Itoa(int(tr.PlayCount)) t.bitrate.Segments[0].(*widget.TextSegment).Text = strconv.Itoa(tr.BitRate) + t.size.Segments[0].(*widget.TextSegment).Text = util.BytesToSizeString(tr.Size) } // Update track num if needed @@ -452,6 +462,7 @@ func (t *TrackRow) Update(tr *subsonic.Child, isPlaying bool, rowNum int) { t.year.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying t.plays.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying t.bitrate.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying + t.size.Segments[0].(*widget.TextSegment).Style.TextStyle.Bold = isPlaying if isPlaying { t.Content.(*fyne.Container).Objects[0] = container.NewCenter(t.playingIcon) @@ -483,6 +494,7 @@ func (t *TrackRow) Update(tr *subsonic.Child, isPlaying bool, rowNum int) { t.favorite.Hidden = !t.tracklist.visibleColumns[ColNumber(ColumnFavorite)] t.plays.Hidden = !t.tracklist.visibleColumns[ColNumber(ColumnPlays)] t.bitrate.Hidden = !t.tracklist.visibleColumns[ColNumber(ColumnBitrate)] + t.size.Hidden = !t.tracklist.visibleColumns[ColNumber(ColumnSize)] t.Refresh() }