-
-
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.
Merge branch 'master' into welcome-dialog
- 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.