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),
TimeZone(stages::timezone::TimeZoneStage),
Locale(stages::locale::LocaleStage),
Keyboard(stages::keyboard::KeyboardStage),
}
enum Message {
@@ -53,6 +54,7 @@ enum Message {
Network(stages::network::Message),
TimeZone(stages::timezone::Message),
Locale(stages::locale::Message),
Keyboard(stages::keyboard::Message),
}
struct KiraState {
@@ -100,6 +102,7 @@ fn view(k_state: &KiraState) -> Element<'_, Message> {
Views::Network(network_stage) => network_stage.view().map(Message::Network),
Views::TimeZone(timezone_stage) => timezone_stage.view().map(Message::TimeZone),
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) {
StageAction::Next(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 => {
k_state.config.config_trail.pop();
@@ -218,6 +222,24 @@ fn update(k_state: &mut KiraState, message: Message) -> Task<Message> {
} else {
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
*/
use crate::kira_scroll_list;
use crate::kira_scroll_list::{self, ListViewMessage};
use crate::stage::{ConfigValue, StageAction, StageResult};
use iced::{Alignment, Length, widget};
use rust_i18n::t;
@@ -43,7 +43,6 @@ impl Layout {
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Variant {
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)]
pub struct KeyboarLayout {
layout: Layout,
@@ -73,7 +81,6 @@ impl KeyboarLayout {
pub fn to_result(&self) -> String {
format!("{}||{}", self.layout.layout, self.variant.variant)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -105,14 +112,15 @@ impl std::fmt::Display for KeyboarLayout {
#[derive(Debug, Clone)]
pub struct KeyboardStage {
models: Vec<KeyboarModel>,
model: Option<KeyboarModel>,
layouts: Vec<Layout>,
layout: Option<usize>,
variants_map: HashMap<String, Vec<Variant>>,
variants: Vec<Variant>,
model: Option<KeyboarModel>,
layout: 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)]
@@ -121,10 +129,9 @@ pub enum Message {
SelectLayout(kira_scroll_list::ListViewMessage),
SelectVariant(kira_scroll_list::ListViewMessage),
AddLayout(usize),
RemoveLayout(usize),
SelectAddedLayout(kira_scroll_list::ListViewMessage),
// AddLayout(usize),
// RemoveLayout(usize),
// SelectAddedLayout(kira_scroll_list::ListViewMessage),
Next,
Back,
}
@@ -180,7 +187,10 @@ fn get_layouts_blocking() -> std::io::Result<(
.unwrap_or_else(Vec::new);
// 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
.iter()
@@ -213,20 +223,25 @@ fn get_layouts_blocking() -> std::io::Result<(
}
impl KeyboardStage {
pub fn new() -> Result<Self, String> {
pub fn new() -> Self {
match get_layouts_blocking() {
Ok((models, layouts, variants_map)) => Ok({
Ok((models, layouts, variants_map)) => {
let def_layout = layouts
.iter()
.enumerate()
.find_map(|(idx, l)| (l.layout == "us").then_some(idx));
let variants = variants_map
.get("us")
.cloned()
.unwrap_or_else(|| Vec::new());
let variants = variants_map["us"].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 {
layouts: layouts,
variants_map: variants_map,
@@ -235,22 +250,32 @@ impl KeyboardStage {
models: models,
layout: def_layout,
variant: Some(0),
keyboard_layouts: Vec::new(),
selected_kbd_layout_id: None,
keyboard_layout: keyboard_layout,
}
}),
}
Err(ex) => {
let err = format!(
println!(
"Exception while trying to get kayboard layouts data from system {}",
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 {
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 {
name: "keyboard".to_string(),
config: Some(HashMap::from([
@@ -258,16 +283,12 @@ impl KeyboardStage {
"model".to_string(),
ConfigValue::String(model.model.clone()),
),
(
"layouts".to_string(),
ConfigValue::Vector(self.keyboard_layouts.iter().map(|kl| ConfigValue::String(kl.to_result())).collect()),
),
("layout".to_string(), ConfigValue::String(k_l.to_result())),
])),
resuts: None,
error: None,
}
}
else {
} else {
StageResult {
name: "keyboard".to_string(),
config: None,
@@ -279,15 +300,40 @@ impl KeyboardStage {
pub fn update(&mut self, message: Message) -> StageAction {
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::Back => StageAction::Back,
_ => StageAction::None,
}
}
pub fn view(&self) -> iced::Element<'_, Message> {
let next_button = if self.model.is_some() && self.keyboard_layouts.len() > 0 {
let next_button = if self.model.is_some() && self.keyboard_layout.is_some() {
widget::button(widget::text(t!("button.next"))).on_press(Message::Next)
} else {
widget::button(widget::text(t!("button.next")))
@@ -296,38 +342,54 @@ impl KeyboardStage {
let main_content = if self.layouts.len() > 0 {
widget::container(
widget::column![
widget::text(t!("keyboard.select_model")),
widget::pick_list(
self.models.clone(),
self.model.clone(),
Message::SelectKeyboardModel,
),
widget::column![
widget::text(t!("keyboard.select_model")),
widget::pick_list(
self.models.clone(),
self.model.clone(),
Message::SelectKeyboardModel,
)
],
widget::row![
widget::column![
widget::text(t!("keyboard.select_layout")),
crate::kira_scroll_list::list_view(&self.layouts, self.layout, Length::Shrink)
.map(Message::SelectLayout)],
crate::kira_scroll_list::list_view(
&self.layouts,
self.layout,
Length::Shrink
)
.map(Message::SelectLayout)
],
widget::column![
widget::text(t!("keyboard.select_variant")),
crate::kira_scroll_list::list_view(&self.variants, self.variant, Length::FillPortion(1))
.map(Message::SelectVariant)],
crate::kira_scroll_list::list_view(
&self.variants,
self.variant,
Length::FillPortion(1)
)
.map(Message::SelectVariant)
],
]
.padding(20)
.spacing(10)
.height(Length::Shrink),
]
.spacing(10)
.align_x(Alignment::Center),
)}
else {
widget::container(widget::text(t!("keyboard.init_error")))
};
)
} else {
widget::container(widget::text(t!("keyboard.init_error")))
};
let back_button = widget::button(widget::text(t!("button.back"))).on_press(Message::Back);
widget::column![
main_content
.padding(iced::Padding {
top: 10.0,
right: 10.0,
bottom: 0.0,
left: 10.0,
})
.height(iced::Length::Fill)
.width(iced::Length::Fill)
.align_x(Alignment::Center)
+1 -1
View File
@@ -176,7 +176,7 @@ impl LocaleStage {
.collect();
// 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();
locales
.iter()