ensure clicking anywhere outside tracklists can unselect all

This commit is contained in:
Drew Weymouth
2024-12-15 15:52:21 -08:00
parent 46153f5fe3
commit 1d342bf413
9 changed files with 113 additions and 48 deletions
+5 -3
View File
@@ -143,14 +143,16 @@ func (a *AlbumPage) Reload() {
go a.load() go a.load()
} }
func (a *AlbumPage) Tapped(*fyne.PointEvent) { var _ CanSelectAll = (*AlbumPage)(nil)
a.tracklist.UnselectAll()
}
func (a *AlbumPage) SelectAll() { func (a *AlbumPage) SelectAll() {
a.tracklist.SelectAll() a.tracklist.SelectAll()
} }
func (a *AlbumPage) UnselectAll() {
a.tracklist.UnselectAll()
}
var _ Scrollable = (*AlbumPage)(nil) var _ Scrollable = (*AlbumPage)(nil)
func (a *AlbumPage) Scroll(scrollAmt float32) { func (a *AlbumPage) Scroll(scrollAmt float32) {
+6 -6
View File
@@ -110,12 +110,6 @@ func newArtistPage(artistID string, cfg *backend.ArtistPageConfig, pool *util.Wi
return a return a
} }
func (a *ArtistPage) Tapped(*fyne.PointEvent) {
if a.tracklistCtr != nil {
a.tracklistCtr.Objects[0].(*widgets.Tracklist).UnselectAll()
}
}
var _ CanSelectAll = (*ArtistPage)(nil) var _ CanSelectAll = (*ArtistPage)(nil)
func (a *ArtistPage) SelectAll() { func (a *ArtistPage) SelectAll() {
@@ -124,6 +118,12 @@ func (a *ArtistPage) SelectAll() {
} }
} }
func (a *ArtistPage) UnselectAll() {
if a.tracklistCtr != nil {
a.tracklistCtr.Objects[0].(*widgets.Tracklist).UnselectAll()
}
}
func (a *ArtistPage) Route() controller.Route { func (a *ArtistPage) Route() controller.Route {
return controller.ArtistRoute(a.artistID) return controller.ArtistRoute(a.artistID)
} }
+7
View File
@@ -36,6 +36,7 @@ type Searchable interface {
// Pages with selection should implement this interface to receive Ctrl+A events // Pages with selection should implement this interface to receive Ctrl+A events
type CanSelectAll interface { type CanSelectAll interface {
SelectAll() SelectAll()
UnselectAll()
} }
// Pages that have one main scrollable view should implement this interface // Pages that have one main scrollable view should implement this interface
@@ -199,6 +200,12 @@ func (b *BrowsingPane) SelectAll() {
} }
} }
func (b *BrowsingPane) UnselectAll() {
if s, ok := b.curPage.(CanSelectAll); ok {
s.UnselectAll()
}
}
func (b *BrowsingPane) ScrollUp() { func (b *BrowsingPane) ScrollUp() {
b.scrollBy(-75) b.scrollBy(-75)
} }
+6 -6
View File
@@ -174,12 +174,6 @@ func (a *FavoritesPage) Route() controller.Route {
return controller.FavoritesRoute() return controller.FavoritesRoute()
} }
func (a *FavoritesPage) Tapped(*fyne.PointEvent) {
if tr := a.tracklistOrNil(); tr != nil {
tr.UnselectAll()
}
}
func (a *FavoritesPage) Reload() { func (a *FavoritesPage) Reload() {
// reload favorite albums view // reload favorite albums view
if a.searchText != "" { if a.searchText != "" {
@@ -287,6 +281,12 @@ func (a *FavoritesPage) SelectAll() {
} }
} }
func (a *FavoritesPage) UnselectAll() {
if a.toggleBtns.ActivatedButtonIndex() == 2 /*songs*/ && a.tracklistCtr != nil {
a.tracklistOrNil().UnselectAll() // can't be nil in this case
}
}
func (a *FavoritesPage) Refresh() { func (a *FavoritesPage) Refresh() {
if a.albumGrid != nil { if a.albumGrid != nil {
a.albumGrid.ShowSuffix = a.cfg.ShowAlbumYears a.albumGrid.ShowSuffix = a.cfg.ShowAlbumYears
+18 -19
View File
@@ -470,31 +470,30 @@ func (a *NowPlayingPage) OnPlayTimeUpdate(curTime, _ float64, seeked bool) {
} }
} }
func (a *NowPlayingPage) currentTracklistOrNil() *widgets.PlayQueueList {
if a.tabs != nil {
switch a.tabs.SelectedIndex() {
case 0: /*queue*/
return a.queueList
case 2: /*related*/
return a.relatedList
}
}
return nil
}
var _ CanSelectAll = (*NowPlayingPage)(nil) var _ CanSelectAll = (*NowPlayingPage)(nil)
func (a *NowPlayingPage) SelectAll() { func (a *NowPlayingPage) SelectAll() {
if a.tabs == nil { if l := a.currentTracklistOrNil(); l != nil {
return l.SelectAll()
}
switch a.tabs.SelectedIndex() {
case 0: /*queue*/
a.queueList.SelectAll()
case 2: /*related*/
a.relatedList.SelectAll()
} }
} }
var _ fyne.Tappable = (*NowPlayingPage)(nil) func (a *NowPlayingPage) UnselectAll() {
if l := a.currentTracklistOrNil(); l != nil {
func (a *NowPlayingPage) Tapped(*fyne.PointEvent) { l.UnselectAll()
if a.tabs == nil {
return
}
switch a.tabs.SelectedIndex() {
case 0: /*queue*/
a.queueList.UnselectAll()
case 2: /*related*/
a.relatedList.UnselectAll()
} }
} }
+5 -3
View File
@@ -139,14 +139,16 @@ func (a *PlaylistPage) Reload() {
go a.load() go a.load()
} }
func (a *PlaylistPage) Tapped(*fyne.PointEvent) { var _ CanSelectAll = (*PlaylistPage)(nil)
a.tracklist.UnselectAll()
}
func (a *PlaylistPage) SelectAll() { func (a *PlaylistPage) SelectAll() {
a.tracklist.SelectAll() a.tracklist.SelectAll()
} }
func (a *PlaylistPage) UnselectAll() {
a.tracklist.UnselectAll()
}
var _ Scrollable = (*PlaylistPage)(nil) var _ Scrollable = (*PlaylistPage)(nil)
func (a *PlaylistPage) Scroll(scrollAmt float32) { func (a *PlaylistPage) Scroll(scrollAmt float32) {
+16
View File
@@ -89,6 +89,18 @@ func (t *TracksPage) Route() controller.Route {
return controller.TracksRoute() return controller.TracksRoute()
} }
var _ CanSelectAll = (*TracksPage)(nil)
func (t *TracksPage) SelectAll() {
// deliberate no-op since we don't want to give the impression
// that you can select all tracks from the server, since only
// some of them are actually loaded into the model
}
func (t *TracksPage) UnselectAll() {
t.currentTracklist().UnselectAll()
}
func (t *TracksPage) Reload() { func (t *TracksPage) Reload() {
t.tracklist.Clear() t.tracklist.Clear()
iter := t.mp.IterateTracks("") iter := t.mp.IterateTracks("")
@@ -161,6 +173,10 @@ func (t *TracksPage) doSearch(query string) {
t.Refresh() t.Refresh()
} }
func (t *TracksPage) currentTracklist() *widgets.Tracklist {
return t.container.Objects[0].(*fyne.Container).Objects[0].(*widgets.Tracklist)
}
func (t *TracksPage) CreateRenderer() fyne.WidgetRenderer { func (t *TracksPage) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(t.container) return widget.NewSimpleRenderer(t.container)
} }
+14
View File
@@ -49,6 +49,7 @@ type Controller struct {
ReloadFunc func() ReloadFunc func()
RefreshPageFunc func() RefreshPageFunc func()
SelectAllPageFunc func() SelectAllPageFunc func()
UnselectAllPageFunc func()
popUpQueueMutex sync.Mutex popUpQueueMutex sync.Mutex
popUpQueue *widget.PopUp popUpQueue *widget.PopUp
@@ -101,6 +102,19 @@ func (m *Controller) SelectAll() {
} }
} }
func (m *Controller) UnselectAll() {
m.popUpQueueMutex.Lock()
if m.popUpQueue != nil && m.popUpQueue.Visible() {
m.popUpQueueList.UnselectAll()
m.popUpQueueMutex.Unlock()
return
}
m.popUpQueueMutex.Unlock()
if m.SelectAllPageFunc != nil {
m.UnselectAllPageFunc()
}
}
func (m *Controller) NavigateTo(route Route) { func (m *Controller) NavigateTo(route Route) {
m.NavHandler(route) m.NavHandler(route)
} }
+28 -3
View File
@@ -38,7 +38,7 @@ type MainWindow struct {
theme *theme.MyTheme theme *theme.MyTheme
haveSystemTray bool haveSystemTray bool
alreadyConnected bool // tracks if we have already connected to a server before alreadyConnected bool // tracks if we have already connected to a server before
container *fyne.Container content *mainWindowContent
// needs to bes shown/hidden when switching between servers based on whether they support radio // needs to bes shown/hidden when switching between servers based on whether they support radio
radioBtn fyne.CanvasObject radioBtn fyne.CanvasObject
@@ -68,6 +68,7 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
m.Controller.CurPageFunc = m.BrowsingPane.CurrentPage m.Controller.CurPageFunc = m.BrowsingPane.CurrentPage
m.Controller.RefreshPageFunc = m.BrowsingPane.RefreshPage m.Controller.RefreshPageFunc = m.BrowsingPane.RefreshPage
m.Controller.SelectAllPageFunc = m.BrowsingPane.SelectAll m.Controller.SelectAllPageFunc = m.BrowsingPane.SelectAll
m.Controller.UnselectAllPageFunc = m.BrowsingPane.UnselectAll
if runtime.GOOS == "darwin" { if runtime.GOOS == "darwin" {
// Fyne will extract out an "About" menu item and // Fyne will extract out an "About" menu item and
@@ -136,8 +137,9 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
m.BrowsingPane.DisableNavigationButtons() m.BrowsingPane.DisableNavigationButtons()
m.addShortcuts() m.addShortcuts()
m.container = container.NewBorder(nil, m.BottomPanel, nil, nil, m.BrowsingPane) m.content = newMainWindowContent(container.NewBorder(nil, m.BottomPanel, nil, nil, m.BrowsingPane),
m.Window.SetContent(fynetooltip.AddWindowToolTipLayer(m.container, m.Window.Canvas())) m.Controller.UnselectAll)
m.Window.SetContent(fynetooltip.AddWindowToolTipLayer(m.content, m.Window.Canvas()))
m.setInitialSize() m.setInitialSize()
m.Window.SetCloseIntercept(func() { m.Window.SetCloseIntercept(func() {
m.SaveWindowSize() m.SaveWindowSize()
@@ -433,3 +435,26 @@ func (m *MainWindow) SaveWindowSize() {
&m.App.Config.Application.WindowWidth, &m.App.Config.Application.WindowWidth,
&m.App.Config.Application.WindowHeight) &m.App.Config.Application.WindowHeight)
} }
// widget just so we can catch a tap event that doesn't land anywhere else
// and call BrowsingPane.UnselectAll()
type mainWindowContent struct {
widget.BaseWidget
content fyne.CanvasObject
onTapped func()
}
func newMainWindowContent(content fyne.CanvasObject, onTapped func()) *mainWindowContent {
w := &mainWindowContent{content: content, onTapped: onTapped}
w.ExtendBaseWidget(w)
return w
}
func (m *mainWindowContent) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(m.content)
}
func (m *mainWindowContent) Tapped(*fyne.PointEvent) {
m.onTapped()
}