More work on keyboard stage, now compiling.

This commit is contained in:
2026-05-06 23:21:12 +02:00
parent 8b3f22909e
commit 9081e301d4
2 changed files with 97 additions and 78 deletions
+5 -2
View File
@@ -22,6 +22,9 @@
"timezone.select_timezone": "Please select preffered time zone",
"timezone.init_error": "Error getting time zones data from system!",
"locale.select_language_locale": "The system language will be set to",
"locale.select_formats_locale": "The numbers and dates locale will be set to"
"locale.select_formats_locale": "The numbers and dates locale will be set to",
"keyboard.select_model": "Select keyboard model",
"keyboard.select_layout": "Select keyboard layout",
"keyboard.select_variant": "Select keyboard variant",
"keyboard.init_error": "Error getting keyboard layouts information from the system!"
}
+91 -75
View File
@@ -29,7 +29,11 @@ pub struct Layout {
layout: String,
description: String,
}
impl std::fmt::Display for Layout {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} ({})", &self.layout, &self.description)
}
}
impl Layout {
pub fn from_str_touple(v: &(&str, &str)) -> Self {
Self {
@@ -39,12 +43,17 @@ impl Layout {
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Variant {
variant: String,
description: String,
}
impl std::fmt::Display for Variant {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} ({})", &self.variant, &self.description)
}
}
impl Variant {
pub fn from_str_touple(v: &(&str, &str)) -> Self {
Self {
@@ -60,11 +69,24 @@ pub struct KeyboarLayout {
variant: Variant,
}
impl KeyboarLayout {
pub fn to_result(&self) -> String {
format!("{}||{}", self.layout.layout, self.variant.variant)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KeyboarModel {
model: String,
description: String,
}
impl std::fmt::Display for KeyboarModel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} ({})", &self.model, &self.description)
}
}
impl KeyboarModel {
pub fn from_str_touple(v: &(&str, &str)) -> Self {
Self {
@@ -74,7 +96,6 @@ impl KeyboarModel {
}
}
impl std::fmt::Display for KeyboarLayout {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}/{}", &self.layout.layout, &self.variant.variant)
@@ -86,17 +107,17 @@ pub struct KeyboardStage {
models: Vec<KeyboarModel>,
layouts: Vec<Layout>,
variants_map: HashMap<String, Vec<Variant>>,
variants: Vec<Variant>,
variants: Vec<Variant>,
model: Option<KeyboarModel>,
layout: Option<Layout>,
variant: Option<Variant>,
layout: Option<usize>,
variant: Option<usize>,
keyboard_layouts: Vec<KeyboarLayout>,
selected_kbd_layout_id: Option<usize>,
}
#[derive(Debug, Clone)]
pub enum Message {
SelectKeyboardModel(kira_scroll_list::ListViewMessage),
SelectKeyboardModel(KeyboarModel),
SelectLayout(kira_scroll_list::ListViewMessage),
SelectVariant(kira_scroll_list::ListViewMessage),
@@ -111,7 +132,11 @@ pub enum Message {
const XKB_RULES_FILE_NAME: &str = "/usr/share/X11/xkb/rules/evdev.lst";
/// Getting list of awailable keyboard layouts from from xkb/rules/evdev.lst file.
fn get_layouts_blocking() -> std::io::Result<(Vec<KeyboarModel>, Vec<Layout>, HashMap<String, Vec<Variant>>)> {
fn get_layouts_blocking() -> std::io::Result<(
Vec<KeyboarModel>,
Vec<Layout>,
HashMap<String, Vec<Variant>>,
)> {
use std::fs::File;
use std::io::{BufReader, Read};
@@ -124,7 +149,6 @@ fn get_layouts_blocking() -> std::io::Result<(Vec<KeyboarModel>, Vec<Layout>, Ha
let raw_sections: Vec<String> = file_content.split("! ").map(str::to_string).collect();
// Parsing models data
let models: Vec<KeyboarModel> = raw_sections
.iter()
@@ -177,9 +201,9 @@ fn get_layouts_blocking() -> std::io::Result<(Vec<KeyboarModel>, Vec<Layout>, Ha
.for_each(|v| {
let maybe_key = variants
.get_mut(v.0)
.and_then(|vrn_vec| Some(vrn_vec.push(v.1)));
.and_then(|vrn_vec| Some(vrn_vec.push(v.1.clone())));
if maybe_key.is_none() {
variants.insert(v.0.to_string(), vec![v.1]);
variants.insert(v.0.to_string(), vec![v.1.clone()]);
}
}),
)
@@ -191,23 +215,30 @@ fn get_layouts_blocking() -> std::io::Result<(Vec<KeyboarModel>, Vec<Layout>, Ha
impl KeyboardStage {
pub fn new() -> Result<Self, String> {
match get_layouts_blocking() {
Ok((models, layouts, variants)) => {
Ok((models, layouts, variants_map)) => Ok({
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 def_model = models[0].clone();
Ok(Self {
layouts: layouts,
variants_map: variants,
variants: Vec::new(),
model: Some(models[0].clone()),
models: models,
layout: None,
variant: None,
keyboard_layouts: Vec::new(),
selected_kbd_layout_id: None,
Self {
layouts: layouts,
variants_map: variants_map,
variants: variants,
model: Some(def_model),
models: models,
layout: def_layout,
variant: Some(0),
keyboard_layouts: Vec::new(),
selected_kbd_layout_id: None,
}
)
}
}),
Err(ex) => {
let err = format!(
"Exception while trying to get kayboard layouts data from system {}",
@@ -219,95 +250,80 @@ impl KeyboardStage {
}
fn gen_result(&self) -> StageResult {
if let Some(time_zone) = &self.selected_zone {
if let Some(model) = &self.model && self.keyboard_layouts.len() > 0 {
StageResult {
name: "time_zone".to_string(),
name: "keyboard".to_string(),
config: Some(HashMap::from([
(
"name".to_string(),
ConfigValue::String(time_zone.to_string()),
"model".to_string(),
ConfigValue::String(model.model.clone()),
),
(
"region".to_string(),
ConfigValue::String(time_zone.region.clone()),
),
(
"zone".to_string(),
ConfigValue::String(time_zone.zone.clone()),
"layouts".to_string(),
ConfigValue::Vector(self.keyboard_layouts.iter().map(|kl| ConfigValue::String(kl.to_result())).collect()),
),
])),
resuts: None,
error: None,
}
} else {
}
else {
StageResult {
name: "time_zone".to_string(),
name: "keyboard".to_string(),
config: None,
resuts: None,
error: None,
error: Some("Something go terrible wrong, there is no keyboard layouts.".into()),
}
}
}
pub fn update(&mut self, message: Message) -> StageAction {
match message {
Message::SelectRegion(scroll_list::ListViewMessage::Select(region_id)) => {
let region = self.regions.get(region_id).unwrap();
self.zones = self
.time_zones
.as_ref()
.unwrap()
.get(region)
.unwrap()
.clone();
self.region_id = Some(region_id);
self.zone_id = None;
//self.selected_zone_text.clear();
StageAction::None
}
Message::SelectZone(scroll_list::ListViewMessage::Select(zone_id)) => {
let zone = TimeZoneData {
region: self.regions[self.region_id.unwrap()].clone(),
zone: self.zones[zone_id].clone(),
};
self.selected_zone_text =
format!("{} {}", t!("timezone.selected_timezone"), zone.to_string());
self.zone_id = Some(zone_id);
self.selected_zone = Some(zone);
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.zone_id.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)
} else {
widget::button(widget::text(t!("button.next")))
};
let main_content = match &self.time_zones {
Ok(_) => widget::container(
let main_content = if self.layouts.len() > 0 {
widget::container(
widget::column![
widget::text(t!("timezone.select_timezone")),
widget::text(t!("keyboard.select_model")),
widget::pick_list(
self.models.clone(),
self.model.clone(),
Message::SelectKeyboardModel,
),
widget::row![
scroll_list::list_view(&self.regions, self.region_id, Length::Shrink)
.map(Message::SelectRegion),
scroll_list::list_view(&self.zones, self.zone_id, Length::FillPortion(1))
.map(Message::SelectZone),
widget::column![
widget::text(t!("keyboard.select_layout")),
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)],
]
.padding(20)
.spacing(10)
.height(Length::Shrink),
widget::text(self.selected_zone_text.clone())
]
.spacing(10)
.align_x(Alignment::Center),
),
)}
else {
widget::container(widget::text(t!("keyboard.init_error")))
};
Err(_) => widget::container(widget::text(t!("timezone.init_error"))),
};
let back_button = widget::button(widget::text(t!("button.back"))).on_press(Message::Back);
widget::column![