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 @@