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)
} }
+22 -8
View File
@@ -41,14 +41,15 @@ type CurPageFunc func() Route
type Controller struct { type Controller struct {
visualizationData visualizationData
AppVersion string AppVersion string
App *backend.App App *backend.App
MainWindow fyne.Window MainWindow fyne.Window
NavHandler NavigationHandler NavHandler NavigationHandler
CurPageFunc CurPageFunc CurPageFunc CurPageFunc
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()
}