Finished locales stage, and work on theming.
This commit is contained in:
+28
-23
@@ -1,25 +1,22 @@
|
||||
// <Kira Installer - universal Linux installer.>
|
||||
// Copyright (C) <2026> <Kira Foundation>
|
||||
// <Kira Installer - universal Linux installer.>
|
||||
// Copyright (C) <2026> <Kira Foundation>
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/*
|
||||
This is License stage. Used to inform user about program legal status.
|
||||
*/
|
||||
|
||||
|
||||
This is License stage. Used to inform user about program legal status.
|
||||
*/
|
||||
|
||||
use iced::{Alignment, widget};
|
||||
|
||||
@@ -74,12 +71,20 @@ impl LicenseStage {
|
||||
widget::button(widget::text(t!("license.button.decline"))).on_press(Message::Decline);
|
||||
|
||||
widget::column![
|
||||
widget::container(widget::column![
|
||||
widget::text(t!("license.accept_text")),
|
||||
widget::container(widget::text(t!("license.license")))
|
||||
.padding(10)
|
||||
.style(widget::container::bordered_box)
|
||||
].align_x(Alignment::Center).padding(20).spacing(10))
|
||||
widget::container(
|
||||
widget::column![
|
||||
widget::text(t!("license.accept_text")).font(iced::Font {
|
||||
weight: iced::font::Weight::Bold,
|
||||
..iced::Font::DEFAULT
|
||||
}),
|
||||
widget::container(widget::text(t!("license.license")))
|
||||
.padding(10)
|
||||
.style(widget::container::bordered_box)
|
||||
]
|
||||
.align_x(Alignment::Center)
|
||||
.padding(20)
|
||||
.spacing(15)
|
||||
)
|
||||
.height(iced::Length::Fill)
|
||||
.width(iced::Length::Fill)
|
||||
.align_x(Alignment::Center)
|
||||
|
||||
+52
-41
@@ -24,14 +24,14 @@ use crate::{
|
||||
};
|
||||
use iced::{Alignment, widget};
|
||||
use rust_i18n::t;
|
||||
use std::{collections::HashMap, default};
|
||||
use std::collections::HashMap;
|
||||
|
||||
const LOCALES_GEN_FILE_NAME: &str = "/etc/locale.gen";
|
||||
const LOCALES_GEN_START_LINE: usize = 17;
|
||||
|
||||
fn default_locale() -> (String, String) {
|
||||
("C.UTF-8".to_string(), "UTF-8".to_string())
|
||||
}
|
||||
// fn default_locale() -> (String, String) {
|
||||
// ("C.UTF-8".to_string(), "UTF-8".to_string())
|
||||
// }
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct LocaleData {
|
||||
@@ -41,20 +41,21 @@ pub struct LocaleData {
|
||||
|
||||
impl std::fmt::Display for LocaleData {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{} ({})", self.description, self.code)
|
||||
write!(f, "{} ({})", self.code, self.description)
|
||||
}
|
||||
}
|
||||
|
||||
impl LocaleData {
|
||||
pub fn default() -> Self {
|
||||
let def = default_locale();
|
||||
Self {
|
||||
code: def.0,
|
||||
description: def.1,
|
||||
code: "C.UTF-8".into(),
|
||||
description: "C locale".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// gets locales list from system "/etc/locale.gen" file
|
||||
/// Filters out non UTF-8 locales
|
||||
fn get_locales_codes_list_blocking() -> std::io::Result<Vec<(String, String)>> {
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read};
|
||||
@@ -86,6 +87,7 @@ fn get_locales_codes_list_blocking() -> std::io::Result<Vec<(String, String)>> {
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
/// Gets locales description from "/usr/share/i18n/locales/" directory.
|
||||
fn get_locales_description_blocking() -> Result<HashMap<String, String>, String> {
|
||||
use std::process::Command;
|
||||
|
||||
@@ -130,7 +132,7 @@ fn get_locales_description_blocking() -> Result<HashMap<String, String>, String>
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LocaleStage {
|
||||
lang_locale: Option<LocaleData>,
|
||||
all_locale: Option<LocaleData>,
|
||||
formats_locale: Option<LocaleData>,
|
||||
locales: Vec<LocaleData>,
|
||||
lang_locale_text: String,
|
||||
all_locale_text: String,
|
||||
@@ -139,7 +141,7 @@ pub struct LocaleStage {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Message {
|
||||
SelectLangLocale(LocaleData),
|
||||
SelectAllLocale(LocaleData),
|
||||
SelectFormatsLocale(LocaleData),
|
||||
Next,
|
||||
Back,
|
||||
}
|
||||
@@ -151,13 +153,12 @@ impl LocaleStage {
|
||||
.get_stage("welcome")
|
||||
.and_then(|v| v.config.and_then(|v| v.get("loc_code").cloned()));
|
||||
|
||||
let loc_codes = get_locales_codes_list_blocking().unwrap();
|
||||
|
||||
let raw_loc_codes = get_locales_codes_list_blocking().unwrap();
|
||||
let raw_loc_descr = get_locales_description_blocking().unwrap();
|
||||
|
||||
// println!("{:?}", raw_loc_descr);
|
||||
//println!("{:?}", raw_loc_descr);
|
||||
|
||||
let locales: Vec<LocaleData> = loc_codes
|
||||
let locales: Vec<LocaleData> = raw_loc_codes
|
||||
.iter()
|
||||
.filter_map(|(code, _)| {
|
||||
code.split_once('.')
|
||||
@@ -186,8 +187,8 @@ impl LocaleStage {
|
||||
LocaleData::default()
|
||||
};
|
||||
|
||||
println!("lang_match {:?}", lang_match);
|
||||
println!("loc_codes {:?}", loc_codes);
|
||||
//println!("lang_match {:?}", lang_match);
|
||||
//println!("loc_codes {:?}", raw_loc_codes);
|
||||
|
||||
// let locale = locales.iter().find(|l| l.code == lang_match.0).cloned();
|
||||
|
||||
@@ -203,7 +204,7 @@ impl LocaleStage {
|
||||
);
|
||||
Self {
|
||||
lang_locale: Some(lang_match.clone()),
|
||||
all_locale: Some(lang_match),
|
||||
formats_locale: Some(lang_match),
|
||||
locales: locales,
|
||||
lang_locale_text: lang_locale_text,
|
||||
all_locale_text: all_locale_text,
|
||||
@@ -212,7 +213,7 @@ impl LocaleStage {
|
||||
|
||||
fn gen_result(&self) -> StageResult {
|
||||
if let Some(lang_locale) = &self.lang_locale
|
||||
&& let Some(all_locale) = &self.all_locale
|
||||
&& let Some(formats_locale) = &self.formats_locale
|
||||
{
|
||||
StageResult {
|
||||
name: "locale".to_string(),
|
||||
@@ -222,25 +223,23 @@ impl LocaleStage {
|
||||
ConfigValue::String(lang_locale.code.clone()),
|
||||
),
|
||||
(
|
||||
"all_locale".to_string(),
|
||||
ConfigValue::String(all_locale.code.clone()),
|
||||
"formats_locale".to_string(),
|
||||
ConfigValue::String(formats_locale.code.clone()),
|
||||
),
|
||||
])),
|
||||
resuts: None,
|
||||
error: None,
|
||||
}
|
||||
} else {
|
||||
let loc = LocaleData::default();
|
||||
StageResult {
|
||||
name: "locale".to_string(),
|
||||
config: Some(HashMap::from([
|
||||
(
|
||||
"lang_locale".to_string(),
|
||||
ConfigValue::String(default_locale().0),
|
||||
),
|
||||
(
|
||||
"all_locale".to_string(),
|
||||
ConfigValue::String(default_locale().0),
|
||||
ConfigValue::String(loc.code.clone()),
|
||||
),
|
||||
("formats_locale".to_string(), ConfigValue::String(loc.code)),
|
||||
])),
|
||||
resuts: None,
|
||||
error: None,
|
||||
@@ -256,10 +255,10 @@ impl LocaleStage {
|
||||
self.lang_locale = Some(loc);
|
||||
StageAction::None
|
||||
}
|
||||
Message::SelectAllLocale(loc) => {
|
||||
Message::SelectFormatsLocale(loc) => {
|
||||
self.all_locale_text =
|
||||
format!("{}: {}", t!("locale.select_formats_locale"), loc.code);
|
||||
self.all_locale = Some(loc);
|
||||
self.formats_locale = Some(loc);
|
||||
StageAction::None
|
||||
}
|
||||
Message::Back => StageAction::Back,
|
||||
@@ -280,20 +279,32 @@ impl LocaleStage {
|
||||
widget::image(welcome_logo_handle)
|
||||
.width(iced::Pixels(128.0))
|
||||
.height(iced::Pixels(128.0)),
|
||||
widget::column![
|
||||
widget::text(self.lang_locale_text.as_str()),
|
||||
widget::pick_list(
|
||||
self.locales.clone(),
|
||||
self.lang_locale.clone(),
|
||||
Message::SelectLangLocale,
|
||||
),
|
||||
widget::text(self.all_locale_text.as_str()),
|
||||
widget::pick_list(
|
||||
self.locales.clone(),
|
||||
self.all_locale.clone(),
|
||||
Message::SelectAllLocale,
|
||||
)
|
||||
]
|
||||
widget::container(
|
||||
widget::column![
|
||||
widget::text(self.lang_locale_text.as_str()),
|
||||
widget::pick_list(
|
||||
self.locales.clone(),
|
||||
self.lang_locale.clone(),
|
||||
Message::SelectLangLocale,
|
||||
)
|
||||
]
|
||||
.spacing(5)
|
||||
)
|
||||
.style(widget::container::bordered_box)
|
||||
.padding(5),
|
||||
widget::container(
|
||||
widget::column![
|
||||
widget::text(self.all_locale_text.as_str()),
|
||||
widget::pick_list(
|
||||
self.locales.clone(),
|
||||
self.formats_locale.clone(),
|
||||
Message::SelectFormatsLocale,
|
||||
)
|
||||
]
|
||||
.spacing(5)
|
||||
)
|
||||
.style(widget::container::bordered_box)
|
||||
.padding(5)
|
||||
]
|
||||
.padding(10)
|
||||
.spacing(10)
|
||||
|
||||
@@ -29,7 +29,6 @@ use crate::stage;
|
||||
use crate::stage::StageResult;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum State {
|
||||
Cheking,
|
||||
@@ -50,6 +49,7 @@ pub struct NetworkStage {
|
||||
use_net_settings: bool,
|
||||
reqire_network: bool,
|
||||
spinner_frames: apng::Frames,
|
||||
logo_handle: widget::image::Handle,
|
||||
status_message: String,
|
||||
}
|
||||
|
||||
@@ -113,7 +113,10 @@ impl NetworkStage {
|
||||
let spinner_frames =
|
||||
apng::Frames::from_bytes(crate::kira_theming::get_spiner_bytes()).unwrap();
|
||||
|
||||
let logo_handle = widget::image::Handle::from_bytes(crate::kira_theming::get_logo_bytes());
|
||||
|
||||
Self {
|
||||
logo_handle: logo_handle,
|
||||
internet_active: false,
|
||||
state: State::Cheking,
|
||||
use_net_settings: false,
|
||||
@@ -178,12 +181,12 @@ impl NetworkStage {
|
||||
}
|
||||
|
||||
pub fn view(&self) -> iced::Element<'_, Message> {
|
||||
let next_button = if (self.state == State::Cheking) || (!self.internet_active && self.reqire_network) {
|
||||
widget::button(widget::text(t!("button.next")))
|
||||
}
|
||||
else {
|
||||
widget::button(widget::text(t!("button.next"))).on_press(Message::Next)
|
||||
};
|
||||
let next_button =
|
||||
if (self.state == State::Cheking) || (!self.internet_active && self.reqire_network) {
|
||||
widget::button(widget::text(t!("button.next")))
|
||||
} else {
|
||||
widget::button(widget::text(t!("button.next"))).on_press(Message::Next)
|
||||
};
|
||||
|
||||
let (back_button, check_button, reuse_checkbox) = match self.state {
|
||||
State::Cheking => (
|
||||
@@ -202,8 +205,16 @@ impl NetworkStage {
|
||||
};
|
||||
|
||||
let spinner_container = match self.state {
|
||||
State::Cheking => widget::container(apng(&self.spinner_frames)),
|
||||
State::Normal => widget::container(widget::space().height(128).width(128)),
|
||||
State::Cheking => widget::container(
|
||||
apng(&self.spinner_frames)
|
||||
.width(iced::Pixels(128.0).into())
|
||||
.height(iced::Pixels(128.0).into()),
|
||||
),
|
||||
State::Normal => widget::container(
|
||||
widget::image(&self.logo_handle)
|
||||
.width(iced::Pixels(128.0))
|
||||
.height(iced::Pixels(128.0)),
|
||||
),
|
||||
};
|
||||
|
||||
let info_column = widget::column![
|
||||
|
||||
Reference in New Issue
Block a user