Monado app switcher, lang update
This commit is contained in:
@@ -10,9 +10,16 @@ mod widget_rectangle;
|
||||
mod widget_sprite;
|
||||
|
||||
use crate::{
|
||||
assets::{normalize_path, AssetPath, AssetPathOwned}, components::{Component, ComponentWeak}, drawing::{self}, globals::WguiGlobals, i18n::Translation, layout::{Layout, LayoutParams, LayoutState, Widget, WidgetID, WidgetMap, WidgetPair}, log::LogErr, parser::{
|
||||
assets::{AssetPath, AssetPathOwned, normalize_path},
|
||||
components::{Component, ComponentWeak},
|
||||
drawing::{self},
|
||||
globals::WguiGlobals,
|
||||
i18n::Translation,
|
||||
layout::{Layout, LayoutParams, LayoutState, Widget, WidgetID, WidgetMap, WidgetPair},
|
||||
log::LogErr,
|
||||
parser::{
|
||||
component_button::parse_component_button,
|
||||
component_checkbox::{parse_component_checkbox, CheckboxKind},
|
||||
component_checkbox::{CheckboxKind, parse_component_checkbox},
|
||||
component_radio_group::parse_component_radio_group,
|
||||
component_slider::parse_component_slider,
|
||||
widget_div::parse_widget_div,
|
||||
@@ -20,7 +27,9 @@ use crate::{
|
||||
widget_label::parse_widget_label,
|
||||
widget_rectangle::parse_widget_rectangle,
|
||||
widget_sprite::parse_widget_sprite,
|
||||
}, widget::ConstructEssentials, windowing::context_menu
|
||||
},
|
||||
widget::ConstructEssentials,
|
||||
windowing::context_menu,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use ouroboros::self_referencing;
|
||||
@@ -215,7 +224,10 @@ impl ParserState {
|
||||
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
||||
) -> anyhow::Result<ParserData> {
|
||||
let Some(template) = self.data.templates.get(template_name) else {
|
||||
anyhow::bail!("{:?}: no template named \"{template_name}\" found", self.path.get_path_buf());
|
||||
anyhow::bail!(
|
||||
"{:?}: no template named \"{template_name}\" found",
|
||||
self.path.get_path_buf().display()
|
||||
);
|
||||
};
|
||||
|
||||
let mut ctx = ParserContext {
|
||||
@@ -280,7 +292,7 @@ impl ParserState {
|
||||
|
||||
for attrib in child.attributes() {
|
||||
let (key, value) = (attrib.name(), attrib.value());
|
||||
|
||||
|
||||
match key {
|
||||
"text" => title = Some(Translation::from_raw_text(value)),
|
||||
"translation" => title = Some(Translation::from_translation_key(value)),
|
||||
@@ -291,7 +303,7 @@ impl ParserState {
|
||||
if !other.starts_with('_') {
|
||||
anyhow::bail!("unexpected \"{other}\" attribute");
|
||||
}
|
||||
attribs.push(AttribPair::new(key, replace_vars(value, &template_params)));
|
||||
attribs.push(AttribPair::new(key, replace_vars(value, template_params)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,14 +317,12 @@ impl ParserState {
|
||||
});
|
||||
}
|
||||
other => {
|
||||
anyhow::bail!("{:?}: unexpected <{other}> tag", self.path.get_path_buf());
|
||||
anyhow::bail!("{:?}: unexpected <{other}> tag", self.path.get_path_buf().display());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(
|
||||
cells,
|
||||
)
|
||||
Ok(cells)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,65 +480,71 @@ impl ParserContext<'_> {
|
||||
insert_color_vars!(self, "faded", def.faded_color, def.translucent_alpha);
|
||||
insert_color_vars!(self, "bg", def.bg_color, def.translucent_alpha);
|
||||
}
|
||||
fn print_invalid_attrib(&self, tag_name: &str, key: &str, value: &str) {
|
||||
log::warn!("{}: <{tag_name}> value for \"{key}\" is invalid: \"{value}\"", self.doc_params.path.get_str());
|
||||
}
|
||||
|
||||
fn print_missing_attrib(&self, tag_name: &str, attr: &str) {
|
||||
log::warn!("{}: <{tag_name}> is missing \"{attr}\".", self.doc_params.path.get_str());
|
||||
}
|
||||
|
||||
fn parse_val(&self, tag_name: &str, key: &str, value: &str) -> Option<f32> {
|
||||
let Ok(val) = value.parse::<f32>() else {
|
||||
self.print_invalid_attrib(tag_name, key, value);
|
||||
return None;
|
||||
};
|
||||
Some(val)
|
||||
}
|
||||
|
||||
fn parse_percent(&self, tag_name: &str, key: &str, value: &str) -> Option<f32> {
|
||||
let Some(val_str) = value.split('%').next() else {
|
||||
self.print_invalid_attrib(tag_name, key, value);
|
||||
return None;
|
||||
};
|
||||
|
||||
let Ok(val) = val_str.parse::<f32>() else {
|
||||
self.print_invalid_attrib(tag_name, key, value);
|
||||
return None;
|
||||
};
|
||||
Some(val / 100.0)
|
||||
}
|
||||
|
||||
fn parse_size_unit<T>(&self, tag_name: &str, key: &str, value: &str) -> Option<T>
|
||||
where
|
||||
T: taffy::prelude::FromPercent + taffy::prelude::FromLength,
|
||||
{
|
||||
if is_percent(value) {
|
||||
Some(taffy::prelude::percent(self.parse_percent(tag_name, key, value)?))
|
||||
} else {
|
||||
Some(taffy::prelude::length(parse_f32(value)?))
|
||||
fn print_invalid_attrib(&self, tag_name: &str, key: &str, value: &str) {
|
||||
log::warn!(
|
||||
"{}: <{tag_name}> value for \"{key}\" is invalid: \"{value}\"",
|
||||
self.doc_params.path.get_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_check_i32(&self, tag_name: &str, key: &str, value: &str, num: &mut i32) -> bool {
|
||||
if let Some(value) = parse_i32(value) {
|
||||
*num = value;
|
||||
true
|
||||
} else {
|
||||
self.print_invalid_attrib(tag_name, key, value);
|
||||
false
|
||||
fn print_missing_attrib(&self, tag_name: &str, attr: &str) {
|
||||
log::warn!(
|
||||
"{}: <{tag_name}> is missing \"{attr}\".",
|
||||
self.doc_params.path.get_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_check_f32(&self, tag_name: &str, key: &str, value: &str, num: &mut f32) -> bool {
|
||||
if let Some(value) = parse_f32(value) {
|
||||
*num = value;
|
||||
true
|
||||
} else {
|
||||
self.print_invalid_attrib(tag_name, key, value);
|
||||
false
|
||||
fn parse_val(&self, tag_name: &str, key: &str, value: &str) -> Option<f32> {
|
||||
let Ok(val) = value.parse::<f32>() else {
|
||||
self.print_invalid_attrib(tag_name, key, value);
|
||||
return None;
|
||||
};
|
||||
Some(val)
|
||||
}
|
||||
|
||||
fn parse_percent(&self, tag_name: &str, key: &str, value: &str) -> Option<f32> {
|
||||
let Some(val_str) = value.split('%').next() else {
|
||||
self.print_invalid_attrib(tag_name, key, value);
|
||||
return None;
|
||||
};
|
||||
|
||||
let Ok(val) = val_str.parse::<f32>() else {
|
||||
self.print_invalid_attrib(tag_name, key, value);
|
||||
return None;
|
||||
};
|
||||
Some(val / 100.0)
|
||||
}
|
||||
|
||||
fn parse_size_unit<T>(&self, tag_name: &str, key: &str, value: &str) -> Option<T>
|
||||
where
|
||||
T: taffy::prelude::FromPercent + taffy::prelude::FromLength,
|
||||
{
|
||||
if is_percent(value) {
|
||||
Some(taffy::prelude::percent(self.parse_percent(tag_name, key, value)?))
|
||||
} else {
|
||||
Some(taffy::prelude::length(parse_f32(value)?))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_check_i32(&self, tag_name: &str, key: &str, value: &str, num: &mut i32) -> bool {
|
||||
if let Some(value) = parse_i32(value) {
|
||||
*num = value;
|
||||
true
|
||||
} else {
|
||||
self.print_invalid_attrib(tag_name, key, value);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_check_f32(&self, tag_name: &str, key: &str, value: &str, num: &mut f32) -> bool {
|
||||
if let Some(value) = parse_f32(value) {
|
||||
*num = value;
|
||||
true
|
||||
} else {
|
||||
self.print_invalid_attrib(tag_name, key, value);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_i32(value: &str) -> Option<i32> {
|
||||
@@ -583,7 +599,6 @@ fn require_tag_by_name<'a>(node: &roxmltree::Node<'a, 'a>, name: &str) -> anyhow
|
||||
get_tag_by_name(node, name).ok_or_else(|| anyhow::anyhow!("Tag \"{name}\" not found"))
|
||||
}
|
||||
|
||||
|
||||
fn parse_widget_other_internal(
|
||||
template: &Rc<Template>,
|
||||
template_parameters: HashMap<Rc<str>, Rc<str>>,
|
||||
@@ -617,7 +632,10 @@ fn parse_widget_other(
|
||||
attribs: &[AttribPair],
|
||||
) -> anyhow::Result<()> {
|
||||
let Some(template) = ctx.get_template(xml_tag_name) else {
|
||||
log::error!("{}: Undefined tag named \"{xml_tag_name}\"", ctx.doc_params.path.get_str());
|
||||
log::error!(
|
||||
"{}: Undefined tag named \"{xml_tag_name}\"",
|
||||
ctx.doc_params.path.get_str()
|
||||
);
|
||||
return Ok(()); // not critical
|
||||
};
|
||||
|
||||
@@ -746,6 +764,7 @@ pub fn replace_vars(input: &str, vars: &HashMap<Rc<str>, Rc<str>>) -> Rc<str> {
|
||||
}
|
||||
|
||||
#[allow(clippy::manual_strip)]
|
||||
#[allow(clippy::single_match_else)]
|
||||
fn process_attrib(
|
||||
template_parameters: &HashMap<Rc<str>, Rc<str>>,
|
||||
ctx: &ParserContext,
|
||||
@@ -760,7 +779,7 @@ fn process_attrib(
|
||||
None => {
|
||||
log::warn!("{}: undefined variable \"{value}\"", ctx.doc_params.path.get_str());
|
||||
AttribPair::new(key, "undefined")
|
||||
},
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AttribPair::new(key, replace_vars(value, template_parameters))
|
||||
@@ -797,7 +816,10 @@ fn process_attribs<'a>(
|
||||
res.push(process_attrib(&file.template_parameters, ctx, macro_key, macro_value));
|
||||
}
|
||||
} else {
|
||||
log::warn!("{}: requested macro named \"{value}\" not found!", ctx.doc_params.path.get_str());
|
||||
log::warn!(
|
||||
"{}: requested macro named \"{value}\" not found!",
|
||||
ctx.doc_params.path.get_str()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
res.push(process_attrib(&file.template_parameters, ctx, key, value));
|
||||
@@ -816,7 +838,10 @@ fn parse_tag_theme<'a>(ctx: &mut ParserContext, node: roxmltree::Node<'a, 'a>) {
|
||||
}
|
||||
"" => { /* ignore */ }
|
||||
_ => {
|
||||
log::warn!("{}: <{child_name}> is not a valid child to <theme>.", ctx.doc_params.path.get_str());
|
||||
log::warn!(
|
||||
"{}: <{child_name}> is not a valid child to <theme>.",
|
||||
ctx.doc_params.path.get_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -837,7 +862,7 @@ fn parse_tag_template(file: &ParserFile, ctx: &mut ParserContext, node: roxmltre
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let Some(name) = template_name else {
|
||||
ctx.print_missing_attrib("template", "name");
|
||||
return;
|
||||
@@ -865,7 +890,11 @@ fn parse_tag_macro(file: &ParserFile, ctx: &mut ParserContext, node: roxmltree::
|
||||
}
|
||||
_ => {
|
||||
if macro_attribs.insert(pair.attrib.clone(), pair.value).is_some() {
|
||||
log::warn!("{}: macro attrib \"{}\" already defined!", ctx.doc_params.path.get_str(), pair.attrib);
|
||||
log::warn!(
|
||||
"{}: macro attrib \"{}\" already defined!",
|
||||
ctx.doc_params.path.get_str(),
|
||||
pair.attrib
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -963,19 +992,29 @@ fn parse_child<'a>(
|
||||
new_widget_id = Some(parse_widget_div(file, ctx, child_node, parent_id, &attribs, tag_name)?);
|
||||
}
|
||||
"rectangle" => {
|
||||
new_widget_id = Some(parse_widget_rectangle(file, ctx, child_node, parent_id, &attribs, tag_name)?);
|
||||
new_widget_id = Some(parse_widget_rectangle(
|
||||
file, ctx, child_node, parent_id, &attribs, tag_name,
|
||||
)?);
|
||||
}
|
||||
"label" => {
|
||||
new_widget_id = Some(parse_widget_label(file, ctx, child_node, parent_id, &attribs, tag_name)?);
|
||||
new_widget_id = Some(parse_widget_label(
|
||||
file, ctx, child_node, parent_id, &attribs, tag_name,
|
||||
)?);
|
||||
}
|
||||
"sprite" => {
|
||||
new_widget_id = Some(parse_widget_sprite(file, ctx, child_node, parent_id, &attribs, tag_name)?);
|
||||
new_widget_id = Some(parse_widget_sprite(
|
||||
file, ctx, child_node, parent_id, &attribs, tag_name,
|
||||
)?);
|
||||
}
|
||||
"image" => {
|
||||
new_widget_id = Some(parse_widget_image(file, ctx, child_node, parent_id, &attribs, tag_name)?);
|
||||
new_widget_id = Some(parse_widget_image(
|
||||
file, ctx, child_node, parent_id, &attribs, tag_name,
|
||||
)?);
|
||||
}
|
||||
"Button" => {
|
||||
new_widget_id = Some(parse_component_button(file, ctx, child_node, parent_id, &attribs, tag_name)?);
|
||||
new_widget_id = Some(parse_component_button(
|
||||
file, ctx, child_node, parent_id, &attribs, tag_name,
|
||||
)?);
|
||||
}
|
||||
"Slider" => {
|
||||
new_widget_id = Some(parse_component_slider(ctx, parent_id, &attribs, tag_name)?);
|
||||
@@ -999,7 +1038,9 @@ fn parse_child<'a>(
|
||||
)?);
|
||||
}
|
||||
"RadioGroup" => {
|
||||
new_widget_id = Some(parse_component_radio_group(file, ctx, child_node, parent_id, &attribs, tag_name)?);
|
||||
new_widget_id = Some(parse_component_radio_group(
|
||||
file, ctx, child_node, parent_id, &attribs, tag_name,
|
||||
)?);
|
||||
}
|
||||
"" => { /* ignore */ }
|
||||
other_tag_name => {
|
||||
|
||||
Reference in New Issue
Block a user