diff --git a/wayvr/src/gui/panel/mod.rs b/wayvr/src/gui/panel/mod.rs index 85e9c6cc..dc8d3a3b 100644 --- a/wayvr/src/gui/panel/mod.rs +++ b/wayvr/src/gui/panel/mod.rs @@ -206,7 +206,7 @@ impl GuiPanel { setup_custom_label::(&mut self.layout, &self.parser_state, elem, app); } else if let Ok(button) = self .parser_state - .fetch_component_from_widget_id_as::(elem.widget_id) + .fetch_component_from_widget_id_as::(&self.layout.state, elem.widget_id) { setup_custom_button::( &mut self.layout, diff --git a/wayvr/src/overlays/edit/mod.rs b/wayvr/src/overlays/edit/mod.rs index 621d884c..0d8ccd0c 100644 --- a/wayvr/src/overlays/edit/mod.rs +++ b/wayvr/src/overlays/edit/mod.rs @@ -373,7 +373,7 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result { let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, parser, attribs, _app| { let Ok(button) = - parser.fetch_component_from_widget_id_as::(attribs.widget_id) + parser.fetch_component_from_widget_id_as::(&layout.state, attribs.widget_id) else { return; }; diff --git a/wayvr/src/overlays/wayvr.rs b/wayvr/src/overlays/wayvr.rs index 4531ea30..92634c24 100644 --- a/wayvr/src/overlays/wayvr.rs +++ b/wayvr/src/overlays/wayvr.rs @@ -205,7 +205,7 @@ impl WvrWindowBackend { let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, parser, attribs, _app| { let Ok(button) = - parser.fetch_component_from_widget_id_as::(attribs.widget_id) + parser.fetch_component_from_widget_id_as::(&layout.state, attribs.widget_id) else { return; }; diff --git a/wayvr/src/overlays/whisper.rs b/wayvr/src/overlays/whisper.rs index 10e3c615..fec62f40 100644 --- a/wayvr/src/overlays/whisper.rs +++ b/wayvr/src/overlays/whisper.rs @@ -96,7 +96,7 @@ pub fn create_whisper( let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, parser, attribs, _app| { let Ok(button) = - parser.fetch_component_from_widget_id_as::(attribs.widget_id) + parser.fetch_component_from_widget_id_as::(&layout.state, attribs.widget_id) else { return; }; diff --git a/wgui/src/layout.rs b/wgui/src/layout.rs index afab62a5..23a57f0b 100644 --- a/wgui/src/layout.rs +++ b/wgui/src/layout.rs @@ -128,6 +128,7 @@ pub struct LayoutState { pub widgets: WidgetMap, pub nodes: WidgetNodeMap, pub tree: taffy::tree::TaffyTree, + pub components_by_widget_id: SecondaryMap, } pub struct ModifyLayoutStateData<'a> { @@ -553,6 +554,7 @@ impl Layout { nodes: WidgetNodeMap::default(), globals, theme: params.theme, + components_by_widget_id: SecondaryMap::default(), }; let size = if params.resize_to_parent { @@ -989,4 +991,27 @@ impl LayoutState { pub fn get_widget_style(&self, id: WidgetID) -> Option<&taffy::Style> { self.get_node_style(*self.nodes.get(id)?) } + + pub fn fetch_component_by_widget_id(&self, widget_id: WidgetID) -> anyhow::Result { + let Some(weak) = self.components_by_widget_id.get(widget_id) else { + anyhow::bail!("Component by widget ID \"{widget_id:?}\" doesn't exist"); + }; + + let Some(component) = weak.upgrade() else { + anyhow::bail!("Component by widget ID \"{widget_id:?}\" has disappeared"); + }; + + Ok(Component(component)) + } + + pub fn fetch_component_from_widget_id_as(&self, widget_id: WidgetID) -> anyhow::Result> { + let component = self.fetch_component_by_widget_id(widget_id)?; + + if !(*component.0).as_any().is::() { + anyhow::bail!("fetch_component_from_widget_id_as({widget_id:?}): type not matching"); + } + + // safety: we just checked the type + unsafe { Ok(Rc::from_raw(Rc::into_raw(component.0).cast())) } + } } diff --git a/wgui/src/parser/component_checkbox.rs b/wgui/src/parser/component_checkbox.rs index 3f011422..d844bcdc 100644 --- a/wgui/src/parser/component_checkbox.rs +++ b/wgui/src/parser/component_checkbox.rs @@ -3,7 +3,7 @@ use crate::{ i18n::Translation, layout::WidgetID, parser::{ - AttribPair, Fetchable, ParserContext, + AttribPair, ParserContext, helpers::{TooltipAttribs, parse_attrib_tooltip}, process_component, style::parse_style, @@ -66,7 +66,8 @@ pub fn parse_component_checkbox( while let Some(parent_id) = maybe_parent_id { if let Ok(radio) = ctx - .data_local + .layout + .state .fetch_component_from_widget_id_as::(parent_id) { radio_group = Some(radio); diff --git a/wgui/src/parser/mod.rs b/wgui/src/parser/mod.rs index 0630a0e9..026e52cc 100644 --- a/wgui/src/parser/mod.rs +++ b/wgui/src/parser/mod.rs @@ -79,7 +79,6 @@ struct ParserFile { #[derive(Default, Clone)] pub struct ParserData { pub components_by_id: HashMap, ComponentWeak>, - pub components_by_widget_id: HashMap, pub components: Vec, pub ids: HashMap, WidgetID>, pub templates: HashMap, Rc