mirror of https://github.com/wayvr-org/wayvr.git
refactor components_by_widget_id
This commit is contained in:
parent
fd8a327395
commit
acaabead52
|
|
@ -206,7 +206,7 @@ impl<S: 'static> GuiPanel<S> {
|
||||||
setup_custom_label::<S>(&mut self.layout, &self.parser_state, elem, app);
|
setup_custom_label::<S>(&mut self.layout, &self.parser_state, elem, app);
|
||||||
} else if let Ok(button) = self
|
} else if let Ok(button) = self
|
||||||
.parser_state
|
.parser_state
|
||||||
.fetch_component_from_widget_id_as::<ComponentButton>(elem.widget_id)
|
.fetch_component_from_widget_id_as::<ComponentButton>(&self.layout.state, elem.widget_id)
|
||||||
{
|
{
|
||||||
setup_custom_button::<S>(
|
setup_custom_button::<S>(
|
||||||
&mut self.layout,
|
&mut self.layout,
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,7 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result<EditModeWrapPanel> {
|
||||||
|
|
||||||
let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, parser, attribs, _app| {
|
let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, parser, attribs, _app| {
|
||||||
let Ok(button) =
|
let Ok(button) =
|
||||||
parser.fetch_component_from_widget_id_as::<ComponentButton>(attribs.widget_id)
|
parser.fetch_component_from_widget_id_as::<ComponentButton>(&layout.state, attribs.widget_id)
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ impl WvrWindowBackend {
|
||||||
let on_custom_attrib: OnCustomAttribFunc =
|
let on_custom_attrib: OnCustomAttribFunc =
|
||||||
Box::new(move |layout, parser, attribs, _app| {
|
Box::new(move |layout, parser, attribs, _app| {
|
||||||
let Ok(button) =
|
let Ok(button) =
|
||||||
parser.fetch_component_from_widget_id_as::<ComponentButton>(attribs.widget_id)
|
parser.fetch_component_from_widget_id_as::<ComponentButton>(&layout.state, attribs.widget_id)
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ pub fn create_whisper(
|
||||||
|
|
||||||
let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, parser, attribs, _app| {
|
let on_custom_attrib: OnCustomAttribFunc = Box::new(move |layout, parser, attribs, _app| {
|
||||||
let Ok(button) =
|
let Ok(button) =
|
||||||
parser.fetch_component_from_widget_id_as::<ComponentButton>(attribs.widget_id)
|
parser.fetch_component_from_widget_id_as::<ComponentButton>(&layout.state, attribs.widget_id)
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,7 @@ pub struct LayoutState {
|
||||||
pub widgets: WidgetMap,
|
pub widgets: WidgetMap,
|
||||||
pub nodes: WidgetNodeMap,
|
pub nodes: WidgetNodeMap,
|
||||||
pub tree: taffy::tree::TaffyTree<WidgetID>,
|
pub tree: taffy::tree::TaffyTree<WidgetID>,
|
||||||
|
pub components_by_widget_id: SecondaryMap<WidgetID, ComponentWeak>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ModifyLayoutStateData<'a> {
|
pub struct ModifyLayoutStateData<'a> {
|
||||||
|
|
@ -553,6 +554,7 @@ impl Layout {
|
||||||
nodes: WidgetNodeMap::default(),
|
nodes: WidgetNodeMap::default(),
|
||||||
globals,
|
globals,
|
||||||
theme: params.theme,
|
theme: params.theme,
|
||||||
|
components_by_widget_id: SecondaryMap::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let size = if params.resize_to_parent {
|
let size = if params.resize_to_parent {
|
||||||
|
|
@ -989,4 +991,27 @@ impl LayoutState {
|
||||||
pub fn get_widget_style(&self, id: WidgetID) -> Option<&taffy::Style> {
|
pub fn get_widget_style(&self, id: WidgetID) -> Option<&taffy::Style> {
|
||||||
self.get_node_style(*self.nodes.get(id)?)
|
self.get_node_style(*self.nodes.get(id)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fetch_component_by_widget_id(&self, widget_id: WidgetID) -> anyhow::Result<Component> {
|
||||||
|
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<T: 'static>(&self, widget_id: WidgetID) -> anyhow::Result<Rc<T>> {
|
||||||
|
let component = self.fetch_component_by_widget_id(widget_id)?;
|
||||||
|
|
||||||
|
if !(*component.0).as_any().is::<T>() {
|
||||||
|
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())) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use crate::{
|
||||||
i18n::Translation,
|
i18n::Translation,
|
||||||
layout::WidgetID,
|
layout::WidgetID,
|
||||||
parser::{
|
parser::{
|
||||||
AttribPair, Fetchable, ParserContext,
|
AttribPair, ParserContext,
|
||||||
helpers::{TooltipAttribs, parse_attrib_tooltip},
|
helpers::{TooltipAttribs, parse_attrib_tooltip},
|
||||||
process_component,
|
process_component,
|
||||||
style::parse_style,
|
style::parse_style,
|
||||||
|
|
@ -66,7 +66,8 @@ pub fn parse_component_checkbox(
|
||||||
|
|
||||||
while let Some(parent_id) = maybe_parent_id {
|
while let Some(parent_id) = maybe_parent_id {
|
||||||
if let Ok(radio) = ctx
|
if let Ok(radio) = ctx
|
||||||
.data_local
|
.layout
|
||||||
|
.state
|
||||||
.fetch_component_from_widget_id_as::<ComponentRadioGroup>(parent_id)
|
.fetch_component_from_widget_id_as::<ComponentRadioGroup>(parent_id)
|
||||||
{
|
{
|
||||||
radio_group = Some(radio);
|
radio_group = Some(radio);
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,6 @@ struct ParserFile {
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct ParserData {
|
pub struct ParserData {
|
||||||
pub components_by_id: HashMap<Rc<str>, ComponentWeak>,
|
pub components_by_id: HashMap<Rc<str>, ComponentWeak>,
|
||||||
pub components_by_widget_id: HashMap<WidgetID, ComponentWeak>,
|
|
||||||
pub components: Vec<Component>,
|
pub components: Vec<Component>,
|
||||||
pub ids: HashMap<Rc<str>, WidgetID>,
|
pub ids: HashMap<Rc<str>, WidgetID>,
|
||||||
pub templates: HashMap<Rc<str>, Rc<Template>>,
|
pub templates: HashMap<Rc<str>, Rc<Template>>,
|
||||||
|
|
@ -91,14 +90,14 @@ pub trait Fetchable {
|
||||||
/// Return a component by its string ID
|
/// Return a component by its string ID
|
||||||
fn fetch_component_by_id(&self, id: &str) -> anyhow::Result<Component>;
|
fn fetch_component_by_id(&self, id: &str) -> anyhow::Result<Component>;
|
||||||
|
|
||||||
/// Return a component by the ID of the widget that owns it
|
/// Fetch a component by widget ID (returns Component)
|
||||||
fn fetch_component_by_widget_id(&self, widget_id: WidgetID) -> anyhow::Result<Component>;
|
fn fetch_component_by_widget_id(&self, state: &LayoutState, widget_id: WidgetID) -> anyhow::Result<Component>;
|
||||||
|
|
||||||
/// Fetch a component by string ID and down‑cast it to a concrete component type `T` (see `components/mod.rs`)
|
/// Fetch a component by string ID and down‑cast it to a concrete component type `T` (see `components/mod.rs`)
|
||||||
fn fetch_component_as<T: 'static>(&self, id: &str) -> anyhow::Result<Rc<T>>;
|
fn fetch_component_as<T: 'static>(&self, id: &str) -> anyhow::Result<Rc<T>>;
|
||||||
|
|
||||||
/// Fetch a component by widget ID and down‑cast it to a concrete component type `T` (see `components/mod.rs`)
|
/// Fetch a component by widget ID and down‑cast it to a concrete component type `T` (see `components/mod.rs`)
|
||||||
fn fetch_component_from_widget_id_as<T: 'static>(&self, widget_id: WidgetID) -> anyhow::Result<Rc<T>>;
|
fn fetch_component_from_widget_id_as<T: 'static>(&self, state: &LayoutState, widget_id: WidgetID) -> anyhow::Result<Rc<T>>;
|
||||||
|
|
||||||
/// Return a widget by its string ID
|
/// Return a widget by its string ID
|
||||||
fn get_widget_id(&self, id: &str) -> anyhow::Result<WidgetID>;
|
fn get_widget_id(&self, id: &str) -> anyhow::Result<WidgetID>;
|
||||||
|
|
@ -137,7 +136,6 @@ impl ParserData {
|
||||||
let ids = std::mem::take(&mut from.ids);
|
let ids = std::mem::take(&mut from.ids);
|
||||||
let components = std::mem::take(&mut from.components);
|
let components = std::mem::take(&mut from.components);
|
||||||
let components_by_id = std::mem::take(&mut from.components_by_id);
|
let components_by_id = std::mem::take(&mut from.components_by_id);
|
||||||
let components_by_widget_id = std::mem::take(&mut from.components_by_widget_id);
|
|
||||||
|
|
||||||
for (id, key) in ids {
|
for (id, key) in ids {
|
||||||
self.ids.insert(id, key);
|
self.ids.insert(id, key);
|
||||||
|
|
@ -150,10 +148,6 @@ impl ParserData {
|
||||||
for (k, v) in components_by_id {
|
for (k, v) in components_by_id {
|
||||||
self.components_by_id.insert(k, v);
|
self.components_by_id.insert(k, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k, v) in components_by_widget_id {
|
|
||||||
self.components_by_widget_id.insert(k, v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,16 +164,12 @@ impl Fetchable for ParserData {
|
||||||
Ok(Component(component))
|
Ok(Component(component))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_component_by_widget_id(&self, widget_id: WidgetID) -> anyhow::Result<Component> {
|
fn fetch_component_by_widget_id(&self, state: &LayoutState, widget_id: WidgetID) -> anyhow::Result<Component> {
|
||||||
let Some(weak) = self.components_by_widget_id.get(&widget_id) else {
|
state.fetch_component_by_widget_id(widget_id)
|
||||||
anyhow::bail!("Component by widget ID \"{widget_id:?}\" doesn't exist");
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let Some(component) = weak.upgrade() else {
|
fn fetch_component_from_widget_id_as<T: 'static>(&self, state: &LayoutState, widget_id: WidgetID) -> anyhow::Result<Rc<T>> {
|
||||||
anyhow::bail!("Component by widget ID \"{widget_id:?}\" has disappeared");
|
state.fetch_component_from_widget_id_as(widget_id)
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Component(component))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_component_as<T: 'static>(&self, id: &str) -> anyhow::Result<Rc<T>> {
|
fn fetch_component_as<T: 'static>(&self, id: &str) -> anyhow::Result<Rc<T>> {
|
||||||
|
|
@ -193,17 +183,6 @@ impl Fetchable for ParserData {
|
||||||
unsafe { Ok(Rc::from_raw(Rc::into_raw(component.0).cast())) }
|
unsafe { Ok(Rc::from_raw(Rc::into_raw(component.0).cast())) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_component_from_widget_id_as<T: 'static>(&self, widget_id: WidgetID) -> anyhow::Result<Rc<T>> {
|
|
||||||
let component = self.fetch_component_by_widget_id(widget_id)?;
|
|
||||||
|
|
||||||
if !(*component.0).as_any().is::<T>() {
|
|
||||||
anyhow::bail!("fetch_component_by_widget_id({widget_id:?}): type not matching");
|
|
||||||
}
|
|
||||||
|
|
||||||
// safety: we just checked the type
|
|
||||||
unsafe { Ok(Rc::from_raw(Rc::into_raw(component.0).cast())) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_widget_id(&self, id: &str) -> anyhow::Result<WidgetID> {
|
fn get_widget_id(&self, id: &str) -> anyhow::Result<WidgetID> {
|
||||||
match self.ids.get(id) {
|
match self.ids.get(id) {
|
||||||
Some(id) => Ok(*id),
|
Some(id) => Ok(*id),
|
||||||
|
|
@ -398,18 +377,18 @@ impl Fetchable for ParserState {
|
||||||
self.data.fetch_component_by_id(id)
|
self.data.fetch_component_by_id(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_component_by_widget_id(&self, widget_id: WidgetID) -> anyhow::Result<Component> {
|
fn fetch_component_by_widget_id(&self, state: &LayoutState, widget_id: WidgetID) -> anyhow::Result<Component> {
|
||||||
self.data.fetch_component_by_widget_id(widget_id)
|
self.data.fetch_component_by_widget_id(state, widget_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_component_from_widget_id_as<T: 'static>(&self, state: &LayoutState, widget_id: WidgetID) -> anyhow::Result<Rc<T>> {
|
||||||
|
self.data.fetch_component_from_widget_id_as(state, widget_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_component_as<T: 'static>(&self, id: &str) -> anyhow::Result<Rc<T>> {
|
fn fetch_component_as<T: 'static>(&self, id: &str) -> anyhow::Result<Rc<T>> {
|
||||||
self.data.fetch_component_as(id)
|
self.data.fetch_component_as(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_component_from_widget_id_as<T: 'static>(&self, widget_id: WidgetID) -> anyhow::Result<Rc<T>> {
|
|
||||||
self.data.fetch_component_from_widget_id_as(widget_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_widget_id(&self, id: &str) -> anyhow::Result<WidgetID> {
|
fn get_widget_id(&self, id: &str) -> anyhow::Result<WidgetID> {
|
||||||
self.data.get_widget_id(id)
|
self.data.get_widget_id(id)
|
||||||
}
|
}
|
||||||
|
|
@ -499,7 +478,8 @@ impl ParserContext<'_> {
|
||||||
|
|
||||||
fn insert_component(&mut self, widget_id: WidgetID, component: Component, id: Option<Rc<str>>) {
|
fn insert_component(&mut self, widget_id: WidgetID, component: Component, id: Option<Rc<str>>) {
|
||||||
self
|
self
|
||||||
.data_local
|
.layout
|
||||||
|
.state
|
||||||
.components_by_widget_id
|
.components_by_widget_id
|
||||||
.insert(widget_id, component.weak());
|
.insert(widget_id, component.weak());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue