wgui: interactable components, rename TextLabel -> WidgetLabel

This commit is contained in:
Aleksander
2025-08-10 11:46:01 +02:00
parent 91e584383f
commit 93a3fee349
26 changed files with 294 additions and 174 deletions

View File

@@ -1,5 +1,5 @@
use crate::{
components::button,
components::{Component, button},
drawing::Color,
i18n::Translation,
layout::WidgetID,
@@ -69,7 +69,7 @@ pub fn parse_component_button<'a, U1, U2>(
},
)?;
process_component(file, ctx, node, component)?;
process_component(file, ctx, node, Component(component))?;
Ok(())
}

View File

@@ -1,5 +1,5 @@
use crate::{
components::slider,
components::{Component, slider},
layout::WidgetID,
parser::{
ParserContext, ParserFile, iter_attribs, parse_check_f32, process_component, style::parse_style,
@@ -48,7 +48,7 @@ pub fn parse_component_slider<'a, U1, U2>(
},
)?;
process_component(file, ctx, node, component)?;
process_component(file, ctx, node, Component(component))?;
Ok(())
}

View File

@@ -7,13 +7,12 @@ mod widget_rectangle;
mod widget_sprite;
use crate::{
any::AnyTrait,
assets::AssetProvider,
components::Component,
components::{Component, ComponentTrait, ComponentWeak},
drawing::{self},
event::EventListenerCollection,
globals::WguiGlobals,
layout::{Layout, WidgetID},
layout::{Layout, LayoutState, Widget, WidgetID},
parser::{
component_button::parse_component_button, component_slider::parse_component_slider,
widget_div::parse_widget_div, widget_label::parse_widget_label,
@@ -56,14 +55,14 @@ pub struct ParserState {
pub ids: HashMap<Rc<str>, WidgetID>,
macro_attribs: HashMap<Rc<str>, MacroAttribs>,
pub var_map: HashMap<Rc<str>, Rc<str>>,
pub components: Vec<Rc<dyn Component>>,
pub components_id_map: HashMap<Rc<str>, std::rc::Weak<dyn Component>>,
pub components: Vec<Component>,
pub components_id_map: HashMap<Rc<str>, std::rc::Weak<dyn ComponentTrait>>,
pub templates: HashMap<Rc<str>, Rc<Template>>,
pub path: PathBuf,
}
impl ParserState {
pub fn fetch_component(&self, id: &str) -> anyhow::Result<Rc<dyn Component>> {
pub fn fetch_component(&self, id: &str) -> anyhow::Result<Component> {
let Some(weak) = self.components_id_map.get(id) else {
anyhow::bail!("Component by ID \"{}\" doesn't exist", id);
};
@@ -72,27 +71,36 @@ impl ParserState {
anyhow::bail!("Component by ID \"{}\" doesn't exist", id);
};
Ok(component)
Ok(Component(component))
}
pub fn fetch_component_as<T: 'static>(&self, id: &str) -> anyhow::Result<Rc<T>> {
let component = self.fetch_component(id)?;
// FIXME: check T type id
log::warn!("fetch_component_as WIP");
unsafe {
let raw = Rc::into_raw(component);
Ok(Rc::from_raw(raw as _))
if !(*component.0).as_any().is::<T>() {
anyhow::bail!("fetch_component_as({}): type not matching", id);
}
// safety: we already checked it above, should be safe to directly cast it
unsafe { Ok(Rc::from_raw(Rc::into_raw(component.0) as _)) }
}
pub fn fetch_widget(&self, id: &str) -> anyhow::Result<WidgetID> {
pub fn get_widget_id(&self, id: &str) -> anyhow::Result<WidgetID> {
match self.ids.get(id) {
Some(id) => Ok(*id),
None => anyhow::bail!("Widget by ID \"{}\" doesn't exist", id),
}
}
pub fn fetch_widget<T: 'static>(&self, state: &LayoutState, id: &str) -> anyhow::Result<Widget> {
let widget_id = self.get_widget_id(id)?;
let widget = state
.widgets
.get(widget_id)
.ok_or_else(|| anyhow::anyhow!("fetch_widget_as({}): widget not found", id))?;
Ok(widget.clone())
}
pub fn process_template<U1, U2>(
&mut self,
template_name: &str,
@@ -153,8 +161,8 @@ struct ParserContext<'a, U1, U2> {
macro_attribs: HashMap<Rc<str>, MacroAttribs>,
ids: HashMap<Rc<str>, WidgetID>,
templates: HashMap<Rc<str>, Rc<Template>>,
components: Vec<Rc<dyn Component>>,
components_id_map: HashMap<Rc<str>, std::rc::Weak<dyn Component>>,
components: Vec<Component>,
components_id_map: HashMap<Rc<str>, ComponentWeak>,
dev_mode: bool,
}
@@ -561,7 +569,7 @@ fn process_component<'a, U1, U2>(
file: &'a ParserFile,
ctx: &mut ParserContext<U1, U2>,
node: roxmltree::Node<'a, 'a>,
component: Rc<dyn Component>,
component: Component,
) -> anyhow::Result<()> {
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
@@ -571,7 +579,7 @@ fn process_component<'a, U1, U2>(
"id" => {
if ctx
.components_id_map
.insert(value.clone(), Rc::downgrade(&component))
.insert(value.clone(), component.weak())
.is_some()
{
log::warn!("duplicate component ID \"{value}\" in the same layout file!");

View File

@@ -1,7 +1,8 @@
use crate::{
layout::WidgetID,
parser::{
ParserContext, ParserFile, iter_attribs, parse_children, parse_widget_universal, style::parse_style,
ParserContext, ParserFile, iter_attribs, parse_children, parse_widget_universal,
style::parse_style,
},
widget,
};
@@ -17,7 +18,7 @@ pub fn parse_widget_div<'a, U1, U2>(
let (new_id, _) = ctx
.layout
.add_child(parent_id, widget::div::Div::create()?, style)?;
.add_child(parent_id, widget::div::WidgetDiv::create()?, style)?;
parse_widget_universal(file, ctx, node, new_id)?;
parse_children(file, ctx, node, new_id)?;

View File

@@ -5,7 +5,7 @@ use crate::{
ParserContext, ParserFile, iter_attribs, parse_children, parse_widget_universal,
style::{parse_style, parse_text_style},
},
widget::text::{TextLabel, TextParams},
widget::label::{WidgetLabelParams, WidgetLabel},
};
pub fn parse_widget_label<'a, U1, U2>(
@@ -14,7 +14,7 @@ pub fn parse_widget_label<'a, U1, U2>(
node: roxmltree::Node<'a, 'a>,
parent_id: WidgetID,
) -> anyhow::Result<()> {
let mut params = TextParams::default();
let mut params = WidgetLabelParams::default();
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
let style = parse_style(&attribs);
@@ -36,7 +36,7 @@ pub fn parse_widget_label<'a, U1, U2>(
let (new_id, _) =
ctx
.layout
.add_child(parent_id, TextLabel::create(&mut i18n, params)?, style)?;
.add_child(parent_id, WidgetLabel::create(&mut i18n, params)?, style)?;
parse_widget_universal(file, ctx, node, new_id)?;
parse_children(file, ctx, node, new_id)?;

View File

@@ -6,7 +6,7 @@ use crate::{
print_invalid_attrib,
style::{parse_color, parse_round, parse_style},
},
widget::{self, rectangle::RectangleParams},
widget::{self, rectangle::WidgetRectangleParams},
};
pub fn parse_widget_rectangle<'a, U1, U2>(
@@ -15,7 +15,7 @@ pub fn parse_widget_rectangle<'a, U1, U2>(
node: roxmltree::Node<'a, 'a>,
parent_id: WidgetID,
) -> anyhow::Result<()> {
let mut params = RectangleParams::default();
let mut params = WidgetRectangleParams::default();
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
let style = parse_style(&attribs);
@@ -57,7 +57,7 @@ pub fn parse_widget_rectangle<'a, U1, U2>(
let (new_id, _) = ctx.layout.add_child(
parent_id,
widget::rectangle::Rectangle::create(params)?,
widget::rectangle::WidgetRectangle::create(params)?,
style,
)?;

View File

@@ -5,7 +5,7 @@ use crate::{
style::parse_style,
},
renderer_vk::text::custom_glyph::{CustomGlyphContent, CustomGlyphData},
widget::sprite::{SpriteBox, SpriteBoxParams},
widget::sprite::{WidgetSprite, WidgetSpriteParams},
};
use super::{parse_color_hex, print_invalid_attrib};
@@ -16,7 +16,7 @@ pub fn parse_widget_sprite<'a, U1, U2>(
node: roxmltree::Node<'a, 'a>,
parent_id: WidgetID,
) -> anyhow::Result<()> {
let mut params = SpriteBoxParams::default();
let mut params = WidgetSpriteParams::default();
let attribs: Vec<_> = iter_attribs(file, ctx, &node, false).collect();
let style = parse_style(&attribs);
@@ -57,7 +57,7 @@ pub fn parse_widget_sprite<'a, U1, U2>(
let (new_id, _) = ctx
.layout
.add_child(parent_id, SpriteBox::create(params)?, style)?;
.add_child(parent_id, WidgetSprite::create(params)?, style)?;
parse_widget_universal(file, ctx, node, new_id)?;
parse_children(file, ctx, node, new_id)?;