Added Browse tab and implemented logic to change stack state

This commit is contained in:
Sumner Evans
2020-01-01 12:14:49 -07:00
parent 6a24fbada5
commit ba35cae6e1
5 changed files with 107 additions and 36 deletions

View File

@@ -96,6 +96,8 @@ class SublimeMusicApp(Gtk.Application):
add_action('add-to-queue', self.on_add_to_queue, parameter_type='as')
add_action('go-to-album', self.on_go_to_album, parameter_type='s')
add_action('go-to-artist', self.on_go_to_artist, parameter_type='s')
add_action(
'browse-to-song', self.on_browse_to_song, parameter_type='s')
add_action(
'go-to-playlist', self.on_go_to_playlist, parameter_type='s')
@@ -581,6 +583,11 @@ class SublimeMusicApp(Gtk.Application):
self.state.selected_artist_id = artist_id.get_string()
self.update_window()
def on_browse_to_song(self, action, song_id):
# Really, we want to browse to the song's parent.
self.state.current_tab = 'browse'
self.update_window()
def on_go_to_playlist(self, action, playlist_id):
self.state.current_tab = 'playlists'
self.state.selected_playlist_id = playlist_id.get_string()

View File

@@ -214,6 +214,12 @@ class CacheManager(metaclass=Singleton):
def ready():
return CacheManager._instance is not None
@staticmethod
def browse_by_tags():
return (
CacheManager._instance is not None
and CacheManager._instance.browse_by_tags)
@staticmethod
def shutdown():
CacheManager.should_exit = True
@@ -523,6 +529,7 @@ class CacheManager(metaclass=Singleton):
before_download: Callable[[], None] = lambda: None,
force: bool = False,
) -> 'CacheManager.Result[List[Union[Artist, ArtistID3]]]':
# TODO: no need to id3ify I think.
cache_name = self.id3ify('artists')
if self.cache.get(cache_name) and not force:
@@ -556,6 +563,7 @@ class CacheManager(metaclass=Singleton):
before_download: Callable[[], None] = lambda: None,
force: bool = False,
) -> 'CacheManager.Result[Union[ArtistWithAlbumsID3, Child]]':
# TODO: no need to id3ify I think.
cache_name = self.id3ify('artist_details')
if artist_id in self.cache.get(cache_name, {}) and not force:
@@ -583,6 +591,7 @@ class CacheManager(metaclass=Singleton):
before_download: Callable[[], None] = lambda: None,
force: bool = False,
) -> 'CacheManager.Result[Union[ArtistInfo, ArtistInfo2]]':
# TODO: no need to id3ify I think.
cache_name = self.id3ify('artist_infos')
if artist_id in self.cache.get(cache_name, {}) and not force:
@@ -663,6 +672,7 @@ class CacheManager(metaclass=Singleton):
# Look at documentation for get_album_list in server.py:
**params,
) -> 'CacheManager.Result[List[Union[Child, AlbumWithSongsID3]]]':
# TODO: no need to id3ify I think.
cache_name = self.id3ify('albums')
if (len(self.cache.get(cache_name, {}).get(type_, [])) > 0

24
sublime/ui/browse.py Normal file
View File

@@ -0,0 +1,24 @@
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject, Pango, GLib, Gio
class BrowsePanel(Gtk.Label):
"""Defines the arist panel."""
__gsignals__ = {
'song-clicked': (
GObject.SignalFlags.RUN_FIRST,
GObject.TYPE_NONE,
(int, object, object),
),
'refresh-window': (
GObject.SignalFlags.RUN_FIRST,
GObject.TYPE_NONE,
(object, bool),
),
}
def __init__(self):
super().__init__(label='ohea')

View File

@@ -1,15 +1,10 @@
import concurrent
from concurrent.futures import Future
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gio, Gtk, GObject, Gdk, GLib, Pango
from fuzzywuzzy import fuzz
from . import albums, artists, playlists, player_controls
from . import albums, artists, browse, playlists, player_controls
from sublime.state_manager import ApplicationState
from sublime.cache_manager import CacheManager, SearchResult
from sublime.cache_manager import CacheManager
from sublime.server.api_objects import Child
from sublime.ui import util
from sublime.ui.common import SpinnerImage
@@ -47,9 +42,13 @@ class MainWindow(Gtk.ApplicationWindow):
self.set_default_size(1150, 768)
# Create the stack
self.albums_panel = albums.AlbumsPanel()
self.artists_panel = artists.ArtistsPanel()
self.browse_panel = browse.BrowsePanel()
self.stack = self.create_stack(
Albums=albums.AlbumsPanel(),
Artists=artists.ArtistsPanel(),
Albums=self.albums_panel,
Browse=self.browse_panel,
Artists=self.artists_panel,
Playlists=playlists.PlaylistsPanel(),
)
self.stack.set_transition_type(
@@ -76,7 +75,19 @@ class MainWindow(Gtk.ApplicationWindow):
self.connect('button-release-event', self.on_button_release)
def update(self, state: ApplicationState, force=False):
# Have to do this before hiding/showing the panels to avoid issues with
# the current_tab being overridden.
self.stack.set_visible_child_name(state.current_tab)
self.browse_by_tags = state.config.server.browse_by_tags
if self.browse_by_tags:
self.browse_panel.hide()
self.albums_panel.show()
self.artists_panel.show()
else:
self.browse_panel.show()
self.albums_panel.hide()
self.artists_panel.hide()
# Update the Connected to label on the popup menu.
if state.config.current_server >= 0:
@@ -88,8 +99,6 @@ class MainWindow(Gtk.ApplicationWindow):
self.connected_to_label.set_markup(
f'<span style="italic">Not Connected to a Server</span>')
self.stack.set_visible_child_name(state.current_tab)
active_panel = self.stack.get_visible_child()
if hasattr(active_panel, 'update'):
active_panel.update(state, force=force)
@@ -339,7 +348,12 @@ class MainWindow(Gtk.ApplicationWindow):
widget.remove(c)
def create_search_result_row(
self, text, action_name, value, artwork_future):
self,
text,
action_name,
value,
artwork_future,
):
row = Gtk.Button(relief=Gtk.ReliefStyle.NONE)
row.connect(
'button-press-event',

View File

@@ -154,12 +154,13 @@ def show_song_popover(
# Determine if we should enable the download button.
download_sensitive, remove_download_sensitive = False, False
albums, artists = set(), set()
albums, artists, parents = set(), set(), set()
for song_id in song_ids:
details = CacheManager.get_song_details(song_id).result()
status = CacheManager.get_cached_status(details)
albums.add(details.albumId)
artists.add(details.artistId)
parents.add(details.parent)
if download_sensitive or status == SongCacheStatus.NOT_CACHED:
download_sensitive = True
@@ -181,6 +182,14 @@ def show_song_popover(
artist_value = GLib.Variant('s', list(artists)[0])
go_to_artist_button.set_action_target_value(artist_value)
browse_to_song = Gtk.ModelButton(
text=f"Browse to {pluralize('song', song_count)}",
action_name='app.browse-to-song',
)
if len(parents) == 1 and list(parents)[0] is not None:
parent_value = GLib.Variant('s', list(parents)[0])
browse_to_song.set_action_target_value(parent_value)
menu_items = [
Gtk.ModelButton(
text='Play next',
@@ -193,31 +202,38 @@ def show_song_popover(
action_target=GLib.Variant('as', song_ids),
),
Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL),
go_to_album_button,
go_to_artist_button,
Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL),
(
Gtk.ModelButton(
text=f"Download {pluralize('song', song_count)}",
sensitive=download_sensitive,
),
on_download_songs_click,
),
(
Gtk.ModelButton(
text=f"Remove {pluralize('download', song_count)}",
sensitive=remove_download_sensitive,
),
on_remove_downloads_click,
),
Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL),
Gtk.ModelButton(
text=f"Add {pluralize('song', song_count)} to playlist",
menu_name='add-to-playlist',
),
*extra_menu_items,
]
if CacheManager.browse_by_tags():
menu_items.extend([go_to_album_button, go_to_artist_button])
else:
menu_items.extend([browse_to_song])
menu_items.extend(
[
Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL),
(
Gtk.ModelButton(
text=f"Download {pluralize('song', song_count)}",
sensitive=download_sensitive,
),
on_download_songs_click,
),
(
Gtk.ModelButton(
text=f"Remove {pluralize('download', song_count)}",
sensitive=remove_download_sensitive,
),
on_remove_downloads_click,
),
Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL),
Gtk.ModelButton(
text=f"Add {pluralize('song', song_count)} to playlist",
menu_name='add-to-playlist',
),
*extra_menu_items,
])
for item in menu_items:
if type(item) == tuple:
el, fn = item