diff --git a/data/com.github.pikaos-linux.pikawelcome.gschema.xml b/data/com.github.pikaos-linux.pikawelcome.gschema.xml
index 31a6f38..ae07e9d 100644
--- a/data/com.github.pikaos-linux.pikawelcome.gschema.xml
+++ b/data/com.github.pikaos-linux.pikawelcome.gschema.xml
@@ -1,6 +1,6 @@
-
+
700
Default window width
@@ -13,5 +13,12 @@
false
Default window maximized behaviour
+
+ true
+ Show PikaOS Welcome on startup.
+
+ Show PikaOS Welcome on startup.
+
+
diff --git a/debian/control b/debian/control
index e45b29b..8272318 100644
--- a/debian/control
+++ b/debian/control
@@ -15,4 +15,4 @@ Rules-Requires-Root: no
Package: pika-welcome
Architecture: any
Depends: ${shlibs:Depends}
-Description: A frontend in GTK 4 and Libadwaita for initial user setup in pika.
+Description: A frontend in GTK 4 and Libadwaita for Post install PikaOS setup.
diff --git a/src/build_ui.rs b/src/build_ui.rs
index 9e65f98..e27a5f4 100644
--- a/src/build_ui.rs
+++ b/src/build_ui.rs
@@ -1,41 +1,56 @@
// GTK crates
use adw::prelude::*;
use adw::*;
+use glib::*;
+use gtk::Orientation;
/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
// application crates
/// first setup crates
use crate::config::*;
-use crate::first_setup::*;
+use crate::save_window_size::save_window_size;
+use crate::welcome_content_page::welcome_content_page;
pub fn build_ui(app: &adw::Application) {
// setup glib
gtk::glib::set_prgname(Some(t!("app_name").to_string()));
glib::set_application_name(&t!("app_name").to_string());
+ let glib_settings = gio::Settings::new(APP_ID);
+
+ let content_box = gtk::Box::builder()
+ .vexpand(true)
+ .hexpand(true)
+ .orientation(Orientation::Vertical)
+ .build();
// create the main Application window
let window = adw::ApplicationWindow::builder()
- // The text on the titlebar
.title(t!("app_name"))
- // link it to the application "app"
.application(app)
- // Add the box called "window_box" to it
- // Application icon
+ .content(&content_box)
.icon_name(APP_ICON)
- // Minimum Size/Default
- .width_request(700)
+ .default_width(glib_settings.int("window-width"))
+ .default_height(glib_settings.int("window-height"))
+ .width_request(300)
.height_request(500)
- // Hide window instead of destroy
- .hide_on_close(true)
- .deletable(false)
- // Startup
.startup_id(APP_ID)
- // build the window
.build();
- first_setup(&window);
+ if glib_settings.boolean("is-maximized") == true {
+ window.maximize()
+ }
+ window.connect_close_request(move |window| {
+ if let Some(application) = window.application() {
+ save_window_size(&window, &glib_settings);
+ application.remove_window(window);
+ }
+ glib::Propagation::Proceed
+ });
+
+ //
+ welcome_content_page(&window, &content_box);
// show the window
window.present()
-}
+}
\ No newline at end of file
diff --git a/src/first_setup/codec_carousel/mod.rs b/src/first_setup/codec_carousel/mod.rs
deleted file mode 100644
index 8d9c25f..0000000
--- a/src/first_setup/codec_carousel/mod.rs
+++ /dev/null
@@ -1,223 +0,0 @@
-use std::cell::RefCell;
-use std::rc::Rc;
-// GTK crates
-use adw::prelude::*;
-use adw::*;
-use glib::*;
-/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
-/// Use all libadwaita libraries (libadwaita -> adw because cargo)
-use gtk::*;
-
-
-
-use std::{thread, time};
-
-use std::{
- error::Error,
-};
-
-use duct::cmd;
-use std::io::prelude::*;
-use std::io::BufReader;
-
-const CODEC_INSTALL_PROG: &str = "
-#! /bin/bash
-set -e
-/usr/lib/pika/pika-welcome/scripts/pika-sudo.sh apt update -y && /usr/lib/pika/pika-welcome/scripts/pika-sudo.sh apt install pika-codecs-meta -y
-";
-
-fn codec_install(
- log_loop_sender: async_channel::Sender,
-) -> Result<(), std::boxed::Box> {
- let (pipe_reader, pipe_writer) = os_pipe::pipe()?;
- let child = cmd!("bash", "-c", CODEC_INSTALL_PROG)
- .stderr_to_stdout()
- .stdout_file(pipe_writer)
- .start()?;
- for line in BufReader::new(pipe_reader).lines() {
- log_loop_sender
- .send_blocking(line?)
- .expect("Channel needs to be opened.")
- }
- child.wait()?;
-
- Ok(())
-}
-
-pub fn codec_carousel(
- first_setup_carousel: &adw::Carousel,
- internet_connected: &Rc>,
- window: &adw::ApplicationWindow,
-) {
- let internet_connected_status = internet_connected.clone();
-
- let (internet_loop_sender, internet_loop_receiver) = async_channel::unbounded();
- let internet_loop_sender = internet_loop_sender.clone();
- // The long running operation runs now in a separate thread
- gio::spawn_blocking(move || loop {
- thread::sleep(time::Duration::from_secs(1));
- internet_loop_sender
- .send_blocking(true)
- .expect("The channel needs to be open.");
- });
-
- let (log_loop_sender, log_loop_receiver) = async_channel::unbounded();
- let log_loop_sender: async_channel::Sender = log_loop_sender.clone();
-
- let (log_status_loop_sender, log_status_loop_receiver) = async_channel::unbounded();
- let log_status_loop_sender: async_channel::Sender = log_status_loop_sender.clone();
-
- let first_setup_codec_box = gtk::Box::builder()
- // that puts items vertically
- .orientation(Orientation::Vertical)
- .valign(gtk::Align::Center)
- .hexpand(true)
- .vexpand(true)
- .build();
-
- let first_setup_codec_box_text = adw::StatusPage::builder()
- .icon_name("media-tape")
- .title(t!("first_setup_codec_box_text_title"))
- .description(t!("first_setup_codec_box_text_description"))
- .build();
- first_setup_codec_box_text.add_css_class("compact");
-
- let first_setup_codec_button = gtk::Button::builder()
- .label(t!("first_setup_codec_button_label"))
- .sensitive(false)
- .build();
-
- first_setup_codec_button.add_css_class("suggested-action");
- first_setup_codec_button.add_css_class("pill");
-
- let first_setup_codec_skip_button = gtk::Button::builder()
- .label(t!("first_setup_codec_skip_button_label"))
- .sensitive(true)
- .width_request(25)
- .build();
-
- let first_setup_codec_buttons_box = gtk::Box::builder()
- .orientation(Orientation::Horizontal)
- .halign(gtk::Align::Center)
- .valign(gtk::Align::End)
- .vexpand(true)
- .hexpand(true)
- .margin_end(15)
- .margin_start(15)
- .margin_bottom(15)
- .margin_top(15)
- .spacing(80)
- .build();
-
- first_setup_codec_skip_button.add_css_class("pill");
-
- let codec_install_log_terminal_buffer = gtk::TextBuffer::builder().build();
-
- let codec_install_log_terminal = gtk::TextView::builder()
- .vexpand(true)
- .hexpand(true)
- .editable(false)
- .buffer(&codec_install_log_terminal_buffer)
- .build();
-
- let codec_install_log_terminal_scroll = gtk::ScrolledWindow::builder()
- .width_request(400)
- .height_request(200)
- .vexpand(true)
- .hexpand(true)
- .child(&codec_install_log_terminal)
- .build();
-
- let codec_install_dialog = adw::MessageDialog::builder()
- .transient_for(window)
- .hide_on_close(true)
- .extra_child(&codec_install_log_terminal_scroll)
- .width_request(400)
- .height_request(200)
- .heading(t!("codec_install_dialog_heading"))
- .build();
- codec_install_dialog.add_response("codec_install_dialog_ok", &t!("system_update_dialog_ok_label"));
-
- first_setup_codec_buttons_box.append(&first_setup_codec_button);
- first_setup_codec_buttons_box.append(&first_setup_codec_skip_button);
-
- first_setup_codec_box.append(&first_setup_codec_box_text);
- first_setup_codec_box.append(&first_setup_codec_buttons_box);
-
- first_setup_carousel.append(&first_setup_codec_box);
-
- let internet_loop_context = MainContext::default();
- // The main loop executes the asynchronous block
- internet_loop_context.spawn_local(
- clone!(@strong internet_connected_status, @weak first_setup_codec_button => async move {
- while let Ok(_state) = internet_loop_receiver.recv().await {
- if *internet_connected_status.borrow_mut() == true {
- first_setup_codec_button.set_sensitive(true);
- first_setup_codec_button.set_label(&t!("first_setup_codec_button_label"));
- } else {
- first_setup_codec_button.set_sensitive(false);
- first_setup_codec_button.set_label(&t!("internet_network_disabled"));
- }
- }
- }),
- );
-
- let log_loop_context = MainContext::default();
- // The main loop executes the asynchronous block
- log_loop_context.spawn_local(clone!(@weak codec_install_log_terminal_buffer, @weak codec_install_dialog => async move {
- while let Ok(state) = log_loop_receiver.recv().await {
- codec_install_log_terminal_buffer.insert(&mut codec_install_log_terminal_buffer.end_iter(), &("\n".to_string() + &state))
- }
- }));
-
- let log_status_loop_context = MainContext::default();
- // The main loop executes the asynchronous block
- log_status_loop_context.spawn_local(clone!(@weak codec_install_dialog, @weak first_setup_codec_button, @weak first_setup_codec_skip_button => async move {
- while let Ok(state) = log_status_loop_receiver.recv().await {
- if state == true {
- codec_install_dialog.set_response_enabled("codec_install_dialog_ok", true);
- codec_install_dialog.set_body(&t!("codec_install_dialog_success_true"));
- first_setup_codec_button.remove_css_class("suggested-action");
- first_setup_codec_skip_button.set_label(&t!("internet_next_button_label"));
- first_setup_codec_skip_button.add_css_class("suggested-action");
- } else {
- first_setup_codec_skip_button.remove_css_class("suggested-action");
- first_setup_codec_skip_button.set_label(&t!("first_setup_codec_skip_button_label"));
- first_setup_codec_button.add_css_class("suggested-action");
- codec_install_dialog.set_response_enabled("codec_install_dialog_ok", true);
- codec_install_dialog.set_body(&t!("codec_install_dialog_success_false"));
- }
- }
- }));
-
- codec_install_log_terminal_buffer.connect_changed(clone!(@weak codec_install_log_terminal, @weak codec_install_log_terminal_buffer,@weak codec_install_log_terminal_scroll => move |_|{
- if codec_install_log_terminal_scroll.vadjustment().upper() - codec_install_log_terminal_scroll.vadjustment().value() > 100.0 {
- codec_install_log_terminal_scroll.vadjustment().set_value(codec_install_log_terminal_scroll.vadjustment().upper())
- }
- }));
-
- first_setup_codec_button.connect_clicked(clone!(@strong internet_connected_status, @weak codec_install_log_terminal,@weak codec_install_log_terminal_buffer, @weak codec_install_dialog,@weak first_setup_carousel => move |_| {
- codec_install_log_terminal_buffer.delete(&mut codec_install_log_terminal_buffer.bounds().0, &mut codec_install_log_terminal_buffer.bounds().1);
- codec_install_dialog.set_response_enabled("codec_install_dialog_ok", false);
- codec_install_dialog.set_body("");
- codec_install_dialog.present();
- // The long running operation runs now in a separate thread
- gio::spawn_blocking(clone!(@strong log_loop_sender, @strong log_status_loop_sender => move || {
- let command = codec_install(log_loop_sender);
- match command {
- Ok(_) => {
- println!("Status: Codec install Successful");
- log_status_loop_sender.send_blocking(true).expect("The channel needs to be open.");
- }
- Err(_) => {
- println!("Status: Codec install Failed");
- log_status_loop_sender.send_blocking(false).expect("The channel needs to be open.");
- }
- }
- }));
- }));
-
- first_setup_codec_skip_button.connect_clicked(clone!(@weak first_setup_carousel => move |_|{
- first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(6), true);
- }));
-}
diff --git a/src/first_setup/driver_carousel/mod.rs b/src/first_setup/driver_carousel/mod.rs
deleted file mode 100644
index c515ca5..0000000
--- a/src/first_setup/driver_carousel/mod.rs
+++ /dev/null
@@ -1,115 +0,0 @@
-use std::cell::RefCell;
-use std::rc::Rc;
-// GTK crates
-use adw::prelude::*;
-use adw::*;
-use glib::*;
-/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
-/// Use all libadwaita libraries (libadwaita -> adw because cargo)
-use gtk::*;
-
-
-
-use std::{thread, time};
-
-use std::{
- process::{Command},
-};
-
-pub fn driver_carousel(
- first_setup_carousel: &adw::Carousel,
- internet_connected: &Rc>,
-) {
- let internet_connected_status = internet_connected.clone();
-
- let (internet_loop_sender, internet_loop_receiver) = async_channel::unbounded();
- let internet_loop_sender = internet_loop_sender.clone();
- // The long running operation runs now in a separate thread
- gio::spawn_blocking(move || loop {
- thread::sleep(time::Duration::from_secs(1));
- internet_loop_sender
- .send_blocking(true)
- .expect("The channel needs to be open.");
- });
-
- let first_setup_driver_box = gtk::Box::builder()
- // that puts items vertically
- .orientation(Orientation::Vertical)
- .valign(gtk::Align::Center)
- .hexpand(true)
- .vexpand(true)
- .build();
-
- let first_setup_driver_box_text = adw::StatusPage::builder()
- .icon_name("audio-card")
- .title(t!("first_setup_driver_box_text_title"))
- .description(t!("first_setup_driver_box_text_description"))
- .build();
- first_setup_driver_box_text.add_css_class("compact");
-
- let first_setup_driver_button = gtk::Button::builder()
- .label(t!("first_setup_driver_button_label"))
- .sensitive(false)
- .build();
-
- first_setup_driver_button.add_css_class("suggested-action");
- first_setup_driver_button.add_css_class("pill");
-
- let first_setup_driver_skip_button = gtk::Button::builder()
- .label(t!("first_setup_driver_skip_button_label"))
- .sensitive(true)
- .width_request(25)
- .build();
-
- let first_setup_driver_buttons_box = gtk::Box::builder()
- .orientation(Orientation::Horizontal)
- .halign(gtk::Align::Center)
- .valign(gtk::Align::End)
- .vexpand(true)
- .hexpand(true)
- .margin_end(15)
- .margin_start(15)
- .margin_bottom(15)
- .margin_top(15)
- .spacing(80)
- .build();
-
- first_setup_driver_skip_button.add_css_class("pill");
-
- first_setup_driver_buttons_box.append(&first_setup_driver_button);
- first_setup_driver_buttons_box.append(&first_setup_driver_skip_button);
-
- first_setup_driver_box.append(&first_setup_driver_box_text);
- first_setup_driver_box.append(&first_setup_driver_buttons_box);
-
- first_setup_carousel.append(&first_setup_driver_box);
-
- let internet_loop_context = MainContext::default();
- // The main loop executes the asynchronous block
- internet_loop_context.spawn_local(
- clone!(@strong internet_connected_status, @weak first_setup_driver_button => async move {
- while let Ok(_state) = internet_loop_receiver.recv().await {
- if *internet_connected_status.borrow_mut() == true {
- first_setup_driver_button.set_sensitive(true);
- first_setup_driver_button.set_label(&t!("first_setup_driver_button_label"));
- } else {
- first_setup_driver_button.set_sensitive(false);
- first_setup_driver_button.set_label(&t!("internet_network_disabled"));
- }
- }
- }),
- );
-
- first_setup_driver_button.connect_clicked(clone!(@weak first_setup_carousel, @weak first_setup_driver_button, @weak first_setup_driver_skip_button => move |_| {
- Command::new("pika-drivers")
- .spawn()
- .expect("pika-drivers failed to start");
- first_setup_driver_button.remove_css_class("suggested-action");
- first_setup_driver_skip_button.set_label(&t!("internet_next_button_label"));
- first_setup_driver_skip_button.add_css_class("suggested-action");
- }));
-
- first_setup_driver_skip_button.connect_clicked(clone!(@weak first_setup_carousel => move |_|{
- first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(5), true);
- }));
-}
diff --git a/src/first_setup/final_carousel/mod.rs b/src/first_setup/final_carousel/mod.rs
deleted file mode 100644
index 21f0ab9..0000000
--- a/src/first_setup/final_carousel/mod.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-// GTK crates
-use adw::prelude::*;
-use adw::*;
-/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
-/// Use all libadwaita libraries (libadwaita -> adw because cargo)
-use gtk::*;
-
-
-
-use duct::cmd;
-
-const REBOOT_PROG: &str = r###"
-#! /bin/bash
-userdel -r -f pikaos
-reboot
-"###;
-
-pub fn final_carousel(first_setup_carousel: &adw::Carousel) {
- let first_setup_final_box = gtk::Box::builder()
- // that puts items vertically
- .orientation(Orientation::Vertical)
- .vexpand(true)
- .valign(Align::Center)
- .hexpand(true)
- .vexpand(true)
- .build();
-
- let first_setup_final_box_text = adw::StatusPage::builder()
- .icon_name("emblem-favorite")
- .title(t!("first_setup_final_box_text_title"))
- .description(t!("first_setup_final_box_text_description"))
- .build();
- first_setup_final_box_text.add_css_class("compact");
-
- let first_setup_start_button = gtk::Button::builder()
- .label(t!("first_setup_reboot_button_label"))
- .halign(Align::Center)
- .build();
-
- first_setup_start_button.add_css_class("suggested-action");
- first_setup_start_button.add_css_class("pill");
-
- first_setup_final_box.append(&first_setup_final_box_text);
- first_setup_final_box.append(&first_setup_start_button);
-
- first_setup_carousel.append(&first_setup_final_box);
-
- first_setup_start_button.connect_clicked( move |_| {
- let _ = cmd!("/usr/lib/pika/pika-welcome/scripts/pika-sudo.sh", "bash", "-c", REBOOT_PROG).read();
- });
-}
diff --git a/src/first_setup/gameutils_carousel/mod.rs b/src/first_setup/gameutils_carousel/mod.rs
deleted file mode 100644
index d43ef9c..0000000
--- a/src/first_setup/gameutils_carousel/mod.rs
+++ /dev/null
@@ -1,223 +0,0 @@
-use std::cell::RefCell;
-use std::rc::Rc;
-// GTK crates
-use adw::prelude::*;
-use adw::*;
-use glib::*;
-/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
-/// Use all libadwaita libraries (libadwaita -> adw because cargo)
-use gtk::*;
-
-
-
-use std::{thread, time};
-
-use std::{
- error::Error,
-};
-
-use duct::cmd;
-use std::io::prelude::*;
-use std::io::BufReader;
-
-const GAMEUTILS_INSTALL_PROG: &str = "
-#! /bin/bash
-set -e
-/usr/lib/pika/pika-welcome/scripts/pika-sudo.sh apt update -y && /usr/lib/pika/pika-welcome/scripts/pika-sudo.sh apt install pika-gameutils-meta -y
-";
-
-fn gameutils_install(
- log_loop_sender: async_channel::Sender,
-) -> Result<(), std::boxed::Box> {
- let (pipe_reader, pipe_writer) = os_pipe::pipe()?;
- let child = cmd!("bash", "-c", GAMEUTILS_INSTALL_PROG)
- .stderr_to_stdout()
- .stdout_file(pipe_writer)
- .start()?;
- for line in BufReader::new(pipe_reader).lines() {
- log_loop_sender
- .send_blocking(line?)
- .expect("Channel needs to be opened.")
- }
- child.wait()?;
-
- Ok(())
-}
-
-pub fn gameutils_carousel(
- first_setup_carousel: &adw::Carousel,
- internet_connected: &Rc>,
- window: &adw::ApplicationWindow,
-) {
- let internet_connected_status = internet_connected.clone();
-
- let (internet_loop_sender, internet_loop_receiver) = async_channel::unbounded();
- let internet_loop_sender = internet_loop_sender.clone();
- // The long running operation runs now in a separate thread
- gio::spawn_blocking(move || loop {
- thread::sleep(time::Duration::from_secs(1));
- internet_loop_sender
- .send_blocking(true)
- .expect("The channel needs to be open.");
- });
-
- let (log_loop_sender, log_loop_receiver) = async_channel::unbounded();
- let log_loop_sender: async_channel::Sender = log_loop_sender.clone();
-
- let (log_status_loop_sender, log_status_loop_receiver) = async_channel::unbounded();
- let log_status_loop_sender: async_channel::Sender = log_status_loop_sender.clone();
-
- let first_setup_gameutils_box = gtk::Box::builder()
- // that puts items vertically
- .orientation(Orientation::Vertical)
- .valign(gtk::Align::Center)
- .hexpand(true)
- .vexpand(true)
- .build();
-
- let first_setup_gameutils_box_text = adw::StatusPage::builder()
- .icon_name("input-gaming")
- .title(t!("first_setup_gameutils_box_text_title"))
- .description(t!("first_setup_gameutils_box_text_description"))
- .build();
- first_setup_gameutils_box_text.add_css_class("compact");
-
- let first_setup_gameutils_button = gtk::Button::builder()
- .label(t!("first_setup_gameutils_button_label"))
- .sensitive(false)
- .build();
-
- first_setup_gameutils_button.add_css_class("suggested-action");
- first_setup_gameutils_button.add_css_class("pill");
-
- let first_setup_gameutils_skip_button = gtk::Button::builder()
- .label(t!("first_setup_gameutils_skip_button_label"))
- .sensitive(true)
- .width_request(25)
- .build();
-
- let first_setup_gameutils_buttons_box = gtk::Box::builder()
- .orientation(Orientation::Horizontal)
- .halign(gtk::Align::Center)
- .valign(gtk::Align::End)
- .vexpand(true)
- .hexpand(true)
- .margin_end(15)
- .margin_start(15)
- .margin_bottom(15)
- .margin_top(15)
- .spacing(80)
- .build();
-
- first_setup_gameutils_skip_button.add_css_class("pill");
-
- let gameutils_install_log_terminal_buffer = gtk::TextBuffer::builder().build();
-
- let gameutils_install_log_terminal = gtk::TextView::builder()
- .vexpand(true)
- .hexpand(true)
- .editable(false)
- .buffer(&gameutils_install_log_terminal_buffer)
- .build();
-
- let gameutils_install_log_terminal_scroll = gtk::ScrolledWindow::builder()
- .width_request(400)
- .height_request(200)
- .vexpand(true)
- .hexpand(true)
- .child(&gameutils_install_log_terminal)
- .build();
-
- let gameutils_install_dialog = adw::MessageDialog::builder()
- .transient_for(window)
- .hide_on_close(true)
- .extra_child(&gameutils_install_log_terminal_scroll)
- .width_request(400)
- .height_request(200)
- .heading(t!("gameutils_install_dialog_heading"))
- .build();
- gameutils_install_dialog.add_response("gameutils_install_dialog_ok", &t!("system_update_dialog_ok_label"));
-
- first_setup_gameutils_buttons_box.append(&first_setup_gameutils_button);
- first_setup_gameutils_buttons_box.append(&first_setup_gameutils_skip_button);
-
- first_setup_gameutils_box.append(&first_setup_gameutils_box_text);
- first_setup_gameutils_box.append(&first_setup_gameutils_buttons_box);
-
- first_setup_carousel.append(&first_setup_gameutils_box);
-
- let internet_loop_context = MainContext::default();
- // The main loop executes the asynchronous block
- internet_loop_context.spawn_local(
- clone!(@strong internet_connected_status, @weak first_setup_gameutils_button => async move {
- while let Ok(_state) = internet_loop_receiver.recv().await {
- if *internet_connected_status.borrow_mut() == true {
- first_setup_gameutils_button.set_sensitive(true);
- first_setup_gameutils_button.set_label(&t!("first_setup_gameutils_button_label"));
- } else {
- first_setup_gameutils_button.set_sensitive(false);
- first_setup_gameutils_button.set_label(&t!("internet_network_disabled"));
- }
- }
- }),
- );
-
- let log_loop_context = MainContext::default();
- // The main loop executes the asynchronous block
- log_loop_context.spawn_local(clone!(@weak gameutils_install_log_terminal_buffer, @weak gameutils_install_dialog => async move {
- while let Ok(state) = log_loop_receiver.recv().await {
- gameutils_install_log_terminal_buffer.insert(&mut gameutils_install_log_terminal_buffer.end_iter(), &("\n".to_string() + &state))
- }
- }));
-
- let log_status_loop_context = MainContext::default();
- // The main loop executes the asynchronous block
- log_status_loop_context.spawn_local(clone!(@weak gameutils_install_dialog, @weak first_setup_gameutils_button, @weak first_setup_gameutils_skip_button => async move {
- while let Ok(state) = log_status_loop_receiver.recv().await {
- if state == true {
- gameutils_install_dialog.set_response_enabled("gameutils_install_dialog_ok", true);
- gameutils_install_dialog.set_body(&t!("gameutils_install_dialog_success_true"));
- first_setup_gameutils_button.remove_css_class("suggested-action");
- first_setup_gameutils_skip_button.set_label("Next");
- first_setup_gameutils_skip_button.add_css_class("suggested-action");
- } else {
- first_setup_gameutils_skip_button.remove_css_class("suggested-action");
- first_setup_gameutils_skip_button.set_label("Skip Meta Package Installation");
- first_setup_gameutils_button.add_css_class("suggested-action");
- gameutils_install_dialog.set_response_enabled("gameutils_install_dialog_ok", true);
- gameutils_install_dialog.set_body(&t!("gameutils_install_dialog_success_false"));
- }
- }
- }));
-
- gameutils_install_log_terminal_buffer.connect_changed(clone!(@weak gameutils_install_log_terminal, @weak gameutils_install_log_terminal_buffer,@weak gameutils_install_log_terminal_scroll => move |_|{
- if gameutils_install_log_terminal_scroll.vadjustment().upper() - gameutils_install_log_terminal_scroll.vadjustment().value() > 100.0 {
- gameutils_install_log_terminal_scroll.vadjustment().set_value(gameutils_install_log_terminal_scroll.vadjustment().upper())
- }
- }));
-
- first_setup_gameutils_button.connect_clicked(clone!(@strong internet_connected_status, @weak gameutils_install_log_terminal,@weak gameutils_install_log_terminal_buffer, @weak gameutils_install_dialog,@weak first_setup_carousel => move |_| {
- gameutils_install_log_terminal_buffer.delete(&mut gameutils_install_log_terminal_buffer.bounds().0, &mut gameutils_install_log_terminal_buffer.bounds().1);
- gameutils_install_dialog.set_response_enabled("gameutils_install_dialog_ok", false);
- gameutils_install_dialog.set_body("");
- gameutils_install_dialog.present();
- // The long running operation runs now in a separate thread
- gio::spawn_blocking(clone!(@strong log_loop_sender, @strong log_status_loop_sender => move || {
- let command = gameutils_install(log_loop_sender);
- match command {
- Ok(_) => {
- println!("Status: gameutils install Successful");
- log_status_loop_sender.send_blocking(true).expect("The channel needs to be open.");
- }
- Err(_) => {
- println!("Status: gameutils install Failed");
- log_status_loop_sender.send_blocking(false).expect("The channel needs to be open.");
- }
- }
- }));
- }));
-
- first_setup_gameutils_skip_button.connect_clicked(clone!(@weak first_setup_carousel => move |_|{
- first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(7), true);
- }));
-}
diff --git a/src/first_setup/initial_carousel/mod.rs b/src/first_setup/initial_carousel/mod.rs
deleted file mode 100644
index 44f7cdd..0000000
--- a/src/first_setup/initial_carousel/mod.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// GTK crates
-use adw::prelude::*;
-use adw::*;
-use glib::*;
-/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
-/// Use all libadwaita libraries (libadwaita -> adw because cargo)
-use gtk::*;
-
-
-use crate::config::{DISTRO_ICON};
-
-pub fn initial_carousel(first_setup_carousel: &adw::Carousel) {
- let first_setup_initial_box = gtk::Box::builder()
- // that puts items vertically
- .orientation(Orientation::Vertical)
- .vexpand(true)
- .valign(Align::Center)
- .hexpand(true)
- .vexpand(true)
- .build();
-
- let first_setup_initial_box_text = adw::StatusPage::builder()
- .icon_name(DISTRO_ICON)
- .title(t!("first_setup_initial_box_text_title"))
- .description(t!("first_setup_initial_box_text_description"))
- .build();
- first_setup_initial_box_text.add_css_class("compact");
-
- let first_setup_start_button = gtk::Button::builder()
- .label(t!("first_setup_start_button_label"))
- .halign(Align::Center)
- .build();
-
- first_setup_start_button.add_css_class("suggested-action");
- first_setup_start_button.add_css_class("pill");
-
- first_setup_initial_box.append(&first_setup_initial_box_text);
- first_setup_initial_box.append(&first_setup_start_button);
-
- first_setup_carousel.append(&first_setup_initial_box);
-
- first_setup_start_button.connect_clicked(clone!(@weak first_setup_carousel => move |_| {
- first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(1), true)
- }));
-}
diff --git a/src/first_setup/internet_carousel/mod.rs b/src/first_setup/internet_carousel/mod.rs
deleted file mode 100644
index 6c0e1be..0000000
--- a/src/first_setup/internet_carousel/mod.rs
+++ /dev/null
@@ -1,196 +0,0 @@
-// GTK crates
-use adw::prelude::*;
-use adw::*;
-use glib::*;
-/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
-/// Use all libadwaita libraries (libadwaita -> adw because cargo)
-use gtk::*;
-
-
-
-//use crate::check_internet_connection;
-use std::cell::RefCell;
-use std::env;
-use std::process::Command;
-use std::rc::Rc;
-
-pub fn internet_carousel(
- first_setup_carousel: &adw::Carousel,
- internet_connected: &Rc>,
- window: &adw::ApplicationWindow,
-) {
- let (internet_loop_sender, internet_loop_receiver) = async_channel::unbounded();
- let internet_loop_sender = internet_loop_sender.clone();
- // The long running operation runs now in a separate thread
- gio::spawn_blocking(move || {
- loop {
- //match check_internet_connection() {
- // Ok(_) => {
- // internet_loop_sender.send_blocking(true).expect("The channel needs to be open.");
- // }
- // Err(_) => {
- // internet_loop_sender.send_blocking(false).expect("The channel needs to be open.");
- // }
- //}
- let check_internet_connection_cli = Command::new("ping")
- .arg("ppa.pika-os.com")
- .arg("-c 1")
- .output()
- .expect("failed to execute process");
- if check_internet_connection_cli.status.success() {
- internet_loop_sender
- .send_blocking(true)
- .expect("The channel needs to be open.");
- } else {
- internet_loop_sender
- .send_blocking(false)
- .expect("The channel needs to be open.");
- }
- }
- });
-
- let first_setup_internet_box = gtk::Box::builder()
- // that puts items vertically
- .orientation(Orientation::Vertical)
- .hexpand(true)
- .vexpand(true)
- .margin_end(15)
- .margin_start(15)
- .margin_bottom(15)
- .margin_top(15)
- .build();
-
- let first_setup_internet_box_text = adw::StatusPage::builder()
- .icon_name("network-cellular-acquiring")
- .title(t!("first_setup_internet_box_text_title"))
- .description(t!("first_setup_internet_box_text_description"))
- .hexpand(true)
- .vexpand(true)
- .valign(Align::Start)
- .build();
- first_setup_internet_box_text.add_css_class("compact");
-
- let internet_skip_button = gtk::Button::builder()
- .label(t!("internet_skip_button_label"))
- .halign(Align::Center)
- .sensitive(false)
- .build();
-
- internet_skip_button.add_css_class("destructive-action");
- internet_skip_button.add_css_class("pill");
-
- let internet_next_button = gtk::Button::builder()
- .label(t!("internet_next_button_label"))
- .halign(Align::Center)
- .sensitive(false)
- .build();
-
- internet_next_button.add_css_class("suggested-action");
- internet_next_button.add_css_class("pill");
-
- let internet_buttons_box = gtk::Box::builder()
- .orientation(Orientation::Horizontal)
- .halign(Align::Center)
- .valign(Align::End)
- .vexpand(true)
- .hexpand(true)
- .margin_end(15)
- .margin_start(15)
- .margin_bottom(15)
- .margin_top(15)
- .spacing(80)
- .build();
-
- let first_setup_internet_button_content_box = gtk::Box::builder()
- .orientation(Orientation::Vertical)
- .build();
-
- let first_setup_internet_button_content_text = gtk::Label::builder()
- .label(t!("first_setup_internet_button_content_text_label"))
- .build();
-
- let first_setup_internet_button_content = adw::ButtonContent::builder()
- .label(t!("first_setup_internet_button_content_label"))
- .icon_name("network-wired")
- .build();
-
- let first_setup_internet_button = gtk::Button::builder()
- .child(&first_setup_internet_button_content_box)
- .halign(Align::Center)
- .valign(Align::Center)
- .build();
-
- internet_buttons_box.append(&internet_skip_button);
- internet_buttons_box.append(&internet_next_button);
-
- first_setup_internet_button_content_box.append(&first_setup_internet_button_content);
- first_setup_internet_button_content_box.append(&first_setup_internet_button_content_text);
-
- first_setup_carousel.append(&first_setup_internet_box);
-
- first_setup_internet_box.append(&first_setup_internet_box_text);
- first_setup_internet_box.append(&first_setup_internet_button);
- first_setup_internet_box.append(&internet_buttons_box);
-
- let first_setup_internet_skip_dialog = adw::MessageDialog::builder()
- .heading(t!("first_setup_internet_skip_dialog_heading"))
- .body(t!("first_setup_internet_skip_dialog_body"))
- .transient_for(window)
- .hide_on_close(true)
- .build();
-
- first_setup_internet_skip_dialog.add_response("skip_cancel", &t!("first_setup_internet_skip_dialog_skip_cancel_label"));
- first_setup_internet_skip_dialog.add_response("skip_confirm", &t!("first_setup_internet_skip_dialog_skip_confirm_label"));
- first_setup_internet_skip_dialog
- .set_response_appearance("skip_confirm", adw::ResponseAppearance::Destructive);
-
- let internet_connected_status = internet_connected.clone();
-
- let internet_loop_context = MainContext::default();
- // The main loop executes the asynchronous block
- internet_loop_context.spawn_local(clone!(@weak internet_skip_button, @weak internet_next_button, @weak first_setup_internet_box_text => async move {
- while let Ok(state) = internet_loop_receiver.recv().await {
- if state == true {
- internet_skip_button.set_sensitive(false);
- internet_next_button.set_sensitive(true);
- first_setup_internet_box_text.set_description(Some(&t!("first_setup_internet_box_text_description_true")));
- first_setup_internet_box_text.set_icon_name(Some("network-cellular-signal-excellent"));
- *internet_connected_status.borrow_mut()=true;
- } else {
- internet_next_button.set_sensitive(false);
- internet_skip_button.set_sensitive(true);
- first_setup_internet_box_text.set_description(Some(&t!("first_setup_internet_box_text_description_false")));
- first_setup_internet_box_text.set_icon_name(Some("network-cellular-offline"));
- *internet_connected_status.borrow_mut()=false;
- }
- }
- }));
-
- first_setup_internet_button.connect_clicked(move |_| {
- let env_xdg_session_desktop = env::var("XDG_SESSION_DESKTOP").unwrap();
- if env_xdg_session_desktop.contains("gnome") || env_xdg_session_desktop.contains("ubuntu") {
- Command::new("gnome-control-center")
- .arg("network")
- .spawn()
- .expect("gnome-control-center failed to start");
- } else {
- Command::new("nm-connection-editor")
- .spawn()
- .expect("nm-connection-editor failed to start");
- }
- });
-
- internet_next_button.connect_clicked(clone!(@weak first_setup_carousel => move |_| {
- first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(2), true);
- }));
-
- internet_skip_button.connect_clicked(
- clone!(@weak first_setup_carousel, @weak first_setup_internet_skip_dialog => move |_| {
- first_setup_internet_skip_dialog.choose(None::<&gio::Cancellable>, move |choice| {
- if choice == "skip_confirm" {
- first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(2), true);
- }
- });
- }),
- );
-}
diff --git a/src/first_setup/mod.rs b/src/first_setup/mod.rs
deleted file mode 100644
index 1925732..0000000
--- a/src/first_setup/mod.rs
+++ /dev/null
@@ -1,83 +0,0 @@
-// GTK crates
-use adw::prelude::*;
-use adw::*;
-use glib::*;
-/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
-/// Use all libadwaita libraries (libadwaita -> adw because cargo)
-
-
-
-//
-use std::cell::RefCell;
-use std::rc::Rc;
-
-// carousel crates
-mod initial_carousel;
-mod internet_carousel;
-mod user_carousel;
-mod update_carousel;
-mod driver_carousel;
-mod codec_carousel;
-mod gameutils_carousel;
-mod final_carousel;
-
-use initial_carousel::*;
-use internet_carousel::*;
-use user_carousel::*;
-use update_carousel::*;
-use driver_carousel::*;
-use codec_carousel::*;
-use gameutils_carousel::*;
-use final_carousel::*;
-
-pub fn first_setup(window: &adw::ApplicationWindow) {
- let first_setup_carousel = adw::Carousel::builder()
- .allow_long_swipes(false)
- .allow_mouse_drag(false)
- .allow_scroll_wheel(false)
- .interactive(false)
- .vexpand(true)
- .hexpand(true)
- .build();
-
- let first_setup_carousel_indicator = adw::CarouselIndicatorDots::builder()
- .carousel(&first_setup_carousel)
- .build();
-
- let first_setup_window_headerbar_back_button = gtk::Button::builder().label(t!("first_setup_window_headerbar_back_button_label")).build();
-
- let first_setup_window_headerbar = adw::HeaderBar::builder()
- .show_start_title_buttons(true)
- .title_widget(&first_setup_carousel_indicator)
- .build();
-
- let first_setup_window_toolbarview = adw::ToolbarView::builder()
- .top_bar_style(ToolbarStyle::Flat)
- .content(&first_setup_carousel)
- .build();
-
- let internet_connected = Rc::new(RefCell::new(false));
-
- first_setup_window_headerbar.pack_start(&first_setup_window_headerbar_back_button);
- first_setup_window_toolbarview.add_top_bar(&first_setup_window_headerbar);
-
- first_setup_window_headerbar_back_button.connect_clicked(clone!(@weak first_setup_carousel => move |_| {
- let first_setup_prev_page = first_setup_carousel.position() - 1.0;
- first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(first_setup_prev_page as u32), true)
- }));
-
- // CAROUSELS
-
- // Initial Carousel
- initial_carousel(&first_setup_carousel);
- internet_carousel(&first_setup_carousel, &internet_connected, &window);
- user_carousel(&first_setup_carousel);
- update_carousel(&first_setup_carousel, &internet_connected, &window);
- driver_carousel(&first_setup_carousel, &internet_connected);
- codec_carousel(&first_setup_carousel, &internet_connected, &window);
- gameutils_carousel(&first_setup_carousel, &internet_connected, &window);
- final_carousel(&first_setup_carousel);
-
- // Add file to window
- window.set_content(Some(&first_setup_window_toolbarview))
-}
diff --git a/src/first_setup/user_carousel/mod.rs b/src/first_setup/user_carousel/mod.rs
deleted file mode 100644
index 12be2db..0000000
--- a/src/first_setup/user_carousel/mod.rs
+++ /dev/null
@@ -1,324 +0,0 @@
-// GTK crates
-use adw::prelude::*;
-use adw::*;
-use glib::*;
-/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
-/// Use all libadwaita libraries (libadwaita -> adw because cargo)
-use gtk::*;
-
-//
-use regex::Regex;
-use std::cell::RefCell;
-use std::rc::Rc;
-use std::{thread, time};
-use duct::cmd;
-
-const USER_CREATE_PROG: &str = r###"
-#! /bin/bash
-USERNAME="$0"
-PASSWORD="$1"
-FULLNAME="$2"
-HOSTNAME="$3"
-adduser --quiet --disabled-password --shell /bin/bash --gecos "${FULLNAME}" "${USERNAME}"
-echo "${USERNAME}":"${PASSWORD}" | chpasswd
-usermod -a -G sudo "${USERNAME}"
-mkdir -p /home/"${USERNAME}"
-cp -rvf /etc/skel/.* /home/"${USERNAME}"/ || true
-chown -R "${USERNAME}":"${USERNAME}" /home/"${USERNAME}"
-usermod -a -G adm,cdrom,sudo,render,dip,video,plugdev,input,render,lpadmin "${USERNAME}"
-rm -rf /etc/sddm.conf.d/zautologin.conf || true
-hostnamectl set-hostname "${HOSTNAME}"
-echo "127.0.0.1 ${HOSTNAME}" >> /etc/hosts
-"###;
-
-fn only_alphanumeric(input: &str) -> bool {
- return input.chars().all(|c| c.is_alphanumeric());
-}
-
-fn uppercase_first_letter(s: &str) -> String {
- let mut c = s.chars();
- match c.next() {
- None => String::new(),
- Some(f) => f.to_uppercase().chain(c).collect(),
- }
-}
-
-pub fn user_carousel(first_setup_carousel: &adw::Carousel) {
- let user_info_username_valid = Rc::new(RefCell::new(false));
- let user_info_full_name_valid = Rc::new(RefCell::new(false));
- let user_info_hostname_valid = Rc::new(RefCell::new(false));
- let user_info_passwords_valid = Rc::new(RefCell::new(false));
-
- let (user_loop_sender, user_loop_receiver) = async_channel::unbounded();
- let user_loop_sender = user_loop_sender.clone();
- // The long running operation runs now in a separate thread
- gio::spawn_blocking(move || loop {
- thread::sleep(time::Duration::from_secs(1));
- user_loop_sender
- .send_blocking(true)
- .expect("The channel needs to be open.");
- });
-
- let first_setup_user_box = gtk::Box::builder()
- // that puts items vertically
- .orientation(Orientation::Vertical)
- .hexpand(true)
- .vexpand(true)
- .margin_end(15)
- .margin_start(15)
- .margin_bottom(15)
- .margin_top(15)
- .build();
-
- let first_setup_user_box_text = adw::StatusPage::builder()
- .title(t!("first_setup_user_box_text_title"))
- .description(t!("first_setup_user_box_text_description"))
- .hexpand(true)
- .valign(Align::Start)
- .build();
- first_setup_user_box_text.add_css_class("compact");
-
- let user_info_box = gtk::Box::builder()
- .orientation(Orientation::Vertical)
- .valign(Align::Center)
- .vexpand(true)
- .hexpand(true)
- .build();
-
- let user_info_box_clamp = adw::Clamp::builder()
- .child(&user_info_box)
- .maximum_size(500)
- .build();
-
- let user_info_username = adw::EntryRow::builder()
- .hexpand(true)
- .title(t!("user_info_username_title"))
- .input_purpose(InputPurpose::Alpha)
- .input_hints(InputHints::LOWERCASE)
- .build();
-
- let user_info_full_name = adw::EntryRow::builder()
- .hexpand(true)
- .title(t!("user_info_full_name_title"))
- .input_purpose(InputPurpose::Name)
- .build();
-
- let user_info_password = adw::PasswordEntryRow::builder()
- .hexpand(true)
- .title(t!("user_info_password_title"))
- .build();
-
- let user_info_hostname = adw::EntryRow::builder()
- .hexpand(true)
- .title(t!("user_info_hostname_title"))
- .build();
-
- let user_info_password_verify = adw::PasswordEntryRow::builder()
- .hexpand(true)
- .title(t!("user_info_password_verify_title"))
- .build();
-
- let user_info_password_verify_revealer = gtk::Revealer::builder()
- .child(&user_info_password_verify)
- .reveal_child(false)
- .transition_type(RevealerTransitionType::SwingDown)
- .build();
-
- let user_info_avatar = adw::Avatar::builder()
- .show_initials(true)
- .size(128)
- .margin_top(15)
- .margin_bottom(15)
- .margin_start(15)
- .margin_end(15)
- .build();
-
- let _user_info_avatar_full_name_binding = user_info_full_name
- .bind_property("text", &user_info_avatar, "text")
- .sync_create()
- .build();
-
- let user_info_listbox = gtk::ListBox::builder()
- .margin_top(15)
- .margin_bottom(15)
- .margin_start(15)
- .margin_end(15)
- .build();
- user_info_listbox.add_css_class("boxed-list");
-
- let error_label = gtk::Label::builder()
- .margin_top(15)
- .margin_bottom(15)
- .margin_start(15)
- .margin_end(15)
- .visible(false)
- .build();
-
- error_label.add_css_class("red-text");
-
- let user_next_button = gtk::Button::builder()
- .label(t!("internet_next_button_label"))
- .sensitive(false)
- .halign(Align::Center)
- .valign(Align::End)
- .vexpand(true)
- .hexpand(true)
- .build();
-
- user_next_button.add_css_class("suggested-action");
- user_next_button.add_css_class("pill");
-
- first_setup_carousel.append(&first_setup_user_box);
-
- user_info_listbox.append(&user_info_username);
- user_info_listbox.append(&user_info_full_name);
- user_info_listbox.append(&user_info_hostname);
- user_info_listbox.append(&user_info_password);
- user_info_listbox.append(&user_info_password_verify_revealer);
-
- user_info_box.append(&user_info_avatar);
- user_info_box.append(&user_info_listbox);
-
- first_setup_user_box.append(&first_setup_user_box_text);
- first_setup_user_box.append(&user_info_box_clamp);
- first_setup_user_box.append(&error_label);
- first_setup_user_box.append(&user_next_button);
-
- // The main loop executes the asynchronous block
- let user_loop_context = MainContext::default();
- user_loop_context.spawn_local(clone!(@strong user_info_username_valid, @strong user_info_full_name_valid,@strong user_info_hostname_valid, @strong user_info_passwords_valid, @weak user_next_button => async move {
- while let Ok(_state) = user_loop_receiver.recv().await {
- if *user_info_username_valid.borrow_mut() == true && *user_info_full_name_valid.borrow_mut() == true && *user_info_hostname_valid.borrow_mut() && *user_info_passwords_valid.borrow_mut() == true {
- user_next_button.set_sensitive(true);
- } else {
- user_next_button.set_sensitive(false);
- }
- }
- }));
-
- user_info_username.connect_changed(clone!(@strong user_info_username_valid, @weak user_info_username, @weak user_info_full_name, @weak error_label => move |_| {
- let user_info_username_string = user_info_username.text().to_string();
-
- user_info_full_name.set_text(&uppercase_first_letter(&user_info_username_string));
-
- if user_info_username_string.len() > 32 {
- user_info_username.set_text(&user_info_username_string[..32]);
- user_info_username.set_position(-1);
- }
-
- if Regex::new(r"[A-Z]").unwrap().is_match(&user_info_username_string) {
- user_info_username.set_text(&user_info_username_string.to_lowercase());
- user_info_username.set_position(-1);
- }
-
- let mut _username_is_root = false;
- let mut _username_is_pikaos = false;
- let mut _username_is_special = false;
-
- if user_info_username_string != "root" {
- _username_is_root=false;
- } else {
- error_label.set_label(&t!("error_label_is_root_label"));
- _username_is_root=true;
- }
-
- if user_info_username_string != "pikaos" {
- _username_is_pikaos=false;
- } else {
- error_label.set_label(&t!("error_label_is_pikaos_label"));
- _username_is_pikaos=true;
- }
-
- if only_alphanumeric(&user_info_username_string) {
- _username_is_special=false;
- } else {
- error_label.set_label(&t!("error_label_username_is_special_label"));
- _username_is_special=true;
- }
-
- if _username_is_root == false && _username_is_pikaos == false && _username_is_special == false {
- error_label.set_visible(false);
- if !user_info_username.text().is_empty() {
- *user_info_username_valid.borrow_mut()=true;
- }
- } else {
- *user_info_username_valid.borrow_mut()=false;
- error_label.set_visible(true);
- }
- }));
-
- user_info_full_name.connect_changed(clone!(@strong user_info_full_name_valid, @weak user_info_full_name, @weak error_label => move |_| {
- let user_info_full_name_string = user_info_full_name.text().to_string();
-
- if user_info_full_name_string.len() > 32 {
- user_info_full_name.set_text(&user_info_full_name_string[..32]);
- user_info_full_name.set_position(-1);
- }
-
- if user_info_full_name.text().is_empty() {
- *user_info_full_name_valid.borrow_mut()=false;
- } else {
- *user_info_full_name_valid.borrow_mut()=true;
- }
- }));
-
- user_info_hostname.connect_changed(clone!(@strong user_info_hostname_valid, @weak user_info_hostname, @weak user_info_full_name, @weak error_label => move |_| {
- let user_info_hostname_string = user_info_hostname.text().to_string();
-
- if user_info_hostname_string.len() > 32 {
- user_info_hostname.set_text(&user_info_hostname_string[..32]);
- user_info_hostname.set_position(-1);
- }
-
- let mut _hostname_is_special = false;
-
- if Regex::new(r"^[A-Za-z0-9\.]*$").unwrap().is_match(&user_info_hostname_string) {
- _hostname_is_special=false;
- } else {
- error_label.set_label(&t!("error_label_hostname_is_special_label"));
- _hostname_is_special=true;
- }
-
- if _hostname_is_special == false {
- error_label.set_visible(false);
- if !user_info_hostname.text().is_empty() {
- *user_info_hostname_valid.borrow_mut()=true;
- }
- } else {
- *user_info_hostname_valid.borrow_mut()=false;
- error_label.set_visible(true);
- }
- }));
-
- user_info_password.connect_changed(clone!(@strong user_info_passwords_valid,@weak user_info_password_verify_revealer, @weak user_info_password, @weak user_info_password_verify, @weak error_label => move |_| {
- if user_info_password.text().is_empty() {
- user_info_password_verify_revealer.set_reveal_child(false)
- } else {
- user_info_password_verify_revealer.set_reveal_child(true)
- }
-
- if user_info_password.text() == user_info_password_verify.text() {
- error_label.set_visible(false);
- *user_info_passwords_valid.borrow_mut()=true;
- } else {
- *user_info_passwords_valid.borrow_mut()=false;
- }
- }));
-
- user_info_password_verify.connect_changed(clone!(@strong user_info_passwords_valid, @weak user_info_password, @weak user_info_password_verify, @weak error_label => move |_| {
- if user_info_password.text() == user_info_password_verify.text() {
- error_label.set_visible(false);
- *user_info_passwords_valid.borrow_mut()=true;
- } else {
- error_label.set_visible(true);
- error_label.set_label(&t!("error_label_password_mismatch_label"));
- *user_info_passwords_valid.borrow_mut()=false;
- }
- }));
-
- user_next_button.connect_clicked(clone!(@weak first_setup_carousel, @weak user_info_username, @weak user_info_hostname, @weak user_info_password, @weak user_info_full_name, @weak user_info_hostname_valid => move |_| {
- let result = cmd!("/usr/lib/pika/pika-welcome/scripts/pika-sudo.sh", "bash", "-c", USER_CREATE_PROG, &user_info_username.text(), &user_info_password.text(), &user_info_full_name.text(), &user_info_hostname.text()).read();
- assert!(result.is_ok());
- first_setup_carousel.scroll_to(&first_setup_carousel.nth_page(3), true);
- }));
-}
diff --git a/src/main.rs b/src/main.rs
index b4ec14f..3365aa0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,6 +9,8 @@ use gdk::Display;
/// Use all libadwaita libraries (libadwaita -> adw because cargo)
use gtk::*;
use single_instance::SingleInstance;
+use glib::*;
+use glib::prelude::*;
use std::boxed::Box;
use users::*;
@@ -17,8 +19,9 @@ use config::{APP_ID};
// application crates
mod build_ui;
use crate::build_ui::build_ui;
+mod save_window_size;
/// first setup crates
-mod first_setup;
+mod welcome_content_page;
// Init translations for current crate.
#[macro_use]
diff --git a/src/save_window_size/mod.rs b/src/save_window_size/mod.rs
new file mode 100644
index 0000000..d125a86
--- /dev/null
+++ b/src/save_window_size/mod.rs
@@ -0,0 +1,14 @@
+use adw::ffi::AdwApplicationWindow;
+use adw::{gio, glib};
+use adw::prelude::SettingsExt;
+use adw::subclass::window;
+use gtk::prelude::GtkWindowExt;
+use glib::*;
+use glib::prelude::*;
+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/welcome_content_page/mod.rs b/src/welcome_content_page/mod.rs
new file mode 100644
index 0000000..c8bf4a3
--- /dev/null
+++ b/src/welcome_content_page/mod.rs
@@ -0,0 +1,131 @@
+// GTK crates
+use adw::prelude::*;
+use adw::*;
+use glib::*;
+/// Use all gtk4 libraries (gtk4 -> gtk because cargo)
+/// Use all libadwaita libraries (libadwaita -> adw because cargo)
+
+
+
+//
+use std::cell::RefCell;
+use std::process::Command;
+use std::rc::Rc;
+use adw::glib::gobject_ffi::GValue;
+use gtk::Orientation::Horizontal;
+
+// carousel crates
+mod update_carousel;
+
+use update_carousel::*;
+use crate::config::{APP_GITHUB, APP_ICON, VERSION};
+
+pub fn welcome_content_page(window: &adw::ApplicationWindow, content_box: >k::Box) {
+ let internet_connected = Rc::new(RefCell::new(false));
+
+ let (internet_loop_sender, internet_loop_receiver) = async_channel::unbounded();
+ let internet_loop_sender = internet_loop_sender.clone();
+ // The long running operation runs now in a separate thread
+ gio::spawn_blocking(move || {
+ loop {
+ //match check_internet_connection() {
+ // Ok(_) => {
+ // internet_loop_sender.send_blocking(true).expect("The channel needs to be open.");
+ // }
+ // Err(_) => {
+ // internet_loop_sender.send_blocking(false).expect("The channel needs to be open.");
+ // }
+ //}
+ let check_internet_connection_cli = Command::new("ping")
+ .arg("ppa.pika-os.com")
+ .arg("-c 1")
+ .output()
+ .expect("failed to execute process");
+ if check_internet_connection_cli.status.success() {
+ internet_loop_sender
+ .send_blocking(true)
+ .expect("The channel needs to be open.");
+ } else {
+ internet_loop_sender
+ .send_blocking(false)
+ .expect("The channel needs to be open.");
+ }
+ }
+ });
+
+ let window_title_bar = gtk::HeaderBar::builder().show_title_buttons(true).build();
+
+ let credits_button = gtk::Button::builder()
+ .icon_name("dialog-information-symbolic")
+ .build();
+
+ let credits_window = adw::AboutWindow::builder()
+ .application_icon(APP_ICON)
+ .application_name(t!("app_name"))
+ .transient_for(window)
+ .version(VERSION)
+ .hide_on_close(true)
+ .developer_name(t!("app_dev"))
+ .issue_url(APP_GITHUB.to_owned() + "/issues")
+ .build();
+
+ content_box.append(&window_title_bar);
+
+ let welcome_content_page_stack = gtk::Stack::builder()
+ .vexpand(true)
+ .hexpand(true)
+ .build();
+
+ let welcome_content_page_stack_sidebar = gtk::StackSidebar::builder()
+ .vexpand(true)
+ .hexpand(true)
+ .stack(&welcome_content_page_stack)
+ .build();
+
+ let welcome_content_page_split_view = adw::OverlaySplitView::builder()
+ .vexpand(true)
+ .hexpand(true)
+ .content(&welcome_content_page_stack)
+ .sidebar(&welcome_content_page_stack_sidebar)
+ .max_sidebar_width(300.0)
+ .min_sidebar_width(300.0)
+ .enable_hide_gesture(true)
+ .enable_show_gesture(true)
+ .build();
+
+ let sidebar_toggle_button = gtk::ToggleButton::builder()
+ .icon_name("view-right-pane-symbolic")
+ .build();
+
+ let _sidebar_toggle_button_binding = welcome_content_page_split_view
+ .bind_property("show_sidebar", &sidebar_toggle_button, "active")
+ .sync_create()
+ .bidirectional()
+ .build();
+
+ let welcome_content_page_split_view_breakpoint = adw::Breakpoint::new(BreakpointCondition::new_length(BreakpointConditionLengthType::MaxWidth, 400.0, LengthUnit::Px));
+ welcome_content_page_split_view_breakpoint.add_setter(&welcome_content_page_split_view, "show_sidebar", &false.to_value());
+
+ window.add_breakpoint(welcome_content_page_split_view_breakpoint);
+
+ window_title_bar.pack_end(&credits_button);
+ window_title_bar.pack_start(&sidebar_toggle_button);
+ content_box.append(&welcome_content_page_split_view);
+
+ credits_button
+ .connect_clicked(clone!(@weak credits_button => move |_| credits_window.present()));
+
+ let internet_connected_status = internet_connected.clone();
+
+ let internet_loop_context = MainContext::default();
+ // The main loop executes the asynchronous block
+ internet_loop_context.spawn_local(clone!(@weak window => async move {
+ while let Ok(state) = internet_loop_receiver.recv().await {
+ if state == true {
+ *internet_connected_status.borrow_mut()=true;
+ } else {
+ *internet_connected_status.borrow_mut()=false;
+ }
+ }
+ }));
+}
diff --git a/src/first_setup/update_carousel/mod.rs b/src/welcome_content_page/update_carousel/mod.rs
similarity index 100%
rename from src/first_setup/update_carousel/mod.rs
rename to src/welcome_content_page/update_carousel/mod.rs