From 32fd516a0d291d8bb4aaf2872d303ef717fe911a Mon Sep 17 00:00:00 2001 From: Cassidy James Blaede Date: Wed, 7 Aug 2024 13:48:39 -0600 Subject: [PATCH 1/5] window: Toggle end timestamp between duration and time remaining Addresses one part of https://gitlab.gnome.org/GNOME/Incubator/showtime/-/issues/70 Adding the wall-clock-time when the video will complete could be handled in a separate MR --- data/org.gnome.Showtime.gschema.xml.in | 10 ++++++ showtime/gtk/window.blp | 8 +++-- showtime/window.py | 49 ++++++++++++++++++-------- 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/data/org.gnome.Showtime.gschema.xml.in b/data/org.gnome.Showtime.gschema.xml.in index 4b7bc4b..abce18b 100644 --- a/data/org.gnome.Showtime.gschema.xml.in +++ b/data/org.gnome.Showtime.gschema.xml.in @@ -2,9 +2,19 @@ + + + + + + "Duration" + What to show in the end timestamp position + E.g. total duration of the video or the amount of time remaining + false + diff --git a/showtime/gtk/window.blp b/showtime/gtk/window.blp index bf4b43c..aca9f08 100644 --- a/showtime/gtk/window.blp +++ b/showtime/gtk/window.blp @@ -415,16 +415,18 @@ template $ShowtimeWindow: Adw.ApplicationWindow { } [end] - Label duration_label { + Button end_timestamp_button { label: "0∶00"; margin-start: 3; - margin-end: 12; + margin-end: 0; + tooltip-text: _("Toggle Duration/Remaining"); styles [ "caption", "numeric", "timestamp", - "dim-label" + "dim-label", + "flat" ] } } diff --git a/showtime/window.py b/showtime/window.py index 7acd3a2..ed13887 100644 --- a/showtime/window.py +++ b/showtime/window.py @@ -81,7 +81,7 @@ class ShowtimeWindow(Adw.ApplicationWindow): play_button: Gtk.Button = Gtk.Template.Child() position_label: Gtk.Label = Gtk.Template.Child() seek_scale: Gtk.Scale = Gtk.Template.Child() - duration_label: Gtk.Label = Gtk.Template.Child() + end_timestamp_button: Gtk.Button = Gtk.Template.Child() volume_menu_button: Gtk.MenuButton = Gtk.Template.Child() volume_button: Gtk.Button = Gtk.Template.Child() @@ -293,6 +293,8 @@ class ShowtimeWindow(Adw.ApplicationWindow): ), ) + self.end_timestamp_button.connect("clicked", self.cycle_end_timestamp_type) + self.volume_scale.connect( "change-value", lambda _obj, _scroll, val: self.play.set_volume(max(val, 0)), @@ -368,24 +370,20 @@ class ShowtimeWindow(Adw.ApplicationWindow): self.paused = False case GstPlay.PlayMessage.DURATION_CHANGED: - self.duration_label.set_label( - nanoseconds_to_timestamp( - GstPlay.PlayMessage.parse_duration_updated(msg) - ) - ) + pos = self.play.get_position() + dur = GstPlay.PlayMessage.parse_duration_updated(msg) + + self.set_end_timestamp_label(pos, dur) case GstPlay.PlayMessage.POSITION_UPDATED: - self.seek_scale.set_value( - GstPlay.PlayMessage.parse_position_updated(msg) - / self.play.get_duration() - ) + pos = GstPlay.PlayMessage.parse_position_updated(msg) + dur = self.play.get_duration() + + self.seek_scale.set_value(pos / dur) # TODO: This can probably be done only every second instead - self.position_label.set_label( - nanoseconds_to_timestamp( - GstPlay.PlayMessage.parse_position_updated(msg) - ) - ) + self.position_label.set_label(nanoseconds_to_timestamp(pos)) + self.set_end_timestamp_label(pos, dur) case GstPlay.PlayMessage.SEEK_DONE: pos = self.play.get_position() @@ -393,6 +391,7 @@ class ShowtimeWindow(Adw.ApplicationWindow): self.seek_scale.set_value(pos / dur) self.position_label.set_label(nanoseconds_to_timestamp(pos)) + self.set_end_timestamp_label(pos, dur) logging.debug("Seeked to %i.", pos) case GstPlay.PlayMessage.MEDIA_INFO_UPDATED: @@ -911,6 +910,26 @@ class ShowtimeWindow(Adw.ApplicationWindow): (anim.skip if initial else anim.play)() logging.debug("Resized window to %i×%i.", int(nat_width), int(nat_height)) + def set_end_timestamp_label (self, pos: int, dur: int) -> None: + match shared.state_schema.get_enum("end-timestamp-type"): + case 0: # Duration + self.end_timestamp_button.set_label( + nanoseconds_to_timestamp(dur) + ) + case 1: # Remaining + self.end_timestamp_button.set_label( + "-" + nanoseconds_to_timestamp(dur - pos) + ) + + def cycle_end_timestamp_type (self, *_args: Any) -> None: + match shared.state_schema.get_enum("end-timestamp-type"): + case 0: + shared.state_schema.set_enum("end-timestamp-type", 1) + case 1: + shared.state_schema.set_enum("end-timestamp-type", 0) + + self.set_end_timestamp_label(self.play.get_position(), self.play.get_duration()) + @Gtk.Template.Callback() def _resume(self, *_args: Any) -> None: self.unpause() -- GitLab From 5edb28ecd227018ca7dd5c9b68a331f363bc2bb8 Mon Sep 17 00:00:00 2001 From: kramo Date: Wed, 7 Aug 2024 22:28:35 +0200 Subject: [PATCH 2/5] window: Fix end_timestamp_button padding --- showtime/gtk/style.css | 4 ++++ showtime/gtk/window.blp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/showtime/gtk/style.css b/showtime/gtk/style.css index 07d7f14..0bbd0bf 100644 --- a/showtime/gtk/style.css +++ b/showtime/gtk/style.css @@ -46,6 +46,10 @@ toast { -gtk-icon-size: 21px; } +#end-timestamp-button { + padding: 0 12px; +} + .no-knob { padding: 6px 9px 6px 15px; } diff --git a/showtime/gtk/window.blp b/showtime/gtk/window.blp index aca9f08..f057cbf 100644 --- a/showtime/gtk/window.blp +++ b/showtime/gtk/window.blp @@ -416,9 +416,9 @@ template $ShowtimeWindow: Adw.ApplicationWindow { [end] Button end_timestamp_button { + name: "end-timestamp-button"; label: "0∶00"; margin-start: 3; - margin-end: 0; tooltip-text: _("Toggle Duration/Remaining"); styles [ -- GitLab From b53bcfc1b82bc4498912846b7988bd264ae01791 Mon Sep 17 00:00:00 2001 From: Cassidy James Blaede Date: Wed, 7 Aug 2024 15:48:06 -0600 Subject: [PATCH 3/5] window: Cache end-timestamp-type GSetting, ensure all windows are updated --- showtime/gtk/window.blp | 1 + showtime/shared.py.in | 2 ++ showtime/shared.pyi | 2 ++ showtime/window.py | 27 +++++++++++++++++---------- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/showtime/gtk/window.blp b/showtime/gtk/window.blp index f057cbf..cc38e71 100644 --- a/showtime/gtk/window.blp +++ b/showtime/gtk/window.blp @@ -420,6 +420,7 @@ template $ShowtimeWindow: Adw.ApplicationWindow { label: "0∶00"; margin-start: 3; tooltip-text: _("Toggle Duration/Remaining"); + clicked => $_cycle_end_timestamp_type(); styles [ "caption", diff --git a/showtime/shared.py.in b/showtime/shared.py.in index 1e7918a..d057159 100644 --- a/showtime/shared.py.in +++ b/showtime/shared.py.in @@ -39,6 +39,8 @@ state_schema = Gio.Settings.new(APP_ID + ".State") cache_path = Path(GLib.get_user_cache_dir()) / "showtime" log_files = [] +end_timestamp_type = state_schema.get_enum("end-timestamp-type") + # For large enough monitors, occupy 40% of the screen area when opening a window with a video DEFAULT_OCCUPY_SCREEN = 0.4 diff --git a/showtime/shared.pyi b/showtime/shared.pyi index 2ce30c9..d434040 100644 --- a/showtime/shared.pyi +++ b/showtime/shared.pyi @@ -39,6 +39,8 @@ state_schema: Gio.Settings cache_path: Path log_files: list[Path] +end_timestamp_type: int + DEFAULT_OCCUPY_SCREEN: float SMALL_SCREEN_AREA: int SMALL_OCCUPY_SCREEN: float diff --git a/showtime/window.py b/showtime/window.py index ed13887..198d6d0 100644 --- a/showtime/window.py +++ b/showtime/window.py @@ -293,7 +293,10 @@ class ShowtimeWindow(Adw.ApplicationWindow): ), ) - self.end_timestamp_button.connect("clicked", self.cycle_end_timestamp_type) + shared.state_schema.connect( + "changed::end-timestamp-type", + self.__on_end_timestamp_type_changed + ) self.volume_scale.connect( "change-value", @@ -373,7 +376,7 @@ class ShowtimeWindow(Adw.ApplicationWindow): pos = self.play.get_position() dur = GstPlay.PlayMessage.parse_duration_updated(msg) - self.set_end_timestamp_label(pos, dur) + self.__set_end_timestamp_label(pos, dur) case GstPlay.PlayMessage.POSITION_UPDATED: pos = GstPlay.PlayMessage.parse_position_updated(msg) @@ -383,7 +386,7 @@ class ShowtimeWindow(Adw.ApplicationWindow): # TODO: This can probably be done only every second instead self.position_label.set_label(nanoseconds_to_timestamp(pos)) - self.set_end_timestamp_label(pos, dur) + self.__set_end_timestamp_label(pos, dur) case GstPlay.PlayMessage.SEEK_DONE: pos = self.play.get_position() @@ -391,7 +394,7 @@ class ShowtimeWindow(Adw.ApplicationWindow): self.seek_scale.set_value(pos / dur) self.position_label.set_label(nanoseconds_to_timestamp(pos)) - self.set_end_timestamp_label(pos, dur) + self.__set_end_timestamp_label(pos, dur) logging.debug("Seeked to %i.", pos) case GstPlay.PlayMessage.MEDIA_INFO_UPDATED: @@ -910,8 +913,12 @@ class ShowtimeWindow(Adw.ApplicationWindow): (anim.skip if initial else anim.play)() logging.debug("Resized window to %i×%i.", int(nat_width), int(nat_height)) - def set_end_timestamp_label (self, pos: int, dur: int) -> None: - match shared.state_schema.get_enum("end-timestamp-type"): + def __on_end_timestamp_type_changed(self, *_args: Any) -> None: + shared.end_timestamp_type = shared.state_schema.get_enum("end-timestamp-type") + self.__set_end_timestamp_label(self.play.get_position(), self.play.get_duration()) + + def __set_end_timestamp_label (self, pos: int, dur: int) -> None: + match shared.end_timestamp_type: case 0: # Duration self.end_timestamp_button.set_label( nanoseconds_to_timestamp(dur) @@ -920,15 +927,15 @@ class ShowtimeWindow(Adw.ApplicationWindow): self.end_timestamp_button.set_label( "-" + nanoseconds_to_timestamp(dur - pos) ) - - def cycle_end_timestamp_type (self, *_args: Any) -> None: - match shared.state_schema.get_enum("end-timestamp-type"): + @Gtk.Template.Callback() + def _cycle_end_timestamp_type (self, *_args: Any) -> None: + match shared.end_timestamp_type: case 0: shared.state_schema.set_enum("end-timestamp-type", 1) case 1: shared.state_schema.set_enum("end-timestamp-type", 0) - self.set_end_timestamp_label(self.play.get_position(), self.play.get_duration()) + self.__set_end_timestamp_label(self.play.get_position(), self.play.get_duration()) @Gtk.Template.Callback() def _resume(self, *_args: Any) -> None: -- GitLab From 396f63c1109a287e9388615ec7ec349d56fa23d2 Mon Sep 17 00:00:00 2001 From: Cassidy James Blaede Date: Wed, 7 Aug 2024 15:51:35 -0600 Subject: [PATCH 4/5] window: fix whitespace --- showtime/window.py | 1 + 1 file changed, 1 insertion(+) diff --git a/showtime/window.py b/showtime/window.py index 198d6d0..a247bba 100644 --- a/showtime/window.py +++ b/showtime/window.py @@ -927,6 +927,7 @@ class ShowtimeWindow(Adw.ApplicationWindow): self.end_timestamp_button.set_label( "-" + nanoseconds_to_timestamp(dur - pos) ) + @Gtk.Template.Callback() def _cycle_end_timestamp_type (self, *_args: Any) -> None: match shared.end_timestamp_type: -- GitLab From 8a71fdc32fb61e6ab53a583cf68ea20acc19690a Mon Sep 17 00:00:00 2001 From: kramo Date: Tue, 13 Aug 2024 15:38:43 +0200 Subject: [PATCH 5/5] general: Format window.py --- showtime/window.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/showtime/window.py b/showtime/window.py index a247bba..ded97f7 100644 --- a/showtime/window.py +++ b/showtime/window.py @@ -294,8 +294,7 @@ class ShowtimeWindow(Adw.ApplicationWindow): ) shared.state_schema.connect( - "changed::end-timestamp-type", - self.__on_end_timestamp_type_changed + "changed::end-timestamp-type", self.__on_end_timestamp_type_changed ) self.volume_scale.connect( @@ -915,28 +914,30 @@ class ShowtimeWindow(Adw.ApplicationWindow): def __on_end_timestamp_type_changed(self, *_args: Any) -> None: shared.end_timestamp_type = shared.state_schema.get_enum("end-timestamp-type") - self.__set_end_timestamp_label(self.play.get_position(), self.play.get_duration()) + self.__set_end_timestamp_label( + self.play.get_position(), self.play.get_duration() + ) - def __set_end_timestamp_label (self, pos: int, dur: int) -> None: + def __set_end_timestamp_label(self, pos: int, dur: int) -> None: match shared.end_timestamp_type: - case 0: # Duration - self.end_timestamp_button.set_label( - nanoseconds_to_timestamp(dur) - ) - case 1: # Remaining + case 0: # Duration + self.end_timestamp_button.set_label(nanoseconds_to_timestamp(dur)) + case 1: # Remaining self.end_timestamp_button.set_label( "-" + nanoseconds_to_timestamp(dur - pos) ) @Gtk.Template.Callback() - def _cycle_end_timestamp_type (self, *_args: Any) -> None: + def _cycle_end_timestamp_type(self, *_args: Any) -> None: match shared.end_timestamp_type: case 0: shared.state_schema.set_enum("end-timestamp-type", 1) case 1: shared.state_schema.set_enum("end-timestamp-type", 0) - self.__set_end_timestamp_label(self.play.get_position(), self.play.get_duration()) + self.__set_end_timestamp_label( + self.play.get_position(), self.play.get_duration() + ) @Gtk.Template.Callback() def _resume(self, *_args: Any) -> None: -- GitLab