diff --git a/Cargo.toml b/Cargo.toml index 0b8f791..c0156b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ async-channel = "2.1.1" fragile = "2.0.0" glib = "0.18.5" gtk = { version = "0.7.3", package = "gtk4", features = ["v4_12"] } +# parted = { version = "0.1.5", package = "libparted" } pretty-bytes = "0.2.2" time = "0.3.31" vte = { version = "0.0.2", package = "zoha-vte4", features = ["v0_72"] } diff --git a/src/automatic_partitioning/main.rs b/src/automatic_partitioning/main.rs deleted file mode 100644 index 1013cb7..0000000 --- a/src/automatic_partitioning/main.rs +++ /dev/null @@ -1,279 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; - -use std::io::BufRead; -use std::io::BufReader; -use std::process::Command; -use std::process::Stdio; -use std::time::Instant; -use std::env; -use pretty_bytes::converter::convert; - -use std::thread; -use std::time::*; - -use std::fs; -use std::path::Path; -pub fn automatic_partitioning(partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer) { - let partition_method_automatic_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .margin_bottom(15) - .margin_top(15) - .margin_end(15) - .margin_start(15) - .build(); - - let partition_method_automatic_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the partitioning page - let partition_method_automatic_header_text = gtk::Label::builder() - .label("Automatic Partitioning Installer") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - partition_method_automatic_header_text.add_css_class("header_sized_text"); - - // the header icon for the partitioning icon - let partition_method_automatic_header_icon = gtk::Image::builder() - .icon_name("media-playlist-shuffle") - .halign(gtk::Align::Start) - .hexpand(true) - .pixel_size(78) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - - let partition_method_automatic_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - let partition_method_automatic_selection_text = gtk::Label::builder() - .label("Choose the Drive you want to install PikaOS on\nNote: This will erase the entire drive backup your data!") - .justify(Justification::Center) - .halign(gtk::Align::Center) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - partition_method_automatic_selection_text.add_css_class("medium_sized_text"); - - let devices_selection_expander_row = adw::ExpanderRow::builder() - .title("No disk selected for selection") - .build(); - - let null_checkbutton = gtk::CheckButton::builder() - .build(); - - let devices_selection_expander_row_viewport = gtk::ScrolledWindow::builder() - .height_request(200) - .build(); - - let devices_selection_expander_row_viewport_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - devices_selection_expander_row_viewport.set_child(Some(&devices_selection_expander_row_viewport_box)); - - let devices_selection_expander_row_viewport_listbox = gtk::ListBox::builder() - .selection_mode(SelectionMode::None) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - devices_selection_expander_row_viewport_listbox.add_css_class("boxed-list"); - devices_selection_expander_row_viewport_listbox.append(&devices_selection_expander_row); - - devices_selection_expander_row.add_row(&devices_selection_expander_row_viewport); - - let partition_method_automatic_get_devices_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("get_block_devices") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|e| panic!("failed {}", e)); - let partition_method_automatic_get_devices_reader = BufReader::new(partition_method_automatic_get_devices_cli.stdout.expect("could not get stdout")); - - let partition_method_automatic_disk_error_label = gtk::Label::builder() - .label("No Disk specified.") - .halign(Align::Start) - .valign(Align::End) - .vexpand(true) - .build(); - partition_method_automatic_disk_error_label.add_css_class("small_error_text"); - - let partition_method_automatic_luks_error_label = gtk::Label::builder() - .label("LUKS Encryption Enabled but no password provided.") - .halign(Align::Start) - .valign(Align::End) - .vexpand(true) - .visible(false) - .build(); - partition_method_automatic_luks_error_label.add_css_class("small_error_text"); - - let partition_method_automatic_luks_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - let partition_method_automatic_luks_checkbutton = gtk::CheckButton::builder() - .label("Enable LUKS2 Disk Encryption") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - let partition_method_automatic_luks_listbox = gtk::ListBox::builder() - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - partition_method_automatic_luks_listbox.add_css_class("boxed-list"); - - let partition_method_automatic_luks_password_entry = adw::PasswordEntryRow::builder() - .title("LUKS Password") - .hexpand(true) - .sensitive(false) - .build(); - - let partition_method_automatic_target_buffer = gtk::TextBuffer::builder() - .build(); - - let partition_method_automatic_luks_buffer = gtk::TextBuffer::builder() - .build(); - - for device in partition_method_automatic_get_devices_reader.lines() { - let device = device.unwrap(); - let device_size_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("get_block_size") - .arg(device.clone()) - .output() - .expect("failed to execute process"); - let device_size = String::from_utf8(device_size_cli.stdout).expect("Failed to create float").trim().parse::().unwrap(); - let device_button = gtk::CheckButton::builder() - .valign(Align::Center) - .can_focus(false) - .build(); - device_button.set_group(Some(&null_checkbutton)); - let device_row = adw::ActionRow::builder() - .activatable_widget(&device_button) - .title(device.clone()) - .subtitle(pretty_bytes::converter::convert(device_size)) - .build(); - device_row.add_prefix(&device_button); - devices_selection_expander_row_viewport_box.append(&device_row); - device_button.connect_toggled(clone!(@weak device_button,@weak partition_method_automatic_luks_password_entry, @weak devices_selection_expander_row, @weak bottom_next_button, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| { - if device_button.is_active() == true { - devices_selection_expander_row.set_title(&device); - if device_size > 39000000000.0 { - partition_method_automatic_disk_error_label.set_visible(false); - if partition_method_automatic_luks_checkbutton.is_active() == true { - if partition_method_automatic_luks_error_label.get_visible() { - // - } else { - bottom_next_button.set_sensitive(true); - } - } else { - partition_method_automatic_target_buffer.set_text(&device); - partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); - bottom_next_button.set_sensitive(true); - } - } else { - partition_method_automatic_disk_error_label.set_visible(true); - partition_method_automatic_disk_error_label.set_label("Disk Size too small, PikaOS needs 40GB Disk"); - bottom_next_button.set_sensitive(false); - } - } - })); - } - - partition_method_automatic_luks_checkbutton.connect_toggled(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| { - if partition_method_automatic_luks_checkbutton.is_active() == true { - partition_method_automatic_luks_password_entry.set_sensitive(true); - if partition_method_automatic_luks_password_entry.text().to_string().is_empty() { - partition_method_automatic_luks_error_label.set_visible(true); - bottom_next_button.set_sensitive(false); - } else { - partition_method_automatic_luks_error_label.set_visible(false); - if partition_method_automatic_disk_error_label.get_visible() { - // - } else { - bottom_next_button.set_sensitive(true); - } - } - } else { - partition_method_automatic_luks_password_entry.set_sensitive(false); - partition_method_automatic_luks_error_label.set_visible(false); - if partition_method_automatic_disk_error_label.get_visible() { - // - } else { - bottom_next_button.set_sensitive(true); - } - } - })); - - partition_method_automatic_luks_password_entry.connect_changed(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_luks_buffer => move |_| { - if partition_method_automatic_luks_checkbutton.is_active() == true { - partition_method_automatic_luks_password_entry.set_sensitive(true); - if partition_method_automatic_luks_password_entry.text().to_string().is_empty() { - partition_method_automatic_luks_error_label.set_visible(true); - bottom_next_button.set_sensitive(false); - } else { - partition_method_automatic_luks_error_label.set_visible(false); - if partition_method_automatic_disk_error_label.get_visible() { - // - } else { - partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); - bottom_next_button.set_sensitive(true); - } - } - } else { - partition_method_automatic_luks_password_entry.set_sensitive(false); - partition_method_automatic_luks_error_label.set_visible(false); - if partition_method_automatic_disk_error_label.get_visible() { - // - } else { - partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); - bottom_next_button.set_sensitive(true); - } - } - })); - - partition_method_automatic_luks_listbox.append(&partition_method_automatic_luks_password_entry); - partition_method_automatic_luks_box.append(&partition_method_automatic_luks_checkbutton); - partition_method_automatic_luks_box.append(&partition_method_automatic_luks_listbox); - partition_method_automatic_header_box.append(&partition_method_automatic_header_text); - partition_method_automatic_header_box.append(&partition_method_automatic_header_icon); - partition_method_automatic_selection_box.append(&partition_method_automatic_selection_text); - partition_method_automatic_main_box.append(&partition_method_automatic_header_box); - partition_method_automatic_main_box.append(&partition_method_automatic_selection_box); - partition_method_automatic_main_box.append(&devices_selection_expander_row_viewport_listbox); - partition_method_automatic_main_box.append(&partition_method_automatic_luks_box); - partition_method_automatic_main_box.append(&partition_method_automatic_luks_error_label); - partition_method_automatic_main_box.append(&partition_method_automatic_disk_error_label); - - partitioning_stack.add_titled(&partition_method_automatic_main_box, Some("partition_method_automatic_page"), "partition_method_automatic_page"); - - return(partition_method_automatic_target_buffer, partition_method_automatic_luks_buffer) -} \ No newline at end of file diff --git a/src/automatic_partitioning/mod.rs b/src/automatic_partitioning/mod.rs index 5a8f649..1013cb7 100644 --- a/src/automatic_partitioning/mod.rs +++ b/src/automatic_partitioning/mod.rs @@ -1 +1,279 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +use std::io::BufRead; +use std::io::BufReader; +use std::process::Command; +use std::process::Stdio; +use std::time::Instant; +use std::env; +use pretty_bytes::converter::convert; + +use std::thread; +use std::time::*; + +use std::fs; +use std::path::Path; +pub fn automatic_partitioning(partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer) { + let partition_method_automatic_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .margin_bottom(15) + .margin_top(15) + .margin_end(15) + .margin_start(15) + .build(); + + let partition_method_automatic_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the partitioning page + let partition_method_automatic_header_text = gtk::Label::builder() + .label("Automatic Partitioning Installer") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + partition_method_automatic_header_text.add_css_class("header_sized_text"); + + // the header icon for the partitioning icon + let partition_method_automatic_header_icon = gtk::Image::builder() + .icon_name("media-playlist-shuffle") + .halign(gtk::Align::Start) + .hexpand(true) + .pixel_size(78) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + + let partition_method_automatic_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + let partition_method_automatic_selection_text = gtk::Label::builder() + .label("Choose the Drive you want to install PikaOS on\nNote: This will erase the entire drive backup your data!") + .justify(Justification::Center) + .halign(gtk::Align::Center) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + partition_method_automatic_selection_text.add_css_class("medium_sized_text"); + + let devices_selection_expander_row = adw::ExpanderRow::builder() + .title("No disk selected for selection") + .build(); + + let null_checkbutton = gtk::CheckButton::builder() + .build(); + + let devices_selection_expander_row_viewport = gtk::ScrolledWindow::builder() + .height_request(200) + .build(); + + let devices_selection_expander_row_viewport_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + devices_selection_expander_row_viewport.set_child(Some(&devices_selection_expander_row_viewport_box)); + + let devices_selection_expander_row_viewport_listbox = gtk::ListBox::builder() + .selection_mode(SelectionMode::None) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + devices_selection_expander_row_viewport_listbox.add_css_class("boxed-list"); + devices_selection_expander_row_viewport_listbox.append(&devices_selection_expander_row); + + devices_selection_expander_row.add_row(&devices_selection_expander_row_viewport); + + let partition_method_automatic_get_devices_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("get_block_devices") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap_or_else(|e| panic!("failed {}", e)); + let partition_method_automatic_get_devices_reader = BufReader::new(partition_method_automatic_get_devices_cli.stdout.expect("could not get stdout")); + + let partition_method_automatic_disk_error_label = gtk::Label::builder() + .label("No Disk specified.") + .halign(Align::Start) + .valign(Align::End) + .vexpand(true) + .build(); + partition_method_automatic_disk_error_label.add_css_class("small_error_text"); + + let partition_method_automatic_luks_error_label = gtk::Label::builder() + .label("LUKS Encryption Enabled but no password provided.") + .halign(Align::Start) + .valign(Align::End) + .vexpand(true) + .visible(false) + .build(); + partition_method_automatic_luks_error_label.add_css_class("small_error_text"); + + let partition_method_automatic_luks_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + let partition_method_automatic_luks_checkbutton = gtk::CheckButton::builder() + .label("Enable LUKS2 Disk Encryption") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + let partition_method_automatic_luks_listbox = gtk::ListBox::builder() + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + partition_method_automatic_luks_listbox.add_css_class("boxed-list"); + + let partition_method_automatic_luks_password_entry = adw::PasswordEntryRow::builder() + .title("LUKS Password") + .hexpand(true) + .sensitive(false) + .build(); + + let partition_method_automatic_target_buffer = gtk::TextBuffer::builder() + .build(); + + let partition_method_automatic_luks_buffer = gtk::TextBuffer::builder() + .build(); + + for device in partition_method_automatic_get_devices_reader.lines() { + let device = device.unwrap(); + let device_size_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("get_block_size") + .arg(device.clone()) + .output() + .expect("failed to execute process"); + let device_size = String::from_utf8(device_size_cli.stdout).expect("Failed to create float").trim().parse::().unwrap(); + let device_button = gtk::CheckButton::builder() + .valign(Align::Center) + .can_focus(false) + .build(); + device_button.set_group(Some(&null_checkbutton)); + let device_row = adw::ActionRow::builder() + .activatable_widget(&device_button) + .title(device.clone()) + .subtitle(pretty_bytes::converter::convert(device_size)) + .build(); + device_row.add_prefix(&device_button); + devices_selection_expander_row_viewport_box.append(&device_row); + device_button.connect_toggled(clone!(@weak device_button,@weak partition_method_automatic_luks_password_entry, @weak devices_selection_expander_row, @weak bottom_next_button, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| { + if device_button.is_active() == true { + devices_selection_expander_row.set_title(&device); + if device_size > 39000000000.0 { + partition_method_automatic_disk_error_label.set_visible(false); + if partition_method_automatic_luks_checkbutton.is_active() == true { + if partition_method_automatic_luks_error_label.get_visible() { + // + } else { + bottom_next_button.set_sensitive(true); + } + } else { + partition_method_automatic_target_buffer.set_text(&device); + partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); + bottom_next_button.set_sensitive(true); + } + } else { + partition_method_automatic_disk_error_label.set_visible(true); + partition_method_automatic_disk_error_label.set_label("Disk Size too small, PikaOS needs 40GB Disk"); + bottom_next_button.set_sensitive(false); + } + } + })); + } + + partition_method_automatic_luks_checkbutton.connect_toggled(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_target_buffer, @weak partition_method_automatic_luks_buffer => move |_| { + if partition_method_automatic_luks_checkbutton.is_active() == true { + partition_method_automatic_luks_password_entry.set_sensitive(true); + if partition_method_automatic_luks_password_entry.text().to_string().is_empty() { + partition_method_automatic_luks_error_label.set_visible(true); + bottom_next_button.set_sensitive(false); + } else { + partition_method_automatic_luks_error_label.set_visible(false); + if partition_method_automatic_disk_error_label.get_visible() { + // + } else { + bottom_next_button.set_sensitive(true); + } + } + } else { + partition_method_automatic_luks_password_entry.set_sensitive(false); + partition_method_automatic_luks_error_label.set_visible(false); + if partition_method_automatic_disk_error_label.get_visible() { + // + } else { + bottom_next_button.set_sensitive(true); + } + } + })); + + partition_method_automatic_luks_password_entry.connect_changed(clone!(@weak partition_method_automatic_luks_checkbutton, @weak partition_method_automatic_luks_password_entry, @weak partition_method_automatic_disk_error_label, @weak partition_method_automatic_luks_error_label, @weak bottom_next_button, @weak partition_method_automatic_luks_buffer => move |_| { + if partition_method_automatic_luks_checkbutton.is_active() == true { + partition_method_automatic_luks_password_entry.set_sensitive(true); + if partition_method_automatic_luks_password_entry.text().to_string().is_empty() { + partition_method_automatic_luks_error_label.set_visible(true); + bottom_next_button.set_sensitive(false); + } else { + partition_method_automatic_luks_error_label.set_visible(false); + if partition_method_automatic_disk_error_label.get_visible() { + // + } else { + partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); + bottom_next_button.set_sensitive(true); + } + } + } else { + partition_method_automatic_luks_password_entry.set_sensitive(false); + partition_method_automatic_luks_error_label.set_visible(false); + if partition_method_automatic_disk_error_label.get_visible() { + // + } else { + partition_method_automatic_luks_buffer.set_text(&partition_method_automatic_luks_password_entry.text().to_string()); + bottom_next_button.set_sensitive(true); + } + } + })); + + partition_method_automatic_luks_listbox.append(&partition_method_automatic_luks_password_entry); + partition_method_automatic_luks_box.append(&partition_method_automatic_luks_checkbutton); + partition_method_automatic_luks_box.append(&partition_method_automatic_luks_listbox); + partition_method_automatic_header_box.append(&partition_method_automatic_header_text); + partition_method_automatic_header_box.append(&partition_method_automatic_header_icon); + partition_method_automatic_selection_box.append(&partition_method_automatic_selection_text); + partition_method_automatic_main_box.append(&partition_method_automatic_header_box); + partition_method_automatic_main_box.append(&partition_method_automatic_selection_box); + partition_method_automatic_main_box.append(&devices_selection_expander_row_viewport_listbox); + partition_method_automatic_main_box.append(&partition_method_automatic_luks_box); + partition_method_automatic_main_box.append(&partition_method_automatic_luks_error_label); + partition_method_automatic_main_box.append(&partition_method_automatic_disk_error_label); + + partitioning_stack.add_titled(&partition_method_automatic_main_box, Some("partition_method_automatic_page"), "partition_method_automatic_page"); + + return(partition_method_automatic_target_buffer, partition_method_automatic_luks_buffer) +} \ No newline at end of file diff --git a/src/build_ui.rs b/src/build_ui.rs index 3453b4f..67e9844 100644 --- a/src/build_ui.rs +++ b/src/build_ui.rs @@ -12,21 +12,21 @@ use gtk::subclass::layout_child; use std::path::Path; -use crate::save_window_size::main::save_window_size; +use crate::save_window_size::save_window_size; -use crate::welcome_page::main::welcome_page; +use crate::welcome_page::welcome_page; -use crate::efi_error_page::main::efi_error_page; +use crate::efi_error_page::efi_error_page; -use crate::language_page::main::language_page; +use crate::language_page::language_page; -use crate::eula_page::main::eula_page; +use crate::eula_page::eula_page; -use crate::timezone_page::main::timezone_page; +use crate::timezone_page::timezone_page; -use crate::keyboard_page::main::keyboard_page; +use crate::keyboard_page::keyboard_page; -use crate::partitioning_page::main::partitioning_page; +use crate::partitioning_page::partitioning_page; // build ui function linked to app startup above pub fn build_ui(app: &adw::Application) { diff --git a/src/done_page/main.rs b/src/done_page/main.rs deleted file mode 100644 index 33285b0..0000000 --- a/src/done_page/main.rs +++ /dev/null @@ -1,242 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; - -use std::fs; -use std::path::Path; -use std::process::Command; - -pub fn done_page(done_main_box: >k::Box, content_stack: >k::Stack, window: &adw::ApplicationWindow) { - // the header box for the installation_successful page - let done_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the installation_successful page - let done_header_text = gtk::Label::builder() - .label("We're done!") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - done_header_text.add_css_class("header_sized_text"); - - // the header icon for the installation_successful icon - let done_header_icon = gtk::Image::builder() - .icon_name("debian-swirl") - .halign(gtk::Align::Start) - .hexpand(true) - .pixel_size(78) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - - - // Successful install yard - // the header box for the installation_successful page - let installation_successful_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // make installation_successful selection box for choosing installation or live media - let installation_successful_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .margin_bottom(15) - .margin_top(15) - .margin_start(15) - .margin_end(15) - .build(); - - let installation_successful_big_icon = gtk::Image::builder() - .icon_name("emblem-default") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .pixel_size(256) - .margin_top(0) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - let installation_successful_text = gtk::Label::builder() - .label("The installation of PikaOS has been completed sucessfully.") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .build(); - installation_successful_text.add_css_class("header_sized_text"); - - let installation_successful_buttons_line = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .margin_bottom(15) - .margin_top(15) - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .vexpand(true) - .hexpand(true) - .build(); - - let installation_successful_exit_button = gtk::Button::builder() - .label("Exit") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .margin_start(5) - .margin_end(5) - .build(); - - let installation_successful_reboot_button = gtk::Button::builder() - .label("Reboot") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .margin_start(5) - .margin_end(5) - .build(); - - // / installation_successful_selection_box appends - - // / installation_successful_main_box appends - //// Add the installation_successful header to installation_successful main box - installation_successful_main_box.append(&done_header_box); - //// Add the installation_successful selection/page content box to installation_successful main box - installation_successful_main_box.append(&installation_successful_selection_box); - - installation_successful_buttons_line.append(&installation_successful_reboot_button); - installation_successful_buttons_line.append(&installation_successful_exit_button); - - // Start Appending widgets to boxes - - // / installation_successful_selection_box appends - //// add live and install media button to installation_successful page selections - installation_successful_selection_box.append(&installation_successful_big_icon); - installation_successful_selection_box.append(&installation_successful_text); - installation_successful_selection_box.append(&installation_successful_buttons_line); - - // / installation_successful_main_box appends - //// Add the installation_successful selection/page content box to installation_successful main box - installation_successful_main_box.append(&installation_successful_selection_box); - - installation_successful_exit_button.connect_clicked(clone!(@weak window => move |_| window.close())); - installation_successful_reboot_button.connect_clicked(move |_| { - Command::new("reboot") - .spawn() - .expect("reboot failed to start"); - }); - - // Failed install yard - // the header box for the installation_failed page - let installation_failed_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // make installation_failed selection box for choosing installation or live media - let installation_failed_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .margin_bottom(15) - .margin_top(15) - .margin_start(15) - .margin_end(15) - .build(); - - let installation_failed_big_icon = gtk::Image::builder() - .icon_name("emblem-default") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .pixel_size(256) - .margin_top(0) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - let installation_failed_text = gtk::Label::builder() - .label("PikaOS has Failed!\nCheck logs for further info.") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .build(); - installation_failed_text.add_css_class("header_sized_text"); - - let installation_failed_buttons_line = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .margin_bottom(15) - .margin_top(15) - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .vexpand(true) - .hexpand(true) - .build(); - - let installation_failed_exit_button = gtk::Button::builder() - .label("Exit") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .margin_start(5) - .margin_end(5) - .build(); - - let installation_failed_logs_button = gtk::Button::builder() - .label("Logs") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .margin_start(5) - .margin_end(5) - .build(); - - // / installation_failed_selection_box appends - - // / installation_failed_main_box appends - //// Add the installation_failed header to installation_failed main box - installation_failed_main_box.append(&done_header_box); - //// Add the installation_failed selection/page content box to installation_failed main box - installation_failed_main_box.append(&installation_failed_selection_box); - - installation_failed_buttons_line.append(&installation_failed_logs_button); - installation_failed_buttons_line.append(&installation_failed_exit_button); - - // Start Appending widgets to boxes - - // / installation_failed_selection_box appends - //// add live and install media button to installation_failed page selections - installation_failed_selection_box.append(&installation_failed_big_icon); - installation_failed_selection_box.append(&installation_failed_text); - installation_failed_selection_box.append(&installation_failed_buttons_line); - - // / installation_failed_main_box appends - //// Add the installation_failed selection/page content box to installation_failed main box - installation_failed_main_box.append(&installation_failed_selection_box); - - installation_failed_exit_button.connect_clicked(clone!(@weak window => move |_| window.close())); - installation_failed_logs_button.connect_clicked(move |_| { - Command::new("xdg-open") - .arg("/tmp/pika-installer-gtk4-log") - .spawn() - .expect("xdg-open failed to start"); - }); - - // / done_header_box appends - //// Add the installation_successful page header text and icon - done_header_box.append(&done_header_text); - done_header_box.append(&done_header_icon); - - // / done_header_box appends - //// Add the installation_successful page header text and icon - done_header_box.append(&done_header_text); - done_header_box.append(&done_header_icon); - - done_main_box.append(&done_header_box); - if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() { - done_main_box.append(&installation_successful_main_box) - } else { - done_main_box.append(&installation_failed_main_box) - } -} \ No newline at end of file diff --git a/src/done_page/mod.rs b/src/done_page/mod.rs index 5a8f649..e944520 100644 --- a/src/done_page/mod.rs +++ b/src/done_page/mod.rs @@ -1 +1,242 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +use std::fs; +use std::path::Path; +use std::process::Command; + +pub fn done_page(done_main_box: >k::Box, content_stack: >k::Stack, window: &adw::ApplicationWindow) { + // the header box for the installation_successful page + let done_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the installation_successful page + let done_header_text = gtk::Label::builder() + .label("We're done!") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + done_header_text.add_css_class("header_sized_text"); + + // the header icon for the installation_successful icon + let done_header_icon = gtk::Image::builder() + .icon_name("debian-swirl") + .halign(gtk::Align::Start) + .hexpand(true) + .pixel_size(78) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + + + // Successful install yard + // the header box for the installation_successful page + let installation_successful_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // make installation_successful selection box for choosing installation or live media + let installation_successful_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .margin_bottom(15) + .margin_top(15) + .margin_start(15) + .margin_end(15) + .build(); + + let installation_successful_big_icon = gtk::Image::builder() + .icon_name("emblem-default") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .pixel_size(256) + .margin_top(0) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + let installation_successful_text = gtk::Label::builder() + .label("The installation of PikaOS has been completed sucessfully.") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .build(); + installation_successful_text.add_css_class("header_sized_text"); + + let installation_successful_buttons_line = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .margin_bottom(15) + .margin_top(15) + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .vexpand(true) + .hexpand(true) + .build(); + + let installation_successful_exit_button = gtk::Button::builder() + .label("Exit") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .margin_start(5) + .margin_end(5) + .build(); + + let installation_successful_reboot_button = gtk::Button::builder() + .label("Reboot") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .margin_start(5) + .margin_end(5) + .build(); + + // / installation_successful_selection_box appends + + // / installation_successful_main_box appends + //// Add the installation_successful header to installation_successful main box + installation_successful_main_box.append(&done_header_box); + //// Add the installation_successful selection/page content box to installation_successful main box + installation_successful_main_box.append(&installation_successful_selection_box); + + installation_successful_buttons_line.append(&installation_successful_reboot_button); + installation_successful_buttons_line.append(&installation_successful_exit_button); + + // Start Appending widgets to boxes + + // / installation_successful_selection_box appends + //// add live and install media button to installation_successful page selections + installation_successful_selection_box.append(&installation_successful_big_icon); + installation_successful_selection_box.append(&installation_successful_text); + installation_successful_selection_box.append(&installation_successful_buttons_line); + + // / installation_successful_main_box appends + //// Add the installation_successful selection/page content box to installation_successful main box + installation_successful_main_box.append(&installation_successful_selection_box); + + installation_successful_exit_button.connect_clicked(clone!(@weak window => move |_| window.close())); + installation_successful_reboot_button.connect_clicked(move |_| { + Command::new("reboot") + .spawn() + .expect("reboot failed to start"); + }); + + // Failed install yard + // the header box for the installation_failed page + let installation_failed_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // make installation_failed selection box for choosing installation or live media + let installation_failed_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .margin_bottom(15) + .margin_top(15) + .margin_start(15) + .margin_end(15) + .build(); + + let installation_failed_big_icon = gtk::Image::builder() + .icon_name("emblem-default") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .pixel_size(256) + .margin_top(0) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + let installation_failed_text = gtk::Label::builder() + .label("PikaOS has Failed!\nCheck logs for further info.") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .build(); + installation_failed_text.add_css_class("header_sized_text"); + + let installation_failed_buttons_line = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .margin_bottom(15) + .margin_top(15) + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .vexpand(true) + .hexpand(true) + .build(); + + let installation_failed_exit_button = gtk::Button::builder() + .label("Exit") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .margin_start(5) + .margin_end(5) + .build(); + + let installation_failed_logs_button = gtk::Button::builder() + .label("Logs") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .margin_start(5) + .margin_end(5) + .build(); + + // / installation_failed_selection_box appends + + // / installation_failed_main_box appends + //// Add the installation_failed header to installation_failed main box + installation_failed_main_box.append(&done_header_box); + //// Add the installation_failed selection/page content box to installation_failed main box + installation_failed_main_box.append(&installation_failed_selection_box); + + installation_failed_buttons_line.append(&installation_failed_logs_button); + installation_failed_buttons_line.append(&installation_failed_exit_button); + + // Start Appending widgets to boxes + + // / installation_failed_selection_box appends + //// add live and install media button to installation_failed page selections + installation_failed_selection_box.append(&installation_failed_big_icon); + installation_failed_selection_box.append(&installation_failed_text); + installation_failed_selection_box.append(&installation_failed_buttons_line); + + // / installation_failed_main_box appends + //// Add the installation_failed selection/page content box to installation_failed main box + installation_failed_main_box.append(&installation_failed_selection_box); + + installation_failed_exit_button.connect_clicked(clone!(@weak window => move |_| window.close())); + installation_failed_logs_button.connect_clicked(move |_| { + Command::new("xdg-open") + .arg("/tmp/pika-installer-gtk4-log") + .spawn() + .expect("xdg-open failed to start"); + }); + + // / done_header_box appends + //// Add the installation_successful page header text and icon + done_header_box.append(&done_header_text); + done_header_box.append(&done_header_icon); + + // / done_header_box appends + //// Add the installation_successful page header text and icon + done_header_box.append(&done_header_text); + done_header_box.append(&done_header_icon); + + done_main_box.append(&done_header_box); + if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() { + done_main_box.append(&installation_successful_main_box) + } else { + done_main_box.append(&installation_failed_main_box) + } +} \ No newline at end of file diff --git a/src/drive_mount_row/imp.rs b/src/drive_mount_row/imp.rs index 8a46725..367fe8d 100644 --- a/src/drive_mount_row/imp.rs +++ b/src/drive_mount_row/imp.rs @@ -78,7 +78,7 @@ impl ObjectImpl for DriveMountRow { let partition_row_expander_adw_listbox = gtk::ListBox::builder() .margin_end(5) - .margin_start(5) + .margin_start(0) .margin_top(5) .margin_bottom(5) .build(); @@ -112,7 +112,7 @@ impl ObjectImpl for DriveMountRow { .build(); let partition_row_delete_button = gtk::Button::builder() - .margin_end(5) + .margin_end(0) .margin_start(5) .margin_top(5) .margin_bottom(5) diff --git a/src/efi_error_page/main.rs b/src/efi_error_page/main.rs deleted file mode 100644 index cb4436f..0000000 --- a/src/efi_error_page/main.rs +++ /dev/null @@ -1,110 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; - -pub fn efi_error_page(window: &adw::ApplicationWindow, content_stack: >k::Stack) { - // the header box for the efi_error page - let efi_error_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // the header box for the efi_error page - let efi_error_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the efi_error page - let efi_error_header_text = gtk::Label::builder() - .label("Unsupported boot platform") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - efi_error_header_text.add_css_class("header_sized_text"); - - // the header icon for the efi_error icon - let efi_error_header_icon = gtk::Image::builder() - .icon_name("emblem-error") - .halign(gtk::Align::Start) - .hexpand(true) - .pixel_size(78) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - - // make efi_error selection box for choosing installation or live media - let efi_error_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .margin_bottom(15) - .margin_top(15) - .margin_start(15) - .margin_end(15) - .build(); - - - let efi_error_text = gtk::Label::builder() - .vexpand(true) - .hexpand(true) - .label("PikaOS Only works on GPT UEFI Systems, this machine is booted in CSM/LEGACY mode.") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .build(); - efi_error_text.add_css_class("big_error_text"); - - let kill_me_button = gtk::Button::builder() - .label("Exit") - .vexpand(true) - .hexpand(true) - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .build(); - - // / efi_error_selection_box appends - - // / efi_error_header_box appends - //// Add the efi_error page header text and icon - efi_error_header_box.append(&efi_error_header_text); - efi_error_header_box.append(&efi_error_header_icon); - - // / efi_error_main_box appends - //// Add the efi_error header to efi_error main box - efi_error_main_box.append(&efi_error_header_box); - //// Add the efi_error selection/page content box to efi_error main box - efi_error_main_box.append(&efi_error_selection_box); - - // Start Appending widgets to boxes - - // / efi_error_selection_box appends - //// add live and install media button to efi_error page selections - efi_error_selection_box.append(&efi_error_text); - efi_error_selection_box.append(&kill_me_button); - - // / efi_error_header_box appends - //// Add the efi_error page header text and icon - efi_error_header_box.append(&efi_error_header_text); - efi_error_header_box.append(&efi_error_header_icon); - - // / efi_error_main_box appends - //// Add the efi_error header to efi_error main box - efi_error_main_box.append(&efi_error_header_box); - //// Add the efi_error selection/page content box to efi_error main box - efi_error_main_box.append(&efi_error_selection_box); - - // / Content stack appends - //// Add the efi_error_main_box as page: efi_error_page, Give it nice title - content_stack.add_titled(&efi_error_main_box, Some("efi_error_page"), "Welcome"); - - kill_me_button.connect_clicked(clone!(@weak window => move |_| window.close())); -} \ No newline at end of file diff --git a/src/efi_error_page/mod.rs b/src/efi_error_page/mod.rs index 5a8f649..a1828d4 100644 --- a/src/efi_error_page/mod.rs +++ b/src/efi_error_page/mod.rs @@ -1 +1,110 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +pub fn efi_error_page(window: &adw::ApplicationWindow, content_stack: >k::Stack) { + // the header box for the efi_error page + let efi_error_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // the header box for the efi_error page + let efi_error_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the efi_error page + let efi_error_header_text = gtk::Label::builder() + .label("Unsupported boot platform") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + efi_error_header_text.add_css_class("header_sized_text"); + + // the header icon for the efi_error icon + let efi_error_header_icon = gtk::Image::builder() + .icon_name("emblem-error") + .halign(gtk::Align::Start) + .hexpand(true) + .pixel_size(78) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + + // make efi_error selection box for choosing installation or live media + let efi_error_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .margin_bottom(15) + .margin_top(15) + .margin_start(15) + .margin_end(15) + .build(); + + + let efi_error_text = gtk::Label::builder() + .vexpand(true) + .hexpand(true) + .label("PikaOS Only works on GPT UEFI Systems, this machine is booted in CSM/LEGACY mode.") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .build(); + efi_error_text.add_css_class("big_error_text"); + + let kill_me_button = gtk::Button::builder() + .label("Exit") + .vexpand(true) + .hexpand(true) + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .build(); + + // / efi_error_selection_box appends + + // / efi_error_header_box appends + //// Add the efi_error page header text and icon + efi_error_header_box.append(&efi_error_header_text); + efi_error_header_box.append(&efi_error_header_icon); + + // / efi_error_main_box appends + //// Add the efi_error header to efi_error main box + efi_error_main_box.append(&efi_error_header_box); + //// Add the efi_error selection/page content box to efi_error main box + efi_error_main_box.append(&efi_error_selection_box); + + // Start Appending widgets to boxes + + // / efi_error_selection_box appends + //// add live and install media button to efi_error page selections + efi_error_selection_box.append(&efi_error_text); + efi_error_selection_box.append(&kill_me_button); + + // / efi_error_header_box appends + //// Add the efi_error page header text and icon + efi_error_header_box.append(&efi_error_header_text); + efi_error_header_box.append(&efi_error_header_icon); + + // / efi_error_main_box appends + //// Add the efi_error header to efi_error main box + efi_error_main_box.append(&efi_error_header_box); + //// Add the efi_error selection/page content box to efi_error main box + efi_error_main_box.append(&efi_error_selection_box); + + // / Content stack appends + //// Add the efi_error_main_box as page: efi_error_page, Give it nice title + content_stack.add_titled(&efi_error_main_box, Some("efi_error_page"), "Welcome"); + + kill_me_button.connect_clicked(clone!(@weak window => move |_| window.close())); +} \ No newline at end of file diff --git a/src/eula_page/main.rs b/src/eula_page/main.rs deleted file mode 100644 index c168615..0000000 --- a/src/eula_page/main.rs +++ /dev/null @@ -1,195 +0,0 @@ - // Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; - -use std::io::BufRead; -use std::io::BufReader; -use std::process::Command; -use std::process::Stdio; -use std::time::Instant; - -pub fn eula_page(content_stack: >k::Stack) { - - // create the bottom box for next and back buttons - let bottom_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .valign(gtk::Align::End) - .vexpand(true) - .build(); - - // Next and back button - let bottom_back_button = gtk::Button::builder() - .label("Back") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::Start) - .hexpand(true) - .build(); - let bottom_next_button = gtk::Button::builder() - .label("Next") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::End) - .hexpand(true) - .sensitive(false) - .build(); - - // Start Applying css classes - bottom_next_button.add_css_class("suggested-action"); - - // / bottom_box appends - //// Add the next and back buttons - bottom_box.append(&bottom_back_button); - bottom_box.append(&bottom_next_button); - - // the header box for the eula page - let eula_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // the header box for the eula page - let eula_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the eula page - let eula_header_text = gtk::Label::builder() - .label("PikaOS User license Agreement") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - eula_header_text.add_css_class("header_sized_text"); - - // the header icon for the eula icon - let eula_header_icon = gtk::Image::builder() - .icon_name("error-correct") - .halign(gtk::Align::Start) - .hexpand(true) - .pixel_size(78) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - - // make eula selection box for choosing installation or live media - let eula_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // / eula_header_box appends - //// Add the eula page header text and icon - eula_header_box.append(&eula_header_text); - eula_header_box.append(&eula_header_icon); - - // / eula_main_box appends - //// Add the eula header to eula main box - eula_main_box.append(&eula_header_box); - //// Add the eula selection/page content box to eula main box - eula_main_box.append(&eula_selection_box); - - // text above eula selection box - let eula_selection_text = gtk::Label::builder() - .label("Please carefully read and make sure you consent to the following before installing PikaOS:") - .halign(gtk::Align::Center) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - eula_selection_text.add_css_class("medium_sized_text"); - - let eula_buffer = gtk::TextBuffer::builder() - .text("There are a few things to keep in mind: - 1 - You understand that this distribution is -NOT- to be considered an ‘Ubuntu Flavor’. - 2 - This is a hobby distribution, so we will try our best to provide formal support but it will -NOT- be guaranteed. - 3 - Although PikaOS might provide identical patches and user experience to the Nobara project, we are -NOT- directly a part of them so questions and bug reports should not be sent directly to them (they dont have to deal with it!) - 4 - While the installer is running DO NOT INTERRUPT IT! or you will end up with a corrupted system. - 5 - Try to use pikman instead of apt when using the terminal, it is much faster! - 6 - You understand the xone driver downloads needed binaries locally and does not directly package or distribute any copyrighted firmware or other related data. - 7 - Automatic partitioning will format all partitons on a drive, so if you want to dualboot make a separate EFI partition for PikaOS and use manual partitioning - 8 - In case you need the login info for this session: - - username: pikaos - - password: - MEANING: JUST PRESS ENTER") - .build(); - - let eula_selection_text_view = gtk::TextView::builder() - .hexpand(true) - .vexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .editable(false) - .buffer(&eula_buffer) - .build(); - - let eula_selection_text_scroll = gtk::ScrolledWindow::builder() - .height_request(350) - .child(&eula_selection_text_view) - .build(); - - let eula_accept_checkbutton = gtk::CheckButton::builder() - .label("I Agree and Accept the User license Agreement") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - // / eula_selection_box appends - //// add text and and entry to eula page selections - eula_selection_box.append(&eula_selection_text); - eula_selection_box.append(&eula_selection_text_scroll); - eula_selection_box.append(&eula_accept_checkbutton); - - // / eula_header_box appends - //// Add the eula page header text and icon - eula_header_box.append(&eula_header_text); - eula_header_box.append(&eula_header_icon); - - // / eula_main_box appends - //// Add the eula header to eula main box - eula_main_box.append(&eula_header_box); - //// Add the eula selection/page content box to eula main box - eula_main_box.append(&eula_selection_box); - - eula_main_box.append(&bottom_box); - - // / Content stack appends - //// Add the eula_main_box as page: eula_page, Give it nice title - content_stack.add_titled(&eula_main_box, Some("eula_page"), "EULA"); - - eula_accept_checkbutton.connect_toggled(clone!(@weak eula_accept_checkbutton, @weak bottom_next_button => move |_| { - if eula_accept_checkbutton.is_active() == true { - bottom_next_button.set_sensitive(true); - } else { - bottom_next_button.set_sensitive(false) - } - })); - - bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { - content_stack.set_visible_child_name("timezone_page") - })); - bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| { - content_stack.set_visible_child_name("language_page") - })); - -} diff --git a/src/eula_page/mod.rs b/src/eula_page/mod.rs index 5a8f649..8d5d834 100644 --- a/src/eula_page/mod.rs +++ b/src/eula_page/mod.rs @@ -1 +1,195 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +use std::io::BufRead; +use std::io::BufReader; +use std::process::Command; +use std::process::Stdio; +use std::time::Instant; + +pub fn eula_page(content_stack: >k::Stack) { + + // create the bottom box for next and back buttons + let bottom_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .valign(gtk::Align::End) + .vexpand(true) + .build(); + + // Next and back button + let bottom_back_button = gtk::Button::builder() + .label("Back") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::Start) + .hexpand(true) + .build(); + let bottom_next_button = gtk::Button::builder() + .label("Next") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::End) + .hexpand(true) + .sensitive(false) + .build(); + + // Start Applying css classes + bottom_next_button.add_css_class("suggested-action"); + + // / bottom_box appends + //// Add the next and back buttons + bottom_box.append(&bottom_back_button); + bottom_box.append(&bottom_next_button); + + // the header box for the eula page + let eula_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // the header box for the eula page + let eula_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the eula page + let eula_header_text = gtk::Label::builder() + .label("PikaOS User license Agreement") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + eula_header_text.add_css_class("header_sized_text"); + + // the header icon for the eula icon + let eula_header_icon = gtk::Image::builder() + .icon_name("error-correct") + .halign(gtk::Align::Start) + .hexpand(true) + .pixel_size(78) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + + // make eula selection box for choosing installation or live media + let eula_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // / eula_header_box appends + //// Add the eula page header text and icon + eula_header_box.append(&eula_header_text); + eula_header_box.append(&eula_header_icon); + + // / eula_main_box appends + //// Add the eula header to eula main box + eula_main_box.append(&eula_header_box); + //// Add the eula selection/page content box to eula main box + eula_main_box.append(&eula_selection_box); + + // text above eula selection box + let eula_selection_text = gtk::Label::builder() + .label("Please carefully read and make sure you consent to the following before installing PikaOS:") + .halign(gtk::Align::Center) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + eula_selection_text.add_css_class("medium_sized_text"); + + let eula_buffer = gtk::TextBuffer::builder() + .text("There are a few things to keep in mind: + 1 - You understand that this distribution is -NOT- to be considered an ‘Ubuntu Flavor’. + 2 - This is a hobby distribution, so we will try our best to provide formal support but it will -NOT- be guaranteed. + 3 - Although PikaOS might provide identical patches and user experience to the Nobara project, we are -NOT- directly a part of them so questions and bug reports should not be sent directly to them (they dont have to deal with it!) + 4 - While the installer is running DO NOT INTERRUPT IT! or you will end up with a corrupted system. + 5 - Try to use pikman instead of apt when using the terminal, it is much faster! + 6 - You understand the xone driver downloads needed binaries locally and does not directly package or distribute any copyrighted firmware or other related data. + 7 - Automatic partitioning will format all partitons on a drive, so if you want to dualboot make a separate EFI partition for PikaOS and use manual partitioning + 8 - In case you need the login info for this session: + - username: pikaos + - password: + MEANING: JUST PRESS ENTER") + .build(); + + let eula_selection_text_view = gtk::TextView::builder() + .hexpand(true) + .vexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .editable(false) + .buffer(&eula_buffer) + .build(); + + let eula_selection_text_scroll = gtk::ScrolledWindow::builder() + .height_request(350) + .child(&eula_selection_text_view) + .build(); + + let eula_accept_checkbutton = gtk::CheckButton::builder() + .label("I Agree and Accept the User license Agreement") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + // / eula_selection_box appends + //// add text and and entry to eula page selections + eula_selection_box.append(&eula_selection_text); + eula_selection_box.append(&eula_selection_text_scroll); + eula_selection_box.append(&eula_accept_checkbutton); + + // / eula_header_box appends + //// Add the eula page header text and icon + eula_header_box.append(&eula_header_text); + eula_header_box.append(&eula_header_icon); + + // / eula_main_box appends + //// Add the eula header to eula main box + eula_main_box.append(&eula_header_box); + //// Add the eula selection/page content box to eula main box + eula_main_box.append(&eula_selection_box); + + eula_main_box.append(&bottom_box); + + // / Content stack appends + //// Add the eula_main_box as page: eula_page, Give it nice title + content_stack.add_titled(&eula_main_box, Some("eula_page"), "EULA"); + + eula_accept_checkbutton.connect_toggled(clone!(@weak eula_accept_checkbutton, @weak bottom_next_button => move |_| { + if eula_accept_checkbutton.is_active() == true { + bottom_next_button.set_sensitive(true); + } else { + bottom_next_button.set_sensitive(false) + } + })); + + bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { + content_stack.set_visible_child_name("timezone_page") + })); + bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| { + content_stack.set_visible_child_name("language_page") + })); + +} diff --git a/src/install_page/main.rs b/src/install_page/main.rs deleted file mode 100644 index 95ead21..0000000 --- a/src/install_page/main.rs +++ /dev/null @@ -1,597 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; -use vte::prelude::*; -use vte::*; - -use crate::done_page::main::done_page; - -use std::process::Command; -use pretty_bytes::converter::convert; - -use std::fs; -use std::path::Path; - -pub fn install_page(done_main_box: >k::Box, install_main_box: >k::Box ,content_stack: >k::Stack, window: &adw::ApplicationWindow) { - - // create the bottom box for next and back buttons - let bottom_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .valign(gtk::Align::End) - .vexpand(true) - .build(); - - // Next and back button - let bottom_back_button = gtk::Button::builder() - .label("Back") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::Start) - .hexpand(true) - .build(); - - // / bottom_box appends - //// Add the next and back buttons - bottom_box.append(&bottom_back_button); - - let install_nested_stack = gtk::Stack::builder() - .transition_type(StackTransitionType::SlideLeftRight) - .build(); - - let install_confirm_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // the header box for the install page - let install_confirm_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the install page - let install_confirm_header_text = gtk::Label::builder() - .label("Sit back, Relax, and watch the show.") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - install_confirm_header_text.add_css_class("header_sized_text"); - - // the header icon for the install icon - let install_confirm_header_icon = gtk::Spinner::builder() - .halign(gtk::Align::Start) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - install_confirm_header_icon.start(); - - // make install selection box for choosing installation or live media - let install_confirm_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .halign(gtk::Align::Fill) - .valign(gtk::Align::Center) - .vexpand(true) - .hexpand(true) - .build(); - - let install_confirm_details_boxed_list = gtk::ListBox::builder() - .margin_top(15) - .margin_bottom(15) - .margin_start(256) - .margin_end(256) - .halign(gtk::Align::Fill) - .valign(gtk::Align::Center) - .hexpand(true) - .build(); - install_confirm_details_boxed_list.add_css_class("boxed-list"); - - let install_confirm_detail_language = adw::ActionRow::builder() - .title("Language:") - .subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-lang.txt").expect("Unable to read file")) - .build(); - install_confirm_detail_language.add_css_class("property"); - - let install_confirm_detail_timezone = adw::ActionRow::builder() - .title("Time zone:") - .subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-timezone.txt").expect("Unable to read file")) - .build(); - install_confirm_detail_timezone.add_css_class("property"); - - let install_confirm_detail_keyboard = adw::ActionRow::builder() - .title("Keyboard layout:") - .subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-keyboard.txt").expect("Unable to read file")) - .build(); - install_confirm_detail_keyboard.add_css_class("property"); - - let install_confirm_detail_target = adw::ActionRow::builder() - .title("Install Target:") - .build(); - - if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() { - install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-manual.txt").expect("Unable to read file")); - } else { - install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt").expect("Unable to read file")); - } - install_confirm_detail_target.add_css_class("property"); - - if Path::new("/tmp/pika-installer-gtk4-target-auto.txt").exists() { - let target_block_device = &fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt").expect("Unable to read file"); - let target_size_cli = Command::new("sudo") - .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") - .arg("get_block_size") - .arg(target_block_device) - .output() - .expect("failed to execute process"); - let target_size = String::from_utf8(target_size_cli.stdout).expect("Failed to create float").trim().parse::().unwrap(); - let mut target_p3_size = 0.0; - if (target_size * 40.0) / 100.0 >= 150000000000.0 { - target_p3_size = 150000000000.0 ; - } else if (target_size * 40.0) / 100.0 <= 36507222016.0 { - target_p3_size = 36507222016.0 ; - } else { - target_p3_size = (target_size * 40.0) / 100.0 ; - } - let target_p4_size = target_size - (target_p3_size + 1536.0); - if Path::new("/tmp/pika-installer-p3-size.txt").exists() { - fs::remove_file("/tmp/pika-installer-p3-size.txt").expect("Bad permissions on /tmp/pika-installer-p3-size.txt"); - } - let target_p3_sector = target_p3_size + 1537.0; - fs::write("/tmp/pika-installer-p3-size.txt", target_p3_sector.to_string()).expect("Unable to write file"); - let mut p1_row_text = String::new(); - let mut p2_row_text = String::new(); - let mut p3_row_text = String::new(); - let mut p4_row_text = String::new(); - if target_block_device.contains("nvme") { - p1_row_text = "512 MB ".to_owned() + target_block_device + "p1" + " as fat32" + " on /boot/efi"; - p2_row_text = "1 GB ".to_owned() + target_block_device + "p2" + " as ext4" + " on /boot"; - p3_row_text = pretty_bytes::converter::convert(target_p3_size) + " " + target_block_device + "p3" + " as btrfs" + " on /"; - p4_row_text = pretty_bytes::converter::convert(target_p4_size) + " " + target_block_device + "p4" + " as btrfs" + " on /home"; - } else { - p1_row_text = "512 MB ".to_owned() + target_block_device + "1" + " as fat32" + " on /boot/efi"; - p2_row_text = "1 GB ".to_owned() + target_block_device + "2" + " as ext4" + " on /boot"; - p3_row_text = pretty_bytes::converter::convert(target_p3_size) + " " + target_block_device + "3" + " as btrfs" + " on /"; - p4_row_text = pretty_bytes::converter::convert(target_p4_size) + " " + target_block_device + "4" + " as btrfs" + " on /home"; - } - let install_confirm_p1 = adw::ActionRow::builder() - .title(p1_row_text.clone()) - .build(); - let install_confirm_p2 = adw::ActionRow::builder() - .title(p2_row_text.clone()) - .build(); - let install_confirm_p3 = adw::ActionRow::builder() - .title(p3_row_text.clone()) - .build(); - let install_confirm_p4 = adw::ActionRow::builder() - .title(p4_row_text.clone()) - .build(); - // / install_confirm_selection_box appends - //// add live and install media button to install page selections - install_confirm_details_boxed_list.append(&install_confirm_detail_language); - install_confirm_details_boxed_list.append(&install_confirm_detail_timezone); - install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard); - install_confirm_details_boxed_list.append(&install_confirm_detail_target); - install_confirm_details_boxed_list.append(&install_confirm_p1); - install_confirm_details_boxed_list.append(&install_confirm_p2); - install_confirm_details_boxed_list.append(&install_confirm_p3); - install_confirm_details_boxed_list.append(&install_confirm_p4); - } else { - // / install_confirm_selection_box appends - //// add live and install media button to install page selections - install_confirm_details_boxed_list.append(&install_confirm_detail_language); - install_confirm_details_boxed_list.append(&install_confirm_detail_timezone); - install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard); - install_confirm_details_boxed_list.append(&install_confirm_detail_target); - } - - let install_confirm_button = gtk::Button::builder() - .label("Confirm & Install PikaOS") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .build(); - install_confirm_button.add_css_class("destructive-action"); - - // / install_confirm_header_box appends - //// Add the install page header text and icon - install_confirm_header_box.append(&install_confirm_header_text); - install_confirm_header_box.append(&install_confirm_header_icon); - - // / install_confirm_box appends - //// Add the install header to install main box - install_confirm_box.append(&install_confirm_header_box); - //// Add the install selection/page content box to install main box - install_confirm_box.append(&install_confirm_selection_box); - - // Start Appending widgets to boxes - - // - install_confirm_selection_box.append(&install_confirm_details_boxed_list); - install_confirm_selection_box.append(&install_confirm_button); - - // / install_confirm_header_box appends - //// Add the install page header text and icon - install_confirm_header_box.append(&install_confirm_header_text); - install_confirm_header_box.append(&install_confirm_header_icon); - - // / install_confirm_box appends - //// Add the install header to install main box - install_confirm_box.append(&install_confirm_header_box); - //// Add the install selection/page content box to install main box - install_confirm_box.append(&install_confirm_selection_box); - - install_main_box.append(&install_nested_stack); - - install_confirm_box.append(&bottom_box); - - /// - - let install_progress_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - let install_progress_log_stack = gtk::Stack::builder() - .transition_type(StackTransitionType::SlideUpDown) - .build(); - - let install_progress_log_terminal = vte::Terminal::builder() - .vexpand(true) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .input_enabled(false) - .build(); - - let placeholder_icon = gtk::Image::builder() - .icon_name("debian-swirl") - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .hexpand(true) - .vexpand(true) - .pixel_size(512) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - let progress_bar_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .margin_start(15) - .margin_end(15) - .build(); - - let install_progress_bar = gtk::ProgressBar::builder() - .hexpand(true) - .margin_start(15) - .margin_end(15) - .margin_top(15) - .margin_bottom(15) - .show_text(true) - .build(); - - let progress_log_button_content = adw::ButtonContent::builder() - .label("View Logs") - .icon_name("terminal") - .build(); - - let progress_log_button = gtk::Button::builder() - .child(&progress_log_button_content) - .margin_start(15) - .margin_end(15) - .margin_top(15) - .margin_bottom(15) - .build(); - - progress_bar_box.append(&install_progress_bar); - progress_bar_box.append(&progress_log_button); - - install_progress_log_stack.add_titled(&placeholder_icon, Some("slideshow_page"), "slideshow_page"); - install_progress_log_stack.add_titled(&install_progress_log_terminal, Some("terminal_log_page"), "terminal_log_page"); - - install_progress_box.append(&install_progress_log_stack); - install_progress_box.append(&progress_bar_box); - - install_nested_stack.add_titled(&install_confirm_box, Some("confirm_page"), "confirm_page"); - install_nested_stack.add_titled(&install_progress_box, Some("progress_page"), "progress_page"); - - // - - // - - install_confirm_button.connect_clicked(clone!(@weak install_nested_stack, @weak install_progress_log_terminal, @weak install_progress_bar, @weak done_main_box, @weak content_stack, @weak window => move |_| { - install_nested_stack.set_visible_child_name("progress_page"); - begin_install(&install_progress_log_terminal, &install_progress_bar, &done_main_box, &content_stack, &window); - })); - - progress_log_button.connect_clicked(clone!(@weak install_progress_log_stack => move |_| { - if install_progress_log_stack.visible_child_name() == Some(GString::from_string_unchecked("slideshow_page".into())) { - install_progress_log_stack.set_visible_child_name("terminal_log_page"); - } else { - install_progress_log_stack.set_visible_child_name("slideshow_page"); - } - })); - - bottom_back_button.connect_clicked(clone!(@weak content_stack, @weak install_main_box, @weak install_nested_stack => move |_| { - content_stack.set_visible_child_name("partitioning_page"); - install_main_box.remove(&install_nested_stack) - })); -} - -fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress_bar: >k::ProgressBar, done_main_box: >k::Box, content_stack: >k::Stack, window: &adw::ApplicationWindow) { - // SPAWN TERMINAL WITH PIKAINSTALL PROCESS - install_progress_log_terminal.spawn_async( - PtyFlags::DEFAULT, - Some(""), - &["/usr/lib/pika/pika-installer-gtk4/scripts/begin-install.sh"], - &[], - SpawnFlags::DEFAULT, - || {}, - -1, - None::<&gio::Cancellable>, - move |result| { - match result { - Ok(_) => { eprintln!("could not spawn terminal")} - Err(err) => { - eprintln!("could not spawn terminal: {}", err); - } - } - }, - ); - // wait till /tmp/pika-installer-gtk4-status-parting.txt to change progressbar - let (parting_status_sender, parting_status_receiver) = async_channel::unbounded(); - let parting_status_sender = parting_status_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(move || { - let parting_status = true; - while parting_status == true { - if Path::new("/tmp/pika-installer-gtk4-status-parting.txt").exists() == true { - parting_status_sender - .send_blocking(true) - .expect("The channel needs to be open."); - break - } - } - }); - let parting_status_main_context = MainContext::default(); - // The main loop executes the asynchronous block - parting_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { - while let Ok(parting_status_state) = parting_status_receiver.recv().await { - - if parting_status_state == true { - println!("Installation status: Parting"); - install_progress_bar.set_fraction(0.20); - install_progress_bar.set_text(Some("Partitioning The Disk Target.")); - } - } - })); - // wait till /tmp/pika-installer-gtk4-status-image.txt to change progressbar - let (image_status_sender, image_status_receiver) = async_channel::unbounded(); - let image_status_sender = image_status_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(move || { - let image_status = true; - while image_status == true { - if Path::new("/tmp/pika-installer-gtk4-status-image.txt").exists() == true { - image_status_sender - .send_blocking(true) - .expect("The channel needs to be open."); - break - } - } - }); - let image_status_main_context = MainContext::default(); - // The main loop executes the asynchronous block - image_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { - while let Ok(image_status_state) = image_status_receiver.recv().await { - - if image_status_state == true { - println!("Installation status: Imaging"); - install_progress_bar.set_fraction(0.60); - install_progress_bar.set_text(Some("Writing image to target.")); - } - } - })); - // wait till /tmp/pika-installer-gtk4-status-flag1.txt to change progressbar - let (flag1_status_sender, flag1_status_receiver) = async_channel::unbounded(); - let flag1_status_sender = flag1_status_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(move || { - let flag1_status = true; - while flag1_status == true { - if Path::new("/tmp/pika-installer-gtk4-status-flag1.txt").exists() == true { - flag1_status_sender - .send_blocking(true) - .expect("The channel needs to be open."); - break - } - } - }); - let flag1_status_main_context = MainContext::default(); - // The main loop executes the asynchronous block - flag1_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { - while let Ok(flag1_status_state) = flag1_status_receiver.recv().await { - - if flag1_status_state == true { - println!("Installation status: Flag1"); - install_progress_bar.set_fraction(0.65); - install_progress_bar.set_text(Some("Enabling bls_boot flag on /boot.")); - } - } - })); - // wait till /tmp/pika-installer-gtk4-status-flag2.txt to change progressbar - let (flag2_status_sender, flag2_status_receiver) = async_channel::unbounded(); - let flag2_status_sender = flag2_status_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(move || { - let flag2_status = true; - while flag2_status == true { - if Path::new("/tmp/pika-installer-gtk4-status-flag2.txt").exists() == true { - flag2_status_sender - .send_blocking(true) - .expect("The channel needs to be open."); - break - } - } - }); - let flag2_status_main_context = MainContext::default(); - // The main loop executes the asynchronous block - flag2_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { - while let Ok(flag2_status_state) = flag2_status_receiver.recv().await { - - if flag2_status_state == true { - println!("Installation status: Flag2"); - install_progress_bar.set_fraction(0.70); - install_progress_bar.set_text(Some("Enabling efi flag on /boot/efi.")); - } - } - })); - // wait till /tmp/pika-installer-gtk4-status-crypt.txt to change progressbar - let (crypt_status_sender, crypt_status_receiver) = async_channel::unbounded(); - let crypt_status_sender = crypt_status_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(move || { - let crypt_status = true; - while crypt_status == true { - if Path::new("/tmp/pika-installer-gtk4-status-crypt.txt").exists() == true { - crypt_status_sender - .send_blocking(true) - .expect("The channel needs to be open."); - break - } - } - }); - let crypt_status_main_context = MainContext::default(); - // The main loop executes the asynchronous block - crypt_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { - while let Ok(crypt_status_state) = crypt_status_receiver.recv().await { - - if crypt_status_state == true { - println!("Installation status: Crypttab"); - install_progress_bar.set_fraction(0.75); - install_progress_bar.set_text(Some("Setting up encryption crypttab.")); - } - } - })); - // wait till /tmp/pika-installer-gtk4-status-lang.txt to change progressbar - let (lang_status_sender, lang_status_receiver) = async_channel::unbounded(); - let lang_status_sender = lang_status_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(move || { - let lang_status = true; - while lang_status == true { - if Path::new("/tmp/pika-installer-gtk4-status-lang.txt").exists() == true { - lang_status_sender - .send_blocking(true) - .expect("The channel needs to be open."); - break - } - } - }); - let lang_status_main_context = MainContext::default(); - // The main loop executes the asynchronous block - lang_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { - while let Ok(lang_status_state) = lang_status_receiver.recv().await { - - if lang_status_state == true { - println!("Installation status: Language"); - install_progress_bar.set_fraction(0.80); - install_progress_bar.set_text(Some("Setting Up Language and Keyboard.")); - } - } - })); - // wait till /tmp/pika-installer-gtk4-status-boot.txt to change progressbar - let (boot_status_sender, boot_status_receiver) = async_channel::unbounded(); - let boot_status_sender = boot_status_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(move || { - let boot_status = true; - while boot_status == true { - if Path::new("/tmp/pika-installer-gtk4-status-boot.txt").exists() == true { - boot_status_sender - .send_blocking(true) - .expect("The channel needs to be open."); - break - } - } - }); - let boot_status_main_context = MainContext::default(); - // The main loop executes the asynchronous block - boot_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { - while let Ok(boot_status_state) = boot_status_receiver.recv().await { - - if boot_status_state == true { - println!("Installation status: Bootloader"); - install_progress_bar.set_fraction(0.85); - install_progress_bar.set_text(Some("Configuring bootloader.")); - } - } - })); - // wait till /tmp/pika-installer-gtk4-status-post.txt to change progressbar - let (post_status_sender, post_status_receiver) = async_channel::unbounded(); - let post_status_sender = post_status_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(move || { - let post_status = true; - while post_status == true { - if Path::new("/tmp/pika-installer-gtk4-status-post.txt").exists() == true { - post_status_sender - .send_blocking(true) - .expect("The channel needs to be open."); - break - } - } - }); - let post_status_main_context = MainContext::default(); - // The main loop executes the asynchronous block - post_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { - while let Ok(post_status_state) = post_status_receiver.recv().await { - - if post_status_state == true { - println!("Installation status: Post Install"); - install_progress_bar.set_fraction(0.90); - install_progress_bar.set_text(Some("Running post installation script.")); - } - } - })); - // wait till /tmp/pika-installer-gtk4-successful.txt to change progressbar - let (done_status_sender, done_status_receiver) = async_channel::unbounded(); - let done_status_sender = done_status_sender.clone(); - // The long running operation runs now in a separate thread - gio::spawn_blocking(move || { - let done_status = true; - while done_status == true { - if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() == true || Path::new("/tmp/pika-installer-gtk4-fail.txt").exists() == true { - done_status_sender - .send_blocking(true) - .expect("The channel needs to be open."); - break - } - } - }); - let done_status_main_context = MainContext::default(); - // The main loop executes the asynchronous block - done_status_main_context.spawn_local(clone!(@weak done_main_box, @weak content_stack, @weak window => async move { - while let Ok(done_status_state) = done_status_receiver.recv().await { - if done_status_state == true { - println!("Installation status: Done"); - done_page(&done_main_box ,&content_stack, &window); - content_stack.set_visible_child_name("done_page"); - } - } - })); -} \ No newline at end of file diff --git a/src/install_page/mod.rs b/src/install_page/mod.rs index 5a8f649..c865e38 100644 --- a/src/install_page/mod.rs +++ b/src/install_page/mod.rs @@ -1 +1,597 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; +use vte::prelude::*; +use vte::*; + +use crate::done_page::done_page; + +use std::process::Command; +use pretty_bytes::converter::convert; + +use std::fs; +use std::path::Path; + +pub fn install_page(done_main_box: >k::Box, install_main_box: >k::Box ,content_stack: >k::Stack, window: &adw::ApplicationWindow) { + + // create the bottom box for next and back buttons + let bottom_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .valign(gtk::Align::End) + .vexpand(true) + .build(); + + // Next and back button + let bottom_back_button = gtk::Button::builder() + .label("Back") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::Start) + .hexpand(true) + .build(); + + // / bottom_box appends + //// Add the next and back buttons + bottom_box.append(&bottom_back_button); + + let install_nested_stack = gtk::Stack::builder() + .transition_type(StackTransitionType::SlideLeftRight) + .build(); + + let install_confirm_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // the header box for the install page + let install_confirm_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the install page + let install_confirm_header_text = gtk::Label::builder() + .label("Sit back, Relax, and watch the show.") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + install_confirm_header_text.add_css_class("header_sized_text"); + + // the header icon for the install icon + let install_confirm_header_icon = gtk::Spinner::builder() + .halign(gtk::Align::Start) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + install_confirm_header_icon.start(); + + // make install selection box for choosing installation or live media + let install_confirm_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .halign(gtk::Align::Fill) + .valign(gtk::Align::Center) + .vexpand(true) + .hexpand(true) + .build(); + + let install_confirm_details_boxed_list = gtk::ListBox::builder() + .margin_top(15) + .margin_bottom(15) + .margin_start(256) + .margin_end(256) + .halign(gtk::Align::Fill) + .valign(gtk::Align::Center) + .hexpand(true) + .build(); + install_confirm_details_boxed_list.add_css_class("boxed-list"); + + let install_confirm_detail_language = adw::ActionRow::builder() + .title("Language:") + .subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-lang.txt").expect("Unable to read file")) + .build(); + install_confirm_detail_language.add_css_class("property"); + + let install_confirm_detail_timezone = adw::ActionRow::builder() + .title("Time zone:") + .subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-timezone.txt").expect("Unable to read file")) + .build(); + install_confirm_detail_timezone.add_css_class("property"); + + let install_confirm_detail_keyboard = adw::ActionRow::builder() + .title("Keyboard layout:") + .subtitle(fs::read_to_string("/tmp/pika-installer-gtk4-keyboard.txt").expect("Unable to read file")) + .build(); + install_confirm_detail_keyboard.add_css_class("property"); + + let install_confirm_detail_target = adw::ActionRow::builder() + .title("Install Target:") + .build(); + + if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() { + install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-manual.txt").expect("Unable to read file")); + } else { + install_confirm_detail_target.set_subtitle(&fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt").expect("Unable to read file")); + } + install_confirm_detail_target.add_css_class("property"); + + if Path::new("/tmp/pika-installer-gtk4-target-auto.txt").exists() { + let target_block_device = &fs::read_to_string("/tmp/pika-installer-gtk4-target-auto.txt").expect("Unable to read file"); + let target_size_cli = Command::new("sudo") + .arg("/usr/lib/pika/pika-installer-gtk4/scripts/partition-utility.sh") + .arg("get_block_size") + .arg(target_block_device) + .output() + .expect("failed to execute process"); + let target_size = String::from_utf8(target_size_cli.stdout).expect("Failed to create float").trim().parse::().unwrap(); + let mut target_p3_size = 0.0; + if (target_size * 40.0) / 100.0 >= 150000000000.0 { + target_p3_size = 150000000000.0 ; + } else if (target_size * 40.0) / 100.0 <= 36507222016.0 { + target_p3_size = 36507222016.0 ; + } else { + target_p3_size = (target_size * 40.0) / 100.0 ; + } + let target_p4_size = target_size - (target_p3_size + 1536.0); + if Path::new("/tmp/pika-installer-p3-size.txt").exists() { + fs::remove_file("/tmp/pika-installer-p3-size.txt").expect("Bad permissions on /tmp/pika-installer-p3-size.txt"); + } + let target_p3_sector = target_p3_size + 1537.0; + fs::write("/tmp/pika-installer-p3-size.txt", target_p3_sector.to_string()).expect("Unable to write file"); + let mut p1_row_text = String::new(); + let mut p2_row_text = String::new(); + let mut p3_row_text = String::new(); + let mut p4_row_text = String::new(); + if target_block_device.contains("nvme") { + p1_row_text = "512 MB ".to_owned() + target_block_device + "p1" + " as fat32" + " on /boot/efi"; + p2_row_text = "1 GB ".to_owned() + target_block_device + "p2" + " as ext4" + " on /boot"; + p3_row_text = pretty_bytes::converter::convert(target_p3_size) + " " + target_block_device + "p3" + " as btrfs" + " on /"; + p4_row_text = pretty_bytes::converter::convert(target_p4_size) + " " + target_block_device + "p4" + " as btrfs" + " on /home"; + } else { + p1_row_text = "512 MB ".to_owned() + target_block_device + "1" + " as fat32" + " on /boot/efi"; + p2_row_text = "1 GB ".to_owned() + target_block_device + "2" + " as ext4" + " on /boot"; + p3_row_text = pretty_bytes::converter::convert(target_p3_size) + " " + target_block_device + "3" + " as btrfs" + " on /"; + p4_row_text = pretty_bytes::converter::convert(target_p4_size) + " " + target_block_device + "4" + " as btrfs" + " on /home"; + } + let install_confirm_p1 = adw::ActionRow::builder() + .title(p1_row_text.clone()) + .build(); + let install_confirm_p2 = adw::ActionRow::builder() + .title(p2_row_text.clone()) + .build(); + let install_confirm_p3 = adw::ActionRow::builder() + .title(p3_row_text.clone()) + .build(); + let install_confirm_p4 = adw::ActionRow::builder() + .title(p4_row_text.clone()) + .build(); + // / install_confirm_selection_box appends + //// add live and install media button to install page selections + install_confirm_details_boxed_list.append(&install_confirm_detail_language); + install_confirm_details_boxed_list.append(&install_confirm_detail_timezone); + install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard); + install_confirm_details_boxed_list.append(&install_confirm_detail_target); + install_confirm_details_boxed_list.append(&install_confirm_p1); + install_confirm_details_boxed_list.append(&install_confirm_p2); + install_confirm_details_boxed_list.append(&install_confirm_p3); + install_confirm_details_boxed_list.append(&install_confirm_p4); + } else { + // / install_confirm_selection_box appends + //// add live and install media button to install page selections + install_confirm_details_boxed_list.append(&install_confirm_detail_language); + install_confirm_details_boxed_list.append(&install_confirm_detail_timezone); + install_confirm_details_boxed_list.append(&install_confirm_detail_keyboard); + install_confirm_details_boxed_list.append(&install_confirm_detail_target); + } + + let install_confirm_button = gtk::Button::builder() + .label("Confirm & Install PikaOS") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .build(); + install_confirm_button.add_css_class("destructive-action"); + + // / install_confirm_header_box appends + //// Add the install page header text and icon + install_confirm_header_box.append(&install_confirm_header_text); + install_confirm_header_box.append(&install_confirm_header_icon); + + // / install_confirm_box appends + //// Add the install header to install main box + install_confirm_box.append(&install_confirm_header_box); + //// Add the install selection/page content box to install main box + install_confirm_box.append(&install_confirm_selection_box); + + // Start Appending widgets to boxes + + // + install_confirm_selection_box.append(&install_confirm_details_boxed_list); + install_confirm_selection_box.append(&install_confirm_button); + + // / install_confirm_header_box appends + //// Add the install page header text and icon + install_confirm_header_box.append(&install_confirm_header_text); + install_confirm_header_box.append(&install_confirm_header_icon); + + // / install_confirm_box appends + //// Add the install header to install main box + install_confirm_box.append(&install_confirm_header_box); + //// Add the install selection/page content box to install main box + install_confirm_box.append(&install_confirm_selection_box); + + install_main_box.append(&install_nested_stack); + + install_confirm_box.append(&bottom_box); + + /// + + let install_progress_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + let install_progress_log_stack = gtk::Stack::builder() + .transition_type(StackTransitionType::SlideUpDown) + .build(); + + let install_progress_log_terminal = vte::Terminal::builder() + .vexpand(true) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .input_enabled(false) + .build(); + + let placeholder_icon = gtk::Image::builder() + .icon_name("debian-swirl") + .halign(gtk::Align::Center) + .valign(gtk::Align::Center) + .hexpand(true) + .vexpand(true) + .pixel_size(512) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + let progress_bar_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .margin_start(15) + .margin_end(15) + .build(); + + let install_progress_bar = gtk::ProgressBar::builder() + .hexpand(true) + .margin_start(15) + .margin_end(15) + .margin_top(15) + .margin_bottom(15) + .show_text(true) + .build(); + + let progress_log_button_content = adw::ButtonContent::builder() + .label("View Logs") + .icon_name("terminal") + .build(); + + let progress_log_button = gtk::Button::builder() + .child(&progress_log_button_content) + .margin_start(15) + .margin_end(15) + .margin_top(15) + .margin_bottom(15) + .build(); + + progress_bar_box.append(&install_progress_bar); + progress_bar_box.append(&progress_log_button); + + install_progress_log_stack.add_titled(&placeholder_icon, Some("slideshow_page"), "slideshow_page"); + install_progress_log_stack.add_titled(&install_progress_log_terminal, Some("terminal_log_page"), "terminal_log_page"); + + install_progress_box.append(&install_progress_log_stack); + install_progress_box.append(&progress_bar_box); + + install_nested_stack.add_titled(&install_confirm_box, Some("confirm_page"), "confirm_page"); + install_nested_stack.add_titled(&install_progress_box, Some("progress_page"), "progress_page"); + + // + + // + + install_confirm_button.connect_clicked(clone!(@weak install_nested_stack, @weak install_progress_log_terminal, @weak install_progress_bar, @weak done_main_box, @weak content_stack, @weak window => move |_| { + install_nested_stack.set_visible_child_name("progress_page"); + begin_install(&install_progress_log_terminal, &install_progress_bar, &done_main_box, &content_stack, &window); + })); + + progress_log_button.connect_clicked(clone!(@weak install_progress_log_stack => move |_| { + if install_progress_log_stack.visible_child_name() == Some(GString::from_string_unchecked("slideshow_page".into())) { + install_progress_log_stack.set_visible_child_name("terminal_log_page"); + } else { + install_progress_log_stack.set_visible_child_name("slideshow_page"); + } + })); + + bottom_back_button.connect_clicked(clone!(@weak content_stack, @weak install_main_box, @weak install_nested_stack => move |_| { + content_stack.set_visible_child_name("partitioning_page"); + install_main_box.remove(&install_nested_stack) + })); +} + +fn begin_install(install_progress_log_terminal: &vte::Terminal, install_progress_bar: >k::ProgressBar, done_main_box: >k::Box, content_stack: >k::Stack, window: &adw::ApplicationWindow) { + // SPAWN TERMINAL WITH PIKAINSTALL PROCESS + install_progress_log_terminal.spawn_async( + PtyFlags::DEFAULT, + Some(""), + &["/usr/lib/pika/pika-installer-gtk4/scripts/begin-install.sh"], + &[], + SpawnFlags::DEFAULT, + || {}, + -1, + None::<&gio::Cancellable>, + move |result| { + match result { + Ok(_) => { eprintln!("could not spawn terminal")} + Err(err) => { + eprintln!("could not spawn terminal: {}", err); + } + } + }, + ); + // wait till /tmp/pika-installer-gtk4-status-parting.txt to change progressbar + let (parting_status_sender, parting_status_receiver) = async_channel::unbounded(); + let parting_status_sender = parting_status_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(move || { + let parting_status = true; + while parting_status == true { + if Path::new("/tmp/pika-installer-gtk4-status-parting.txt").exists() == true { + parting_status_sender + .send_blocking(true) + .expect("The channel needs to be open."); + break + } + } + }); + let parting_status_main_context = MainContext::default(); + // The main loop executes the asynchronous block + parting_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { + while let Ok(parting_status_state) = parting_status_receiver.recv().await { + + if parting_status_state == true { + println!("Installation status: Parting"); + install_progress_bar.set_fraction(0.20); + install_progress_bar.set_text(Some("Partitioning The Disk Target.")); + } + } + })); + // wait till /tmp/pika-installer-gtk4-status-image.txt to change progressbar + let (image_status_sender, image_status_receiver) = async_channel::unbounded(); + let image_status_sender = image_status_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(move || { + let image_status = true; + while image_status == true { + if Path::new("/tmp/pika-installer-gtk4-status-image.txt").exists() == true { + image_status_sender + .send_blocking(true) + .expect("The channel needs to be open."); + break + } + } + }); + let image_status_main_context = MainContext::default(); + // The main loop executes the asynchronous block + image_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { + while let Ok(image_status_state) = image_status_receiver.recv().await { + + if image_status_state == true { + println!("Installation status: Imaging"); + install_progress_bar.set_fraction(0.60); + install_progress_bar.set_text(Some("Writing image to target.")); + } + } + })); + // wait till /tmp/pika-installer-gtk4-status-flag1.txt to change progressbar + let (flag1_status_sender, flag1_status_receiver) = async_channel::unbounded(); + let flag1_status_sender = flag1_status_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(move || { + let flag1_status = true; + while flag1_status == true { + if Path::new("/tmp/pika-installer-gtk4-status-flag1.txt").exists() == true { + flag1_status_sender + .send_blocking(true) + .expect("The channel needs to be open."); + break + } + } + }); + let flag1_status_main_context = MainContext::default(); + // The main loop executes the asynchronous block + flag1_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { + while let Ok(flag1_status_state) = flag1_status_receiver.recv().await { + + if flag1_status_state == true { + println!("Installation status: Flag1"); + install_progress_bar.set_fraction(0.65); + install_progress_bar.set_text(Some("Enabling bls_boot flag on /boot.")); + } + } + })); + // wait till /tmp/pika-installer-gtk4-status-flag2.txt to change progressbar + let (flag2_status_sender, flag2_status_receiver) = async_channel::unbounded(); + let flag2_status_sender = flag2_status_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(move || { + let flag2_status = true; + while flag2_status == true { + if Path::new("/tmp/pika-installer-gtk4-status-flag2.txt").exists() == true { + flag2_status_sender + .send_blocking(true) + .expect("The channel needs to be open."); + break + } + } + }); + let flag2_status_main_context = MainContext::default(); + // The main loop executes the asynchronous block + flag2_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { + while let Ok(flag2_status_state) = flag2_status_receiver.recv().await { + + if flag2_status_state == true { + println!("Installation status: Flag2"); + install_progress_bar.set_fraction(0.70); + install_progress_bar.set_text(Some("Enabling efi flag on /boot/efi.")); + } + } + })); + // wait till /tmp/pika-installer-gtk4-status-crypt.txt to change progressbar + let (crypt_status_sender, crypt_status_receiver) = async_channel::unbounded(); + let crypt_status_sender = crypt_status_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(move || { + let crypt_status = true; + while crypt_status == true { + if Path::new("/tmp/pika-installer-gtk4-status-crypt.txt").exists() == true { + crypt_status_sender + .send_blocking(true) + .expect("The channel needs to be open."); + break + } + } + }); + let crypt_status_main_context = MainContext::default(); + // The main loop executes the asynchronous block + crypt_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { + while let Ok(crypt_status_state) = crypt_status_receiver.recv().await { + + if crypt_status_state == true { + println!("Installation status: Crypttab"); + install_progress_bar.set_fraction(0.75); + install_progress_bar.set_text(Some("Setting up encryption crypttab.")); + } + } + })); + // wait till /tmp/pika-installer-gtk4-status-lang.txt to change progressbar + let (lang_status_sender, lang_status_receiver) = async_channel::unbounded(); + let lang_status_sender = lang_status_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(move || { + let lang_status = true; + while lang_status == true { + if Path::new("/tmp/pika-installer-gtk4-status-lang.txt").exists() == true { + lang_status_sender + .send_blocking(true) + .expect("The channel needs to be open."); + break + } + } + }); + let lang_status_main_context = MainContext::default(); + // The main loop executes the asynchronous block + lang_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { + while let Ok(lang_status_state) = lang_status_receiver.recv().await { + + if lang_status_state == true { + println!("Installation status: Language"); + install_progress_bar.set_fraction(0.80); + install_progress_bar.set_text(Some("Setting Up Language and Keyboard.")); + } + } + })); + // wait till /tmp/pika-installer-gtk4-status-boot.txt to change progressbar + let (boot_status_sender, boot_status_receiver) = async_channel::unbounded(); + let boot_status_sender = boot_status_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(move || { + let boot_status = true; + while boot_status == true { + if Path::new("/tmp/pika-installer-gtk4-status-boot.txt").exists() == true { + boot_status_sender + .send_blocking(true) + .expect("The channel needs to be open."); + break + } + } + }); + let boot_status_main_context = MainContext::default(); + // The main loop executes the asynchronous block + boot_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { + while let Ok(boot_status_state) = boot_status_receiver.recv().await { + + if boot_status_state == true { + println!("Installation status: Bootloader"); + install_progress_bar.set_fraction(0.85); + install_progress_bar.set_text(Some("Configuring bootloader.")); + } + } + })); + // wait till /tmp/pika-installer-gtk4-status-post.txt to change progressbar + let (post_status_sender, post_status_receiver) = async_channel::unbounded(); + let post_status_sender = post_status_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(move || { + let post_status = true; + while post_status == true { + if Path::new("/tmp/pika-installer-gtk4-status-post.txt").exists() == true { + post_status_sender + .send_blocking(true) + .expect("The channel needs to be open."); + break + } + } + }); + let post_status_main_context = MainContext::default(); + // The main loop executes the asynchronous block + post_status_main_context.spawn_local(clone!(@weak install_progress_bar => async move { + while let Ok(post_status_state) = post_status_receiver.recv().await { + + if post_status_state == true { + println!("Installation status: Post Install"); + install_progress_bar.set_fraction(0.90); + install_progress_bar.set_text(Some("Running post installation script.")); + } + } + })); + // wait till /tmp/pika-installer-gtk4-successful.txt to change progressbar + let (done_status_sender, done_status_receiver) = async_channel::unbounded(); + let done_status_sender = done_status_sender.clone(); + // The long running operation runs now in a separate thread + gio::spawn_blocking(move || { + let done_status = true; + while done_status == true { + if Path::new("/tmp/pika-installer-gtk4-successful.txt").exists() == true || Path::new("/tmp/pika-installer-gtk4-fail.txt").exists() == true { + done_status_sender + .send_blocking(true) + .expect("The channel needs to be open."); + break + } + } + }); + let done_status_main_context = MainContext::default(); + // The main loop executes the asynchronous block + done_status_main_context.spawn_local(clone!(@weak done_main_box, @weak content_stack, @weak window => async move { + while let Ok(done_status_state) = done_status_receiver.recv().await { + if done_status_state == true { + println!("Installation status: Done"); + done_page(&done_main_box ,&content_stack, &window); + content_stack.set_visible_child_name("done_page"); + } + } + })); +} \ No newline at end of file diff --git a/src/keyboard_page/main.rs b/src/keyboard_page/main.rs deleted file mode 100644 index 5d9a403..0000000 --- a/src/keyboard_page/main.rs +++ /dev/null @@ -1,252 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; - -use std::io::BufRead; -use std::io::BufReader; -use std::process::Command; -use std::process::Stdio; -use std::time::Instant; -use std::str; - -use std::fs; -use std::path::Path; - -pub fn keyboard_page(content_stack: >k::Stack) { - - // create the bottom box for next and back buttons - let bottom_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .valign(gtk::Align::End) - .vexpand(true) - .build(); - - // Next and back button - let bottom_back_button = gtk::Button::builder() - .label("Back") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::Start) - .hexpand(true) - .build(); - let bottom_next_button = gtk::Button::builder() - .label("Next") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::End) - .hexpand(true) - .sensitive(false) - .build(); - - // Start Applying css classes - bottom_next_button.add_css_class("suggested-action"); - - // / bottom_box appends - //// Add the next and back buttons - bottom_box.append(&bottom_back_button); - bottom_box.append(&bottom_next_button); - - // the header box for the keyboard page - let keyboard_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // the header box for the keyboard page - let keyboard_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the keyboard page - let keyboard_header_text = gtk::Label::builder() - .label("Select a keyboard") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - keyboard_header_text.add_css_class("header_sized_text"); - - // the header icon for the keyboard icon - let keyboard_header_icon = gtk::Image::builder() - .icon_name("keyboard") - .halign(gtk::Align::Start) - .hexpand(true) - .pixel_size(78) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - - // make keyboard selection box for choosing installation or live media - let keyboard_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // / keyboard_header_box appends - //// Add the keyboard page header text and icon - keyboard_header_box.append(&keyboard_header_text); - keyboard_header_box.append(&keyboard_header_icon); - - // / keyboard_main_box appends - //// Add the keyboard header to keyboard main box - keyboard_main_box.append(&keyboard_header_box); - //// Add the keyboard selection/page content box to keyboard main box - keyboard_main_box.append(&keyboard_selection_box); - - // text above keyboard selection box - let keyboard_selection_text = gtk::Label::builder() - .label("Please select a Keyboard layout for the system to use") - .halign(gtk::Align::Center) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - keyboard_selection_text.add_css_class("medium_sized_text"); - - let keyboard_selection_expander_row = adw::ExpanderRow::builder() - .title("No Keyboard Layout selected") - .build(); - - let null_checkbutton = gtk::CheckButton::builder() - .label("No Keyboard Layout selected") - .build(); - - let keyboard_selection_expander_row_viewport = gtk::ScrolledWindow::builder() - .height_request(200) - .build(); - - let keyboard_selection_expander_row_viewport_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - let keyboard_selection_expander_row_viewport_listbox = gtk::ListBox::builder() - .selection_mode(SelectionMode::None) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - keyboard_selection_expander_row_viewport_listbox.add_css_class("boxed-list"); - keyboard_selection_expander_row_viewport_listbox.append(&keyboard_selection_expander_row); - - keyboard_selection_expander_row_viewport.set_child(Some(&keyboard_selection_expander_row_viewport_box)); - - keyboard_selection_expander_row.add_row(&keyboard_selection_expander_row_viewport); - - let current_keyboard_cli = Command::new("localectl") - .arg("status") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|e| panic!("failed {}", e)); - let current_keyboard_grep = Command::new("grep") - .arg("X11 Layout") - .stdin(Stdio::from(current_keyboard_cli.stdout.unwrap())) // Pipe through. - .stdout(Stdio::piped()) - .spawn() - .unwrap(); - let current_keyboard_cut = Command::new("cut") - .arg("-d:") - .arg("-f2") - .stdin(Stdio::from(current_keyboard_grep.stdout.unwrap())) - .stdout(Stdio::piped()) - .spawn() - .unwrap(); - - let current_keyboard_output = current_keyboard_cut.wait_with_output().unwrap(); - let current_keyboard = str::from_utf8(¤t_keyboard_output.stdout).unwrap().trim(); - - let keyboard_layout_cli = Command::new("localectl") - .arg("list-x11-keymap-layouts") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|e| panic!("failed {}", e)); - - let keyboard_layout_stdout = keyboard_layout_cli.stdout.expect("could not get stdout"); - let keyboard_layout_reader = BufReader::new(keyboard_layout_stdout); - - let keyboard_data_buffer = gtk::TextBuffer::builder() - .build(); - - for keyboard_layout in keyboard_layout_reader.lines() { - let keyboard_layout = keyboard_layout.unwrap(); - let keyboard_layout_clone = keyboard_layout.clone(); - let keyboard_layout_checkbutton = gtk::CheckButton::builder() - .label(keyboard_layout.clone()) - .build(); - keyboard_layout_checkbutton.set_group(Some(&null_checkbutton)); - keyboard_selection_expander_row_viewport_box.append(&keyboard_layout_checkbutton); - keyboard_layout_checkbutton.connect_toggled(clone!(@weak keyboard_layout_checkbutton, @weak keyboard_selection_expander_row, @weak bottom_next_button, @weak keyboard_data_buffer => move |_| { - if keyboard_layout_checkbutton.is_active() == true { - keyboard_selection_expander_row.set_title(&keyboard_layout); - bottom_next_button.set_sensitive(true); - keyboard_data_buffer.set_text(&keyboard_layout); - Command::new("setxkbmap") - .arg("-layout") - .arg(keyboard_layout.clone()) - .spawn() - .expect("keyboard failed to start"); - } - })); - if current_keyboard.contains(&(keyboard_layout_clone)) { - keyboard_layout_checkbutton.set_active(true); - } - } - - // / keyboard_selection_box appends - //// add text and and entry to keyboard page selections - keyboard_selection_box.append(&keyboard_selection_text); - keyboard_selection_box.append(&keyboard_selection_expander_row_viewport_listbox); - - // / keyboard_header_box appends - //// Add the keyboard page header text and icon - keyboard_header_box.append(&keyboard_header_text); - keyboard_header_box.append(&keyboard_header_icon); - - // / keyboard_main_box appends - //// Add the keyboard header to keyboard main box - keyboard_main_box.append(&keyboard_header_box); - //// Add the keyboard selection/page content box to keyboard main box - keyboard_main_box.append(&keyboard_selection_box); - - //// Add the keyboard selection/page content box to keyboard main box - keyboard_main_box.append(>k::Entry::builder().hexpand(true).valign(Align::End).vexpand(false).margin_bottom(15).margin_top(15).margin_end(15).margin_start(15).placeholder_text("Test Your Keyboard here!").build()); - - keyboard_main_box.append(&bottom_box); - - // / Content stack appends - //// Add the keyboard_main_box as page: keyboard_page, Give it nice title - content_stack.add_titled(&keyboard_main_box, Some("keyboard_page"), "Keyboard"); - - let keyboard_data_buffer_clone = keyboard_data_buffer.clone(); - - bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { - if Path::new("/tmp/pika-installer-gtk4-keyboard.txt").exists() { - fs::remove_file("/tmp/pika-installer-gtk4-keyboard.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-keyboard.txt"); - } - fs::write("/tmp/pika-installer-gtk4-keyboard.txt", keyboard_data_buffer_clone.text(&keyboard_data_buffer_clone.bounds().0, &keyboard_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); - content_stack.set_visible_child_name("partitioning_page") - })); - - bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| { - content_stack.set_visible_child_name("timezone_page") - })); - -} diff --git a/src/keyboard_page/mod.rs b/src/keyboard_page/mod.rs index 5a8f649..0bb283b 100644 --- a/src/keyboard_page/mod.rs +++ b/src/keyboard_page/mod.rs @@ -1 +1,252 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +use std::io::BufRead; +use std::io::BufReader; +use std::process::Command; +use std::process::Stdio; +use std::time::Instant; +use std::str; + +use std::fs; +use std::path::Path; + +pub fn keyboard_page(content_stack: >k::Stack) { + + // create the bottom box for next and back buttons + let bottom_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .valign(gtk::Align::End) + .vexpand(true) + .build(); + + // Next and back button + let bottom_back_button = gtk::Button::builder() + .label("Back") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::Start) + .hexpand(true) + .build(); + let bottom_next_button = gtk::Button::builder() + .label("Next") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::End) + .hexpand(true) + .sensitive(false) + .build(); + + // Start Applying css classes + bottom_next_button.add_css_class("suggested-action"); + + // / bottom_box appends + //// Add the next and back buttons + bottom_box.append(&bottom_back_button); + bottom_box.append(&bottom_next_button); + + // the header box for the keyboard page + let keyboard_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // the header box for the keyboard page + let keyboard_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the keyboard page + let keyboard_header_text = gtk::Label::builder() + .label("Select a keyboard") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + keyboard_header_text.add_css_class("header_sized_text"); + + // the header icon for the keyboard icon + let keyboard_header_icon = gtk::Image::builder() + .icon_name("keyboard") + .halign(gtk::Align::Start) + .hexpand(true) + .pixel_size(78) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + + // make keyboard selection box for choosing installation or live media + let keyboard_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // / keyboard_header_box appends + //// Add the keyboard page header text and icon + keyboard_header_box.append(&keyboard_header_text); + keyboard_header_box.append(&keyboard_header_icon); + + // / keyboard_main_box appends + //// Add the keyboard header to keyboard main box + keyboard_main_box.append(&keyboard_header_box); + //// Add the keyboard selection/page content box to keyboard main box + keyboard_main_box.append(&keyboard_selection_box); + + // text above keyboard selection box + let keyboard_selection_text = gtk::Label::builder() + .label("Please select a Keyboard layout for the system to use") + .halign(gtk::Align::Center) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + keyboard_selection_text.add_css_class("medium_sized_text"); + + let keyboard_selection_expander_row = adw::ExpanderRow::builder() + .title("No Keyboard Layout selected") + .build(); + + let null_checkbutton = gtk::CheckButton::builder() + .label("No Keyboard Layout selected") + .build(); + + let keyboard_selection_expander_row_viewport = gtk::ScrolledWindow::builder() + .height_request(200) + .build(); + + let keyboard_selection_expander_row_viewport_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + let keyboard_selection_expander_row_viewport_listbox = gtk::ListBox::builder() + .selection_mode(SelectionMode::None) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + keyboard_selection_expander_row_viewport_listbox.add_css_class("boxed-list"); + keyboard_selection_expander_row_viewport_listbox.append(&keyboard_selection_expander_row); + + keyboard_selection_expander_row_viewport.set_child(Some(&keyboard_selection_expander_row_viewport_box)); + + keyboard_selection_expander_row.add_row(&keyboard_selection_expander_row_viewport); + + let current_keyboard_cli = Command::new("localectl") + .arg("status") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap_or_else(|e| panic!("failed {}", e)); + let current_keyboard_grep = Command::new("grep") + .arg("X11 Layout") + .stdin(Stdio::from(current_keyboard_cli.stdout.unwrap())) // Pipe through. + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + let current_keyboard_cut = Command::new("cut") + .arg("-d:") + .arg("-f2") + .stdin(Stdio::from(current_keyboard_grep.stdout.unwrap())) + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + + let current_keyboard_output = current_keyboard_cut.wait_with_output().unwrap(); + let current_keyboard = str::from_utf8(¤t_keyboard_output.stdout).unwrap().trim(); + + let keyboard_layout_cli = Command::new("localectl") + .arg("list-x11-keymap-layouts") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap_or_else(|e| panic!("failed {}", e)); + + let keyboard_layout_stdout = keyboard_layout_cli.stdout.expect("could not get stdout"); + let keyboard_layout_reader = BufReader::new(keyboard_layout_stdout); + + let keyboard_data_buffer = gtk::TextBuffer::builder() + .build(); + + for keyboard_layout in keyboard_layout_reader.lines() { + let keyboard_layout = keyboard_layout.unwrap(); + let keyboard_layout_clone = keyboard_layout.clone(); + let keyboard_layout_checkbutton = gtk::CheckButton::builder() + .label(keyboard_layout.clone()) + .build(); + keyboard_layout_checkbutton.set_group(Some(&null_checkbutton)); + keyboard_selection_expander_row_viewport_box.append(&keyboard_layout_checkbutton); + keyboard_layout_checkbutton.connect_toggled(clone!(@weak keyboard_layout_checkbutton, @weak keyboard_selection_expander_row, @weak bottom_next_button, @weak keyboard_data_buffer => move |_| { + if keyboard_layout_checkbutton.is_active() == true { + keyboard_selection_expander_row.set_title(&keyboard_layout); + bottom_next_button.set_sensitive(true); + keyboard_data_buffer.set_text(&keyboard_layout); + Command::new("setxkbmap") + .arg("-layout") + .arg(keyboard_layout.clone()) + .spawn() + .expect("keyboard failed to start"); + } + })); + if current_keyboard.contains(&(keyboard_layout_clone)) { + keyboard_layout_checkbutton.set_active(true); + } + } + + // / keyboard_selection_box appends + //// add text and and entry to keyboard page selections + keyboard_selection_box.append(&keyboard_selection_text); + keyboard_selection_box.append(&keyboard_selection_expander_row_viewport_listbox); + + // / keyboard_header_box appends + //// Add the keyboard page header text and icon + keyboard_header_box.append(&keyboard_header_text); + keyboard_header_box.append(&keyboard_header_icon); + + // / keyboard_main_box appends + //// Add the keyboard header to keyboard main box + keyboard_main_box.append(&keyboard_header_box); + //// Add the keyboard selection/page content box to keyboard main box + keyboard_main_box.append(&keyboard_selection_box); + + //// Add the keyboard selection/page content box to keyboard main box + keyboard_main_box.append(>k::Entry::builder().hexpand(true).valign(Align::End).vexpand(false).margin_bottom(15).margin_top(15).margin_end(15).margin_start(15).placeholder_text("Test Your Keyboard here!").build()); + + keyboard_main_box.append(&bottom_box); + + // / Content stack appends + //// Add the keyboard_main_box as page: keyboard_page, Give it nice title + content_stack.add_titled(&keyboard_main_box, Some("keyboard_page"), "Keyboard"); + + let keyboard_data_buffer_clone = keyboard_data_buffer.clone(); + + bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { + if Path::new("/tmp/pika-installer-gtk4-keyboard.txt").exists() { + fs::remove_file("/tmp/pika-installer-gtk4-keyboard.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-keyboard.txt"); + } + fs::write("/tmp/pika-installer-gtk4-keyboard.txt", keyboard_data_buffer_clone.text(&keyboard_data_buffer_clone.bounds().0, &keyboard_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); + content_stack.set_visible_child_name("partitioning_page") + })); + + bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| { + content_stack.set_visible_child_name("timezone_page") + })); + +} diff --git a/src/language_page/main.rs b/src/language_page/main.rs deleted file mode 100644 index afed32b..0000000 --- a/src/language_page/main.rs +++ /dev/null @@ -1,243 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; - -use std::io::BufRead; -use std::io::BufReader; -use std::process::Command; -use std::process::Stdio; -use std::time::Instant; -use std::env; - -use std::fs; -use std::path::Path; - - -pub fn language_page(content_stack: >k::Stack) { - - // create the bottom box for next and back buttons - let bottom_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .valign(gtk::Align::End) - .vexpand(true) - .build(); - - // Next and back button - let bottom_back_button = gtk::Button::builder() - .label("Back") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::Start) - .hexpand(true) - .build(); - let bottom_next_button = gtk::Button::builder() - .label("Next") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::End) - .hexpand(true) - .sensitive(false) - .build(); - - // Start Applying css classes - bottom_next_button.add_css_class("suggested-action"); - - // / bottom_box appends - //// Add the next and back buttons - bottom_box.append(&bottom_back_button); - bottom_box.append(&bottom_next_button); - - // the header box for the language page - let language_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // the header box for the language page - let language_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the language page - let language_header_text = gtk::Label::builder() - .label("Select a language") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - language_header_text.add_css_class("header_sized_text"); - - // the header icon for the language icon - let language_header_icon = gtk::Image::builder() - .icon_name("locale") - .halign(gtk::Align::Start) - .hexpand(true) - .pixel_size(78) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - - // make language selection box for choosing installation or live media - let language_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // / language_header_box appends - //// Add the language page header text and icon - language_header_box.append(&language_header_text); - language_header_box.append(&language_header_icon); - - // / language_main_box appends - //// Add the language header to language main box - language_main_box.append(&language_header_box); - //// Add the language selection/page content box to language main box - language_main_box.append(&language_selection_box); - - // text above language selection box - let language_selection_text = gtk::Label::builder() - .label("Please select a locale for the system to use") - .halign(gtk::Align::Center) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - language_selection_text.add_css_class("medium_sized_text"); - - let language_selection_expander_row = adw::ExpanderRow::builder() - .title("No locale selected") - .build(); - - let null_checkbutton = gtk::CheckButton::builder() - .label("No locale selected") - .build(); - - let language_selection_expander_row_viewport = gtk::ScrolledWindow::builder() - .height_request(200) - .build(); - - let language_selection_expander_row_viewport_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - language_selection_expander_row_viewport.set_child(Some(&language_selection_expander_row_viewport_box)); - - let language_selection_expander_row_viewport_listbox = gtk::ListBox::builder() - .selection_mode(SelectionMode::None) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - language_selection_expander_row_viewport_listbox.add_css_class("boxed-list"); - language_selection_expander_row_viewport_listbox.append(&language_selection_expander_row); - - language_selection_expander_row.add_row(&language_selection_expander_row_viewport); - - let current_locale = match env::var_os("LANG") { - Some(v) => v.into_string().unwrap(), - None => panic!("$LANG is not set") - }; - - let locale_cli = Command::new("locale") - .arg("-a") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|e| panic!("failed {}", e)); - let locale_cli_cut = Command::new("cut") - .arg("-d.") - .arg("-f1") - .stdin(Stdio::from(locale_cli.stdout.unwrap())) // Pipe through. - .stdout(Stdio::piped()) - .spawn() - .unwrap(); - let locale_cli_sort = Command::new("sort") - .arg("-u") - .stdin(Stdio::from(locale_cli_cut.stdout.unwrap())) - .stdout(Stdio::piped()) - .spawn() - .unwrap(); - - let locale_reader = BufReader::new(locale_cli_sort.stdout.expect("could not get stdout")); - - let lang_data_buffer = gtk::TextBuffer::builder() - .build(); - - for locale in locale_reader.lines() { - let locale = locale.unwrap(); - let locale_clone = locale.clone(); - let locale_checkbutton = gtk::CheckButton::builder() - .label(locale.clone()) - .build(); - locale_checkbutton.set_group(Some(&null_checkbutton)); - language_selection_expander_row_viewport_box.append(&locale_checkbutton); - locale_checkbutton.connect_toggled(clone!(@weak locale_checkbutton, @weak language_selection_expander_row, @weak bottom_next_button, @weak lang_data_buffer => move |_| { - if locale_checkbutton.is_active() == true { - language_selection_expander_row.set_title(&locale); - bottom_next_button.set_sensitive(true); - lang_data_buffer.set_text(&locale); - } - })); - if current_locale.contains(&(locale_clone)) { - locale_checkbutton.set_active(true); - } - } - - // / language_selection_box appends - //// add text and and entry to language page selections - language_selection_box.append(&language_selection_text); - language_selection_box.append(&language_selection_expander_row_viewport_listbox); - - // / language_header_box appends - //// Add the language page header text and icon - language_header_box.append(&language_header_text); - language_header_box.append(&language_header_icon); - - // / language_main_box appends - //// Add the language header to language main box - language_main_box.append(&language_header_box); - //// Add the language selection/page content box to language main box - language_main_box.append(&language_selection_box); - - language_main_box.append(&bottom_box); - - // / Content stack appends - //// Add the language_main_box as page: language_page, Give it nice title - content_stack.add_titled(&language_main_box, Some("language_page"), "Language"); - - let lang_data_buffer_clone = lang_data_buffer.clone(); - - bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { - if Path::new("/tmp/pika-installer-gtk4-lang.txt").exists() { - fs::remove_file("/tmp/pika-installer-gtk4-lang.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-lang.txt"); - } - fs::write("/tmp/pika-installer-gtk4-lang.txt", lang_data_buffer_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); - Command::new("sudo") - .arg("localectl") - .arg("set-locale") - .arg("LANG=".to_owned() + &lang_data_buffer_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.bounds().1, true).to_string() + ".UTF-8") - .spawn() - .expect("locale failed to start"); - content_stack.set_visible_child_name("eula_page") - })); - bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| { - content_stack.set_visible_child_name("welcome_page") - })); -} diff --git a/src/language_page/mod.rs b/src/language_page/mod.rs index 5a8f649..dee5ec4 100644 --- a/src/language_page/mod.rs +++ b/src/language_page/mod.rs @@ -1 +1,243 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +use std::io::BufRead; +use std::io::BufReader; +use std::process::Command; +use std::process::Stdio; +use std::time::Instant; +use std::env; + +use std::fs; +use std::path::Path; + + +pub fn language_page(content_stack: >k::Stack) { + + // create the bottom box for next and back buttons + let bottom_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .valign(gtk::Align::End) + .vexpand(true) + .build(); + + // Next and back button + let bottom_back_button = gtk::Button::builder() + .label("Back") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::Start) + .hexpand(true) + .build(); + let bottom_next_button = gtk::Button::builder() + .label("Next") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::End) + .hexpand(true) + .sensitive(false) + .build(); + + // Start Applying css classes + bottom_next_button.add_css_class("suggested-action"); + + // / bottom_box appends + //// Add the next and back buttons + bottom_box.append(&bottom_back_button); + bottom_box.append(&bottom_next_button); + + // the header box for the language page + let language_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // the header box for the language page + let language_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the language page + let language_header_text = gtk::Label::builder() + .label("Select a language") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + language_header_text.add_css_class("header_sized_text"); + + // the header icon for the language icon + let language_header_icon = gtk::Image::builder() + .icon_name("locale") + .halign(gtk::Align::Start) + .hexpand(true) + .pixel_size(78) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + + // make language selection box for choosing installation or live media + let language_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // / language_header_box appends + //// Add the language page header text and icon + language_header_box.append(&language_header_text); + language_header_box.append(&language_header_icon); + + // / language_main_box appends + //// Add the language header to language main box + language_main_box.append(&language_header_box); + //// Add the language selection/page content box to language main box + language_main_box.append(&language_selection_box); + + // text above language selection box + let language_selection_text = gtk::Label::builder() + .label("Please select a locale for the system to use") + .halign(gtk::Align::Center) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + language_selection_text.add_css_class("medium_sized_text"); + + let language_selection_expander_row = adw::ExpanderRow::builder() + .title("No locale selected") + .build(); + + let null_checkbutton = gtk::CheckButton::builder() + .label("No locale selected") + .build(); + + let language_selection_expander_row_viewport = gtk::ScrolledWindow::builder() + .height_request(200) + .build(); + + let language_selection_expander_row_viewport_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + language_selection_expander_row_viewport.set_child(Some(&language_selection_expander_row_viewport_box)); + + let language_selection_expander_row_viewport_listbox = gtk::ListBox::builder() + .selection_mode(SelectionMode::None) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + language_selection_expander_row_viewport_listbox.add_css_class("boxed-list"); + language_selection_expander_row_viewport_listbox.append(&language_selection_expander_row); + + language_selection_expander_row.add_row(&language_selection_expander_row_viewport); + + let current_locale = match env::var_os("LANG") { + Some(v) => v.into_string().unwrap(), + None => panic!("$LANG is not set") + }; + + let locale_cli = Command::new("locale") + .arg("-a") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap_or_else(|e| panic!("failed {}", e)); + let locale_cli_cut = Command::new("cut") + .arg("-d.") + .arg("-f1") + .stdin(Stdio::from(locale_cli.stdout.unwrap())) // Pipe through. + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + let locale_cli_sort = Command::new("sort") + .arg("-u") + .stdin(Stdio::from(locale_cli_cut.stdout.unwrap())) + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + + let locale_reader = BufReader::new(locale_cli_sort.stdout.expect("could not get stdout")); + + let lang_data_buffer = gtk::TextBuffer::builder() + .build(); + + for locale in locale_reader.lines() { + let locale = locale.unwrap(); + let locale_clone = locale.clone(); + let locale_checkbutton = gtk::CheckButton::builder() + .label(locale.clone()) + .build(); + locale_checkbutton.set_group(Some(&null_checkbutton)); + language_selection_expander_row_viewport_box.append(&locale_checkbutton); + locale_checkbutton.connect_toggled(clone!(@weak locale_checkbutton, @weak language_selection_expander_row, @weak bottom_next_button, @weak lang_data_buffer => move |_| { + if locale_checkbutton.is_active() == true { + language_selection_expander_row.set_title(&locale); + bottom_next_button.set_sensitive(true); + lang_data_buffer.set_text(&locale); + } + })); + if current_locale.contains(&(locale_clone)) { + locale_checkbutton.set_active(true); + } + } + + // / language_selection_box appends + //// add text and and entry to language page selections + language_selection_box.append(&language_selection_text); + language_selection_box.append(&language_selection_expander_row_viewport_listbox); + + // / language_header_box appends + //// Add the language page header text and icon + language_header_box.append(&language_header_text); + language_header_box.append(&language_header_icon); + + // / language_main_box appends + //// Add the language header to language main box + language_main_box.append(&language_header_box); + //// Add the language selection/page content box to language main box + language_main_box.append(&language_selection_box); + + language_main_box.append(&bottom_box); + + // / Content stack appends + //// Add the language_main_box as page: language_page, Give it nice title + content_stack.add_titled(&language_main_box, Some("language_page"), "Language"); + + let lang_data_buffer_clone = lang_data_buffer.clone(); + + bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { + if Path::new("/tmp/pika-installer-gtk4-lang.txt").exists() { + fs::remove_file("/tmp/pika-installer-gtk4-lang.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-lang.txt"); + } + fs::write("/tmp/pika-installer-gtk4-lang.txt", lang_data_buffer_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); + Command::new("sudo") + .arg("localectl") + .arg("set-locale") + .arg("LANG=".to_owned() + &lang_data_buffer_clone.text(&lang_data_buffer_clone.bounds().0, &lang_data_buffer_clone.bounds().1, true).to_string() + ".UTF-8") + .spawn() + .expect("locale failed to start"); + content_stack.set_visible_child_name("eula_page") + })); + bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| { + content_stack.set_visible_child_name("welcome_page") + })); +} diff --git a/src/manual_partitioning/main.rs b/src/manual_partitioning/main.rs deleted file mode 100644 index de79bdd..0000000 --- a/src/manual_partitioning/main.rs +++ /dev/null @@ -1,153 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; - -use std::io::BufRead; -use std::io::BufReader; -use std::process::Command; -use std::process::Stdio; -use std::time::Instant; -use std::env; -use pretty_bytes::converter::convert; - -use std::thread; -use std::time::*; - -use std::fs; -use std::path::Path; -use crate::drive_mount_row::DriveMountRow; - -fn create_mount_row(listbox: >k::ListBox) -> DriveMountRow { - // Create row - let row = DriveMountRow::new(); - - let listbox_clone = listbox.clone(); - - row.connect_closure( - "row-deleted", - false, - closure_local!(move |_row: DriveMountRow| { - listbox_clone.remove(&_row) - }), - ); - - // Return row - row -} - -//pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) { -pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: >k::Stack, bottom_next_button: >k::Button) { - let partition_method_manual_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .margin_bottom(15) - .margin_top(15) - .margin_end(15) - .margin_start(15) - .build(); - - let partition_method_manual_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the partitioning page - let partition_method_manual_header_text = gtk::Label::builder() - .label("Manual Partitioning Installer") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - partition_method_manual_header_text.add_css_class("header_sized_text"); - - // the header icon for the partitioning icon - let partition_method_manual_header_icon = gtk::Image::builder() - .icon_name("input-tablet") - .halign(gtk::Align::Start) - .hexpand(true) - .pixel_size(78) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - - let partition_method_manual_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - let partition_method_manual_gparted_button_content_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - let partition_method_manual_gparted_button_content_text = gtk::Label::builder() - .label("Use this utility to partition/mount/format your drives.") - .build(); - - let partition_method_manual_gparted_button_content = adw::ButtonContent::builder() - .label("Open GPARTED") - .icon_name("gparted") - .build(); - - let partition_method_manual_gparted_button = gtk::Button::builder() - .child(&partition_method_manual_gparted_button_content_box) - .halign(Align::Center) - .valign(Align::Start) - .build(); - - let drive_mounts_adw_listbox = gtk::ListBox::builder() - .hexpand(true) - .vexpand(true) - .build(); - drive_mounts_adw_listbox.add_css_class("boxed-list"); - - let drive_mounts_viewport = gtk::ScrolledWindow::builder() - .halign(Align::Center) - .valign(Align::Center) - .margin_top(30) - .margin_bottom(30) - .margin_start(30) - .margin_end(30) - .propagate_natural_height(true) - .propagate_natural_width(true) - .hexpand(true) - .vexpand(true) - .child(&drive_mounts_adw_listbox) - .build(); - - let drive_mount_add_button = gtk::Button::builder() - .icon_name("list-add") - .build(); - - partition_method_manual_header_box.append(&partition_method_manual_header_text); - partition_method_manual_header_box.append(&partition_method_manual_header_icon); - partition_method_manual_main_box.append(&partition_method_manual_header_box); - partition_method_manual_main_box.append(&partition_method_manual_selection_box); - partition_method_manual_gparted_button_content_box.append(&partition_method_manual_gparted_button_content); - partition_method_manual_gparted_button_content_box.append(&partition_method_manual_gparted_button_content_text); - partition_method_manual_main_box.append(&partition_method_manual_gparted_button); - drive_mounts_adw_listbox.append(&drive_mount_add_button); - partition_method_manual_main_box.append(&drive_mounts_viewport); - - partition_method_manual_gparted_button.connect_clicked(move |_| { - Command::new("gparted") - .spawn() - .expect("gparted failed to start"); - }); - - drive_mount_add_button.connect_clicked(clone!(@weak drive_mounts_adw_listbox => move |_|{ - drive_mounts_adw_listbox.append(&create_mount_row(&drive_mounts_adw_listbox)) - })); - - partitioning_stack.add_titled(&partition_method_manual_main_box, Some("partition_method_manual_page"), "partition_method_manual_page"); - - //return(partition_method_manual_target_buffer, partition_method_manual_luks_buffer, partition_method_manual_luks_password_entry) -} diff --git a/src/manual_partitioning/mod.rs b/src/manual_partitioning/mod.rs index 5a8f649..4f7ff42 100644 --- a/src/manual_partitioning/mod.rs +++ b/src/manual_partitioning/mod.rs @@ -1 +1,204 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +//use parted::*; + +use std::cell::RefCell; +use std::rc::Rc; + +use std::{ + hash::{ + Hash, + }, + collections::{ + HashSet + }, + io::{ + BufRead, + BufReader, + }, + process::{ + Command, + Stdio, + }, + time::{ + Instant, + }, + fs, + path::{ + Path, + }, +}; +use std::ops::DerefMut; + +use pretty_bytes::converter::convert; +use crate::drive_mount_row::DriveMountRow; + +fn create_mount_row(listbox: >k::ListBox) -> DriveMountRow { + // Create row + let row = DriveMountRow::new(); + + let listbox_clone = listbox.clone(); + + row.connect_closure( + "row-deleted", + false, + closure_local!(move |_row: DriveMountRow| { + listbox_clone.remove(&_row) + }), + ); + + // Return row + row +} + +fn has_unique_elements(iter: T) -> bool + where + T: IntoIterator, + T::Item: Eq + Hash, +{ + let mut uniq = HashSet::new(); + iter.into_iter().all(move |x| uniq.insert(x)) +} + +//pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: >k::Stack, bottom_next_button: >k::Button) -> (gtk::TextBuffer, gtk::TextBuffer, adw::PasswordEntryRow) { +pub fn manual_partitioning(window: &adw::ApplicationWindow, partitioning_stack: >k::Stack, bottom_next_button: >k::Button, manual_drive_partition_array: Rc>>, manual_drive_mountpoint_array: Rc>>, manual_drive_mountopt_array: Rc>>) { + let partition_method_manual_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .margin_bottom(15) + .margin_top(15) + .margin_end(15) + .margin_start(15) + .build(); + + let partition_method_manual_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the partitioning page + let partition_method_manual_header_text = gtk::Label::builder() + .label("Manual Partitioning Installer") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + partition_method_manual_header_text.add_css_class("header_sized_text"); + + // the header icon for the partitioning icon + let partition_method_manual_header_icon = gtk::Image::builder() + .icon_name("input-tablet") + .halign(gtk::Align::Start) + .hexpand(true) + .pixel_size(78) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + + let partition_method_manual_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + let partition_method_manual_gparted_button_content_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + let partition_method_manual_gparted_button_content_text = gtk::Label::builder() + .label("Use this utility to partition/mount/format your drives.") + .build(); + + let partition_method_manual_gparted_button_content = adw::ButtonContent::builder() + .label("Open GPARTED") + .icon_name("gparted") + .build(); + + let partition_method_manual_gparted_button = gtk::Button::builder() + .child(&partition_method_manual_gparted_button_content_box) + .halign(Align::Center) + .valign(Align::Start) + .build(); + + let drive_mounts_adw_listbox = gtk::ListBox::builder() + .hexpand(true) + .vexpand(true) + .build(); + drive_mounts_adw_listbox.add_css_class("boxed-list"); + + let drive_mounts_viewport = gtk::ScrolledWindow::builder() + .halign(Align::Center) + .valign(Align::Center) + .margin_top(30) + .margin_bottom(30) + .margin_start(30) + .margin_end(30) + .propagate_natural_height(true) + .propagate_natural_width(true) + .hexpand(true) + .vexpand(true) + .child(&drive_mounts_adw_listbox) + .build(); + + let drive_mount_add_button = gtk::Button::builder() + .icon_name("list-add") + .build(); + + partition_method_manual_header_box.append(&partition_method_manual_header_text); + partition_method_manual_header_box.append(&partition_method_manual_header_icon); + partition_method_manual_main_box.append(&partition_method_manual_header_box); + partition_method_manual_main_box.append(&partition_method_manual_selection_box); + partition_method_manual_gparted_button_content_box.append(&partition_method_manual_gparted_button_content); + partition_method_manual_gparted_button_content_box.append(&partition_method_manual_gparted_button_content_text); + partition_method_manual_main_box.append(&partition_method_manual_gparted_button); + drive_mounts_adw_listbox.append(&drive_mount_add_button); + partition_method_manual_main_box.append(&drive_mounts_viewport); + + partition_method_manual_gparted_button.connect_clicked(move |_| { + Command::new("gparted") + .spawn() + .expect("gparted failed to start"); + }); + + drive_mount_add_button.connect_clicked(clone!(@weak drive_mounts_adw_listbox => move |_|{ + drive_mounts_adw_listbox.append(&create_mount_row(&drive_mounts_adw_listbox)) + })); + + let debug_button = gtk::Button::builder() + .label("debug") + .build(); + + partition_method_manual_main_box.append(&debug_button); + + debug_button.connect_clicked(clone!(@weak drive_mounts_adw_listbox => move |_| { + let mut counter = drive_mounts_adw_listbox.first_child(); + + // usage of while loop + manual_drive_mountpoint_array.borrow_mut().clear(); + while let Some(row) = counter { + if row.widget_name() == "DriveMountRow" { + manual_drive_mountpoint_array.borrow_mut().push(row.clone().property("mountpoint")) + } + counter = row.next_sibling(); + } + + if !has_unique_elements(manual_drive_mountpoint_array.borrow_mut().deref_mut()) { + println!("FAK") + } + })); + + + partitioning_stack.add_titled(&partition_method_manual_main_box, Some("partition_method_manual_page"), "partition_method_manual_page"); + + //return(partition_method_manual_target_buffer, partition_method_manual_luks_buffer, partition_method_manual_luks_password_entry) +} diff --git a/src/partitioning_page/main.rs b/src/partitioning_page/main.rs deleted file mode 100644 index 020d383..0000000 --- a/src/partitioning_page/main.rs +++ /dev/null @@ -1,281 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; - -use crate::automatic_partitioning::main::automatic_partitioning; -use crate::manual_partitioning::main::manual_partitioning; -use crate::install_page::main::install_page; - -use std::io::BufRead; -use std::io::BufReader; -use std::process::Command; -use std::process::Stdio; -use std::time::Instant; -use std::env; -use pretty_bytes::converter::convert; - -use std::thread; -use std::time::*; - -use std::fs; -use std::path::Path; - -use crate::install_page; - -pub fn partitioning_page(done_main_box: >k::Box, install_main_box: >k::Box ,content_stack: >k::Stack, window: &adw::ApplicationWindow) { - - // create the bottom box for next and back buttons - let bottom_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .valign(gtk::Align::End) - .vexpand(true) - .build(); - - // Next and back button - let bottom_back_button = gtk::Button::builder() - .label("Back") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::Start) - .hexpand(true) - .build(); - let bottom_next_button = gtk::Button::builder() - .label("Next") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::End) - .hexpand(true) - .sensitive(false) - .build(); - - // Start Applying css classes - bottom_next_button.add_css_class("suggested-action"); - - // / bottom_box appends - //// Add the next and back buttons - bottom_box.append(&bottom_back_button); - bottom_box.append(&bottom_next_button); - - // the header box for the partitioning page - let partitioning_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // the header box for the partitioning page - let partitioning_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the partitioning page - let partitioning_header_text = gtk::Label::builder() - .label("Choose an install method") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - partitioning_header_text.add_css_class("header_sized_text"); - - // the header icon for the partitioning icon - let partitioning_header_icon = gtk::Image::builder() - .icon_name("media-floppy") - .halign(gtk::Align::Start) - .hexpand(true) - .pixel_size(78) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - - // a stack for the 2 partitioning methods - let partitioning_stack = gtk::Stack::builder() - .transition_type(StackTransitionType::SlideLeftRight) - .build(); - - let partitioning_method_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // make partitioning selection box for choosing installation or live media - let partitioning_selection_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .spacing(200) - .build(); - - let manual_method_button_content_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .margin_top(30) - .margin_bottom(30) - .build(); - - let manual_method_button_content_image = gtk::Image::builder() - .icon_name("input-tablet") - .pixel_size(128) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - let manual_method_button_content_text = gtk::Label::builder() - .label("Manually Partition The Drive") - .margin_top(0) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - manual_method_button_content_text.add_css_class("medium_sized_text"); - - let automatic_method_button_content_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .margin_top(20) - .margin_bottom(20) - .margin_end(15) - .margin_start(15) - .build(); - - let automatic_method_button_content_image = gtk::Image::builder() - .icon_name("media-playlist-shuffle") - .pixel_size(128) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - let automatic_method_button_content_text = gtk::Label::builder() - .label("Automatically Partition\nThe Drive") - .margin_top(0) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - automatic_method_button_content_text.add_css_class("medium_sized_text"); - - let manual_method_button = gtk::Button::builder() - .child(&manual_method_button_content_box) - .vexpand(true) - .hexpand(true) - .halign(gtk::Align::End) - .valign(gtk::Align::Center) - .build(); - - - let automatic_method_button = gtk::Button::builder() - .child(&automatic_method_button_content_box) - .vexpand(true) - .hexpand(true) - .halign(gtk::Align::Start) - .valign(gtk::Align::Center) - .build(); - - // / manual_method_button_content_box appends - //// add image and text to the manual_method_button - manual_method_button_content_box.append(&manual_method_button_content_image); - manual_method_button_content_box.append(&manual_method_button_content_text); - - // / automatic_method_button_content_box appends - //// add image and text to the automatic_method_button - automatic_method_button_content_box.append(&automatic_method_button_content_image); - automatic_method_button_content_box.append(&automatic_method_button_content_text); - - // / partitioning_selection_box appends - //// add live and install media button to partitioning page selections - partitioning_selection_box.append(&manual_method_button); - partitioning_selection_box.append(&automatic_method_button); - - // / partitioning_header_box appends - //// Add the partitioning page header text and icon - partitioning_header_box.append(&partitioning_header_text); - partitioning_header_box.append(&partitioning_header_icon); - - partitioning_method_main_box.append(&partitioning_header_box); - partitioning_method_main_box.append(&partitioning_selection_box); - - manual_method_button_content_box.append(&manual_method_button_content_image); - - /// add all pages to partitioning stack - partitioning_stack.add_titled(&partitioning_method_main_box, Some("partition_method_select_page"), "partition_method_select_page"); - let partitioning_page_automatic_partitioning = automatic_partitioning(&partitioning_stack, &bottom_next_button); - let partitioning_page_manual_partitioning= manual_partitioning(window, &partitioning_stack, &bottom_next_button); - - // add everything to the main box - partitioning_main_box.append(&partitioning_stack); - partitioning_main_box.append(&bottom_box); - - // / Content stack appends - //// Add the partitioning_main_box as page: partitioning_page, Give it nice title - content_stack.add_titled(&partitioning_main_box, Some("partitioning_page"), "Partitioning"); - - automatic_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_automatic_page"))); - manual_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_manual_page"))); - - //let partition_method_automatic_target_buffer_clone = partitioning_page_automatic_partitioning.0.clone(); - - //let partition_method_automatic_luks_buffer_clone = partitioning_page_automatic_partitioning.1.clone(); - - //let partition_method_manual_target_buffer_clone = partitioning_page_manual_partitioning.0.clone(); - - //let partition_method_manual_luks_buffer_clone = partitioning_page_manual_partitioning.1.clone(); - - bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { - content_stack.set_visible_child_name("install_page") - })); - bottom_back_button.connect_clicked(clone!(@weak content_stack, @weak partitioning_stack, @weak partitioning_main_box, @weak bottom_next_button => move |_| { - content_stack.set_visible_child_name("keyboard_page"); - partitioning_stack.set_visible_child_name("partition_method_select_page"); - bottom_next_button.set_sensitive(false); - })); - - bottom_next_button.connect_clicked(clone!(@weak content_stack, @weak partitioning_stack, @weak install_main_box, @weak window, @weak done_main_box => move |_| { - if Path::new("/tmp/pika-installer-gtk4-target-auto.txt").exists() { - fs::remove_file("/tmp/pika-installer-gtk4-target-auto.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-auto.txt"); - } - if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() { - fs::remove_file("/tmp/pika-installer-gtk4-target-manual.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt"); - } - if Path::new("/tmp/pika-installer-gtk4-target-automatic-luks.txt").exists() { - fs::remove_file("/tmp/pika-installer-gtk4-target-automatic-luks.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt"); - } - if Path::new("/tmp/pika-installer-gtk4-target-manual-luks.txt").exists() { - fs::remove_file("/tmp/pika-installer-gtk4-target-manual-luks.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt"); - } - if partitioning_stack.visible_child_name() == Some(GString::from_string_unchecked("partition_method_automatic_page".into())) { - //fs::write("/tmp/pika-installer-gtk4-target-auto.txt", partition_method_automatic_target_buffer_clone.text(&partition_method_automatic_target_buffer_clone.bounds().0, &partition_method_automatic_target_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); - //let automatic_luks_result = partition_method_automatic_luks_buffer_clone.text(&partition_method_automatic_luks_buffer_clone.bounds().0, &partition_method_automatic_luks_buffer_clone.bounds().1, true).to_string(); - //if automatic_luks_result.is_empty() { - // // - //} else { - // fs::write("/tmp/pika-installer-gtk4-target-automatic-luks.txt", automatic_luks_result); - //} - install_page(&done_main_box, &install_main_box, &content_stack, &window); - content_stack.set_visible_child_name("install_page"); - } else { - //fs::write("/tmp/pika-installer-gtk4-target-manual.txt", partition_method_manual_target_buffer_clone.text(&partition_method_manual_target_buffer_clone.bounds().0, &partition_method_manual_target_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); - //partition_method_manual_luks_buffer_clone.set_text(&partitioning_page_manual_partitioning.2.text().to_string()); - //let manual_luks_result = partition_method_manual_luks_buffer_clone.text(&partition_method_manual_luks_buffer_clone.bounds().0, &partition_method_manual_luks_buffer_clone.bounds().1, true).to_string(); - //if manual_luks_result.is_empty() { - // // - //} else { - // fs::write("/tmp/pika-installer-gtk4-target-manual-luks.txt", manual_luks_result); - //} - install_page(&done_main_box, &install_main_box, &content_stack, &window); - content_stack.set_visible_child_name("install_page"); - } - })); - -} diff --git a/src/partitioning_page/mod.rs b/src/partitioning_page/mod.rs index 5a8f649..41fd4d3 100644 --- a/src/partitioning_page/mod.rs +++ b/src/partitioning_page/mod.rs @@ -1 +1,290 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +use crate::automatic_partitioning::automatic_partitioning; +use crate::manual_partitioning::manual_partitioning; +use crate::install_page::install_page; + +use std::io::BufRead; +use std::io::BufReader; +use std::process::Command; +use std::process::Stdio; +use std::time::Instant; +use std::env; +use pretty_bytes::converter::convert; + +use std::thread; +use std::time::*; + +use std::fs; +use std::path::Path; + +use std::cell::RefCell; +use std::ops::Deref; +use std::rc::Rc; + +use crate::install_page; + +pub fn partitioning_page(done_main_box: >k::Box, install_main_box: >k::Box ,content_stack: >k::Stack, window: &adw::ApplicationWindow) { + + let manual_drive_partition_array : Rc>> = Default::default(); + let manual_drive_mountpoint_array : Rc>> = Default::default(); + let manual_drive_mountopt_array : Rc>> = Default::default(); + + // create the bottom box for next and back buttons + let bottom_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .valign(gtk::Align::End) + .vexpand(true) + .build(); + + // Next and back button + let bottom_back_button = gtk::Button::builder() + .label("Back") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::Start) + .hexpand(true) + .build(); + let bottom_next_button = gtk::Button::builder() + .label("Next") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::End) + .hexpand(true) + .sensitive(false) + .build(); + + // Start Applying css classes + bottom_next_button.add_css_class("suggested-action"); + + // / bottom_box appends + //// Add the next and back buttons + bottom_box.append(&bottom_back_button); + bottom_box.append(&bottom_next_button); + + // the header box for the partitioning page + let partitioning_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // the header box for the partitioning page + let partitioning_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the partitioning page + let partitioning_header_text = gtk::Label::builder() + .label("Choose an install method") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + partitioning_header_text.add_css_class("header_sized_text"); + + // the header icon for the partitioning icon + let partitioning_header_icon = gtk::Image::builder() + .icon_name("media-floppy") + .halign(gtk::Align::Start) + .hexpand(true) + .pixel_size(78) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + + // a stack for the 2 partitioning methods + let partitioning_stack = gtk::Stack::builder() + .transition_type(StackTransitionType::SlideLeftRight) + .build(); + + let partitioning_method_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // make partitioning selection box for choosing installation or live media + let partitioning_selection_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .spacing(200) + .build(); + + let manual_method_button_content_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .margin_top(30) + .margin_bottom(30) + .build(); + + let manual_method_button_content_image = gtk::Image::builder() + .icon_name("input-tablet") + .pixel_size(128) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + let manual_method_button_content_text = gtk::Label::builder() + .label("Manually Partition The Drive") + .margin_top(0) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + manual_method_button_content_text.add_css_class("medium_sized_text"); + + let automatic_method_button_content_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .margin_top(20) + .margin_bottom(20) + .margin_end(15) + .margin_start(15) + .build(); + + let automatic_method_button_content_image = gtk::Image::builder() + .icon_name("media-playlist-shuffle") + .pixel_size(128) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + let automatic_method_button_content_text = gtk::Label::builder() + .label("Automatically Partition\nThe Drive") + .margin_top(0) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + automatic_method_button_content_text.add_css_class("medium_sized_text"); + + let manual_method_button = gtk::Button::builder() + .child(&manual_method_button_content_box) + .vexpand(true) + .hexpand(true) + .halign(gtk::Align::End) + .valign(gtk::Align::Center) + .build(); + + + let automatic_method_button = gtk::Button::builder() + .child(&automatic_method_button_content_box) + .vexpand(true) + .hexpand(true) + .halign(gtk::Align::Start) + .valign(gtk::Align::Center) + .build(); + + // / manual_method_button_content_box appends + //// add image and text to the manual_method_button + manual_method_button_content_box.append(&manual_method_button_content_image); + manual_method_button_content_box.append(&manual_method_button_content_text); + + // / automatic_method_button_content_box appends + //// add image and text to the automatic_method_button + automatic_method_button_content_box.append(&automatic_method_button_content_image); + automatic_method_button_content_box.append(&automatic_method_button_content_text); + + // / partitioning_selection_box appends + //// add live and install media button to partitioning page selections + partitioning_selection_box.append(&manual_method_button); + partitioning_selection_box.append(&automatic_method_button); + + // / partitioning_header_box appends + //// Add the partitioning page header text and icon + partitioning_header_box.append(&partitioning_header_text); + partitioning_header_box.append(&partitioning_header_icon); + + partitioning_method_main_box.append(&partitioning_header_box); + partitioning_method_main_box.append(&partitioning_selection_box); + + manual_method_button_content_box.append(&manual_method_button_content_image); + + /// add all pages to partitioning stack + automatic_method_button.connect_clicked(clone!(@strong manual_drive_mountpoint_array => move |_| println!("{}", manual_drive_mountpoint_array.borrow().deref().into_iter().nth(0).unwrap()))); + partitioning_stack.add_titled(&partitioning_method_main_box, Some("partition_method_select_page"), "partition_method_select_page"); + let partitioning_page_automatic_partitioning = automatic_partitioning(&partitioning_stack, &bottom_next_button); + let partitioning_page_manual_partitioning= manual_partitioning(window, &partitioning_stack, &bottom_next_button, manual_drive_partition_array, manual_drive_mountpoint_array, manual_drive_mountopt_array); + + // add everything to the main box + partitioning_main_box.append(&partitioning_stack); + partitioning_main_box.append(&bottom_box); + + // / Content stack appends + //// Add the partitioning_main_box as page: partitioning_page, Give it nice title + content_stack.add_titled(&partitioning_main_box, Some("partitioning_page"), "Partitioning"); + + //automatic_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_automatic_page"))); + manual_method_button.connect_clicked(clone!(@weak partitioning_stack => move |_| partitioning_stack.set_visible_child_name("partition_method_manual_page"))); + + //let partition_method_automatic_target_buffer_clone = partitioning_page_automatic_partitioning.0.clone(); + + //let partition_method_automatic_luks_buffer_clone = partitioning_page_automatic_partitioning.1.clone(); + + //let partition_method_manual_target_buffer_clone = partitioning_page_manual_partitioning.0.clone(); + + //let partition_method_manual_luks_buffer_clone = partitioning_page_manual_partitioning.1.clone(); + + bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { + content_stack.set_visible_child_name("install_page") + })); + bottom_back_button.connect_clicked(clone!(@weak content_stack, @weak partitioning_stack, @weak partitioning_main_box, @weak bottom_next_button => move |_| { + content_stack.set_visible_child_name("keyboard_page"); + partitioning_stack.set_visible_child_name("partition_method_select_page"); + bottom_next_button.set_sensitive(false); + })); + + bottom_next_button.connect_clicked(clone!(@weak content_stack, @weak partitioning_stack, @weak install_main_box, @weak window, @weak done_main_box => move |_| { + if Path::new("/tmp/pika-installer-gtk4-target-auto.txt").exists() { + fs::remove_file("/tmp/pika-installer-gtk4-target-auto.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-auto.txt"); + } + if Path::new("/tmp/pika-installer-gtk4-target-manual.txt").exists() { + fs::remove_file("/tmp/pika-installer-gtk4-target-manual.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt"); + } + if Path::new("/tmp/pika-installer-gtk4-target-automatic-luks.txt").exists() { + fs::remove_file("/tmp/pika-installer-gtk4-target-automatic-luks.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt"); + } + if Path::new("/tmp/pika-installer-gtk4-target-manual-luks.txt").exists() { + fs::remove_file("/tmp/pika-installer-gtk4-target-manual-luks.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-target-manual.txt"); + } + if partitioning_stack.visible_child_name() == Some(GString::from_string_unchecked("partition_method_automatic_page".into())) { + //fs::write("/tmp/pika-installer-gtk4-target-auto.txt", partition_method_automatic_target_buffer_clone.text(&partition_method_automatic_target_buffer_clone.bounds().0, &partition_method_automatic_target_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); + //let automatic_luks_result = partition_method_automatic_luks_buffer_clone.text(&partition_method_automatic_luks_buffer_clone.bounds().0, &partition_method_automatic_luks_buffer_clone.bounds().1, true).to_string(); + //if automatic_luks_result.is_empty() { + // // + //} else { + // fs::write("/tmp/pika-installer-gtk4-target-automatic-luks.txt", automatic_luks_result); + //} + install_page(&done_main_box, &install_main_box, &content_stack, &window); + content_stack.set_visible_child_name("install_page"); + } else { + //fs::write("/tmp/pika-installer-gtk4-target-manual.txt", partition_method_manual_target_buffer_clone.text(&partition_method_manual_target_buffer_clone.bounds().0, &partition_method_manual_target_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); + //partition_method_manual_luks_buffer_clone.set_text(&partitioning_page_manual_partitioning.2.text().to_string()); + //let manual_luks_result = partition_method_manual_luks_buffer_clone.text(&partition_method_manual_luks_buffer_clone.bounds().0, &partition_method_manual_luks_buffer_clone.bounds().1, true).to_string(); + //if manual_luks_result.is_empty() { + // // + //} else { + // fs::write("/tmp/pika-installer-gtk4-target-manual-luks.txt", manual_luks_result); + //} + install_page(&done_main_box, &install_main_box, &content_stack, &window); + content_stack.set_visible_child_name("install_page"); + } + })); + +} diff --git a/src/save_window_size/main.rs b/src/save_window_size/main.rs deleted file mode 100644 index 5ccb439..0000000 --- a/src/save_window_size/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; - -// Save current window size to glib -pub fn save_window_size(window: &adw::ApplicationWindow, glib_settings: &gio::Settings) { - - let size = window.default_size(); - - let _ = glib_settings.set_int("window-width", size.0); - let _ = glib_settings.set_int("window-height", size.1); - let _ = glib_settings.set_boolean("is-maximized", window.is_maximized()); -} diff --git a/src/save_window_size/mod.rs b/src/save_window_size/mod.rs index 5a8f649..b072be5 100644 --- a/src/save_window_size/mod.rs +++ b/src/save_window_size/mod.rs @@ -1 +1,19 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; + +// Save current window size to glib +pub fn save_window_size(window: &adw::ApplicationWindow, glib_settings: &gio::Settings) { + + let size = window.default_size(); + + let _ = glib_settings.set_int("window-width", size.0); + let _ = glib_settings.set_int("window-height", size.1); + let _ = glib_settings.set_boolean("is-maximized", window.is_maximized()); +} diff --git a/src/timezone_page/main.rs b/src/timezone_page/main.rs deleted file mode 100644 index 3941c66..0000000 --- a/src/timezone_page/main.rs +++ /dev/null @@ -1,239 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; - -use std::io::BufRead; -use std::io::BufReader; -use std::process::Command; -use std::process::Stdio; -use std::time::Instant; -use std::str; - -use std::fs; -use std::path::Path; - -pub fn timezone_page(content_stack: >k::Stack) { - - // create the bottom box for next and back buttons - let bottom_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .valign(gtk::Align::End) - .vexpand(true) - .build(); - - // Next and back button - let bottom_back_button = gtk::Button::builder() - .label("Back") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::Start) - .hexpand(true) - .build(); - let bottom_next_button = gtk::Button::builder() - .label("Next") - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .halign(gtk::Align::End) - .hexpand(true) - .sensitive(false) - .build(); - - // Start Applying css classes - bottom_next_button.add_css_class("suggested-action"); - - // / bottom_box appends - //// Add the next and back buttons - bottom_box.append(&bottom_back_button); - bottom_box.append(&bottom_next_button); - - // the header box for the timezone page - let timezone_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // the header box for the timezone page - let timezone_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the timezone page - let timezone_header_text = gtk::Label::builder() - .label("Select a timezone") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - timezone_header_text.add_css_class("header_sized_text"); - - // the header icon for the timezone icon - let timezone_header_icon = gtk::Image::builder() - .icon_name("clock") - .halign(gtk::Align::Start) - .hexpand(true) - .pixel_size(78) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - - // make timezone selection box for choosing installation or live media - let timezone_selection_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // / timezone_header_box appends - //// Add the timezone page header text and icon - timezone_header_box.append(&timezone_header_text); - timezone_header_box.append(&timezone_header_icon); - - // / timezone_main_box appends - //// Add the timezone header to timezone main box - timezone_main_box.append(&timezone_header_box); - //// Add the timezone selection/page content box to timezone main box - timezone_main_box.append(&timezone_selection_box); - - // text above timezone selection box - let timezone_selection_text = gtk::Label::builder() - .label("Please select a Time Zone for the system to use") - .halign(gtk::Align::Center) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - timezone_selection_text.add_css_class("medium_sized_text"); - - let timezone_selection_expander_row = adw::ExpanderRow::builder() - .title("No Time Zone selected") - .build(); - - let null_checkbutton = gtk::CheckButton::builder() - .label("No Time Zone selected") - .build(); - - let timezone_selection_expander_row_viewport = gtk::ScrolledWindow::builder() - .height_request(200) - .build(); - - let timezone_selection_expander_row_viewport_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - let timezone_selection_expander_row_viewport_listbox = gtk::ListBox::builder() - .selection_mode(SelectionMode::None) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - timezone_selection_expander_row_viewport_listbox.add_css_class("boxed-list"); - timezone_selection_expander_row_viewport_listbox.append(&timezone_selection_expander_row); - - timezone_selection_expander_row_viewport.set_child(Some(&timezone_selection_expander_row_viewport_box)); - - timezone_selection_expander_row.add_row(&timezone_selection_expander_row_viewport); - - let current_timezone_cli = Command::new("timedatectl") - .arg("show") - .arg("--va") - .arg("-p") - .arg("Timezone") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|e| panic!("failed {}", e)); - - let current_timezone_output = current_timezone_cli.wait_with_output().unwrap(); - let current_timezone = str::from_utf8(¤t_timezone_output.stdout).unwrap().trim(); - - let timezone_layout_cli = Command::new("timedatectl") - .arg("list-timezones") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|e| panic!("failed {}", e)); - - let timezone_layout_stdout = timezone_layout_cli.stdout.expect("could not get stdout"); - let timezone_layout_reader = BufReader::new(timezone_layout_stdout); - - let timezone_data_buffer = gtk::TextBuffer::builder() - .build(); - - for timezone_layout in timezone_layout_reader.lines() { - let timezone_layout = timezone_layout.unwrap(); - let timezone_layout_clone = timezone_layout.clone(); - let timezone_layout_checkbutton = gtk::CheckButton::builder() - .label(timezone_layout.clone()) - .build(); - timezone_layout_checkbutton.set_group(Some(&null_checkbutton)); - timezone_selection_expander_row_viewport_box.append(&timezone_layout_checkbutton); - timezone_layout_checkbutton.connect_toggled(clone!(@weak timezone_layout_checkbutton, @weak timezone_selection_expander_row, @weak bottom_next_button, @weak timezone_data_buffer => move |_| { - if timezone_layout_checkbutton.is_active() == true { - timezone_selection_expander_row.set_title(&timezone_layout); - bottom_next_button.set_sensitive(true); - timezone_data_buffer.set_text(&timezone_layout); - } - })); - if current_timezone.contains(&(timezone_layout_clone)) { - timezone_layout_checkbutton.set_active(true); - } - } - - // / timezone_selection_box appends - //// add text and and entry to timezone page selections - timezone_selection_box.append(&timezone_selection_text); - timezone_selection_box.append(&timezone_selection_expander_row_viewport_listbox); - - // / timezone_header_box appends - //// Add the timezone page header text and icon - timezone_header_box.append(&timezone_header_text); - timezone_header_box.append(&timezone_header_icon); - - // / timezone_main_box appends - //// Add the timezone header to timezone main box - timezone_main_box.append(&timezone_header_box); - //// Add the timezone selection/page content box to timezone main box - timezone_main_box.append(&timezone_selection_box); - - timezone_main_box.append(&bottom_box); - - // / Content stack appends - //// Add the timezone_main_box as page: timezone_page, Give it nice title - content_stack.add_titled(&timezone_main_box, Some("timezone_page"), "Time Zone"); - - let timezone_data_buffer_clone = timezone_data_buffer.clone(); - - bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { - if Path::new("/tmp/pika-installer-gtk4-timezone.txt").exists() { - fs::remove_file("/tmp/pika-installer-gtk4-timezone.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-timezone.txt"); - } - fs::write("/tmp/pika-installer-gtk4-timezone.txt", timezone_data_buffer_clone.text(&timezone_data_buffer_clone.bounds().0, &timezone_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); - Command::new("sudo") - .arg("timedatectl") - .arg("set-timezone") - .arg(&timezone_data_buffer_clone.text(&timezone_data_buffer_clone.bounds().0, &timezone_data_buffer_clone.bounds().1, true).to_string()) - .spawn() - .expect("timezone failed to start"); - content_stack.set_visible_child_name("keyboard_page") - })); - bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| { - content_stack.set_visible_child_name("eula_page") - })); - -} diff --git a/src/timezone_page/mod.rs b/src/timezone_page/mod.rs index 5a8f649..dcf65bc 100644 --- a/src/timezone_page/mod.rs +++ b/src/timezone_page/mod.rs @@ -1 +1,239 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +use std::io::BufRead; +use std::io::BufReader; +use std::process::Command; +use std::process::Stdio; +use std::time::Instant; +use std::str; + +use std::fs; +use std::path::Path; + +pub fn timezone_page(content_stack: >k::Stack) { + + // create the bottom box for next and back buttons + let bottom_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .valign(gtk::Align::End) + .vexpand(true) + .build(); + + // Next and back button + let bottom_back_button = gtk::Button::builder() + .label("Back") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::Start) + .hexpand(true) + .build(); + let bottom_next_button = gtk::Button::builder() + .label("Next") + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .halign(gtk::Align::End) + .hexpand(true) + .sensitive(false) + .build(); + + // Start Applying css classes + bottom_next_button.add_css_class("suggested-action"); + + // / bottom_box appends + //// Add the next and back buttons + bottom_box.append(&bottom_back_button); + bottom_box.append(&bottom_next_button); + + // the header box for the timezone page + let timezone_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // the header box for the timezone page + let timezone_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the timezone page + let timezone_header_text = gtk::Label::builder() + .label("Select a timezone") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + timezone_header_text.add_css_class("header_sized_text"); + + // the header icon for the timezone icon + let timezone_header_icon = gtk::Image::builder() + .icon_name("clock") + .halign(gtk::Align::Start) + .hexpand(true) + .pixel_size(78) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + + // make timezone selection box for choosing installation or live media + let timezone_selection_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // / timezone_header_box appends + //// Add the timezone page header text and icon + timezone_header_box.append(&timezone_header_text); + timezone_header_box.append(&timezone_header_icon); + + // / timezone_main_box appends + //// Add the timezone header to timezone main box + timezone_main_box.append(&timezone_header_box); + //// Add the timezone selection/page content box to timezone main box + timezone_main_box.append(&timezone_selection_box); + + // text above timezone selection box + let timezone_selection_text = gtk::Label::builder() + .label("Please select a Time Zone for the system to use") + .halign(gtk::Align::Center) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + timezone_selection_text.add_css_class("medium_sized_text"); + + let timezone_selection_expander_row = adw::ExpanderRow::builder() + .title("No Time Zone selected") + .build(); + + let null_checkbutton = gtk::CheckButton::builder() + .label("No Time Zone selected") + .build(); + + let timezone_selection_expander_row_viewport = gtk::ScrolledWindow::builder() + .height_request(200) + .build(); + + let timezone_selection_expander_row_viewport_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + let timezone_selection_expander_row_viewport_listbox = gtk::ListBox::builder() + .selection_mode(SelectionMode::None) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + timezone_selection_expander_row_viewport_listbox.add_css_class("boxed-list"); + timezone_selection_expander_row_viewport_listbox.append(&timezone_selection_expander_row); + + timezone_selection_expander_row_viewport.set_child(Some(&timezone_selection_expander_row_viewport_box)); + + timezone_selection_expander_row.add_row(&timezone_selection_expander_row_viewport); + + let current_timezone_cli = Command::new("timedatectl") + .arg("show") + .arg("--va") + .arg("-p") + .arg("Timezone") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap_or_else(|e| panic!("failed {}", e)); + + let current_timezone_output = current_timezone_cli.wait_with_output().unwrap(); + let current_timezone = str::from_utf8(¤t_timezone_output.stdout).unwrap().trim(); + + let timezone_layout_cli = Command::new("timedatectl") + .arg("list-timezones") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap_or_else(|e| panic!("failed {}", e)); + + let timezone_layout_stdout = timezone_layout_cli.stdout.expect("could not get stdout"); + let timezone_layout_reader = BufReader::new(timezone_layout_stdout); + + let timezone_data_buffer = gtk::TextBuffer::builder() + .build(); + + for timezone_layout in timezone_layout_reader.lines() { + let timezone_layout = timezone_layout.unwrap(); + let timezone_layout_clone = timezone_layout.clone(); + let timezone_layout_checkbutton = gtk::CheckButton::builder() + .label(timezone_layout.clone()) + .build(); + timezone_layout_checkbutton.set_group(Some(&null_checkbutton)); + timezone_selection_expander_row_viewport_box.append(&timezone_layout_checkbutton); + timezone_layout_checkbutton.connect_toggled(clone!(@weak timezone_layout_checkbutton, @weak timezone_selection_expander_row, @weak bottom_next_button, @weak timezone_data_buffer => move |_| { + if timezone_layout_checkbutton.is_active() == true { + timezone_selection_expander_row.set_title(&timezone_layout); + bottom_next_button.set_sensitive(true); + timezone_data_buffer.set_text(&timezone_layout); + } + })); + if current_timezone.contains(&(timezone_layout_clone)) { + timezone_layout_checkbutton.set_active(true); + } + } + + // / timezone_selection_box appends + //// add text and and entry to timezone page selections + timezone_selection_box.append(&timezone_selection_text); + timezone_selection_box.append(&timezone_selection_expander_row_viewport_listbox); + + // / timezone_header_box appends + //// Add the timezone page header text and icon + timezone_header_box.append(&timezone_header_text); + timezone_header_box.append(&timezone_header_icon); + + // / timezone_main_box appends + //// Add the timezone header to timezone main box + timezone_main_box.append(&timezone_header_box); + //// Add the timezone selection/page content box to timezone main box + timezone_main_box.append(&timezone_selection_box); + + timezone_main_box.append(&bottom_box); + + // / Content stack appends + //// Add the timezone_main_box as page: timezone_page, Give it nice title + content_stack.add_titled(&timezone_main_box, Some("timezone_page"), "Time Zone"); + + let timezone_data_buffer_clone = timezone_data_buffer.clone(); + + bottom_next_button.connect_clicked(clone!(@weak content_stack => move |_| { + if Path::new("/tmp/pika-installer-gtk4-timezone.txt").exists() { + fs::remove_file("/tmp/pika-installer-gtk4-timezone.txt").expect("Bad permissions on /tmp/pika-installer-gtk4-timezone.txt"); + } + fs::write("/tmp/pika-installer-gtk4-timezone.txt", timezone_data_buffer_clone.text(&timezone_data_buffer_clone.bounds().0, &timezone_data_buffer_clone.bounds().1, true).to_string()).expect("Unable to write file"); + Command::new("sudo") + .arg("timedatectl") + .arg("set-timezone") + .arg(&timezone_data_buffer_clone.text(&timezone_data_buffer_clone.bounds().0, &timezone_data_buffer_clone.bounds().1, true).to_string()) + .spawn() + .expect("timezone failed to start"); + content_stack.set_visible_child_name("keyboard_page") + })); + bottom_back_button.connect_clicked(clone!(@weak content_stack => move |_| { + content_stack.set_visible_child_name("eula_page") + })); + +} diff --git a/src/welcome_page/main.rs b/src/welcome_page/main.rs deleted file mode 100644 index 7f2cc90..0000000 --- a/src/welcome_page/main.rs +++ /dev/null @@ -1,169 +0,0 @@ -// Use libraries -/// Use all gtk4 libraries (gtk4 -> gtk because cargo) -/// Use all libadwaita libraries (libadwaita -> adw because cargo) -use gtk::prelude::*; -use gtk::*; -use adw::prelude::*; -use adw::*; -use glib::*; -use gdk::Display; -use gtk::subclass::layout_child; - -pub fn welcome_page(window: &adw::ApplicationWindow, content_stack: >k::Stack) { - // the header box for the welcome page - let welcome_main_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - // the header box for the welcome page - let welcome_header_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .build(); - - // the header text for the welcome page - let welcome_header_text = gtk::Label::builder() - .label("Welcome to PikaOS") - .halign(gtk::Align::End) - .hexpand(true) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(5) - .build(); - welcome_header_text.add_css_class("header_sized_text"); - - // the header icon for the welcome icon - let welcome_header_icon = gtk::Image::builder() - .icon_name("debian-swirl") - .halign(gtk::Align::Start) - .hexpand(true) - .pixel_size(78) - .margin_top(15) - .margin_bottom(15) - .margin_start(0) - .margin_end(15) - .build(); - - // make welcome selection box for choosing installation or live media - let welcome_selection_box = gtk::Box::builder() - .orientation(Orientation::Horizontal) - .spacing(200) - .build(); - - let live_media_button_content_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - let live_media_button_content_image = gtk::Image::builder() - .icon_name("drive-optical") - .pixel_size(128) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - let live_media_button_content_text = gtk::Label::builder() - .label("Use PikaOS in Live media") - .margin_top(0) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - live_media_button_content_text.add_css_class("medium_sized_text"); - - let install_media_button_content_box = gtk::Box::builder() - .orientation(Orientation::Vertical) - .build(); - - let install_media_button_content_image = gtk::Image::builder() - .icon_name("drive-harddisk") - .pixel_size(128) - .margin_top(15) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - - let install_media_button_content_text = gtk::Label::builder() - .label("Install Distro to System") - .margin_top(0) - .margin_bottom(15) - .margin_start(15) - .margin_end(15) - .build(); - install_media_button_content_text.add_css_class("medium_sized_text"); - - let live_media_button = gtk::Button::builder() - .child(&live_media_button_content_box) - .vexpand(true) - .hexpand(true) - .halign(gtk::Align::End) - .valign(gtk::Align::Center) - .build(); - - - let install_media_button = gtk::Button::builder() - .child(&install_media_button_content_box) - .vexpand(true) - .hexpand(true) - .halign(gtk::Align::Start) - .valign(gtk::Align::Center) - .build(); - - // / live_media_button_content_box appends - //// add image and text to the live_media_button - live_media_button_content_box.append(&live_media_button_content_image); - live_media_button_content_box.append(&live_media_button_content_text); - - // / install_media_button_content_box appends - //// add image and text to the install_media_button - install_media_button_content_box.append(&install_media_button_content_image); - install_media_button_content_box.append(&install_media_button_content_text); - - // / welcome_selection_box appends - //// add live and install media button to welcome page selections - welcome_selection_box.append(&live_media_button); - welcome_selection_box.append(&install_media_button); - - // / welcome_header_box appends - //// Add the welcome page header text and icon - welcome_header_box.append(&welcome_header_text); - welcome_header_box.append(&welcome_header_icon); - - // / welcome_main_box appends - //// Add the welcome header to welcome main box - welcome_main_box.append(&welcome_header_box); - //// Add the welcome selection/page content box to welcome main box - welcome_main_box.append(&welcome_selection_box); - - // Start Appending widgets to boxes - - // / live_media_button_content_box appends - //// add image and text to the live_media_button - live_media_button_content_box.append(&live_media_button_content_image); - - - // / welcome_selection_box appends - //// add live and install media button to welcome page selections - welcome_selection_box.append(&live_media_button); - welcome_selection_box.append(&install_media_button); - - // / welcome_header_box appends - //// Add the welcome page header text and icon - welcome_header_box.append(&welcome_header_text); - welcome_header_box.append(&welcome_header_icon); - - // / welcome_main_box appends - //// Add the welcome header to welcome main box - welcome_main_box.append(&welcome_header_box); - //// Add the welcome selection/page content box to welcome main box - welcome_main_box.append(&welcome_selection_box); - - // / Content stack appends - //// Add the welcome_main_box as page: welcome_page, Give it nice title - content_stack.add_titled(&welcome_main_box, Some("welcome_page"), "Welcome"); - - install_media_button.connect_clicked(clone!(@weak content_stack => move |_| content_stack.set_visible_child_name("language_page"))); - live_media_button.connect_clicked(clone!(@weak window => move |_| window.close())); -} diff --git a/src/welcome_page/mod.rs b/src/welcome_page/mod.rs index 5a8f649..4209e06 100644 --- a/src/welcome_page/mod.rs +++ b/src/welcome_page/mod.rs @@ -1 +1,169 @@ -pub mod main; \ No newline at end of file +// Use libraries +/// Use all gtk4 libraries (gtk4 -> gtk because cargo) +/// Use all libadwaita libraries (libadwaita -> adw because cargo) +use gtk::prelude::*; +use gtk::*; +use adw::prelude::*; +use adw::*; +use glib::*; +use gdk::Display; +use gtk::subclass::layout_child; + +pub fn welcome_page(window: &adw::ApplicationWindow, content_stack: >k::Stack) { + // the header box for the welcome page + let welcome_main_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + // the header box for the welcome page + let welcome_header_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .build(); + + // the header text for the welcome page + let welcome_header_text = gtk::Label::builder() + .label("Welcome to PikaOS") + .halign(gtk::Align::End) + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(5) + .build(); + welcome_header_text.add_css_class("header_sized_text"); + + // the header icon for the welcome icon + let welcome_header_icon = gtk::Image::builder() + .icon_name("debian-swirl") + .halign(gtk::Align::Start) + .hexpand(true) + .pixel_size(78) + .margin_top(15) + .margin_bottom(15) + .margin_start(0) + .margin_end(15) + .build(); + + // make welcome selection box for choosing installation or live media + let welcome_selection_box = gtk::Box::builder() + .orientation(Orientation::Horizontal) + .spacing(200) + .build(); + + let live_media_button_content_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + let live_media_button_content_image = gtk::Image::builder() + .icon_name("drive-optical") + .pixel_size(128) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + let live_media_button_content_text = gtk::Label::builder() + .label("Use PikaOS in Live media") + .margin_top(0) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + live_media_button_content_text.add_css_class("medium_sized_text"); + + let install_media_button_content_box = gtk::Box::builder() + .orientation(Orientation::Vertical) + .build(); + + let install_media_button_content_image = gtk::Image::builder() + .icon_name("drive-harddisk") + .pixel_size(128) + .margin_top(15) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + + let install_media_button_content_text = gtk::Label::builder() + .label("Install Distro to System") + .margin_top(0) + .margin_bottom(15) + .margin_start(15) + .margin_end(15) + .build(); + install_media_button_content_text.add_css_class("medium_sized_text"); + + let live_media_button = gtk::Button::builder() + .child(&live_media_button_content_box) + .vexpand(true) + .hexpand(true) + .halign(gtk::Align::End) + .valign(gtk::Align::Center) + .build(); + + + let install_media_button = gtk::Button::builder() + .child(&install_media_button_content_box) + .vexpand(true) + .hexpand(true) + .halign(gtk::Align::Start) + .valign(gtk::Align::Center) + .build(); + + // / live_media_button_content_box appends + //// add image and text to the live_media_button + live_media_button_content_box.append(&live_media_button_content_image); + live_media_button_content_box.append(&live_media_button_content_text); + + // / install_media_button_content_box appends + //// add image and text to the install_media_button + install_media_button_content_box.append(&install_media_button_content_image); + install_media_button_content_box.append(&install_media_button_content_text); + + // / welcome_selection_box appends + //// add live and install media button to welcome page selections + welcome_selection_box.append(&live_media_button); + welcome_selection_box.append(&install_media_button); + + // / welcome_header_box appends + //// Add the welcome page header text and icon + welcome_header_box.append(&welcome_header_text); + welcome_header_box.append(&welcome_header_icon); + + // / welcome_main_box appends + //// Add the welcome header to welcome main box + welcome_main_box.append(&welcome_header_box); + //// Add the welcome selection/page content box to welcome main box + welcome_main_box.append(&welcome_selection_box); + + // Start Appending widgets to boxes + + // / live_media_button_content_box appends + //// add image and text to the live_media_button + live_media_button_content_box.append(&live_media_button_content_image); + + + // / welcome_selection_box appends + //// add live and install media button to welcome page selections + welcome_selection_box.append(&live_media_button); + welcome_selection_box.append(&install_media_button); + + // / welcome_header_box appends + //// Add the welcome page header text and icon + welcome_header_box.append(&welcome_header_text); + welcome_header_box.append(&welcome_header_icon); + + // / welcome_main_box appends + //// Add the welcome header to welcome main box + welcome_main_box.append(&welcome_header_box); + //// Add the welcome selection/page content box to welcome main box + welcome_main_box.append(&welcome_selection_box); + + // / Content stack appends + //// Add the welcome_main_box as page: welcome_page, Give it nice title + content_stack.add_titled(&welcome_main_box, Some("welcome_page"), "Welcome"); + + install_media_button.connect_clicked(clone!(@weak content_stack => move |_| content_stack.set_visible_child_name("language_page"))); + live_media_button.connect_clicked(clone!(@weak window => move |_| window.close())); +}