parser: ignore_in_mode attribute; watch additions

This commit is contained in:
galister
2025-08-03 17:26:34 +09:00
parent eaa81450b5
commit b2902f8f7f
9 changed files with 68 additions and 9 deletions

View File

@@ -20,7 +20,8 @@ impl TestbedAny {
let globals = WguiGlobals::new(Box::new(assets::Asset {}))?; let globals = WguiGlobals::new(Box::new(assets::Asset {}))?;
let (layout, state) = wgui::parser::new_layout_from_assets(globals, listeners, &path)?; let (layout, state) =
wgui::parser::new_layout_from_assets(globals, listeners, &path, false)?;
Ok(Self { layout, state }) Ok(Self { layout, state })
} }
} }

View File

@@ -17,7 +17,8 @@ impl TestbedGeneric {
let globals = WguiGlobals::new(Box::new(assets::Asset {}))?; let globals = WguiGlobals::new(Box::new(assets::Asset {}))?;
let (layout, state) = wgui::parser::new_layout_from_assets(globals, listeners, XML_PATH)?; let (layout, state) =
wgui::parser::new_layout_from_assets(globals, listeners, XML_PATH, false)?;
Ok(Self { layout, state }) Ok(Self { layout, state })
} }

View File

@@ -75,6 +75,7 @@ impl ParserState {
listeners: &mut EventListenerCollection<U1, U2>, listeners: &mut EventListenerCollection<U1, U2>,
widget_id: WidgetID, widget_id: WidgetID,
template_parameters: HashMap<Rc<str>, Rc<str>>, template_parameters: HashMap<Rc<str>, Rc<str>>,
dev_mode: bool,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let Some(template) = self.templates.get(template_name) else { let Some(template) = self.templates.get(template_name) else {
anyhow::bail!("no template named \"{}\" found", template_name); anyhow::bail!("no template named \"{}\" found", template_name);
@@ -88,6 +89,7 @@ impl ParserState {
var_map: self.var_map.clone(), // FIXME: prevent copying var_map: self.var_map.clone(), // FIXME: prevent copying
components: self.components.clone(), // FIXME: prevent copying components: self.components.clone(), // FIXME: prevent copying
templates: Default::default(), templates: Default::default(),
dev_mode,
}; };
let file = ParserFile { let file = ParserFile {
@@ -126,6 +128,7 @@ struct ParserContext<'a, U1, U2> {
ids: HashMap<Rc<str>, WidgetID>, ids: HashMap<Rc<str>, WidgetID>,
templates: HashMap<Rc<str>, Rc<Template>>, templates: HashMap<Rc<str>, Rc<Template>>,
components: Vec<Rc<dyn Component>>, components: Vec<Rc<dyn Component>>,
dev_mode: bool,
} }
// Parses a color from a HTML hex string // Parses a color from a HTML hex string
@@ -557,6 +560,21 @@ fn parse_children<'a, U1, U2>(
parent_id: WidgetID, parent_id: WidgetID,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
for child_node in node.children() { for child_node in node.children() {
match node.attribute("ignore_in_mode") {
Some("dev") => {
if !ctx.dev_mode {
continue;
}
}
Some("live") => {
if ctx.dev_mode {
continue;
}
}
Some(s) => print_invalid_attrib("ignore_in_mode", s),
_ => {}
};
match child_node.tag_name().name() { match child_node.tag_name().name() {
"include" => { "include" => {
parse_tag_include(file, ctx, child_node, parent_id)?; parse_tag_include(file, ctx, child_node, parent_id)?;
@@ -591,6 +609,7 @@ fn parse_children<'a, U1, U2>(
fn create_default_context<'a, U1, U2>( fn create_default_context<'a, U1, U2>(
layout: &'a mut Layout, layout: &'a mut Layout,
listeners: &'a mut EventListenerCollection<U1, U2>, listeners: &'a mut EventListenerCollection<U1, U2>,
dev_mode: bool,
) -> ParserContext<'a, U1, U2> { ) -> ParserContext<'a, U1, U2> {
ParserContext { ParserContext {
layout, layout,
@@ -600,6 +619,7 @@ fn create_default_context<'a, U1, U2>(
templates: Default::default(), templates: Default::default(),
macro_attribs: Default::default(), macro_attribs: Default::default(),
components: Default::default(), components: Default::default(),
dev_mode,
} }
} }
@@ -608,10 +628,11 @@ pub fn parse_from_assets<U1, U2>(
listeners: &mut EventListenerCollection<U1, U2>, listeners: &mut EventListenerCollection<U1, U2>,
parent_id: WidgetID, parent_id: WidgetID,
path: &str, path: &str,
dev_mode: bool,
) -> anyhow::Result<ParserState> { ) -> anyhow::Result<ParserState> {
let path = PathBuf::from(path); let path = PathBuf::from(path);
let mut ctx = create_default_context(layout, listeners); let mut ctx = create_default_context(layout, listeners, dev_mode);
let (file, node_layout) = get_doc_from_path(&mut ctx, &path)?; let (file, node_layout) = get_doc_from_path(&mut ctx, &path)?;
parse_document_root(file, &mut ctx, parent_id, node_layout)?; parse_document_root(file, &mut ctx, parent_id, node_layout)?;
@@ -635,10 +656,11 @@ pub fn new_layout_from_assets<U1, U2>(
globals: WguiGlobals, globals: WguiGlobals,
listeners: &mut EventListenerCollection<U1, U2>, listeners: &mut EventListenerCollection<U1, U2>,
path: &str, path: &str,
dev_mode: bool,
) -> anyhow::Result<(Layout, ParserState)> { ) -> anyhow::Result<(Layout, ParserState)> {
let mut layout = Layout::new(globals)?; let mut layout = Layout::new(globals)?;
let widget = layout.root_widget; let widget = layout.root_widget;
let state = parse_from_assets(&mut layout, listeners, widget, path)?; let state = parse_from_assets(&mut layout, listeners, widget, path, dev_mode)?;
Ok((layout, state)) Ok((layout, state))
} }

View File

@@ -2,7 +2,7 @@
<theme> <theme>
<var key="border" value="2" /> <var key="border" value="2" />
<var key="kbd_color" value="#a6da95" /> <var key="kbd_color" value="#a6da95" />
<var key="set_color" value="#dddddd" /> <var key="set_color" value="#cad3f5" />
<var key="clock0_color" value="#cad3f5" /> <var key="clock0_color" value="#cad3f5" />
<var key="clock0_size" value="46" /> <var key="clock0_size" value="46" />
@@ -18,6 +18,15 @@
<sprite color="~device_color" width="${size}" height="${size}" src="${src}" /> <sprite color="~device_color" width="${size}" height="${size}" src="${src}" />
</template> </template>
<template name="Set">
<div align_items="center" justify_content="center" flex_wrap="wrap" align_content="center">
<sprite width="40" height="40" color="~set_color" src="watch/set2.svg" />
<div position="absolute" margin_top="11" >
<label text="${name}" size="24" color="#000000" weight="bold" />
</div>
</div>
</template>
<elements> <elements>
<div width="400" height="200"> <div width="400" height="200">
<rectangle width="100%" height="100%" padding="4" box_sizing="content_box" flex_wrap="wrap" gap="16" color="~bg_color"> <rectangle width="100%" height="100%" padding="4" box_sizing="content_box" flex_wrap="wrap" gap="16" color="~bg_color">
@@ -38,14 +47,31 @@
</div> </div>
<div width="10" height="100%" /> <div width="10" height="100%" />
<div id="clock_alt" flex_direction="column" padding="4"> <div id="clock_alt" flex_direction="column" padding="4">
<div width="100%" padding="2" />
<label text="Paris" id="clock1_tz" color="~clock_alt1_color" size="~clock_alt_tz_size" weight="bold" /> <label text="Paris" id="clock1_tz" color="~clock_alt1_color" size="~clock_alt_tz_size" weight="bold" />
<div width="100%" padding="2" />
<label text="23:59" id="clock1_time" color="~clock_alt1_color" size="~clock_alt_size" weight="bold" /> <label text="23:59" id="clock1_time" color="~clock_alt1_color" size="~clock_alt_size" weight="bold" />
<label text="Chicago" id="clock2_tz" color="~clock_alt2_color" size="~clock_alt_tz_size" weight="bold" />
<div width="100%" padding="2" /> <div width="100%" padding="2" />
<label text="Chicago" id="clock2_tz" color="~clock_alt2_color" size="~clock_alt_tz_size" weight="bold" />
<label text="23:59" id="clock2_time" color="~clock_alt2_color" size="~clock_alt_size" weight="bold" /> <label text="23:59" id="clock2_time" color="~clock_alt2_color" size="~clock_alt_size" weight="bold" />
</div> </div>
</div> </div>
<div width="100%" flex_direction="row">
<div id="btn_home">
<sprite color="~set_color" width="40" height="40" src="watch/home.svg" />
</div>
<div id="sets" ignore_in_mode="dev">
<!-- Will populate <Set> tags at runtime -->
</div>
<div ignore_in_mode="live">
<!-- Example sets for testing -->
<Set name="A" />
<Set name="B" />
<Set name="C" />
</div>
<div id="btn_edit">
<sprite color="~set_color" width="40" height="40" src="watch/edit.svg" />
</div>
</div>
</rectangle> </rectangle>
</div> </div>
</elements> </elements>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE --><path fill="white" d="m18.9 21l-5.475-5.475l2.1-2.1L21 18.9zM5.1 21L3 18.9L9.9 12l-1.7-1.7l-.7.7l-1.275-1.275v2.05l-.7.7L2.5 9.45l.7-.7h2.05L4 7.5l3.55-3.55q.5-.5 1.075-.725T9.8 3t1.175.225t1.075.725l-2.3 2.3L11 7.5l-.7.7L12 9.9l2.25-2.25q-.1-.275-.162-.575t-.063-.6q0-1.475 1.013-2.488t2.487-1.012q.375 0 .713.075t.687.225L16.45 5.75l1.8 1.8l2.475-2.475q.175.35.238.687t.062.713q0 1.475-1.012 2.488t-2.488 1.012q-.3 0-.6-.05t-.575-.175z"/></svg>

After

Width:  |  Height:  |  Size: 645 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE --><path fill="white" d="M4 21v-9.375L2.2 13L1 11.4L12 3l11 8.4l-1.2 1.575l-1.8-1.35V21zm4-6q-.425 0-.712-.288T7 14t.288-.712T8 13t.713.288T9 14t-.288.713T8 15m4 0q-.425 0-.712-.288T11 14t.288-.712T12 13t.713.288T13 14t-.288.713T12 15m4 0q-.425 0-.712-.288T15 14t.288-.712T16 13t.713.288T17 14t-.288.713T16 15"/></svg>

After

Width:  |  Height:  |  Size: 514 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE --><path fill="white" d="M20 15v-5q0-1.25-.875-2.125T17 7H6V4q0-.825.588-1.412T8 2h12q.825 0 1.413.588T22 4v9q0 .825-.587 1.413T20 15M4 22q-.825 0-1.412-.587T2 20v-9q0-.825.588-1.412T4 9h12q.825 0 1.413.588T18 11v9q0 .825-.587 1.413T16 22z"/></svg>

After

Width:  |  Height:  |  Size: 444 B

View File

@@ -44,8 +44,12 @@ impl<S> GuiPanel<S> {
pub fn new_from_template(app: &mut AppState, path: &str, state: S) -> anyhow::Result<Self> { pub fn new_from_template(app: &mut AppState, path: &str, state: S) -> anyhow::Result<Self> {
let mut listeners = EventListenerCollection::<AppState, S>::default(); let mut listeners = EventListenerCollection::<AppState, S>::default();
let (layout, parser_state) = let (layout, parser_state) = wgui::parser::new_layout_from_assets(
wgui::parser::new_layout_from_assets(app.wgui_globals.clone(), &mut listeners, path)?; app.wgui_globals.clone(),
&mut listeners,
path,
false,
)?;
let context = WguiContext::new(&mut app.wgui_shared, 1.0)?; let context = WguiContext::new(&mut app.wgui_shared, 1.0)?;
let mut timestep = Timestep::new(); let mut timestep = Timestep::new();

View File

@@ -79,6 +79,7 @@ where
app.wgui_globals.clone(), app.wgui_globals.clone(),
&mut panel.listeners, &mut panel.listeners,
"gui/keyboard.xml", "gui/keyboard.xml",
false,
)?; )?;
for row in 0..layout.key_sizes.len() { for row in 0..layout.key_sizes.len() {
@@ -163,6 +164,7 @@ where
&mut panel.listeners, &mut panel.listeners,
div, div,
params, params,
false,
)?; )?;
if let Some(widget_id) = gui_state_key.ids.get(&*my_id) { if let Some(widget_id) = gui_state_key.ids.get(&*my_id) {