diff --git a/data/icons/arrow-pointing-at-line-down-symbolic.svg b/data/icons/arrow-pointing-at-line-down-symbolic.svg new file mode 100644 index 0000000..eaefb41 --- /dev/null +++ b/data/icons/arrow-pointing-at-line-down-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/data/icons/file-manager-symbolic.svg b/data/icons/file-manager-symbolic.svg new file mode 100644 index 0000000..db0aa5a --- /dev/null +++ b/data/icons/file-manager-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/data/icons/loupe-large-symbolic.svg b/data/icons/loupe-large-symbolic.svg new file mode 100644 index 0000000..8472dea --- /dev/null +++ b/data/icons/loupe-large-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/data/icons/server-pick-symbolic.svg b/data/icons/server-pick-symbolic.svg new file mode 100644 index 0000000..7ea37f1 --- /dev/null +++ b/data/icons/server-pick-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/data/icons/snapshots-alt-symbolic.svg b/data/icons/snapshots-alt-symbolic.svg new file mode 100644 index 0000000..f6bc5b7 --- /dev/null +++ b/data/icons/snapshots-alt-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/src/main_window/window.blp b/src/main_window/window.blp index 6c57d95..e95ad4e 100644 --- a/src/main_window/window.blp +++ b/src/main_window/window.blp @@ -5,7 +5,7 @@ template $WarehouseWindow: Adw.ApplicationWindow { title: "Warehouse"; // default-width: 240; default-width: 865; - width-request: 360; + width-request: 400; height-request: 360; Adw.Breakpoint main_breakpoint { condition ("min-width: 865") @@ -31,6 +31,7 @@ template $WarehouseWindow: Adw.ApplicationWindow { [start] Button sidebar_button { icon-name: "dock-left-symbolic"; + tooltip-text: _("Hide Sidebar"); } [end] MenuButton main_menu { @@ -41,9 +42,87 @@ template $WarehouseWindow: Adw.ApplicationWindow { } content: ScrolledWindow { - ListBox { - Adw.ActionRow { - title: "test"; + ListBox navigation_row_listbox { + styles ["navigation-sidebar"] + + Box packages_row { + margin-top: 12; + margin-bottom: 12; + margin-start: 6; + margin-end: 6; + spacing: 12; + + Image icon { + icon-name: "flatpak-symbolic"; + } + + Label { + label: _("Packages"); + } + } + + Box remotes_row { + margin-top: 12; + margin-bottom: 12; + margin-start: 6; + margin-end: 6; + spacing: 12; + + Image { + icon-name: "server-pick-symbolic"; + } + + Label { + label: _("Remotes"); + } + } + + Box user_data_row { + margin-top: 12; + margin-bottom: 12; + margin-start: 6; + margin-end: 6; + spacing: 12; + + Image { + icon-name: "file-manager-symbolic"; + } + + Label { + label: _("User Data"); + } + } + + Box snapshots_row { + margin-top: 12; + margin-bottom: 12; + margin-start: 6; + margin-end: 6; + spacing: 12; + + Image { + icon-name: "snapshots-alt-symbolic"; + } + + Label { + label: _("Snapshots"); + } + } + + Box install_row { + margin-top: 12; + margin-bottom: 12; + margin-start: 6; + margin-end: 6; + spacing: 12; + + Image { + icon-name: "arrow-pointing-at-line-down-symbolic"; + } + + Label { + label: _("Install Packages"); + } } } } diff --git a/src/main_window/window.py b/src/main_window/window.py index 7e5026e..d661159 100644 --- a/src/main_window/window.py +++ b/src/main_window/window.py @@ -33,13 +33,36 @@ class WarehouseWindow(Adw.ApplicationWindow): main_breakpoint = gtc() main_split = gtc() sidebar_button = gtc() + navigation_row_listbox = gtc() + packages_row = gtc() + remotes_row = gtc() + user_data_row = gtc() + snapshots_row = gtc() + install_row = gtc() def key_handler(self, controller, keyval, keycode, state): if keyval == Gdk.KEY_w and state == Gdk.ModifierType.CONTROL_MASK: self.close() + if keyval == Gdk.KEY_Escape: self.batch_mode_button.set_active(False) + def navigation_handler(self, _, row, hide_sidebar=True): + row = row.get_child() + page = self.pages[row] + + if hide_sidebar and self.main_split.get_collapsed(): + self.main_split.set_show_sidebar(False) + + if type(self.main_split.get_content()) == page: + # Skip when the user clicks on the row that is already showing the page + return + + if page.instance: + self.main_split.set_content(page.instance) + else: + self.main_split.set_content(page(main_window=self)) + def __init__(self, **kwargs): super().__init__(**kwargs) @@ -47,6 +70,9 @@ class WarehouseWindow(Adw.ApplicationWindow): self.settings = Gio.Settings.new("io.github.flattool.Warehouse") event_controller = Gtk.EventControllerKey() file_drop = Gtk.DropTarget.new(Gio.File, Gdk.DragAction.COPY) + self.pages = { + self.packages_row: PackagesPage, + } # Apply self.settings.bind("window-width", self, "default-width", Gio.SettingsBindFlags.DEFAULT) @@ -55,11 +81,15 @@ class WarehouseWindow(Adw.ApplicationWindow): self.settings.bind("is-fullscreen", self, "fullscreened", Gio.SettingsBindFlags.DEFAULT) self.add_controller(event_controller) # self.scrolled_window.add_controller(file_drop) - self.main_split.set_content(PackagesPage(self)) + # self.main_split.set_content(PackagesPage(self)) if Config.DEVEL: self.add_css_class("devel") # Connections event_controller.connect("key-pressed", self.key_handler) + self.navigation_row_listbox.connect("row-activated", self.navigation_handler) # file_drop.connect("drop", self.drop_callback) - self.sidebar_button.connect("clicked", lambda *_: self.main_split.set_show_sidebar(False)) \ No newline at end of file + self.sidebar_button.connect("clicked", lambda *_: self.main_split.set_show_sidebar(False)) + + self.navigation_row_listbox.get_row_at_index(0).activate() + self.main_split.set_show_sidebar(True) \ No newline at end of file diff --git a/src/packages_page/packages_page.blp b/src/packages_page/packages_page.blp index f19edac..df337da 100644 --- a/src/packages_page/packages_page.blp +++ b/src/packages_page/packages_page.blp @@ -20,24 +20,83 @@ template $PackagesPage : Adw.BreakpointBin { sidebar: Adw.NavigationPage { title: "Packages"; - Adw.ToolbarView { + Adw.ToolbarView packages_tbv { [top] Adw.HeaderBar { [start] Button sidebar_button { icon-name: "dock-left-symbolic"; - visible: false; + tooltip-text: _("Show Sidebar"); + } + [start] + ToggleButton search_button { + icon-name: "loupe-large-symbolic"; + tooltip-text: _("Search Packages"); + } + [start] + Button filter_button { + icon-name: "funnel-symbolic"; + tooltip-text: _("Filter Packages"); } [end] Button refresh_button { icon-name: "arrow-circular-top-right-symbolic"; + tooltip-text: _("Refresh List"); } + [end] + ToggleButton select_button { + icon-name: "selection-mode-symbolic"; + tooltip-text: _("Select Packages"); + } + } + [top] + SearchBar search_bar { + search-mode-enabled: bind search_button.active bidirectional; + key-capture-widget: packages_tbv; + SearchEntry search_entry { + hexpand: true; + } } ScrolledWindow { ListBox packages_list_box { styles ["navigation-sidebar"] } } + [bottom] + Revealer { + reveal-child: bind select_button.active; + transition-type: slide_up; + [center] + Box { + styles ["toolbar"] + hexpand: true; + homogeneous: true; + Button { + styles ["raised"] + Adw.ButtonContent { + icon-name: "selection-mode-symbolic"; + label: _("Select All"); + can-shrink: true; + } + } + Button { + styles ["raised"] + Adw.ButtonContent { + icon-name: "edit-copy-symbolic"; + label: _("Copy"); + can-shrink: true; + } + } + Button { + styles ["raised"] + Adw.ButtonContent { + icon-name: "user-trash-symbolic"; + label: _("Uninstall"); + can-shrink: true; + } + } + } + } } } ; diff --git a/src/packages_page/packages_page.py b/src/packages_page/packages_page.py index 1f337f8..ad9a9a2 100644 --- a/src/packages_page/packages_page.py +++ b/src/packages_page/packages_page.py @@ -12,6 +12,11 @@ class PackagesPage(Adw.BreakpointBin): refresh_button = gtc() packages_list_box = gtc() + # Referred to in the main window + # It is used to determine if a new page should be made or not + # This must be set to the created object from within the class's __init__ method + instance = None + def generate_list(self, *args): self.packages_list_box.remove_all() for package in HostInfo.flatpaks: @@ -28,10 +33,12 @@ class PackagesPage(Adw.BreakpointBin): # Apply HostInfo.get_flatpaks(callback=self.generate_list) + self.__class__.instance = self # Connections main_window.main_split.connect("notify::show-sidebar", lambda sidebar, *_: self.sidebar_button.set_visible(sidebar.get_collapsed() or not sidebar.get_show_sidebar())) - # main_window.main_split.connect("notify::collapsed", lambda sidebar, *_: self.sidebar_button.set_visible) + main_window.main_split.connect("notify::collapsed", lambda sidebar, *_: self.sidebar_button.set_visible(sidebar.get_collapsed() or not sidebar.get_show_sidebar())) self.sidebar_button.connect("clicked", lambda *_: main_window.main_split.set_show_sidebar(True)) self.refresh_button.connect("clicked", lambda *_: HostInfo.get_flatpaks(callback=self.generate_list)) # self.packages_list_box.connect("row-selected", self.row_select_handler) + diff --git a/src/warehouse.gresource.xml b/src/warehouse.gresource.xml index ca66e41..274e010 100644 --- a/src/warehouse.gresource.xml +++ b/src/warehouse.gresource.xml @@ -33,5 +33,10 @@ ../data/icons/arrow-turn-left-down-symbolic.svg ../data/icons/arrow-circular-top-right-symbolic.svg ../data/icons/dock-left-symbolic.svg + ../data/icons/server-pick-symbolic.svg + ../data/icons/file-manager-symbolic.svg + ../data/icons/snapshots-alt-symbolic.svg + ../data/icons/arrow-pointing-at-line-down-symbolic.svg + ../data/icons/loupe-large-symbolic.svg diff --git a/src/widgets/app_row.py b/src/widgets/app_row.py index 58ae286..5456b9e 100644 --- a/src/widgets/app_row.py +++ b/src/widgets/app_row.py @@ -19,5 +19,6 @@ class AppRow(Adw.ActionRow): self.set_subtitle(package.info["id"]) if package.icon_path: self.image.set_from_file(package.icon_path) + self.image.add_css_class("icon-dropshadow") # Connections \ No newline at end of file