Refresh button on playlist view; better player controls

This commit is contained in:
Sumner Evans
2019-06-27 21:25:36 -06:00
parent 2abbbd0bea
commit ee47d63cb4
5 changed files with 89 additions and 15 deletions

View File

@@ -86,6 +86,8 @@ class LibremsonicApp(Gtk.Application):
add_action('repeat-press', self.on_repeat_press)
add_action('shuffle-press', self.on_shuffle_press)
add_action('mute-toggle', self.on_mute_toggle)
def do_activate(self):
# We only allow a single window and raise any existing ones
if not self.window:
@@ -107,6 +109,8 @@ class LibremsonicApp(Gtk.Application):
self.on_stack_change)
self.window.connect('song-clicked', self.on_song_clicked)
self.window.player_controls.connect('song-scrub', self.on_song_scrub)
self.window.player_controls.volume_slider.connect(
'value-changed', self.on_volume_change)
# Display the window.
self.window.show_all()
@@ -141,7 +145,14 @@ class LibremsonicApp(Gtk.Application):
def on_prev_track(self, action, params):
current_idx = self.state.play_queue.index(self.state.current_song.id)
self.play_song(self.state.play_queue[current_idx - 1])
# Go back to the beginning of the song if we are past 5 seconds.
# Otherwise, go to the previous song.
if self.player.time_pos < 5:
song_to_play = current_idx - 1
else:
song_to_play = current_idx
self.play_song(self.state.play_queue[song_to_play])
def on_repeat_press(self, action, params):
print('repeat press')
@@ -183,6 +194,22 @@ class LibremsonicApp(Gtk.Application):
new_time = self.state.current_song.duration * (scrub_value / 100)
self.player.command('seek', str(new_time), 'absolute')
def on_mute_toggle(self, action, _):
if self.state.volume == 0:
new_volume = self.state.old_volume
else:
self.state.old_volume = self.state.volume
new_volume = 0
self.state.volume = new_volume
self.player.volume = new_volume
self.update_window()
def on_volume_change(self, scale):
self.state.volume = scale.get_value()
self.player.volume = self.state.volume
self.update_window()
# ########## HELPER METHODS ########## #
def show_configure_servers_dialog(self):
"""Show the Connect to Server dialog."""

View File

@@ -152,6 +152,11 @@ class CacheManager(metaclass=Singleton):
return str(abs_path)
def delete_cache(self, relative_path: Union[Path, str]):
abs_path = self.calculate_abs_path(relative_path)
if abs_path.exists():
abs_path.unlink()
def get_playlists(
self,
before_download: Callable[[], None],
@@ -184,7 +189,14 @@ class CacheManager(metaclass=Singleton):
self.save_cache_info()
return self.playlist_details[playlist_id]
playlist_details = self.playlist_details[playlist_id]
# Invalidate the cached photo if we are forcing a retrieval
# from the server.
if force:
self.delete_cache(playlist_details.coverArt)
return playlist_details
return CacheManager.executor.submit(do_get_playlist)

View File

@@ -10,9 +10,11 @@ class ApplicationState:
current_song: Child
config_file: str
playing: bool = False
song_progress: float = 0.0
play_queue: List[str]
volume: int = 100
old_volume: int = 100
# TODO save these values that aren't necessarily config to disk
def load_config(self):
self.config = get_config(self.config_file)

View File

@@ -3,7 +3,7 @@ import math
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Pango, GObject
from gi.repository import Gtk, Pango, GObject, Gio
from libremsonic.state_manager import ApplicationState
from libremsonic.cache_manager import CacheManager
@@ -53,7 +53,26 @@ class PlayerControls(Gtk.ActionBar):
self.play_button.set_sensitive(has_current_song)
self.next_button.set_sensitive(has_current_song and has_next_song)
# Volume button and slider
if state.volume == 0:
icon_name = 'muted'
elif state.volume < 30:
icon_name = 'low'
elif state.volume < 70:
icon_name = 'medium'
else:
icon_name = 'high'
icon = Gio.ThemedIcon(name='audio-volume-' + icon_name)
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
self.volume_mute_toggle.remove(self.volume_mute_toggle.get_child())
self.volume_mute_toggle.add(image)
self.volume_mute_toggle.show_all()
self.volume_slider.set_value(state.volume)
if not has_current_song:
# TODO should probably clear out something?
return
self.update_cover_art(state.current_song.coverArt, size='70')
@@ -197,18 +216,16 @@ class PlayerControls(Gtk.ActionBar):
box.pack_start(up_next_button, False, True, 5)
# Volume mute toggle
# TODO connect it to something.
self.volume_mute_toggle = util.button_with_icon('audio-volume-high')
self.volume_mute_toggle.set_action_name('app.mute-toggle')
box.pack_start(self.volume_mute_toggle, False, True, 0)
# Volume slider
# TODO connect it to something.
volume_slider = Gtk.Scale.new_with_range(
self.volume_slider = Gtk.Scale.new_with_range(
orientation=Gtk.Orientation.HORIZONTAL, min=0, max=100, step=5)
volume_slider.set_name('volume-slider')
volume_slider.set_draw_value(False)
volume_slider.set_value(100)
box.pack_start(volume_slider, True, True, 0)
self.volume_slider.set_name('volume-slider')
self.volume_slider.set_draw_value(False)
box.pack_start(self.volume_slider, True, True, 0)
vbox.pack_start(box, False, True, 0)
vbox.pack_start(Gtk.Box(), True, True, 0)

View File

@@ -46,9 +46,9 @@ class PlaylistsPanel(Gtk.Paned):
self.new_playlist.connect('clicked', self.on_new_playlist_clicked)
playlist_list_actions.pack_start(self.new_playlist)
refresh_button = util.button_with_icon('view-refresh')
refresh_button.connect('clicked', self.on_list_refresh_click)
playlist_list_actions.pack_end(refresh_button)
list_refresh_button = util.button_with_icon('view-refresh')
list_refresh_button.connect('clicked', self.on_list_refresh_click)
playlist_list_actions.pack_end(list_refresh_button)
playlist_list_vbox.add(playlist_list_actions)
@@ -112,8 +112,19 @@ class PlaylistsPanel(Gtk.Paned):
artwork_overlay.add_overlay(self.artwork_spinner)
self.big_info_panel.pack_start(artwork_overlay, False, False, 0)
# Name, comment, number of songs, etc.
# Action buttons, name, comment, number of songs, etc.
playlist_details_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
# Action buttons
# TODO hide this if there is no selected playlist
action_button_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
view_refresh_button = util.button_with_icon('view-refresh')
view_refresh_button.connect('clicked', self.on_view_refresh_click)
action_button_box.pack_end(view_refresh_button, False, False, 5)
playlist_details_box.pack_start(action_button_box, False, False, 5)
playlist_details_box.pack_start(Gtk.Box(), True, False, 0)
self.playlist_indicator = self.make_label(name='playlist-indicator')
@@ -215,6 +226,11 @@ class PlaylistsPanel(Gtk.Paned):
def on_list_refresh_click(self, button):
self.update_playlist_list(force=True)
def on_view_refresh_click(self, button):
playlist_id = self.playlist_map[
self.playlist_list.get_selected_row().get_index()]
self.update_playlist_view(playlist_id, force=True)
def on_song_double_click(self, treeview, idx, column):
# The song ID is in the last column of the model.
song_id = self.playlist_song_model[idx][-1]