-
-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* First sketchy redesign of sleep timer * Clean up sleep timer view model, fix quirks * Remove togglable sleep timer fadeout preference Instead of this being an optional thing, let's make it an actual feature, and use it always * Format changed files * Move timer row constructors to functions, clean up * Show timer button now that it works on mobile * Add remaining time when adding +5 minutes to chapter end * Reuse tick from player for sleep timer This makes everything much simpler, and also makes it sure, that the two counters are synchronized visually * 20 hours for sleep timer is way too much. Reduce it to 5 * Format changed files * Adjustments in UI file * Looks like we were doing some unnecessary work * Another bits of obsolete code * Fix a Gtk warning * Make the spin row a bit nicer to use with hacks
- Loading branch information
Showing
16 changed files
with
265 additions
and
322 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,150 @@ | ||
from __future__ import annotations | ||
|
||
import inject | ||
from gi.repository import Gtk | ||
from gi.repository import Adw, Gio, GLib, Gtk | ||
|
||
from cozy.view_model.sleep_timer_view_model import SleepTimerViewModel, SystemPowerControl | ||
from cozy.control.time_format import min_to_human_readable, seconds_to_time | ||
from cozy.view_model.sleep_timer_view_model import SleepTimerViewModel | ||
|
||
|
||
@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/timer_popover.ui') | ||
class SleepTimer(Gtk.Popover): | ||
@Gtk.Template.from_resource("/com/github/geigi/cozy/ui/sleep_timer_dialog.ui") | ||
class SleepTimer(Adw.Dialog): | ||
__gtype_name__ = "SleepTimer" | ||
|
||
_view_model = inject.attr(SleepTimerViewModel) | ||
|
||
timer_scale: Gtk.Scale = Gtk.Template.Child() | ||
timer_label: Gtk.Label = Gtk.Template.Child() | ||
timer_grid: Gtk.Grid = Gtk.Template.Child() | ||
min_label: Gtk.Label = Gtk.Template.Child() | ||
chapter_switch: Gtk.Switch = Gtk.Template.Child() | ||
|
||
power_control_switch: Gtk.Switch = Gtk.Template.Child() | ||
power_control_options: Gtk.Box = Gtk.Template.Child() | ||
system_shutdown_radiob: Gtk.CheckButton = Gtk.Template.Child() | ||
system_suspend_radiob: Gtk.CheckButton = Gtk.Template.Child() | ||
list: Adw.PreferencesGroup = Gtk.Template.Child() | ||
stack: Gtk.Stack = Gtk.Template.Child() | ||
set_timer_button: Gtk.Button = Gtk.Template.Child() | ||
timer_state: Adw.StatusPage = Gtk.Template.Child() | ||
toolbarview: Adw.ToolbarView = Gtk.Template.Child() | ||
till_end_of_chapter_button_row: Adw.ButtonRow = Gtk.Template.Child() | ||
|
||
def __init__(self, timer_image: Gtk.Image): | ||
def __init__(self, parent_button: Gtk.Button): | ||
super().__init__() | ||
self._parent_button = parent_button | ||
|
||
self._timer_image: Gtk.Image = timer_image | ||
self.custom_adjustment = Gtk.Adjustment(lower=1, upper=300, value=20, step_increment=1) | ||
|
||
self._init_timer_scale() | ||
self._connect_widgets() | ||
timer_action_group = Gio.SimpleActionGroup() | ||
self.insert_action_group("timer", timer_action_group) | ||
|
||
self._connect_view_model() | ||
self.sleep_timer_action = Gio.SimpleAction( | ||
name="selected", state=GLib.Variant("n", 0), parameter_type=GLib.VariantType("n") | ||
) | ||
timer_action_group.add_action(self.sleep_timer_action) | ||
self.sleep_timer_action.connect("notify::state", self._on_timer_interval_selected) | ||
|
||
first_row = self._create_timer_selection_row(5) | ||
self.list.add(first_row) | ||
|
||
for duration in (15, 30, 60, -2): | ||
self.list.add(self._create_timer_selection_row(duration, first_row)) | ||
|
||
self._on_timer_scale_changed(self.timer_scale) | ||
self.spin_row = self._create_spin_timer_row(first_row) | ||
self.list.add(self.spin_row) | ||
self.custom_adjustment.connect("value-changed", self._update_custom_interval_text) | ||
self._update_custom_interval_text() | ||
|
||
def _connect_widgets(self): | ||
self.timer_scale.connect("value-changed", self._on_timer_scale_changed) | ||
self.chapter_switch.connect("state-set", self._on_chapter_switch_changed) | ||
self.power_control_switch.connect("state-set", self._on_power_options_switch_changed) | ||
self.system_suspend_radiob.connect("toggled", self._on_system_action_radio_button_changed) | ||
self.system_shutdown_radiob.connect("toggled", self._on_system_action_radio_button_changed) | ||
self._connect_view_model() | ||
|
||
def _connect_view_model(self): | ||
self._view_model.bind_to("stop_after_chapter", self._on_stop_after_chapter_changed) | ||
self._view_model.bind_to("remaining_seconds", self._on_remaining_seconds_changed) | ||
self._view_model.bind_to("timer_enabled", self._on_timer_enabled_changed) | ||
|
||
def _init_timer_scale(self): | ||
for i in range(0, 121, 30): | ||
self.timer_scale.add_mark(i, Gtk.PositionType.RIGHT, None) | ||
|
||
def _on_timer_scale_changed(self, scale: Gtk.Scale): | ||
value = scale.get_value() | ||
|
||
if value > 0: | ||
self.timer_label.set_visible(True) | ||
self.min_label.set_text(_("min")) | ||
text = str(int(value)) | ||
self.timer_label.set_text(text) | ||
self._view_model.remaining_seconds = value * 60 | ||
else: | ||
self.min_label.set_text(_("Off")) | ||
self.timer_label.set_visible(False) | ||
self._view_model.remaining_seconds = 0 | ||
|
||
def _on_chapter_switch_changed(self, _, state): | ||
self.timer_grid.set_sensitive(not state) | ||
self._view_model.stop_after_chapter = state | ||
def _add_radio_button_to_timer_row( | ||
self, row: Adw.ActionRow, action_target: int, group: Gtk.CheckButton | None | ||
) -> None: | ||
radio = Gtk.CheckButton( | ||
css_classes=["selection-mode"], | ||
group=group, | ||
action_name="timer.selected", | ||
action_target=GLib.Variant("n", action_target), | ||
can_focus=False, | ||
) | ||
row.radio = radio | ||
row.set_activatable_widget(radio) | ||
row.add_prefix(radio) | ||
|
||
def _create_timer_selection_row( | ||
self, duration: int, group: Adw.ActionRow | None = None | ||
) -> Adw.ActionRow: | ||
title = _("End of Chapter") if duration == -2 else min_to_human_readable(duration) | ||
row = Adw.ActionRow(title=title) | ||
self._add_radio_button_to_timer_row(row, duration, group.radio if group else None) | ||
|
||
return row | ||
|
||
def _create_spin_timer_row(self, group: Adw.ActionRow) -> Adw.SpinRow: | ||
spin_row = Adw.SpinRow(adjustment=self.custom_adjustment) | ||
spin_row.add_css_class("sleep-timer") | ||
self._add_radio_button_to_timer_row(spin_row, -1, group.radio) | ||
|
||
spin_button = spin_row.get_first_child().get_last_child().get_last_child() | ||
spin_button.set_halign(Gtk.Align.END) | ||
|
||
spin_row.connect("input", lambda x, y: spin_row.activate() or 0) | ||
|
||
return spin_row | ||
|
||
def _update_custom_interval_text(self, *_) -> None: | ||
self.spin_row.set_title(min_to_human_readable(self.custom_adjustment.get_value())) | ||
|
||
def _on_timer_interval_selected(self, action, _): | ||
value = action.get_state().unpack() | ||
if value != 0: | ||
self.set_timer_button.set_sensitive(True) | ||
|
||
def _on_remaining_seconds_changed(self): | ||
if self._view_model.remaining_seconds < 1: | ||
value = 0 | ||
else: | ||
value = int(self._view_model.remaining_seconds / 60) + 1 | ||
|
||
self.timer_scale.set_value(value) | ||
self.timer_state.set_title(seconds_to_time(self._view_model.remaining_seconds)) | ||
|
||
def _on_power_options_switch_changed(self, _, state): | ||
self.power_control_options.set_sensitive(state) | ||
def _on_stop_after_chapter_changed(self): | ||
self.till_end_of_chapter_button_row.set_visible(not self._view_model.stop_after_chapter) | ||
if self._view_model.stop_after_chapter: | ||
self.timer_state.set_title(_("Stopping After Current Chapter")) | ||
|
||
if not state: | ||
self._view_model.system_power_control = SystemPowerControl.OFF | ||
def _on_timer_enabled_changed(self): | ||
self.stack.set_visible_child_name( | ||
"running" if self._view_model.timer_enabled else "uninitiated" | ||
) | ||
self.toolbarview.set_reveal_bottom_bars(not self._view_model.timer_enabled) | ||
self._parent_button.set_icon_name( | ||
"bed-symbolic" if self._view_model.timer_enabled else "no-bed-symbolic" | ||
) | ||
|
||
def present(self, *_) -> None: | ||
super().present(inject.instance("MainWindow").window) | ||
|
||
@Gtk.Template.Callback() | ||
def close(self, *_): | ||
super().close() | ||
|
||
@Gtk.Template.Callback() | ||
def set_timer(self, *_): | ||
super().close() | ||
|
||
value = self.sleep_timer_action.get_state().unpack() | ||
if value == -1: | ||
self._view_model.remaining_seconds = self.custom_adjustment.get_value() * 60 | ||
elif value == -2: | ||
self._view_model.stop_after_chapter = True | ||
else: | ||
self._on_system_action_radio_button_changed(None) | ||
self._view_model.remaining_seconds = value * 60 | ||
|
||
def _on_system_action_radio_button_changed(self, _): | ||
if self.system_suspend_radiob.get_active(): | ||
self._view_model.system_power_control = SystemPowerControl.SUSPEND | ||
@Gtk.Template.Callback() | ||
def plus_5_minutes(self, *_): | ||
if self._view_model.stop_after_chapter: | ||
self._view_model.remaining_seconds = self._view_model.get_remaining_from_chapter() + 300 | ||
else: | ||
self._view_model.system_power_control = SystemPowerControl.SHUTDOWN | ||
|
||
def _on_stop_after_chapter_changed(self): | ||
self.chapter_switch.set_active(self._view_model.stop_after_chapter) | ||
self._view_model.remaining_seconds += 300 | ||
|
||
def _on_timer_enabled_changed(self): | ||
self._timer_image.set_from_icon_name('bed-symbolic' if self._view_model.timer_enabled else 'no-bed-symbolic') | ||
@Gtk.Template.Callback() | ||
def till_end_of_chapter(self, *_): | ||
self._view_model.stop_after_chapter = True | ||
|
||
@Gtk.Template.Callback() | ||
def cancel_timer(self, *_): | ||
super().close() | ||
self._view_model.remaining_seconds = 0 | ||
self._view_model.stop_after_chapter = False |
Oops, something went wrong.