From e287b60ebb07d82b1ab9b91e3e9c80d277cbadc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=B3=20Albert=20i=20Beltran?= Date: Fri, 24 May 2024 09:14:31 +0200 Subject: [PATCH] Detail Window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use reusable Detail Window instead of a Popover for each task Signed-off-by: Simó Albert i Beltran --- errands/state.py | 4 + .../widgets/shared/task_toolbar/__init__.py | 1 + .../shared/task_toolbar/detail_window.py | 108 ++++++++++++++++++ .../widgets/shared/task_toolbar/toolbar.py | 96 +--------------- 4 files changed, 119 insertions(+), 90 deletions(-) create mode 100644 errands/widgets/shared/task_toolbar/detail_window.py diff --git a/errands/state.py b/errands/state.py index 4c77adbc..4dd32f41 100644 --- a/errands/state.py +++ b/errands/state.py @@ -12,6 +12,7 @@ from errands.lib.notifications import ErrandsNotificationsDaemon from errands.widgets.loading_page import ErrandsLoadingPage from errands.widgets.shared.task_toolbar import ( + DetailWindow, ErrandsDateTimeWindow, ErrandsAttachmentsWindow, ErrandsNotesWindow, @@ -72,12 +73,14 @@ class State: # Attachments window attachments_window: ErrandsAttachmentsWindow | None = None + detail_window: DetailWindow | None = None priority_window: PriorityWindow | None = None tag_window: TagWindow | None = None @classmethod def init(cls) -> None: from errands.widgets.shared.task_toolbar import ( + DetailWindow, ErrandsNotesWindow, ErrandsDateTimeWindow, ErrandsAttachmentsWindow, @@ -85,6 +88,7 @@ def init(cls) -> None: TagWindow, ) + cls.detail_window = DetailWindow() cls.notes_window = ErrandsNotesWindow() cls.priority_window = PriorityWindow() cls.tag_window = TagWindow() diff --git a/errands/widgets/shared/task_toolbar/__init__.py b/errands/widgets/shared/task_toolbar/__init__.py index 14639e89..065b1102 100644 --- a/errands/widgets/shared/task_toolbar/__init__.py +++ b/errands/widgets/shared/task_toolbar/__init__.py @@ -3,6 +3,7 @@ ErrandsAttachmentsWindow, ) from errands.widgets.shared.task_toolbar.datetime_window import ErrandsDateTimeWindow +from errands.widgets.shared.task_toolbar.detail_window import DetailWindow from errands.widgets.shared.task_toolbar.notes_window import ErrandsNotesWindow from errands.widgets.shared.task_toolbar.priority_window import PriorityWindow from errands.widgets.shared.task_toolbar.tag_window import TagWindow diff --git a/errands/widgets/shared/task_toolbar/detail_window.py b/errands/widgets/shared/task_toolbar/detail_window.py new file mode 100644 index 00000000..c0263ac0 --- /dev/null +++ b/errands/widgets/shared/task_toolbar/detail_window.py @@ -0,0 +1,108 @@ +# Copyright 2024 Vlad Krupinskii +# SPDX-License-Identifier: MIT + +from __future__ import annotations + +from datetime import datetime +from typing import TYPE_CHECKING + +from gi.repository import Adw, Gtk # type:ignore + +from errands.lib.logging import Log +from errands.lib.sync.sync import Sync +from errands.state import State +from errands.widgets.shared.color_selector import ErrandsColorSelector +from errands.widgets.shared.components.boxes import ErrandsBox +from errands.widgets.shared.components.buttons import ErrandsCheckButton +from errands.widgets.shared.components.toolbar_view import ErrandsToolbarView + +if TYPE_CHECKING: + from errands.widgets.task import Task + from errands.widgets.today.today_task import TodayTask + + +class DetailWindow(Adw.Dialog): + def __init__(self): + super().__init__() + self.task = None + self.__build_ui() + + # ------ PRIVATE METHODS ------ # + + def __build_ui(self) -> None: + self.set_follows_content_size(True) + self.set_title(_("Details")) + + self.color_selector: ErrandsColorSelector = ErrandsColorSelector( + on_color_selected=self.__on_accent_color_selected + ) + self.created_label = Gtk.Label( + label=_("Created:"), + halign=Gtk.Align.START, + margin_bottom=6, + margin_end=6, + margin_start=6, + css_classes=["caption-heading"], + ) + self.changed_label = Gtk.Label( + label=_("Changed:"), + halign=Gtk.Align.START, + margin_end=6, + margin_start=6, + css_classes=["caption-heading"], + ) + + self.set_child( + ErrandsToolbarView( + top_bars=[Adw.HeaderBar()], + top_bar_style=Adw.ToolbarStyle.RAISED, + content=ErrandsBox( + orientation=Gtk.Orientation.VERTICAL, + margin_bottom=6, + margin_top=6, + margin_end=6, + margin_start=6, + spacing=3, + children=[ + self.color_selector, + self.created_label, + self.changed_label, + ], + ), + ) + ) + + def __on_accent_color_selected( + self, _color_selector, btn: ErrandsCheckButton, color: str + ) -> None: + if not btn.get_active() or self.task.block_signals: + return + Log.debug(f"Task: change color to '{color}'") + if color != self.task.task_data.color: + self.task.update_props( + ["color", "synced"], [color if color != "none" else "", False] + ) + self.task.update_color() + Sync.sync() + + # ------ PUBLIC METHODS ------ # + + def show(self, task: Task | TodayTask): + self.task = task + + # Update dates + created_date: str = datetime.fromisoformat( + self.task.task_data.created_at + ).strftime("%Y.%m.%d %H:%M:%S") + changed_date: str = datetime.fromisoformat( + self.task.task_data.changed_at + ).strftime("%Y.%m.%d %H:%M:%S") + self.created_label.set_label(_("Created:") + " " + created_date) + self.changed_label.set_label(_("Changed:") + " " + changed_date) + + # Update color + self.task.block_signals = True + self.color_selector.select_color(self.task.task_data.color) + self.task.block_signals = False + + self.present(State.main_window) diff --git a/errands/widgets/shared/task_toolbar/toolbar.py b/errands/widgets/shared/task_toolbar/toolbar.py index 038e8eb3..cfef7a86 100644 --- a/errands/widgets/shared/task_toolbar/toolbar.py +++ b/errands/widgets/shared/task_toolbar/toolbar.py @@ -6,15 +6,12 @@ from datetime import datetime from typing import TYPE_CHECKING -from gi.repository import Adw, Gio, GLib, GObject, Gtk # type:ignore +from gi.repository import Adw, Gio, GLib, Gtk # type:ignore -from errands.lib.logging import Log -from errands.lib.sync.sync import Sync from errands.lib.utils import get_human_datetime from errands.state import State -from errands.widgets.shared.color_selector import ErrandsColorSelector from errands.widgets.shared.components.boxes import ErrandsBox -from errands.widgets.shared.components.buttons import ErrandsButton, ErrandsCheckButton +from errands.widgets.shared.components.buttons import ErrandsButton if TYPE_CHECKING: @@ -84,61 +81,12 @@ def __build_ui(self) -> None: on_click=lambda *_: State.attachments_window.show(self.task), ) - # Menu button - menu_top_section: Gio.Menu = Gio.Menu() - menu_colors_item: Gio.MenuItem = Gio.MenuItem() - menu_colors_item.set_attribute_value("custom", GLib.Variant("s", "color")) - menu_top_section.append_item(menu_colors_item) - - menu: Gio.Menu = Gio.Menu() - menu.append_section(None, menu_top_section) - - menu_bottom_section: Gio.Menu = Gio.Menu() - menu_created_item: Gio.MenuItem = Gio.MenuItem() - menu_created_item.set_attribute_value("custom", GLib.Variant("s", "created")) - menu_bottom_section.append_item(menu_created_item) - menu_changed_item: Gio.MenuItem = Gio.MenuItem() - menu_changed_item.set_attribute_value("custom", GLib.Variant("s", "changed")) - menu_bottom_section.append_item(menu_changed_item) - menu.append_section(None, menu_bottom_section) - - popover_menu = Gtk.PopoverMenu(menu_model=menu) - - # Colors - self.color_selector: ErrandsColorSelector = ErrandsColorSelector( - on_color_selected=self.__on_accent_color_selected - ) - popover_menu.add_child(self.color_selector, "color") - - # Created label - self.created_label = Gtk.Label( - label=_("Created:"), - halign=Gtk.Align.START, - margin_bottom=6, - margin_end=6, - margin_start=6, - css_classes=["caption-heading"], - ) - popover_menu.add_child(self.created_label, "created") - - # Changed label - self.changed_label = Gtk.Label( - label=_("Changed:"), - halign=Gtk.Align.START, - margin_end=6, - margin_start=6, - css_classes=["caption-heading"], - ) - popover_menu.add_child(self.changed_label, "changed") - - menu_btn: Gtk.MenuButton = Gtk.MenuButton( - popover=popover_menu, + detail_btn: ErrandsButton = ErrandsButton( + tooltip_text=_("Details"), icon_name="errands-more-symbolic", css_classes=["flat"], - valign=Gtk.Align.CENTER, - tooltip_text=_("More"), + on_click=lambda *_: State.detail_window.show(self.task), ) - menu_btn.connect("notify::active", self._on_menu_toggled) self.append( ErrandsBox( @@ -149,7 +97,7 @@ def __build_ui(self) -> None: self.priority_btn, tag_btn, self.attachments_btn, - menu_btn, + detail_btn, ], ) ) @@ -190,35 +138,3 @@ def update_ui(self): self.attachments_btn.remove_css_class("accent") if len(self.task.task_data.attachments) > 0: self.attachments_btn.add_css_class("accent") - - def __on_accent_color_selected( - self, _color_selector, btn: ErrandsCheckButton, color: str - ) -> None: - if not btn.get_active() or self.task.block_signals: - return - Log.debug(f"Task: change color to '{color}'") - if color != self.task.task_data.color: - self.task.update_props( - ["color", "synced"], [color if color != "none" else "", False] - ) - self.task.update_color() - Sync.sync() - - def _on_menu_toggled(self, btn: Gtk.MenuButton, active: bool) -> None: - if not btn.get_active(): - return - - # Update dates - created_date: str = datetime.fromisoformat( - self.task.task_data.created_at - ).strftime("%Y.%m.%d %H:%M:%S") - changed_date: str = datetime.fromisoformat( - self.task.task_data.changed_at - ).strftime("%Y.%m.%d %H:%M:%S") - self.created_label.set_label(_("Created:") + " " + created_date) - self.changed_label.set_label(_("Changed:") + " " + changed_date) - - # Update color - self.task.block_signals = True - self.color_selector.select_color(self.task.task_data.color) - self.task.block_signals = False