diff --git a/src/build_ui.rs b/src/build_ui.rs index dc7045d..7cec331 100644 --- a/src/build_ui.rs +++ b/src/build_ui.rs @@ -6,6 +6,19 @@ use crate::{ use gtk::{gio, glib, prelude::*}; use std::{cell::RefCell, path::Path, rc::Rc}; +#[derive(Default, Clone, Debug)] +pub struct PikaLocale { + pub name: String, + pub pretty_name: String +} + +#[derive(Default, Clone, Debug)] +pub struct PikaKeymap { + pub name: String, + pub variant: Option, + pub pretty_name: String +} + pub fn build_ui(app: &adw::Application) { glib::set_prgname(Some("application_name")); glib::set_application_name(&t!("application_name")); @@ -53,9 +66,8 @@ pub fn build_ui(app: &adw::Application) { _ => efi_error_page::efi_error_page(&window, &carousel), } - let language_selection_text_refcell: Rc> = Rc::new(RefCell::default()); - let keymap_base_selection_text_refcell: Rc> = Rc::new(RefCell::default()); - let keymap_varient_selection_text_refcell: Rc> = Rc::new(RefCell::default()); + let language_selection_text_refcell: Rc> = Rc::new(RefCell::default()); + let keymap_selection_text_refcell: Rc> = Rc::new(RefCell::default()); let timezone_selection_text_refcell: Rc> = Rc::new(RefCell::default()); let partition_method_type_refcell: Rc> = Rc::new(RefCell::default()); let partition_method_automatic_target_refcell: Rc> = @@ -87,8 +99,7 @@ pub fn build_ui(app: &adw::Application) { keyboard_page::keyboard_page( &carousel, - &keymap_base_selection_text_refcell, - &keymap_varient_selection_text_refcell, + &keymap_selection_text_refcell, &language_changed_action, ); diff --git a/src/installation_summary_page/mod.rs b/src/installation_summary_page/mod.rs new file mode 100644 index 0000000..80eb09c --- /dev/null +++ b/src/installation_summary_page/mod.rs @@ -0,0 +1,239 @@ +use crate::installer_stack_page; +use adw::prelude::*; +use glib::{clone, closure_local}; +use gnome_desktop::XkbInfoExt; +use gtk::{gio, glib, prelude::*}; +use std::{cell::RefCell, fs, path::Path, process::Command, rc::Rc}; + +struct PikaKeymap { + name: String, + pretty_name: String +} + +pub fn keyboard_page( + main_carousel: &adw::Carousel, + keymap_base_data_refcell: &Rc>, + keymap_variant_data_refcell: &Rc>, + language_changed_action: &gio::SimpleAction, +) { + let keyboard_page = installer_stack_page::InstallerStackPage::new(); + keyboard_page.set_page_icon("keyboard-symbolic"); + keyboard_page.set_back_visible(true); + keyboard_page.set_next_visible(true); + keyboard_page.set_back_sensitive(true); + keyboard_page.set_next_sensitive(false); + + let content_box = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .hexpand(true) + .vexpand(true) + .build(); + + let null_checkbutton = gtk::CheckButton::builder().build(); + + let keyboard_selection_row_viewport_listbox = gtk::ListBox::builder() + .selection_mode(gtk::SelectionMode::None) + .build(); + keyboard_selection_row_viewport_listbox.add_css_class("boxed-list"); + keyboard_selection_row_viewport_listbox.add_css_class("round-border-only"); + + let keyboard_selection_row_viewport = gtk::ScrolledWindow::builder() + .vexpand(true) + .hexpand(true) + .has_frame(true) + .child(&keyboard_selection_row_viewport_listbox) + .build(); + + keyboard_selection_row_viewport.add_css_class("round-border-only-top-with-padding"); + + let keyboard_search_bar = gtk::SearchEntry::builder() + .hexpand(true) + .margin_top(15) + .margin_bottom(15) + .search_delay(500) + .build(); + + keyboard_search_bar.add_css_class("rounded-all-25"); + + let keyboard_test_entry_boxed_list = gtk::ListBox::builder() + .margin_top(5) + .margin_bottom(5) + .build(); + + keyboard_test_entry_boxed_list.add_css_class("boxed-list"); + + let keyboard_test_entry = adw::EntryRow::builder().build(); + + keyboard_test_entry_boxed_list.append(&keyboard_test_entry); + + keyboard_test_entry_boxed_list.add_css_class("round-border-only-bottom"); + + let current_keymap = "us"; + + let xkbinfo = gnome_desktop::XkbInfo::new(); + + let keymap_list = gnome_desktop::XkbInfo::all_layouts(&xkbinfo); + + let mut sorted_keymap_vec = Vec::new(); + for keymap in keymap_list.iter() { + sorted_keymap_vec.push(PikaKeymap{ + name: keymap.to_string(), + pretty_name: xkbinfo.layout_info(&keymap).unwrap().0.unwrap().to_string() + }) + } + sorted_keymap_vec.sort_by_key(|k| k.pretty_name.clone()); + + for pika_keymap in sorted_keymap_vec { + let keymap = pika_keymap.name; + let keymap_name = pika_keymap.pretty_name; + let keymap_split: Vec = keymap.split("+").map(|s| s.into()).collect(); + let keymap_base = keymap_split.get(0).unwrap().clone(); + let mut keymap_variant = String::new(); + let mut split_index = 0; + for split in keymap_split { + split_index += 1; + if split_index == 1 { + continue; + } + keymap_variant.push_str(&split) + } + let keymap_clone = keymap.clone(); + let keymap_checkbutton = gtk::CheckButton::builder() + .valign(gtk::Align::Center) + .can_focus(false) + .build(); + let keymap_row = adw::ActionRow::builder() + .activatable_widget(&keymap_checkbutton) + .title(keymap_name) + .subtitle(keymap.clone()) + .build(); + keymap_row.add_prefix(&keymap_checkbutton); + keymap_checkbutton.set_group(Some(&null_checkbutton)); + keyboard_selection_row_viewport_listbox.append(&keymap_row); + keymap_checkbutton.connect_toggled(clone!( + #[weak] + keymap_checkbutton, + #[strong] + keymap_base_data_refcell, + #[strong] + keymap_variant_data_refcell, + #[weak] + keyboard_page, + move |_| { + if keymap_checkbutton.is_active() == true { + keyboard_page.set_next_sensitive(true); + if keymap_variant.is_empty() { + *keymap_base_data_refcell.borrow_mut() = String::from(&keymap_base); + Command::new("setxkbmap") + .arg("-layout") + .arg(keymap_base.clone()) + .spawn() + .expect("keyboard failed to start"); + } else { + *keymap_base_data_refcell.borrow_mut() = String::from(&keymap_base); + *keymap_variant_data_refcell.borrow_mut() = String::from(&keymap_variant); + Command::new("setxkbmap") + .arg("-layout") + .arg(keymap_base.clone()) + .arg("-variant") + .arg(keymap_variant.clone()) + .spawn() + .expect("keyboard failed to start"); + } + } + } + )); + if current_keymap == keymap_clone { + keymap_checkbutton.set_active(true); + } + } + + // / content_box appends + //// add text and and entry to keyboard page selections + content_box.append(&keyboard_search_bar); + content_box.append(&keyboard_selection_row_viewport); + content_box.append(&keyboard_test_entry_boxed_list); + + keyboard_search_bar.connect_search_changed(clone!( + #[weak] + keyboard_search_bar, + #[weak] + keyboard_selection_row_viewport_listbox, + move |_| { + let mut counter = keyboard_selection_row_viewport_listbox.first_child(); + while let Some(row) = counter { + if row.widget_name() == "AdwActionRow" { + if !keyboard_search_bar.text().is_empty() { + if row + .property::("subtitle") + .to_lowercase() + .contains(&keyboard_search_bar.text().to_string().to_lowercase()) + || row + .property::("title") + .to_lowercase() + .contains(&keyboard_search_bar.text().to_string().to_lowercase()) + { + row.set_property("visible", true); + keyboard_search_bar.grab_focus(); + } else { + row.set_property("visible", false); + } + } else { + row.set_property("visible", true); + } + } + counter = row.next_sibling(); + } + } + )); + + keyboard_page.set_child_widget(&content_box); + + // + language_changed_action.connect_activate(clone!( + #[weak] + keyboard_page, + #[weak] + keyboard_search_bar, + #[weak] + keyboard_test_entry, + move |_, _| { + keyboard_page.set_page_title(t!("keyboard_page_title")); + keyboard_page.set_page_subtitle(t!("keyboard_page_subtitle")); + keyboard_page.set_back_tooltip_label(t!("back")); + keyboard_page.set_next_tooltip_label(t!("next")); + // + keyboard_search_bar + .set_placeholder_text(Some(&t!("keyboard_search_bar_placeholder_text"))); + // + keyboard_test_entry.set_title(&t!("keyboard_test_entry_title")) + } + )); + // + + keyboard_page.connect_closure( + "back-button-pressed", + false, + closure_local!( + #[weak] + main_carousel, + move |_keyboard_page: installer_stack_page::InstallerStackPage| { + main_carousel.scroll_to(&main_carousel.nth_page(2), true) + } + ), + ); + + keyboard_page.connect_closure( + "next-button-pressed", + false, + closure_local!( + #[weak] + main_carousel, + move |_keyboard_page: installer_stack_page::InstallerStackPage| { + main_carousel.scroll_to(&main_carousel.nth_page(4), true) + } + ), + ); + + main_carousel.append(&keyboard_page); +} diff --git a/src/keyboard_page/mod.rs b/src/keyboard_page/mod.rs index 80eb09c..f81c622 100644 --- a/src/keyboard_page/mod.rs +++ b/src/keyboard_page/mod.rs @@ -1,19 +1,13 @@ -use crate::installer_stack_page; +use crate::{build_ui::PikaKeymap, installer_stack_page}; use adw::prelude::*; use glib::{clone, closure_local}; use gnome_desktop::XkbInfoExt; use gtk::{gio, glib, prelude::*}; use std::{cell::RefCell, fs, path::Path, process::Command, rc::Rc}; -struct PikaKeymap { - name: String, - pretty_name: String -} - pub fn keyboard_page( main_carousel: &adw::Carousel, - keymap_base_data_refcell: &Rc>, - keymap_variant_data_refcell: &Rc>, + keymap_data_refcell: &Rc>, language_changed_action: &gio::SimpleAction, ) { let keyboard_page = installer_stack_page::InstallerStackPage::new(); @@ -78,26 +72,35 @@ pub fn keyboard_page( for keymap in keymap_list.iter() { sorted_keymap_vec.push(PikaKeymap{ name: keymap.to_string(), - pretty_name: xkbinfo.layout_info(&keymap).unwrap().0.unwrap().to_string() + pretty_name: xkbinfo.layout_info(&keymap).unwrap().0.unwrap().to_string(), + variant: { + let keymap_split: Vec = keymap.split("+").map(|s| s.into()).collect(); + let keymap_base = keymap_split.get(0).unwrap().clone(); + let mut keymap_variant = String::new(); + let mut split_index = 0; + for split in keymap_split { + split_index += 1; + if split_index == 1 { + continue; + } + keymap_variant.push_str(&split) + } + if keymap_variant.is_empty() { + None + } else { + Some(keymap_variant) + } + } }) } sorted_keymap_vec.sort_by_key(|k| k.pretty_name.clone()); for pika_keymap in sorted_keymap_vec { + let keymap_clone0 = pika_keymap.clone(); + let keymap_clone1 = pika_keymap.clone(); let keymap = pika_keymap.name; let keymap_name = pika_keymap.pretty_name; - let keymap_split: Vec = keymap.split("+").map(|s| s.into()).collect(); - let keymap_base = keymap_split.get(0).unwrap().clone(); - let mut keymap_variant = String::new(); - let mut split_index = 0; - for split in keymap_split { - split_index += 1; - if split_index == 1 { - continue; - } - keymap_variant.push_str(&split) - } - let keymap_clone = keymap.clone(); + let keymap_variant = pika_keymap.variant; let keymap_checkbutton = gtk::CheckButton::builder() .valign(gtk::Align::Center) .can_focus(false) @@ -114,36 +117,37 @@ pub fn keyboard_page( #[weak] keymap_checkbutton, #[strong] - keymap_base_data_refcell, + keymap_data_refcell, #[strong] - keymap_variant_data_refcell, + keymap_clone0, #[weak] keyboard_page, move |_| { if keymap_checkbutton.is_active() == true { + *keymap_data_refcell.borrow_mut() = keymap_clone0.clone(); keyboard_page.set_next_sensitive(true); - if keymap_variant.is_empty() { - *keymap_base_data_refcell.borrow_mut() = String::from(&keymap_base); - Command::new("setxkbmap") - .arg("-layout") - .arg(keymap_base.clone()) - .spawn() - .expect("keyboard failed to start"); - } else { - *keymap_base_data_refcell.borrow_mut() = String::from(&keymap_base); - *keymap_variant_data_refcell.borrow_mut() = String::from(&keymap_variant); - Command::new("setxkbmap") - .arg("-layout") - .arg(keymap_base.clone()) - .arg("-variant") - .arg(keymap_variant.clone()) - .spawn() - .expect("keyboard failed to start"); + match keymap_variant.clone() { + Some(t) => { + Command::new("setxkbmap") + .arg("-layout") + .arg(&keymap_clone0.name) + .arg("-variant") + .arg(t) + .spawn() + .expect("keyboard failed to start"); + } + None => { + Command::new("setxkbmap") + .arg("-layout") + .arg(&keymap_clone0.name) + .spawn() + .expect("keyboard failed to start"); + } } } } )); - if current_keymap == keymap_clone { + if current_keymap == keymap_clone1.name { keymap_checkbutton.set_active(true); } } diff --git a/src/language_page/mod.rs b/src/language_page/mod.rs index 86f3580..a8525ec 100644 --- a/src/language_page/mod.rs +++ b/src/language_page/mod.rs @@ -1,17 +1,12 @@ -use crate::installer_stack_page; +use crate::{build_ui::PikaLocale, installer_stack_page}; use adw::prelude::*; use glib::{clone, closure_local}; use gtk::{gio, glib, prelude::*}; use std::{cell::RefCell, env, fs, path::Path, process::Command, rc::Rc}; -struct PikaLocale { - name: String, - pretty_name: String -} - pub fn language_page( main_carousel: &adw::Carousel, - lang_data_refcell: &Rc>, + lang_data_refcell: &Rc>, language_changed_action: &gio::SimpleAction, ) { let language_page = installer_stack_page::InstallerStackPage::new(); @@ -99,6 +94,7 @@ pub fn language_page( sorted_locale_vec.sort_by_key(|k| k.pretty_name.clone()); for pika_locale in sorted_locale_vec { + let pika_locale_clone0 = pika_locale.clone(); let locale = pika_locale.name; let locale_clone0 = locale.clone(); let locale_name = pika_locale.pretty_name; @@ -119,12 +115,14 @@ pub fn language_page( locale_checkbutton, #[strong] lang_data_refcell, + #[strong] + pika_locale_clone0, #[weak] language_page, move |_| { if locale_checkbutton.is_active() == true { language_page.set_next_sensitive(true); - *lang_data_refcell.borrow_mut() = String::from(&locale); + *lang_data_refcell.borrow_mut() = pika_locale_clone0.clone(); } } )); @@ -208,7 +206,7 @@ pub fn language_page( // .arg("LANG=".to_owned() + &locale + ".UTF-8") // .spawn() // .expect("locale failed to start"); - rust_i18n::set_locale(&locale); + rust_i18n::set_locale(&locale.name); language_changed_action.activate(None); main_carousel.scroll_to(&main_carousel.nth_page(2), true) }