From c4dba8f1fb6f50c7c741ba0ea0f9c179638f2693 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Mon, 20 Feb 2023 17:14:56 -0800 Subject: [PATCH] beginning work on browse by favorite artists and songs --- ui/browsing/favoritespage.go | 36 ++++++++++++++----- ui/layouts/hboxcustompadding.go | 58 ++++++++++++++++++++++++++++++ ui/widgets/togglebuttongroup.go | 64 +++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 8 deletions(-) create mode 100644 ui/layouts/hboxcustompadding.go create mode 100644 ui/widgets/togglebuttongroup.go diff --git a/ui/browsing/favoritespage.go b/ui/browsing/favoritespage.go index 9d015c1..6b040b2 100644 --- a/ui/browsing/favoritespage.go +++ b/ui/browsing/favoritespage.go @@ -1,7 +1,9 @@ package browsing import ( + "log" "supersonic/backend" + "supersonic/res" "supersonic/ui/widgets" "time" @@ -26,6 +28,7 @@ type FavoritesPage struct { searcher *widgets.Searcher searchText string titleDisp *widget.RichText + toggleBtns *widgets.ToggleButtonGroup container *fyne.Container } @@ -46,6 +49,7 @@ func NewFavoritesPage(sm *backend.ServerManager, pm *backend.PlaybackManager, lm a.grid.OnShowArtistPage = a.onShowArtistPage a.searcher = widgets.NewSearcher() a.searcher.OnSearched = a.OnSearched + a.createToggleButtons(0) a.createContainer(false) return a } @@ -57,6 +61,19 @@ func (a *FavoritesPage) createTitle() { } } +func (a *FavoritesPage) createToggleButtons(activeBtnIdx int) { + a.toggleBtns = widgets.NewToggleButtonGroup(activeBtnIdx, + widget.NewButtonWithIcon("", res.ResDiscInvertPng, func() { + log.Println("albums activated") + }), + widget.NewButtonWithIcon("", res.ResPeopleInvertPng, func() { + log.Println("artists activated") + }), + widget.NewButtonWithIcon("", res.ResMusicnotesInvertPng, func() { + log.Println("songs activated") + })) +} + func (a *FavoritesPage) createContainer(searchGrid bool) { searchVbox := container.NewVBox(layout.NewSpacer(), a.searcher.Entry, layout.NewSpacer()) gr := a.grid @@ -64,7 +81,7 @@ func (a *FavoritesPage) createContainer(searchGrid bool) { gr = a.searchGrid } a.container = container.NewBorder( - container.NewHBox(widgets.NewHSpace(9), a.titleDisp, layout.NewSpacer(), searchVbox, widgets.NewHSpace(15)), + container.NewHBox(widgets.NewHSpace(9), a.titleDisp, container.NewCenter(a.toggleBtns), layout.NewSpacer(), searchVbox, widgets.NewHSpace(15)), nil, nil, nil, gr) } @@ -88,6 +105,7 @@ func restoreFavoritesPage(saved *savedFavoritesPage) *FavoritesPage { if saved.searchText != "" { a.searchGrid = widgets.NewAlbumGridFromState(saved.searchGridState) } + a.createToggleButtons(saved.activeToggleBtn) a.createContainer(saved.searchText != "") return a @@ -107,13 +125,14 @@ func (a *FavoritesPage) Reload() { func (a *FavoritesPage) Save() SavedPage { sf := &savedFavoritesPage{ - pm: a.pm, - sm: a.sm, - im: a.im, - lm: a.lm, - nav: a.nav, - searchText: a.searchText, - gridState: a.grid.SaveToState(), + pm: a.pm, + sm: a.sm, + im: a.im, + lm: a.lm, + nav: a.nav, + searchText: a.searchText, + gridState: a.grid.SaveToState(), + activeToggleBtn: a.toggleBtns.ActivatedButtonIndex(), } if a.searchGrid != nil { sf.searchGridState = a.searchGrid.SaveToState() @@ -181,6 +200,7 @@ type savedFavoritesPage struct { gridState widgets.AlbumGridState searchGridState widgets.AlbumGridState searchText string + activeToggleBtn int nav func(Route) } diff --git a/ui/layouts/hboxcustompadding.go b/ui/layouts/hboxcustompadding.go new file mode 100644 index 0000000..cedac3c --- /dev/null +++ b/ui/layouts/hboxcustompadding.go @@ -0,0 +1,58 @@ +package layouts + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/theme" +) + +var _ fyne.Layout = (*VboxCustomPadding)(nil) + +type HboxCustomPadding struct { + ExtraPad float32 + DisableThemePad bool +} + +func (v *HboxCustomPadding) MinSize(objects []fyne.CanvasObject) fyne.Size { + minSize := fyne.NewSize(0, 0) + for _, child := range objects { + if !child.Visible() { + continue + } + + minSize.Height = fyne.Max(child.MinSize().Height, minSize.Height) + minSize.Width += child.MinSize().Width + } + minSize.Width += (v.themePad() + v.ExtraPad) * float32(len(objects)-1) + return minSize +} + +func (v *HboxCustomPadding) Layout(objects []fyne.CanvasObject, size fyne.Size) { + total := float32(0) + for _, child := range objects { + if !child.Visible() { + continue + } + total += child.MinSize().Width + } + + x, y := float32(0), float32(0) + + extra := float32(0) + for _, child := range objects { + if !child.Visible() { + continue + } + width := child.MinSize().Width + child.Move(fyne.NewPos(x+extra, y)) + x += width + child.Resize(fyne.NewSize(width, size.Height)) + extra += (v.themePad() + v.ExtraPad) + } +} + +func (v *HboxCustomPadding) themePad() float32 { + if v.DisableThemePad { + return 0 + } + return theme.Padding() +} diff --git a/ui/widgets/togglebuttongroup.go b/ui/widgets/togglebuttongroup.go new file mode 100644 index 0000000..bdea9db --- /dev/null +++ b/ui/widgets/togglebuttongroup.go @@ -0,0 +1,64 @@ +package widgets + +import ( + "supersonic/ui/layouts" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/widget" +) + +type ToggleButtonGroup struct { + widget.BaseWidget + + buttonContainer *fyne.Container + + activeBtnIdx int +} + +func NewToggleButtonGroup(activatedBtnIdx int, buttons ...*widget.Button) *ToggleButtonGroup { + t := &ToggleButtonGroup{} + t.ExtendBaseWidget(t) + t.buttonContainer = container.New(&layouts.HboxCustomPadding{DisableThemePad: true}) + for i, b := range buttons { + b.Importance = widget.MediumImportance + t.buttonContainer.Add(b) + prevOnTapped := b.OnTapped + b.OnTapped = func(i int) func() { + return func() { + if t.onTapped(i) && prevOnTapped != nil { + prevOnTapped() + } + } + }(i) + } + if activatedBtnIdx >= 0 && activatedBtnIdx <= len(buttons) { + buttons[activatedBtnIdx].Importance = widget.HighImportance + } + + return t +} + +func (t *ToggleButtonGroup) ActivatedButtonIndex() int { + return t.activeBtnIdx +} + +func (t *ToggleButtonGroup) onTapped(btnIdx int) bool { + for i, b := range t.buttonContainer.Objects { + if i == btnIdx { + b.(*widget.Button).Importance = widget.HighImportance + } else { + b.(*widget.Button).Importance = widget.MediumImportance + } + } + changed := t.activeBtnIdx != btnIdx + t.activeBtnIdx = btnIdx + if changed { + t.Refresh() + } + return changed +} + +func (t *ToggleButtonGroup) CreateRenderer() fyne.WidgetRenderer { + return widget.NewSimpleRenderer(t.buttonContainer) +}