diff --git a/data/icons/dot-symbolic.svg b/data/icons/dot-symbolic.svg
new file mode 100644
index 0000000..c94c8e1
--- /dev/null
+++ b/data/icons/dot-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/data/icons/folder-templates-symbolic.svg b/data/icons/folder-templates-symbolic.svg
new file mode 100644
index 0000000..4e5faac
--- /dev/null
+++ b/data/icons/folder-templates-symbolic.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/data/icons/vertical-arrows-long-symbolic.svg b/data/icons/vertical-arrows-long-symbolic.svg
new file mode 100644
index 0000000..ac7a6ee
--- /dev/null
+++ b/data/icons/vertical-arrows-long-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/src/main_window/window.py b/src/main_window/window.py
index 023e863..8595323 100644
--- a/src/main_window/window.py
+++ b/src/main_window/window.py
@@ -24,6 +24,7 @@ import time
from gi.repository import Adw, Gdk, Gio, GLib, Gtk
from .packages_page import PackagesPage
+from .user_data_page import UserDataPage
from .const import Config
from .error_toast import ErrorToast
from .status_box import StatusBox
@@ -74,6 +75,8 @@ class WarehouseWindow(Adw.ApplicationWindow):
file_drop = Gtk.DropTarget.new(Gio.File, Gdk.DragAction.COPY)
self.pages = {
self.packages_row: PackagesPage,
+
+ self.user_data_row: UserDataPage,
}
# Apply
diff --git a/src/meson.build b/src/meson.build
index 9c2023e..3f25607 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -11,6 +11,8 @@ blueprints = custom_target('blueprints',
'packages_page/packages_page.blp',
'filters_page/filters_page.blp',
'properties_page/properties_page.blp',
+ 'user_data_page/user_data_page.blp',
+ 'widgets/data_box.blp',
'change_version_page/change_version_page.blp',
),
output: '.',
@@ -62,6 +64,8 @@ warehouse_sources = [
'filters_page/filters_page.py',
'properties_page/properties_page.py',
'change_version_page/change_version_page.py',
+ 'user_data_page/user_data_page.py',
+ 'widgets/data_box.py',
'../data/style.css',
]
diff --git a/src/user_data_page/user_data_page.blp b/src/user_data_page/user_data_page.blp
new file mode 100644
index 0000000..1bbd1cd
--- /dev/null
+++ b/src/user_data_page/user_data_page.blp
@@ -0,0 +1,254 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $UserDataPage : Adw.BreakpointBin {
+ // title: _("User Data");
+ width-request: 1;
+ height-request: 1;
+
+ Adw.Breakpoint {
+ condition ("max-width: 585")
+
+ setters {
+ header_bar.show-title: false;
+ switcher_bar.reveal: true;
+ switcher_bar.visible: true;
+ }
+ }
+
+ Adw.ToolbarView {
+ [top]
+ Adw.HeaderBar header_bar {
+ title-widget:
+ Adw.ViewSwitcher {
+ stack: stack;
+ policy: wide;
+ }
+ ;
+ [start]
+ ToggleButton search_button {
+ icon-name: "system-search-symbolic";
+ tooltip-text: _("Search User Data");
+ }
+ [end]
+ MenuButton sort_button {
+ popover: sort_pop;
+ icon-name: "vertical-arrows-long-symbolic";
+ tooltip-text: _("Sort User Data");
+ }
+ [end]
+ ToggleButton select_button {
+ icon-name: "selection-mode-symbolic";
+ tooltip-text: _("Select User Data");
+ }
+ }
+ [top]
+ Adw.Clamp {
+ SearchBar search_bar {
+ search-mode-enabled: bind search_button.active bidirectional;
+ key-capture-widget: template;
+
+ SearchEntry search_entry {
+ hexpand: true;
+ placeholder-text: _("Search User Data");
+ }
+ }
+ }
+ [bottom]
+ Revealer {
+ reveal-child: bind select_button.active;
+ transition-type: slide_up;
+ [center]
+ Box bottom_bar {
+ styles ["toolbar"]
+ hexpand: true;
+ homogeneous: true;
+ Button select_all_button {
+ styles ["raised"]
+ Adw.ButtonContent {
+ icon-name: "selection-mode-symbolic";
+ label: _("Select All");
+ can-shrink: true;
+ }
+ }
+ Button copy_button {
+ styles ["raised"]
+ Adw.ButtonContent {
+ icon-name: "edit-copy-symbolic";
+ label: _("Copy");
+ can-shrink: true;
+ }
+ }
+ Button uninstall_button {
+ styles ["raised"]
+ Adw.ButtonContent {
+ icon-name: "user-trash-symbolic";
+ label: _("Uninstall");
+ can-shrink: true;
+ }
+ }
+ }
+ }
+ [bottom]
+ Adw.ViewSwitcherBar switcher_bar {
+ stack: stack;
+ visible: false;
+ }
+ Adw.ViewStack stack {
+ Adw.ViewStackPage {
+ name: "active";
+ title: _("Active Data");
+ icon-name: "file-manager-symbolic";
+ child:
+ ScrolledWindow {
+ Box {
+ orientation: vertical;
+ Box {
+ orientation: vertical;
+ margin-start: 24;
+ margin-end: 24;
+ Label {
+ label: _("Active User Data");
+ styles ["title-1"]
+ hexpand: true;
+ halign: start;
+ }
+ Label {
+ label: "32 Items - 39.7 GB";
+ styles ["title-3"]
+ hexpand: true;
+ halign: start;
+ }
+ }
+ Separator {
+ margin-start: 12;
+ margin-end: 12;
+ margin-top: 9;
+ margin-bottom: 6;
+ }
+ FlowBox flow_box {
+ styles ["boxed-list"]
+ homogeneous: true;
+ valign: start;
+ selection-mode: none;
+ max-children-per-line: 6;
+ margin-start: 12;
+ margin-end: 12;
+ margin-bottom: 12;
+ }
+ }
+ }
+ ;
+ }
+ Adw.ViewStackPage {
+ name: "leftover";
+ title: _("Leftover Data");
+ icon-name: "folder-templates-symbolic";
+ child:
+ ScrolledWindow {
+ Box {
+ orientation: vertical;
+ Box {
+ orientation: vertical;
+ margin-start: 24;
+ margin-end: 24;
+ Label {
+ label: _("Leftover User Data");
+ styles ["title-1"]
+ hexpand: true;
+ halign: start;
+ }
+ Label {
+ label: "25 Items - 18.6 GB";
+ styles ["title-3"]
+ hexpand: true;
+ halign: start;
+ }
+ }
+ Separator {
+ margin-start: 12;
+ margin-end: 12;
+ margin-top: 9;
+ margin-bottom: 6;
+ }
+ FlowBox {
+ styles ["boxed-list"]
+ homogeneous: true;
+ valign: start;
+ selection-mode: none;
+ max-children-per-line: 6;
+ margin-start: 12;
+ margin-end: 12;
+ margin-bottom: 12;
+ }
+ }
+ }
+ ;
+ }
+ }
+ }
+}
+
+Popover sort_pop {
+ styles ["menu"]
+ Box {
+ orientation: vertical;
+ margin-start: 6;
+ margin-end: 6;
+ margin-top: 6;
+ margin-bottom: 6;
+ Box {
+ homogeneous: true;
+ spacing: 3;
+ ToggleButton asc {
+ styles ["flat"]
+ label: _("Ascending");
+ can-focus: bind asc.active inverted;
+ can-target: bind asc.active inverted;
+ }
+ ToggleButton dsc {
+ styles ["flat"]
+ label: _("Descending");
+ active: bind asc.active inverted bidirectional;
+ can-focus: bind dsc.active inverted;
+ can-target: bind dsc.active inverted;
+ }
+ }
+ Separator {
+ }
+ Box sort_list {
+ orientation: vertical;
+ ToggleButton sort_name {
+ styles ["flat"]
+ can-focus: bind sort_name.active inverted;
+ can-target: bind sort_name.active inverted;
+ Label {
+ styles ["body"]
+ halign: start;
+ label: _("Sort By Name");
+ }
+ }
+ ToggleButton sort_id {
+ styles ["flat"]
+ can-focus: bind sort_id.active inverted;
+ can-target: bind sort_id.active inverted;
+ Label {
+ styles ["body"]
+ halign: start;
+ label: _("Sort By ID");
+ }
+ }
+ ToggleButton sort_size {
+ active: true;
+ can-focus: bind sort_size.active inverted;
+ can-target: bind sort_size.active inverted;
+ styles ["flat"]
+ Label {
+ styles ["body"]
+ halign: start;
+ label: _("Sort By Size");
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/user_data_page/user_data_page.py b/src/user_data_page/user_data_page.py
new file mode 100644
index 0000000..f5ad5a8
--- /dev/null
+++ b/src/user_data_page/user_data_page.py
@@ -0,0 +1,58 @@
+from gi.repository import Adw, Gtk, GLib, Gio, Pango
+from .host_info import HostInfo
+from .error_toast import ErrorToast
+from .data_box import DataBox
+
+@Gtk.Template(resource_path="/io/github/flattool/Warehouse/user_data_page/user_data_page.ui")
+class UserDataPage(Adw.BreakpointBin):
+ __gtype_name__ = 'UserDataPage'
+ gtc = Gtk.Template.Child
+ select_button = gtc()
+ flow_box = gtc()
+ sort_pop = gtc()
+ sort_list = gtc()
+ sort_name = gtc()
+ sort_id = gtc()
+ sort_size = 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 set_selection_mode(self, is_enabled):
+ i = 0
+ while row := self.flow_box.get_child_at_index(i):
+ i += 1
+ row = row.get_child()
+ row.check_button.set_visible(is_enabled)
+ row.check_button.set_active(False)
+
+ def sort_handler(self, button):
+ if button.get_active() == False:
+ return
+ self.sort_name.set_active(self.sort_name is button)
+ self.sort_id.set_active(self.sort_id is button)
+ self.sort_size.set_active(self.sort_size is button)
+ if button is self.sort_name:
+ self.sort_id.grab_focus()
+ else:
+ self.sort_name.grab_focus()
+
+ def __init__(self, main_window, **kwargs):
+ super().__init__(**kwargs)
+
+ # Apply
+ self.__class__.instance = self
+
+ for i in range(10):
+ box = DataBox(main_window, "/home/heliguy/.var/app/io.github.io.github.flattool.Warehouse/")
+ self.flow_box.append(box)
+ self.flow_box.get_child_at_index(i).set_focusable(False)
+
+ # self.select_button.connect("toggled", lambda *_: self.set_selection_mode(self.select_button.get_active()))
+ # self.flow_box.connect("child-activated", lambda _, item: (cb := (row := item.get_child()).check_button).set_active((not cb.get_active()) if row.get_activatable() else False))
+
+ self.sort_name.connect("toggled", self.sort_handler)
+ self.sort_id.connect("toggled", self.sort_handler)
+ self.sort_size.connect("toggled", self.sort_handler)
\ No newline at end of file
diff --git a/src/warehouse.gresource.xml b/src/warehouse.gresource.xml
index 52f9312..5b40ffa 100644
--- a/src/warehouse.gresource.xml
+++ b/src/warehouse.gresource.xml
@@ -9,7 +9,9 @@
filters_page/filters_page.ui
properties_page/properties_page.ui
change_version_page/change_version_page.ui
+ user_data_page/user_data_page.ui
widgets/status_box.ui
+ widgets/data_box.ui
@@ -49,5 +51,8 @@
../data/icons/error-small-symbolic.svg
../data/icons/copy-symbolic.svg
../data/icons/double-ended-arrows-vertical-symbolic.svg
+ ../data/icons/vertical-arrows-long-symbolic.svg
+ ../data/icons/dot-symbolic.svg
+ ../data/icons/folder-templates-symbolic.svg
diff --git a/src/widgets/data_box.blp b/src/widgets/data_box.blp
new file mode 100644
index 0000000..695d814
--- /dev/null
+++ b/src/widgets/data_box.blp
@@ -0,0 +1,77 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $DataBox : ListBox {
+ selection-mode: none;
+ styles ["boxed-list"]
+ Adw.ActionRow row {
+ activatable: bind check_button.visible;
+ width-request: 275;
+ [child]
+ Box root_box {
+ orientation: vertical;
+ Box title_box {
+ margin-top: 12;
+ margin-bottom: 12;
+ Image app_icon {
+ margin-start: 12;
+ margin-end: 12;
+ icon-name: "application-x-executable-symbolic";
+ icon-size: large;
+ }
+ Box label_box {
+ orientation: vertical;
+ Label title_label {
+ label: "No Title Set";
+ hexpand: true;
+ halign: start;
+ ellipsize: middle;
+ margin-end: 12;
+ styles ["title-4"]
+ }
+ Label subtitle_label {
+ label: "No subtitle set";
+ hexpand: true;
+ halign: start;
+ ellipsize: middle;
+ margin-end: 12;
+ }
+ }
+ }
+ Box content_box {
+ spacing: 6;
+ margin-start: 12;
+ margin-end: 6;
+ margin-bottom: 6;
+ Label size_label {
+ label: "No size set";
+ halign: start;
+ hexpand: true;
+ }
+ Button copy_button {
+ icon-name: "copy-symbolic";
+ tooltip-text: _("Copy Path");
+ visible: bind check_button.visible inverted;
+ styles ["flat", "circular"]
+ }
+ Button open_button {
+ icon-name: "folder-open-symbolic";
+ tooltip-text: _("Open User Data");
+ visible: bind check_button.visible inverted;
+ styles ["flat", "circular"]
+ }
+ Button trash_button {
+ icon-name: "user-trash-symbolic";
+ tooltip-text: _("Trash User Data");
+ visible: bind check_button.visible inverted;
+ styles ["flat", "circular"]
+ }
+ CheckButton check_button {
+ visible: false;
+ sensitive: bind check_button.visible;
+ styles ["selection-mode"]
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/widgets/data_box.py b/src/widgets/data_box.py
new file mode 100644
index 0000000..d67c5c1
--- /dev/null
+++ b/src/widgets/data_box.py
@@ -0,0 +1,13 @@
+from gi.repository import Adw, Gtk, GLib, Gio, Pango
+from .host_info import HostInfo
+
+@Gtk.Template(resource_path="/io/github/flattool/Warehouse/widgets/data_box.ui")
+class DataBox(Gtk.ListBox):
+ __gtype_name__ = 'DataBox'
+ gtc = Gtk.Template.Child
+
+ title_label = gtc()
+ check_button = gtc()
+
+ def __init__(self, main_window, path, **kwargs):
+ super().__init__(**kwargs)
\ No newline at end of file