diff --git a/src/meson.build b/src/meson.build index 4b1ef9e..816b91b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -22,6 +22,7 @@ blueprints = custom_target('blueprints', 'snapshot_page/snapshot_page.blp', 'snapshot_page/snapshots_list_page.blp', 'snapshot_page/snapshot_box.blp', + 'snapshot_page/new_snapshot_dialog.blp', 'install_page/install_page.blp', 'install_page/result_row.blp', 'install_page/select_page.blp', @@ -88,6 +89,7 @@ warehouse_sources = [ 'snapshot_page/snapshot_page.py', 'snapshot_page/snapshots_list_page.py', 'snapshot_page/snapshot_box.py', + 'snapshot_page/new_snapshot_dialog.py', 'install_page/install_page.py', 'install_page/result_row.py', 'install_page/select_page.py', diff --git a/src/snapshot_page/new_snapshot_dialog.blp b/src/snapshot_page/new_snapshot_dialog.blp new file mode 100644 index 0000000..eed8004 --- /dev/null +++ b/src/snapshot_page/new_snapshot_dialog.blp @@ -0,0 +1,72 @@ +using Gtk 4.0; +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"] + } + } + [top] + SearchBar search_bar { + search-mode-enabled: bind search_button.active bidirectional; + key-capture-widget: template; + SearchEntry search_entry { + hexpand: true; + placeholder-text: _("Search Apps"); + } + } + 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"] + } + } + } + } + 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"] + } + } + } + } + } +} diff --git a/src/snapshot_page/new_snapshot_dialog.py b/src/snapshot_page/new_snapshot_dialog.py new file mode 100644 index 0000000..a978554 --- /dev/null +++ b/src/snapshot_page/new_snapshot_dialog.py @@ -0,0 +1,64 @@ +from gi.repository import Adw, Gtk, GLib, Gio +from .host_info import HostInfo +from .error_toast import ErrorToast +from .loading_status import LoadingStatus +from .app_row import AppRow +import subprocess, os + +@Gtk.Template(resource_path="/io/github/flattool/Warehouse/snapshot_page/new_snapshot_dialog.ui") +class NewSnapshotDialog(Adw.Dialog): + __gtype_name__ = "NewSnapshotDialog" + gtc = Gtk.Template.Child + + nav_view = gtc() + + app_list_page = gtc() + list_cancel_button = gtc() + next_button = gtc() + listbox = gtc() + + details_page = gtc() + create_button = gtc() + + def row_gesture_handler(self, row): + row.check_button.set_active(not row.check_button.get_active()) + + def row_select_handler(self, row): + if row.check_button.get_active(): + 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")) + + def generate_list(self, *args): + for package in HostInfo.flatpaks: + if package.is_runtime or not os.path.exists(package.data_path): + continue + row = AppRow(package, self.row_gesture_handler) + row.check_button.set_visible(True) + 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)) + + def sort_func(self, row1, row2): + return row1.get_title().lower() > row2.get_title().lower() + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + # Extra Object Creations + self.rows = [] + self.selected_rows = [] + + # Connections + self.list_cancel_button.connect("clicked", lambda *_: self.close()) + self.next_button.connect("clicked", lambda *_: self.nav_view.push(self.details_page)) + + # Apply + Gio.Task.new(None, None, None).run_in_thread(self.generate_list) + self.listbox.set_sort_func(self.sort_func) diff --git a/src/snapshot_page/snapshot_page.py b/src/snapshot_page/snapshot_page.py index 4a2cac5..3a99cf3 100644 --- a/src/snapshot_page/snapshot_page.py +++ b/src/snapshot_page/snapshot_page.py @@ -5,6 +5,7 @@ from .app_row import AppRow from .snapshots_list_page import SnapshotsListPage from .sidebar_button import SidebarButton from .loading_status import LoadingStatus +from .new_snapshot_dialog import NewSnapshotDialog import os, subprocess class LeftoverSnapshotRow(Adw.ActionRow): @@ -184,6 +185,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)) # Apply self.loading_view.set_content(LoadingStatus(_("Loading Snapshots"), _("This should only take a moment"))) diff --git a/src/warehouse.gresource.xml b/src/warehouse.gresource.xml index 1e78244..ba13402 100644 --- a/src/warehouse.gresource.xml +++ b/src/warehouse.gresource.xml @@ -20,6 +20,7 @@ snapshot_page/snapshot_page.ui snapshot_page/snapshots_list_page.ui snapshot_page/snapshot_box.ui + snapshot_page/new_snapshot_dialog.ui install_page/install_page.ui install_page/result_row.ui install_page/select_page.ui