From 5a317f60f9bc835660021627f5236ea5df959c10 Mon Sep 17 00:00:00 2001 From: Heliguy Date: Sun, 8 Sep 2024 13:54:54 -0400 Subject: [PATCH] Make the new snapshots dialog better --- src/snapshot_page/new_snapshot_dialog.blp | 106 +++++++++++++--------- src/snapshot_page/new_snapshot_dialog.py | 78 ++++++++++++---- src/snapshot_page/snapshot_box.py | 2 + src/snapshot_page/snapshot_page.py | 21 +++-- src/snapshot_page/snapshots_list_page.py | 13 ++- 5 files changed, 146 insertions(+), 74 deletions(-) diff --git a/src/snapshot_page/new_snapshot_dialog.blp b/src/snapshot_page/new_snapshot_dialog.blp index eed8004..1965e62 100644 --- a/src/snapshot_page/new_snapshot_dialog.blp +++ b/src/snapshot_page/new_snapshot_dialog.blp @@ -4,31 +4,31 @@ using Adw 1; template $NewSnapshotDialog : Adw.Dialog { follows-content-size: true; width-request: 400; - Adw.NavigationView nav_view { - Adw.NavigationPage app_list_page { - title: _("Choose Applications"); - Adw.ToolbarView { - [top] - Adw.HeaderBar { - show-start-title-buttons: false; - show-end-title-buttons: false; - [start] - Button list_cancel_button { - label: _("Cancel"); - } - [start] - ToggleButton search_button { - icon-name: "loupe-large-symbolic"; - tooltip-text: _("Search Apps"); - } - [end] - Button next_button { - // sensitive: false; - label: _("Next"); - styles ["suggested-action"] - } + Adw.NavigationPage nav_page { + title: "No Title Set"; + Adw.ToolbarView { + [top] + Adw.HeaderBar { + show-start-title-buttons: false; + show-end-title-buttons: false; + [start] + Button list_cancel_button { + label: _("Cancel"); } - [top] + [start] + ToggleButton search_button { + icon-name: "loupe-large-symbolic"; + tooltip-text: _("Search Apps"); + } + [end] + Button create_button { + sensitive: false; + label: _("Create"); + styles ["suggested-action"] + } + } + [top] + Adw.Clamp { SearchBar search_bar { search-mode-enabled: bind search_button.active bidirectional; key-capture-widget: template; @@ -37,35 +37,51 @@ template $NewSnapshotDialog : Adw.Dialog { placeholder-text: _("Search Apps"); } } + } + Adw.Clamp { ScrolledWindow { propagate-natural-height: true; propagate-natural-width: true; - ListBox listbox { - valign: start; - margin-start: 12; - margin-bottom: 12; - margin-top: 12; - margin-end: 12; - selection-mode: none; - styles ["boxed-list"] + Box { + orientation: vertical; + Adw.EntryRow name_entry { + title: "No Title Set"; + margin-start: 12; + margin-end: 12; + margin-top: 12; + margin-bottom: 12; + styles ["card"] + } + ListBox listbox { + valign: start; + margin-start: 12; + margin-end: 12; + // margin-top: 12; + margin-bottom: 12; + selection-mode: none; + styles ["boxed-list"] + } } } } - } - Adw.NavigationPage details_page { - title: _("New Snapshot"); - Adw.ToolbarView { - [top] - Adw.HeaderBar { - show-start-title-buttons: false; - show-end-title-buttons: false; - [end] - Button create_button { - // sensitive: false; - label: _("Snapshot"); - styles ["suggested-action"] + [bottom] + ActionBar { + revealed: bind search_button.visible; + [start] + Button select_all_button { + styles ["raised"] + Adw.ButtonContent { + label: _("Select All"); + icon-name: "selection-mode-symbolic"; } } + [end] + Label total_selected_label { + label: ""; + ellipsize: middle; + margin-end: 6; + visible: false; + } } } } diff --git a/src/snapshot_page/new_snapshot_dialog.py b/src/snapshot_page/new_snapshot_dialog.py index a978554..6cabc14 100644 --- a/src/snapshot_page/new_snapshot_dialog.py +++ b/src/snapshot_page/new_snapshot_dialog.py @@ -10,15 +10,15 @@ class NewSnapshotDialog(Adw.Dialog): __gtype_name__ = "NewSnapshotDialog" gtc = Gtk.Template.Child - nav_view = gtc() - - app_list_page = gtc() + nav_page = gtc() list_cancel_button = gtc() - next_button = gtc() - listbox = gtc() - - details_page = gtc() + search_button = gtc() create_button = gtc() + search_entry = gtc() + name_entry = gtc() + listbox = gtc() + select_all_button = gtc() + total_selected_label = gtc() def row_gesture_handler(self, row): row.check_button.set_active(not row.check_button.get_active()) @@ -28,11 +28,11 @@ class NewSnapshotDialog(Adw.Dialog): self.selected_rows.append(row) else: self.selected_rows.remove(row) - - if (total := len(self.selected_rows)) > 0: - self.app_list_page.set_title(_("{} Selected").format(total)) - else: - self.app_list_page.set_title(_("Choose Applications")) + + self.valid_checker() + total = len(self.selected_rows) + self.total_selected_label.set_label(_("{} Selected").format(total)) + self.total_selected_label.set_visible(total > 0) def generate_list(self, *args): for package in HostInfo.flatpaks: @@ -43,12 +43,43 @@ class NewSnapshotDialog(Adw.Dialog): row.check_button.connect("toggled", lambda *_, row=row: self.row_select_handler(row)) row.set_activatable(True) row.set_activatable_widget(row.check_button) - GLib.idle_add(lambda *_, row=row: self.listbox.append(row)) + self.listbox.append(row) def sort_func(self, row1, row2): - return row1.get_title().lower() > row2.get_title().lower() + return row1.package.info["name"].lower() > row2.package.info["name"].lower() + + def filter_func(self, row): + title = row.get_title().lower() + subtitle = row.get_subtitle().lower() + search = self.search_entry.get_text().lower() + return search in title or search in subtitle + + def on_close(self, *args): + self.search_button.set_active(False) + if len(self.selected_rows) > 1: + while len(self.selected_rows) > 0: + self.selected_rows[0].check_button.set_active(False) - def __init__(self, **kwargs): + def valid_checker(self): + valid = len(self.selected_rows) > 0 and len(self.name_entry.get_text().strip()) > 0 + self.create_button.set_sensitive(valid) + + def on_invalidate(self, search_entry): + self.listbox.invalidate_filter() + + def on_select_all(self, button): + i = 0 + while row := self.listbox.get_row_at_index(i): + i += 1 + row.check_button.set_active(True) + + def set_single(self, package): + row = AppRow(package) + row.set_activatable(False) + self.selected_rows.append(row) + self.listbox.append(row) + + def __init__(self, parent_page, package=None, **kwargs): super().__init__(**kwargs) # Extra Object Creations @@ -56,9 +87,22 @@ class NewSnapshotDialog(Adw.Dialog): self.selected_rows = [] # Connections + self.connect("closed", self.on_close) + self.search_entry.connect("search-changed", self.on_invalidate) self.list_cancel_button.connect("clicked", lambda *_: self.close()) - self.next_button.connect("clicked", lambda *_: self.nav_view.push(self.details_page)) + self.name_entry.connect("changed", lambda *_: self.valid_checker()) + self.select_all_button.connect("clicked", self.on_select_all) # Apply - Gio.Task.new(None, None, None).run_in_thread(self.generate_list) self.listbox.set_sort_func(self.sort_func) + self.listbox.set_filter_func(self.filter_func) + if not package is None: + self.search_entry.set_editable(False) + self.search_button.set_visible(False) + self.nav_page.set_title(_("New Snapshot")) + self.name_entry.set_title(_("Name this Snapshot")) + self.set_single(package) + else: + self.nav_page.set_title(_("New Snapshots")) + self.name_entry.set_title(_("Name these Snapshot")) + self.generate_list() diff --git a/src/snapshot_page/snapshot_box.py b/src/snapshot_page/snapshot_box.py index 7d2ca93..f344278 100644 --- a/src/snapshot_page/snapshot_box.py +++ b/src/snapshot_page/snapshot_box.py @@ -53,6 +53,8 @@ class SnapshotBox(Gtk.Box): name = data['name'] if name != "": self.title.set_label(GLib.markup_escape_text(name)) + else: + self.title.set_label(_("No Name Set")) except Exception as e: self.toast_overlay.add_toast(ErrorToast(_("Could not write data"), str(e)).toast) diff --git a/src/snapshot_page/snapshot_page.py b/src/snapshot_page/snapshot_page.py index 3a99cf3..03bb40d 100644 --- a/src/snapshot_page/snapshot_page.py +++ b/src/snapshot_page/snapshot_page.py @@ -125,21 +125,14 @@ class SnapshotPage(Adw.BreakpointBin): def active_select_handler(self, listbox, row, should_show_content=True, refresh=False): self.leftover_listbox.select_row(None) - self.list_page.set_snapshots(row.package.info["id"], row.package.info["name"], refresh) + self.list_page.set_snapshots(row.package, refresh) self.split_view.set_show_content(should_show_content) def leftover_select_handler(self, listbox, row, should_show_content=True, refresh=False): self.active_listbox.select_row(None) - self.list_page.set_snapshots(row.folder, row.name, refresh) + self.list_page.set_snapshots(row.package, refresh) self.split_view.set_show_content(should_show_content) - def start_loading(self): - self.active_box.set_visible(True) - self.active_listbox.remove_all() - self.leftover_box.set_visible(True) - self.leftover_listbox.remove_all() - self.status_stack.set_visible_child(self.loading_view) - def select_first_row(self): if row := self.active_listbox.get_row_at_index(0): self.active_listbox.select_row(row) @@ -148,8 +141,16 @@ class SnapshotPage(Adw.BreakpointBin): self.leftover_listbox.select_row(row) self.leftover_select_handler(None, row, False, True) + def start_loading(self): + self.active_box.set_visible(True) + self.active_listbox.remove_all() + self.leftover_box.set_visible(True) + self.leftover_listbox.remove_all() + self.status_stack.set_visible_child(self.loading_view) + def end_loading(self): def callback(*args): + self.new_snapshot_dialog = NewSnapshotDialog(self) self.generate_active_list() self.generate_leftover_list() if (not self.active_box.get_visible()) and (not self.leftover_box.get_visible()): @@ -185,7 +186,7 @@ class SnapshotPage(Adw.BreakpointBin): self.leftover_listbox.connect("row-activated", self.leftover_select_handler) self.open_button.connect("clicked", self.open_snapshots_folder, self.toast_overlay) self.status_open_button.connect("clicked", self.open_snapshots_folder, self.no_snapshots_toast) - self.new_button.connect("clicked", lambda *_: NewSnapshotDialog().present(HostInfo.main_window)) + self.new_button.connect("clicked", lambda *_: self.new_snapshot_dialog.present(HostInfo.main_window)) # Apply self.loading_view.set_content(LoadingStatus(_("Loading Snapshots"), _("This should only take a moment"))) diff --git a/src/snapshot_page/snapshots_list_page.py b/src/snapshot_page/snapshots_list_page.py index 98a9d4d..3174439 100644 --- a/src/snapshot_page/snapshots_list_page.py +++ b/src/snapshot_page/snapshots_list_page.py @@ -3,6 +3,7 @@ from .host_info import HostInfo from .error_toast import ErrorToast from .snapshot_box import SnapshotBox from .loading_status import LoadingStatus +from .new_snapshot_dialog import NewSnapshotDialog import os @Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/snapshots_list_page.ui") @@ -14,6 +15,7 @@ class SnapshotsListPage(Adw.NavigationPage): listbox = gtc() toast_overlay = gtc() open_button = gtc() + new_button = gtc() def thread(self, *args): for snapshot in os.listdir(folder := f"{self.snapshots_path}{self.current_folder}/"): @@ -28,12 +30,14 @@ class SnapshotsListPage(Adw.NavigationPage): self.listbox.append(row) self.listbox.get_row_at_index(i).set_activatable(False) - def set_snapshots(self, folder, title, refresh=False): + def set_snapshots(self, package, refresh=False): + folder = package.info["id"] if self.current_folder == folder and not refresh: return + self.current_package = package self.current_folder = folder - self.set_title(_("{} Snapshots").format(title)) + self.set_title(_("{} Snapshots").format(package.info["name"])) self.snapshots_rows.clear() self.listbox.remove_all() @@ -49,6 +53,9 @@ class SnapshotsListPage(Adw.NavigationPage): self.toast_overlay.add_toast(Adw.Toast.new(_("Opened snapshots folder"))) except Exception as e: self.toast_overlay.add_toast(ErrorToast(_("Could not open folder"), str(e)).toast) + + def on_new(self, button): + NewSnapshotDialog(self.parent_page, self.current_package).present(HostInfo.main_window) def __init__(self, parent_page, **kwargs): super().__init__(**kwargs) @@ -57,9 +64,11 @@ class SnapshotsListPage(Adw.NavigationPage): self.parent_page = parent_page self.snapshots_path = parent_page.snapshots_path self.current_folder = None + self.current_package = None self.snapshots_rows = [] # Connections self.open_button.connect("clicked", self.open_snapshots_folder) + self.new_button.connect("clicked", self.on_new) # Apply