Refresh button on playlist view; better player controls
This commit is contained in:
@@ -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."""
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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]
|
||||
|
Reference in New Issue
Block a user