# Copyright 2022 (c) Anna Schumaker. """Our playback control widgets.""" from gi.repository import GObject from gi.repository import Gtk from . import autopause from .. import buttons from .. import window MARGIN = 24 class PillButton(buttons.Button): """A Button with the pill style class.""" def __init__(self, **kwargs): """Initialize a Pill Button.""" super().__init__(large_icon=True, **kwargs) self.add_css_class("pill") class Controls(Gtk.Box): """Our playback control widgets.""" autopause = GObject.Property(type=int, default=-1, minimum=-1, maximum=99) playing = GObject.Property(type=bool, default=False) have_next = GObject.Property(type=bool, default=False) have_previous = GObject.Property(type=bool, default=False) have_track = GObject.Property(type=bool, default=False) editing = GObject.Property(type=bool, default=False) can_activate_next = GObject.Property(type=bool, default=False) can_activate_prev = GObject.Property(type=bool, default=False) can_activate_play_pause = GObject.Property(type=bool, default=False) def __init__(self): """Initialize the Controls.""" super().__init__(valign=Gtk.Align.START, homogeneous=True, halign=Gtk.Align.END, hexpand=False, margin_start=MARGIN/2, margin_end=MARGIN, margin_top=MARGIN, margin_bottom=MARGIN) self._autopause = autopause.Button() self._prev = PillButton(icon_name="media-skip-backward", tooltip_text="previous track", sensitive=False) self._play = PillButton(icon_name="play-large", tooltip_text="play", sensitive=False) self._pause = buttons.SplitButton(icon_name="pause-large", large_icon=True, tooltip_text="pause", secondary=self._autopause, visible=False, sensitive=False) self._next = PillButton(icon_name="media-skip-forward", tooltip_text="next track", sensitive=False) for button in [self._prev, self._play, self._pause, self._next]: self.append(button) self._prev.connect("clicked", self.__on_click, "previous") self._play.connect("clicked", self.__on_click, "play") self._pause.connect("clicked", self.__on_click, "pause") self._next.connect("clicked", self.__on_click, "next") self.bind_property("autopause", self._autopause, "value", GObject.BindingFlags.BIDIRECTIONAL) self.bind_property("playing", self._pause, "visible") self.bind_property("playing", self._play, "visible", GObject.BindingFlags.INVERT_BOOLEAN) self.bind_property("have-next", self._next, "sensitive") self.bind_property("have-previous", self._prev, "sensitive") self.bind_property("have-track", self._play, "sensitive") self.bind_property("have-track", self._pause, "sensitive") self.connect("notify", self.__notify) self.add_css_class("linked") def __on_click(self, button: Gtk.Button, signal: str) -> None: self.emit(signal) def __notify_playing(self, controls: Gtk.Box, param) -> None: if not self.playing and self.autopause != -1: if win := self.get_ancestor(window.Window): win.post_toast("Autopause Cancelled") self.autopause = -1 def __notify(self, controls: Gtk.Box, param) -> None: match param.name: case "editing": allowed = not self.editing self.can_activate_next = self.have_next and allowed self.can_activate_prev = self.have_previous and allowed self.can_activate_play_pause = self.have_track and allowed case "playing": self.__notify_playing(controls, param) case "have-next": self.can_activate_next = self.have_next and not self.editing case "have-previous": can_activate = self.have_previous and not self.editing self.can_activate_prev = can_activate case "have-track": can_activate = self.have_track and not self.editing self.can_activate_play_pause = can_activate def activate_next(self) -> None: """Activate the Next button.""" self._next.activate() def activate_previous(self) -> None: """Activate the Previous button.""" self._prev.activate() def activate_play_pause(self) -> None: """Activate the Play or Pause button.""" if self.playing: self._pause.activate() else: self._play.activate() def decrease_autopause(self) -> None: """Decrease the autopause count.""" self._autopause.decrement() def increase_autopause(self) -> None: """Increase the autopause count.""" self._autopause.increment() @GObject.Signal def previous(self) -> None: """Signals that the Previous button has been clicked.""" @GObject.Signal def play(self) -> None: """Signals that the Play button has been clicked.""" @GObject.Signal def pause(self) -> None: """Signals that the Pause button has been clicked.""" @GObject.Signal def next(self) -> None: """Signals that the Next button has been clicked."""