From 17eac3de50f258ede753faac61daa878ff74ec90 Mon Sep 17 00:00:00 2001 From: "N0\\A" Date: Sun, 1 Feb 2026 20:37:29 +0100 Subject: [PATCH] Actual disk names --- iridium_installer/ui/pages/partitioning.py | 132 +++++++++++++++++++++ iridium_installer/ui/pages/storage.py | 81 +++++++++---- iridium_installer/ui/window.py | 2 + 3 files changed, 189 insertions(+), 26 deletions(-) create mode 100644 iridium_installer/ui/pages/partitioning.py diff --git a/iridium_installer/ui/pages/partitioning.py b/iridium_installer/ui/pages/partitioning.py new file mode 100644 index 0000000..009a968 --- /dev/null +++ b/iridium_installer/ui/pages/partitioning.py @@ -0,0 +1,132 @@ +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, Gdk, Gtk + + +class PartitioningPage(Adw.Bin): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Main Layout + clamp = Adw.Clamp() + clamp.set_maximum_size(800) + self.set_child(clamp) + + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + box.set_spacing(24) + box.set_margin_top(24) + box.set_margin_bottom(24) + clamp.set_child(box) + + # Title + title = Gtk.Label(label="Disk Configuration") + title.add_css_class("title-1") + box.append(title) + + descr = Gtk.Label( + label="Review and modify the partition layout for your installation." + ) + descr.set_wrap(True) + box.append(descr) + + # Selected Disk Info (Mock) + disk_info_group = Adw.PreferencesGroup() + disk_info_group.set_title("Selected Drive") + box.append(disk_info_group) + + row = Adw.ActionRow() + row.set_title("NVMe Samsung 970 EVO") + row.set_subtitle("500 GB - /dev/nvme0n1") + row.set_icon_name("drive-harddisk-solidstate-symbolic") + disk_info_group.add(row) + + # Partition Bar (The "Horizontal Bar") + bar_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + bar_box.set_spacing(12) + box.append(bar_box) + + bar_label = Gtk.Label(label="Partition Layout", xalign=0) + bar_label.add_css_class("heading") + bar_box.append(bar_label) + + # The Visual Bar + # We use a horizontal box with homogeneous=False + visual_bar = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + visual_bar.add_css_class("card") # Gives it a border/background + visual_bar.set_overflow(Gtk.Overflow.HIDDEN) + visual_bar.set_size_request(-1, 60) # Height of the bar + bar_box.append(visual_bar) + + # Segment 1: EFI + seg1 = Gtk.Box() + seg1.set_hexpand(False) + seg1.set_size_request(50, -1) # Mock width for small partition + seg1.add_css_class("accent") # Blue-ish usually + # Add a tooltip or label inside? + seg1.set_tooltip_text("/dev/nvme0n1p1 (EFI) - 512 MB") + visual_bar.append(seg1) + + # Separator (optional, or just rely on boxes) + + # Segment 2: Root + seg2 = Gtk.Box() + seg2.set_hexpand(True) # Takes remaining space + seg2.add_css_class("success") # Green-ish usually + seg2.set_tooltip_text("/dev/nvme0n1p2 (Root) - 499.5 GB") + visual_bar.append(seg2) + + # Legend + legend_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + legend_box.set_spacing(12) + legend_box.set_halign(Gtk.Align.CENTER) + bar_box.append(legend_box) + + self.add_legend_item(legend_box, "accent", "EFI System") + self.add_legend_item(legend_box, "success", "Root Filesystem") + + # Partition Table (Detailed List) + part_list_group = Adw.PreferencesGroup() + part_list_group.set_title("Partitions") + box.append(part_list_group) + + p1 = Adw.ActionRow() + p1.set_title("/dev/nvme0n1p1") + p1.set_subtitle("EFI System Partition - FAT32") + p1.add_suffix(Gtk.Label(label="512 MB")) + part_list_group.add(p1) + + p2 = Adw.ActionRow() + p2.set_title("/dev/nvme0n1p2") + p2.set_subtitle("Root - Ext4") + p2.add_suffix(Gtk.Label(label="499.5 GB")) + part_list_group.add(p2) + + # Controls + actions_group = Adw.PreferencesGroup() + box.append(actions_group) + + btn_row = Adw.ActionRow() + btn_row.set_title("Manual Partitioning") + btn_row.set_subtitle("Open external partition editor (GParted)") + + edit_btn = Gtk.Button(label="Open Editor") + edit_btn.set_valign(Gtk.Align.CENTER) + btn_row.add_suffix(edit_btn) + actions_group.add(btn_row) + + def add_legend_item(self, box, style_class, label_text): + item = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + item.set_spacing(6) + + swatch = Gtk.Box() + swatch.set_size_request(16, 16) + swatch.add_css_class(style_class) + swatch.add_css_class("circular") # Make it round if supported, or just a box + + label = Gtk.Label(label=label_text) + + item.append(swatch) + item.append(label) + box.append(item) diff --git a/iridium_installer/ui/pages/storage.py b/iridium_installer/ui/pages/storage.py index 88fd6c6..18d2372 100644 --- a/iridium_installer/ui/pages/storage.py +++ b/iridium_installer/ui/pages/storage.py @@ -1,3 +1,6 @@ +import json +import subprocess + import gi gi.require_version("Gtk", "4.0") @@ -32,21 +35,25 @@ class StoragePage(Adw.Bin): box.append(descr) # Disk List - group = Adw.PreferencesGroup() - group.set_title("Available Disks") - box.append(group) + self.disk_group = Adw.PreferencesGroup() + self.disk_group.set_title("Available Disks") + box.append(self.disk_group) - # Mock Disks - disks = [ - ( - "NVMe Samsung 970 EVO (500GB)", - "nvme0n1", - "icon-drive-harddisk-solidstate-symbolic", - ), - ("SATA Seagate Barracuda (1TB)", "sda", "icon-drive-harddisk-symbolic"), - ] + # Fetch real disks or fallback to mock + disks = self.get_disks() + if not disks: + disks = [ + ( + "NVMe Samsung 970 EVO (500GB)", + "nvme0n1", + "icon-drive-harddisk-solidstate-symbolic", + ), + ("SATA Seagate Barracuda (1TB)", "sda", "icon-drive-harddisk-symbolic"), + ] self.disk_rows = [] + self.first_radio = None + for name, dev, icon in disks: row = Adw.ActionRow() row.set_title(name) @@ -54,7 +61,7 @@ class StoragePage(Adw.Bin): row.set_icon_name(icon) # Radio button for selection - if not self.disk_rows: + if not self.first_radio: radio = Gtk.CheckButton() self.first_radio = radio else: @@ -65,19 +72,41 @@ class StoragePage(Adw.Bin): row.add_suffix(radio) row.set_activatable_widget(radio) - group.add(row) + self.disk_group.add(row) self.disk_rows.append(row) - # Partitioning Options - part_group = Adw.PreferencesGroup() - part_group.set_title("Configuration") - box.append(part_group) + def get_disks(self): + try: + # lsblk -J -o NAME,SIZE,MODEL,TYPE,TRAN + result = subprocess.run( + ["lsblk", "-J", "-o", "NAME,SIZE,MODEL,TYPE,TRAN"], + capture_output=True, + text=True, + ) + if result.returncode != 0: + print(f"lsblk failed with code {result.returncode}: {result.stderr}") + return [] - auto_row = Adw.ActionRow() - auto_row.set_title("Automatic Partitioning") - auto_row.set_subtitle("Erase disk and install Iridium") - part_switch = Gtk.Switch() - part_switch.set_active(True) - part_switch.set_valign(Gtk.Align.CENTER) - auto_row.add_suffix(part_switch) - part_group.add(auto_row) + data = json.loads(result.stdout) + disks = [] + for device in data.get("blockdevices", []): + # Filter for physical disks usually + if device.get("type") == "disk": + model = device.get("model") + size = device.get("size") + name = f"{model} ({size})" if model else f"Unknown Drive ({size})" + dev = device.get("name") + + tran = device.get("tran", "").lower() if device.get("tran") else "" + if "usb" in tran: + icon = "drive-removable-media-symbolic" + elif "nvme" in dev: + icon = "drive-harddisk-solidstate-symbolic" + else: + icon = "drive-harddisk-symbolic" + + disks.append((name, dev, icon)) + return disks + except Exception as e: + print(f"Error getting disks: {e}") + return [] diff --git a/iridium_installer/ui/window.py b/iridium_installer/ui/window.py index 5c613a8..7582c1d 100644 --- a/iridium_installer/ui/window.py +++ b/iridium_installer/ui/window.py @@ -4,6 +4,7 @@ gi.require_version("Gtk", "4.0") gi.require_version("Adw", "1") from gi.repository import Adw, Gtk +from .pages.partitioning import PartitioningPage from .pages.storage import StoragePage from .pages.user import UserPage from .pages.welcome import WelcomePage @@ -63,6 +64,7 @@ class InstallerWindow(Adw.ApplicationWindow): # Add Pages self.add_page(WelcomePage(), "welcome") self.add_page(StoragePage(), "storage") + self.add_page(PartitioningPage(), "partitioning") self.add_page(UserPage(), "user") # Initialize view