Skip to content

Commit

Permalink
Merge pull request #847 from geigi/fix-seekbar-jumping
Browse files Browse the repository at this point in the history
Fix seekbar jumping when changing playback speed
  • Loading branch information
geigi authored Feb 16, 2024
2 parents fd26154 + 75413b8 commit 90cd028
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 53 deletions.
1 change: 0 additions & 1 deletion cozy/media/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

US_TO_SEC = 10 ** 6
NS_TO_SEC = 10 ** 9
REWIND_SECONDS = 30


class Player(EventSender):
Expand Down
16 changes: 9 additions & 7 deletions cozy/ui/media_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
6 changes: 2 additions & 4 deletions cozy/ui/widgets/playback_speed_popover.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 16 additions & 24 deletions cozy/ui/widgets/seek_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand All @@ -75,32 +69,30 @@ 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("<span font_features='tnum'>" + current_text + "</span>")
self.remaining_label.set_markup("<span font_features='tnum'>-" + remaining_text + "</span>")
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


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, ())
35 changes: 22 additions & 13 deletions cozy/view_model/playback_control_view_model.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -17,26 +15,20 @@ 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)

if self._player.loaded_book:
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
Expand All @@ -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

Expand All @@ -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
Expand Down
12 changes: 8 additions & 4 deletions data/ui/seek_bar.ui
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
<property name="tooltip-text" translatable="true">Elapsed time</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="label">&lt;span font_features=&apos;tnum&apos;&gt;--:--&lt;/span&gt;</property>
<property name="use-markup">true</property>
<property name="label">--:--</property>
<property name="single-line-mode">true</property>
<accessibility>
<property name="label" translatable="true">Elapsed time of current part</property>
</accessibility>
<style>
<class name="numeric"/>
</style>
</object>
</child>
<child>
Expand All @@ -45,12 +47,14 @@
<object class="GtkLabel" id="remaining_label">
<property name="tooltip-text" translatable="true">Remaining time</property>
<property name="halign">start</property>
<property name="label">&lt;span font_features=&apos;tnum&apos;&gt;--:--&lt;/span&gt;</property>
<property name="use-markup">true</property>
<property name="label">--:--</property>
<property name="single-line-mode">true</property>
<accessibility>
<property name="label" translatable="true">Remaining time of current part</property>
</accessibility>
<style>
<class name="numeric"/>
</style>
</object>
</child>
</object>
Expand Down

0 comments on commit 90cd028

Please sign in to comment.