Most work on keyboard stage is done.

This commit is contained in:
2026-05-08 00:24:22 +02:00
parent 9081e301d4
commit 75ef50bed1
3 changed files with 135 additions and 51 deletions
+23 -1
View File
@@ -44,6 +44,7 @@ enum Views {
Network(stages::network::NetworkStage), Network(stages::network::NetworkStage),
TimeZone(stages::timezone::TimeZoneStage), TimeZone(stages::timezone::TimeZoneStage),
Locale(stages::locale::LocaleStage), Locale(stages::locale::LocaleStage),
Keyboard(stages::keyboard::KeyboardStage),
} }
enum Message { enum Message {
@@ -53,6 +54,7 @@ enum Message {
Network(stages::network::Message), Network(stages::network::Message),
TimeZone(stages::timezone::Message), TimeZone(stages::timezone::Message),
Locale(stages::locale::Message), Locale(stages::locale::Message),
Keyboard(stages::keyboard::Message),
} }
struct KiraState { struct KiraState {
@@ -100,6 +102,7 @@ fn view(k_state: &KiraState) -> Element<'_, Message> {
Views::Network(network_stage) => network_stage.view().map(Message::Network), Views::Network(network_stage) => network_stage.view().map(Message::Network),
Views::TimeZone(timezone_stage) => timezone_stage.view().map(Message::TimeZone), Views::TimeZone(timezone_stage) => timezone_stage.view().map(Message::TimeZone),
Views::Locale(locale_stage) => locale_stage.view().map(Message::Locale), Views::Locale(locale_stage) => locale_stage.view().map(Message::Locale),
Views::Keyboard(keyboard_stage) => keyboard_stage.view().map(Message::Keyboard),
} }
} }
@@ -205,7 +208,8 @@ fn update(k_state: &mut KiraState, message: Message) -> Task<Message> {
match locale_view.update(locale_msg) { match locale_view.update(locale_msg) {
StageAction::Next(locale_res) => { StageAction::Next(locale_res) => {
k_state.config.config_trail.push(locale_res); k_state.config.config_trail.push(locale_res);
iced::exit() k_state.current_view = Views::Keyboard(stages::keyboard::KeyboardStage::new());
Task::none()
} }
StageAction::Back => { StageAction::Back => {
k_state.config.config_trail.pop(); k_state.config.config_trail.pop();
@@ -218,6 +222,24 @@ fn update(k_state: &mut KiraState, message: Message) -> Task<Message> {
} else { } else {
Task::none() Task::none()
} }
},
Message::Keyboard(keyboard_msg) => {
if let Views::Keyboard(keyboard_view) = &mut k_state.current_view {
match keyboard_view.update(keyboard_msg) {
StageAction::Next(keyboard_res) => {
k_state.config.config_trail.push(keyboard_res);
iced::exit()
}
StageAction::Back => {
k_state.config.config_trail.pop();
k_state.current_view = Views::Locale(stages::locale::LocaleStage::new(&k_state.config));
Task::none()
}
_ => Task::none(),
}
} else {
Task::none()
}
} }
} }
} }
+111 -49
View File
@@ -18,7 +18,7 @@
This is Keyboar stage, used to select Keyboard Layouts This is Keyboar stage, used to select Keyboard Layouts
*/ */
use crate::kira_scroll_list; use crate::kira_scroll_list::{self, ListViewMessage};
use crate::stage::{ConfigValue, StageAction, StageResult}; use crate::stage::{ConfigValue, StageAction, StageResult};
use iced::{Alignment, Length, widget}; use iced::{Alignment, Length, widget};
use rust_i18n::t; use rust_i18n::t;
@@ -43,7 +43,6 @@ impl Layout {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct Variant { pub struct Variant {
variant: String, variant: String,
@@ -63,6 +62,15 @@ impl Variant {
} }
} }
impl Default for Variant {
fn default() -> Self {
Self {
variant: "default".into(),
description: "Default variant".into(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct KeyboarLayout { pub struct KeyboarLayout {
layout: Layout, layout: Layout,
@@ -73,7 +81,6 @@ impl KeyboarLayout {
pub fn to_result(&self) -> String { pub fn to_result(&self) -> String {
format!("{}||{}", self.layout.layout, self.variant.variant) format!("{}||{}", self.layout.layout, self.variant.variant)
} }
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@@ -105,14 +112,15 @@ impl std::fmt::Display for KeyboarLayout {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct KeyboardStage { pub struct KeyboardStage {
models: Vec<KeyboarModel>, models: Vec<KeyboarModel>,
model: Option<KeyboarModel>,
layouts: Vec<Layout>, layouts: Vec<Layout>,
layout: Option<usize>,
variants_map: HashMap<String, Vec<Variant>>, variants_map: HashMap<String, Vec<Variant>>,
variants: Vec<Variant>, variants: Vec<Variant>,
model: Option<KeyboarModel>,
layout: Option<usize>,
variant: Option<usize>, variant: Option<usize>,
keyboard_layouts: Vec<KeyboarLayout>,
selected_kbd_layout_id: Option<usize>, keyboard_layout: Option<KeyboarLayout>,
// selected_kbd_layout_id: Option<usize>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -121,10 +129,9 @@ pub enum Message {
SelectLayout(kira_scroll_list::ListViewMessage), SelectLayout(kira_scroll_list::ListViewMessage),
SelectVariant(kira_scroll_list::ListViewMessage), SelectVariant(kira_scroll_list::ListViewMessage),
AddLayout(usize), // AddLayout(usize),
RemoveLayout(usize), // RemoveLayout(usize),
SelectAddedLayout(kira_scroll_list::ListViewMessage), // SelectAddedLayout(kira_scroll_list::ListViewMessage),
Next, Next,
Back, Back,
} }
@@ -180,7 +187,10 @@ fn get_layouts_blocking() -> std::io::Result<(
.unwrap_or_else(Vec::new); .unwrap_or_else(Vec::new);
// parsing variants data to HashMap // parsing variants data to HashMap
let mut variants: HashMap<String, Vec<Variant>> = HashMap::new(); let mut variants: HashMap<String, Vec<Variant>> = layouts
.iter()
.map(|l| (l.layout.clone(), vec![Variant::default()]))
.collect();
raw_sections raw_sections
.iter() .iter()
@@ -213,20 +223,25 @@ fn get_layouts_blocking() -> std::io::Result<(
} }
impl KeyboardStage { impl KeyboardStage {
pub fn new() -> Result<Self, String> { pub fn new() -> Self {
match get_layouts_blocking() { match get_layouts_blocking() {
Ok((models, layouts, variants_map)) => Ok({ Ok((models, layouts, variants_map)) => {
let def_layout = layouts let def_layout = layouts
.iter() .iter()
.enumerate() .enumerate()
.find_map(|(idx, l)| (l.layout == "us").then_some(idx)); .find_map(|(idx, l)| (l.layout == "us").then_some(idx));
let variants = variants_map
.get("us") let variants = variants_map["us"].clone();
.cloned()
.unwrap_or_else(|| Vec::new());
let def_model = models[0].clone(); let def_model = models[0].clone();
let keyboard_layout = def_layout.and_then(|li_d| {
Some(KeyboarLayout {
layout: layouts[li_d].clone(),
variant: variants[0].clone(),
})
});
Self { Self {
layouts: layouts, layouts: layouts,
variants_map: variants_map, variants_map: variants_map,
@@ -235,22 +250,32 @@ impl KeyboardStage {
models: models, models: models,
layout: def_layout, layout: def_layout,
variant: Some(0), variant: Some(0),
keyboard_layouts: Vec::new(), keyboard_layout: keyboard_layout,
selected_kbd_layout_id: None,
} }
}), }
Err(ex) => { Err(ex) => {
let err = format!( println!(
"Exception while trying to get kayboard layouts data from system {}", "Exception while trying to get kayboard layouts data from system {}",
ex ex
); );
Err(err) Self {
layouts: Vec::new(),
variants_map: HashMap::new(),
variants: Vec::new(),
model: None,
models: Vec::new(),
layout: None,
variant: None,
keyboard_layout: None,
}
} }
} }
} }
fn gen_result(&self) -> StageResult { fn gen_result(&self) -> StageResult {
if let Some(model) = &self.model && self.keyboard_layouts.len() > 0 { if let Some(model) = &self.model
&& let Some(k_l) = &self.keyboard_layout
{
StageResult { StageResult {
name: "keyboard".to_string(), name: "keyboard".to_string(),
config: Some(HashMap::from([ config: Some(HashMap::from([
@@ -258,16 +283,12 @@ impl KeyboardStage {
"model".to_string(), "model".to_string(),
ConfigValue::String(model.model.clone()), ConfigValue::String(model.model.clone()),
), ),
( ("layout".to_string(), ConfigValue::String(k_l.to_result())),
"layouts".to_string(),
ConfigValue::Vector(self.keyboard_layouts.iter().map(|kl| ConfigValue::String(kl.to_result())).collect()),
),
])), ])),
resuts: None, resuts: None,
error: None, error: None,
} }
} } else {
else {
StageResult { StageResult {
name: "keyboard".to_string(), name: "keyboard".to_string(),
config: None, config: None,
@@ -279,15 +300,40 @@ impl KeyboardStage {
pub fn update(&mut self, message: Message) -> StageAction { pub fn update(&mut self, message: Message) -> StageAction {
match message { match message {
Message::SelectLayout(ListViewMessage::Select(l_id)) => {
if let Some(current_l_id) = self.layout
&& current_l_id != l_id
{
self.layout = Some(l_id);
self.variants = self.variants_map[self.layouts[l_id].layout.as_str()].clone();
self.variant = Some(0);
self.keyboard_layout = Some(KeyboarLayout {
layout: self.layouts[l_id].clone(),
variant: self.variants[0].clone(),
});
}
StageAction::None
}
Message::SelectVariant(ListViewMessage::Select(v_id)) => {
self.variant = Some(v_id);
self.keyboard_layout = Some(KeyboarLayout {
layout: self.layouts[self.layout.unwrap()].clone(),
variant: self.variants[v_id].clone(),
});
StageAction::None
}
Message::SelectKeyboardModel(k_m) => {
self.model = Some(k_m);
StageAction::None
}
Message::Next => StageAction::Next(self.gen_result()), Message::Next => StageAction::Next(self.gen_result()),
Message::Back => StageAction::Back, Message::Back => StageAction::Back,
_ => StageAction::None,
} }
} }
pub fn view(&self) -> iced::Element<'_, Message> { pub fn view(&self) -> iced::Element<'_, Message> {
let next_button = if self.model.is_some() && self.keyboard_layout.is_some() {
let next_button = if self.model.is_some() && self.keyboard_layouts.len() > 0 {
widget::button(widget::text(t!("button.next"))).on_press(Message::Next) widget::button(widget::text(t!("button.next"))).on_press(Message::Next)
} else { } else {
widget::button(widget::text(t!("button.next"))) widget::button(widget::text(t!("button.next")))
@@ -296,38 +342,54 @@ impl KeyboardStage {
let main_content = if self.layouts.len() > 0 { let main_content = if self.layouts.len() > 0 {
widget::container( widget::container(
widget::column![ widget::column![
widget::text(t!("keyboard.select_model")), widget::column![
widget::pick_list( widget::text(t!("keyboard.select_model")),
self.models.clone(), widget::pick_list(
self.model.clone(), self.models.clone(),
Message::SelectKeyboardModel, self.model.clone(),
), Message::SelectKeyboardModel,
)
],
widget::row![ widget::row![
widget::column![ widget::column![
widget::text(t!("keyboard.select_layout")), widget::text(t!("keyboard.select_layout")),
crate::kira_scroll_list::list_view(&self.layouts, self.layout, Length::Shrink) crate::kira_scroll_list::list_view(
.map(Message::SelectLayout)], &self.layouts,
self.layout,
Length::Shrink
)
.map(Message::SelectLayout)
],
widget::column![ widget::column![
widget::text(t!("keyboard.select_variant")), widget::text(t!("keyboard.select_variant")),
crate::kira_scroll_list::list_view(&self.variants, self.variant, Length::FillPortion(1)) crate::kira_scroll_list::list_view(
.map(Message::SelectVariant)], &self.variants,
self.variant,
Length::FillPortion(1)
)
.map(Message::SelectVariant)
],
] ]
.padding(20)
.spacing(10) .spacing(10)
.height(Length::Shrink), .height(Length::Shrink),
] ]
.spacing(10) .spacing(10)
.align_x(Alignment::Center), .align_x(Alignment::Center),
)} )
else { } else {
widget::container(widget::text(t!("keyboard.init_error"))) widget::container(widget::text(t!("keyboard.init_error")))
}; };
let back_button = widget::button(widget::text(t!("button.back"))).on_press(Message::Back); let back_button = widget::button(widget::text(t!("button.back"))).on_press(Message::Back);
widget::column![ widget::column![
main_content main_content
.padding(iced::Padding {
top: 10.0,
right: 10.0,
bottom: 0.0,
left: 10.0,
})
.height(iced::Length::Fill) .height(iced::Length::Fill)
.width(iced::Length::Fill) .width(iced::Length::Fill)
.align_x(Alignment::Center) .align_x(Alignment::Center)
+1 -1
View File
@@ -176,7 +176,7 @@ impl LocaleStage {
.collect(); .collect();
// if we get lang code from wellcome stage, try to fing match with system locales // if we get lang code from wellcome stage, try to fing match with system locales
let lang_match = if let Some(ConfigValue::String(lang)) = maybe_lang { let lang_match = if let Some(ConfigValue::String(lang)) = maybe_lang && lang != "en" {
let lang = lang.replace("-", "_").to_lowercase(); let lang = lang.replace("-", "_").to_lowercase();
locales locales
.iter() .iter()