diff --git a/cozy/media/player.py b/cozy/media/player.py index 472c5563..795ce382 100644 --- a/cozy/media/player.py +++ b/cozy/media/player.py @@ -24,7 +24,6 @@ US_TO_SEC = 10 ** 6 NS_TO_SEC = 10 ** 9 -REWIND_SECONDS = 30 class Player(EventSender): diff --git a/cozy/ui/media_controller.py b/cozy/ui/media_controller.py index fe3e3e05..ae0c64b6 100644 --- a/cozy/ui/media_controller.py +++ b/cozy/ui/media_controller.py @@ -71,15 +71,17 @@ def _connect_view_model(self): def _connect_widgets(self): self.play_button.connect("clicked", self._play_clicked) - self.prev_button.connect("clicked", self._rewind_clicked) - self.next_button.connect("clicked", self._forward_clicked) self.volume_button.connect("value-changed", self._on_volume_button_changed) self.seek_bar.connect("position-changed", self._on_seek_bar_position_changed) - self._cover_img_gesture = Gtk.GestureClick() - self._cover_img_gesture.connect("pressed", self._cover_clicked) - self.cover_img.add_controller(self._cover_img_gesture) + self.prev_button.connect("clicked", self._rewind_clicked) + self.next_button.connect("clicked", self._forward_clicked) + self.seek_bar.connect("rewind", self._rewind_clicked) + self.seek_bar.connect("forward", self._forward_clicked) + cover_click_gesture = Gtk.GestureClick() + cover_click_gesture.connect("pressed", self._cover_clicked) + self.cover_img.add_controller(cover_click_gesture) self.cover_img.set_cursor(Gdk.Cursor.new_from_name("pointer")) def _set_cover_image(self, book: Book): @@ -116,7 +118,7 @@ def _on_play_changed(self): self.play_button.set_icon_name("media-playback-start-symbolic") def _on_position_changed(self): - position = self._playback_control_view_model.position + position = self._playback_control_view_model.relative_position if position is not None: self.seek_bar.position = position @@ -148,4 +150,4 @@ def _on_volume_button_changed(self, _, volume): self._playback_control_view_model.volume = volume def _on_seek_bar_position_changed(self, _, position): - self._playback_control_view_model.position = position + self._playback_control_view_model.relative_position = position diff --git a/cozy/ui/widgets/playback_speed_popover.py b/cozy/ui/widgets/playback_speed_popover.py index 2dd59847..18c9266b 100644 --- a/cozy/ui/widgets/playback_speed_popover.py +++ b/cozy/ui/widgets/playback_speed_popover.py @@ -20,12 +20,10 @@ def __init__(self, **kwargs): self.playback_speed_scale.set_increments(0.02, 0.05) self.playback_speed_scale.connect("value-changed", self._on_playback_speed_scale_changed) - self._connect_view_model() - self._on_playback_speed_changed() - - def _connect_view_model(self): self._view_model.bind_to("playback_speed", self._on_playback_speed_changed) + self._on_playback_speed_changed() + def _on_playback_speed_scale_changed(self, _): speed = round(self.playback_speed_scale.get_value(), 2) self._view_model.playback_speed = speed diff --git a/cozy/ui/widgets/seek_bar.py b/cozy/ui/widgets/seek_bar.py index f901d510..ffadb331 100644 --- a/cozy/ui/widgets/seek_bar.py +++ b/cozy/ui/widgets/seek_bar.py @@ -12,9 +12,12 @@ class SeekBar(Gtk.Box): remaining_label: Gtk.Label = Gtk.Template.Child() remaining_event_box: Gtk.Box = Gtk.Template.Child() + length: float + def __init__(self, **kwargs): super().__init__(**kwargs) + self.length: float = 0.0 self._progress_scale_pressed = False self.progress_scale.connect("value-changed", self._on_progress_scale_changed) @@ -47,15 +50,6 @@ def position(self, new_value: float): if not self._progress_scale_pressed: self.progress_scale.set_value(new_value) - @property - def length(self) -> float: - return self.progress_scale.get_adjustment().get_upper() - - @length.setter - def length(self, new_value: float): - self.progress_scale.set_range(0, new_value) - self._on_progress_scale_changed(None) - @property def sensitive(self) -> bool: return self.progress_scale.get_sensitive() @@ -75,28 +69,23 @@ def visible(self, value: bool): self.remaining_event_box.set_visible(value) def _on_progress_scale_changed(self, _): - position = int(self.progress_scale.get_value()) - total = self.progress_scale.get_adjustment().get_upper() + total = self.length + position = int(total * self.progress_scale.get_value() / 100) + remaining_secs = int(total - position) - remaining_secs: int = int(total - position) - current_text = seconds_to_str(position, total) - remaining_text = seconds_to_str(remaining_secs, total) - self.current_label.set_markup("" + current_text + "") - self.remaining_label.set_markup("-" + remaining_text + "") + self.current_label.set_text(seconds_to_str(position, total)) + self.remaining_label.set_text(seconds_to_str(remaining_secs, total)) def _on_progress_scale_release(self, *_): self._progress_scale_pressed = False value = self.progress_scale.get_value() self.emit("position-changed", value) - def _on_progress_key_pressed(self, _, event): - if event.keyval == Gdk.KEY_Up or event.keyval == Gdk.KEY_Left: - self.position = max(self.position - 30, 0) - self.emit("position-changed", self.position) - elif event.keyval == Gdk.KEY_Down or event.keyval == Gdk.KEY_Right: - max_value = self.progress_scale.get_adjustment().get_upper() - self.position = min(self.position + 30, max_value) - self.emit("position-changed", self.position) + def _on_progress_key_pressed(self, _, event, *__): + if event in {Gdk.KEY_Up, Gdk.KEY_Left}: + self.emit("rewind") + elif event in {Gdk.KEY_Down, Gdk.KEY_Right}: + self.emit("forward") def _on_progress_scale_press(self, *_): self._progress_scale_pressed = True @@ -104,3 +93,6 @@ def _on_progress_scale_press(self, *_): GObject.signal_new('position-changed', SeekBar, GObject.SIGNAL_RUN_LAST, GObject.TYPE_PYOBJECT, (GObject.TYPE_PYOBJECT,)) + +GObject.signal_new('rewind', SeekBar, GObject.SIGNAL_RUN_LAST, GObject.TYPE_PYOBJECT, ()) +GObject.signal_new('forward', SeekBar, GObject.SIGNAL_RUN_LAST, GObject.TYPE_PYOBJECT, ()) diff --git a/cozy/view_model/playback_control_view_model.py b/cozy/view_model/playback_control_view_model.py index 4f24f9b6..8255a49d 100644 --- a/cozy/view_model/playback_control_view_model.py +++ b/cozy/view_model/playback_control_view_model.py @@ -1,5 +1,3 @@ -from typing import Optional - from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable from cozy.ext import inject @@ -17,7 +15,7 @@ def __init__(self): super().__init__() super(Observable, self).__init__() - self._book: Optional[Book] = None + self._book: Book | None = None self._player.add_listener(self._on_player_event) @@ -25,18 +23,12 @@ def __init__(self): self.book = self._player.loaded_book @property - def book(self) -> Optional[Book]: + def book(self) -> Book | None: return self._book @book.setter - def book(self, value: Optional[Book]): - if self._book: - self._book.remove_bind("playback_speed", self._on_playback_speed_changed) - + def book(self, value: Book | None): self._book = value - if value: - self._book.bind_to("playback_speed", self._on_playback_speed_changed) - self._notify("lock_ui") @property @@ -47,7 +39,7 @@ def playing(self) -> bool: return self._player.playing @property - def position(self) -> Optional[float]: + def position(self) -> float | None: if not self._book: return None @@ -62,12 +54,29 @@ def position(self, new_value: int): self._player.position = new_value * self._book.playback_speed @property - def length(self) -> Optional[float]: + def length(self) -> float | None: if not self._player.loaded_book or not self._book: return None return self._player.loaded_book.current_chapter.length / self._book.playback_speed + @property + def relative_position(self) -> float | None: + if not self._player.loaded_book or not self._book: + return None + + position = self._book.current_chapter.position - self._book.current_chapter.start_position + length = self._player.loaded_book.current_chapter.length + return position / NS_TO_SEC / length * 100 + + @relative_position.setter + def relative_position(self, new_value: float) -> None: + if not self._book: + return + + length = self._player.loaded_book.current_chapter.length + self._player.position = new_value / 100 * length + @property def lock_ui(self) -> bool: return not self._book diff --git a/data/ui/seek_bar.ui b/data/ui/seek_bar.ui index 2254819d..2b91b6d2 100644 --- a/data/ui/seek_bar.ui +++ b/data/ui/seek_bar.ui @@ -15,12 +15,14 @@ Elapsed time end center - <span font_features='tnum'>--:--</span> - true + --:-- true Elapsed time of current part + @@ -45,12 +47,14 @@ Remaining time start - <span font_features='tnum'>--:--</span> - true + --:-- true Remaining time of current part +