From 654bb95f90d0bbe195a65808d9408f184ccbec8b Mon Sep 17 00:00:00 2001 From: Byson94 Date: Mon, 18 Aug 2025 11:14:32 +0530 Subject: [PATCH] feat: did some stuff that could possible make create widget work --- crates/ewwii/src/app.rs | 4 +- .../ewwii/src/widgets/widget_definitions.rs | 33 ++++--- crates/iirhai/src/widgetnode.rs | 99 ++++++++++++------- examples/data-structures/ewwii.rhai | 3 - 4 files changed, 90 insertions(+), 49 deletions(-) diff --git a/crates/ewwii/src/app.rs b/crates/ewwii/src/app.rs index f7883dd..3e429db 100644 --- a/crates/ewwii/src/app.rs +++ b/crates/ewwii/src/app.rs @@ -330,7 +330,7 @@ impl App { root_widget.style_context().add_class(window_name); let monitor = get_gdk_monitor(initiator.monitor.clone())?; - let mut ewwii_window = initialize_window::(&initiator, monitor, root_widget)?; + let mut ewwii_window = initialize_window::(&initiator, monitor, root_widget.clone())?; ewwii_window.gtk_window.style_context().add_class(window_name); // listening/polling @@ -345,7 +345,7 @@ impl App { match generate_new_widgetnode(&vars, &config_path).await { Ok(new_widget) => { - let _ = widget_reg_store.update_widget_tree(new_widget); + let _ = widget_reg_store.update_widget_tree(new_widget, root_widget.clone()); } Err(e) => { log::error!("Failed to generate new widgetnode: {:#}", e); diff --git a/crates/ewwii/src/widgets/widget_definitions.rs b/crates/ewwii/src/widgets/widget_definitions.rs index 754bd34..87a59b8 100644 --- a/crates/ewwii/src/widgets/widget_definitions.rs +++ b/crates/ewwii/src/widgets/widget_definitions.rs @@ -63,7 +63,7 @@ pub struct WidgetRegistry { } pub enum PatchGtkWidget { - Create(WidgetNode), + Create(WidgetNode, u64), Update(u64, Map), Remove(u64), } @@ -73,15 +73,13 @@ impl WidgetRegistry { Self { widgets: HashMap::new(), stored_widget_node: wn.cloned() } } - pub fn update_widget_tree(&mut self, new_tree: WidgetNode) -> Result<(), anyhow::Error> { + pub fn update_widget_tree(&mut self, new_tree: WidgetNode, root_widget: gtk::Widget) -> Result<()> { let old_tree = self.stored_widget_node.take(); - let patch = Self::diff_trees(old_tree.as_ref(), &new_tree); + let patch = Self::diff_trees(old_tree.as_ref(), &new_tree, root_widget); for op in patch { match op { - PatchGtkWidget::Create(w_node) => { - build_gtk_widget(WidgetInput::Node(w_node), self)?; - } + PatchGtkWidget::Create(w_node, parent_id) => self.create_widget(w_node, parent_id).expect("failed to create new gtk widget"), PatchGtkWidget::Update(widget_id, new_props) => { self.update_props(widget_id, new_props); } @@ -93,26 +91,25 @@ impl WidgetRegistry { Ok(()) } - pub fn diff_trees(old: Option<&WidgetNode>, new: &WidgetNode) -> Vec { + pub fn diff_trees(old: Option<&WidgetNode>, new: &WidgetNode, root_widget: gtk::Widget) -> Vec { let mut patch = Vec::new(); let mut old_map = HashMap::new(); if let Some(old_node) = old { - let _ = get_id_to_widget_info(old_node, &mut old_map); + let _ = get_id_to_widget_info(old_node, &mut old_map, None); } let mut new_map = HashMap::new(); - let _ = get_id_to_widget_info(new, &mut new_map); + let _ = get_id_to_widget_info(new, &mut new_map, None); // Updates and creations for (id, new_info) in &new_map { match old_map.get(id) { Some(old_info) if props_differ(&old_info.props, &new_info.props) => { - log::debug!("Widget {} props changed: {:?}", id, new_info.props); patch.push(PatchGtkWidget::Update(*id, new_info.props.clone())); } None => { - patch.push(PatchGtkWidget::Create(new_info.node.clone())); + patch.push(PatchGtkWidget::Create(new_info.node.clone(), new_info.parent_id.expect("Parent ID must exist"))); } _ => {} } @@ -128,6 +125,20 @@ impl WidgetRegistry { patch } + pub fn create_widget(&mut self, widget_node: WidgetNode, parent_id: u64) -> Result<()> { + if let Some(parent) = self.widgets.get(&parent_id) { + let parent_widget = parent.widget.clone(); + + let gtk_widget = build_gtk_widget(WidgetInput::Node(widget_node.clone()), self)?; + + if let Some(container) = parent_widget.dynamic_cast::().ok() { + container.add(>k_widget); + } + } + + Ok(()) + } + pub fn update_props(&self, widget_id: u64, new_props: Map) { if let Some(entry) = self.widgets.get(&widget_id) { (entry.update_fn)(&new_props); diff --git a/crates/iirhai/src/widgetnode.rs b/crates/iirhai/src/widgetnode.rs index f3044b8..911700a 100644 --- a/crates/iirhai/src/widgetnode.rs +++ b/crates/iirhai/src/widgetnode.rs @@ -45,105 +45,131 @@ pub struct WidgetInfo { pub props: Map, pub widget_type: String, pub children: Vec, + pub parent_id: Option } -pub fn get_id_to_widget_info(node: &WidgetNode, id_to_props: &mut HashMap) -> Result<()> { +pub fn get_id_to_widget_info( + node: &WidgetNode, + id_to_props: &mut HashMap, + parent_id: Option, +) -> Result<()> { match node { WidgetNode::Box { props, children } => { - insert_wdgt_info(node, props, "Box", children.clone(), id_to_props)?; + let id = hash_props_and_type(props, "Box"); + insert_wdgt_info(node, props, "Box", children.clone(), parent_id, id_to_props)?; for child in children { - get_id_to_widget_info(child, id_to_props)?; + get_id_to_widget_info(child, id_to_props, Some(id))?; } } WidgetNode::CenterBox { props, children } => { - insert_wdgt_info(node, props, "CenterBox", children.clone(), id_to_props)?; + let id = hash_props_and_type(props, "CenterBox"); + insert_wdgt_info(node, props, "CenterBox", children.clone(), parent_id, id_to_props)?; for child in children { - get_id_to_widget_info(child, id_to_props)?; + get_id_to_widget_info(child, id_to_props, Some(id))?; } } WidgetNode::EventBox { props, children } => { - insert_wdgt_info(node, props, "EventBox", children.clone(), id_to_props)?; + let id = hash_props_and_type(props, "EventBox"); + insert_wdgt_info(node, props, "EventBox", children.clone(), parent_id, id_to_props)?; for child in children { - get_id_to_widget_info(child, id_to_props)?; + get_id_to_widget_info(child, id_to_props, Some(id))?; } } WidgetNode::CircularProgress { props } => { - insert_wdgt_info(node, props, "CircularProgress", vec![], id_to_props)?; + let id = hash_props_and_type(props, "CircularProgress"); + insert_wdgt_info(node, props, "CircularProgress", vec![], parent_id, id_to_props)?; } WidgetNode::Graph { props } => { - insert_wdgt_info(node, props, "Graph", vec![], id_to_props)?; + let id = hash_props_and_type(props, "Graph"); + insert_wdgt_info(node, props, "Graph", vec![], parent_id, id_to_props)?; } WidgetNode::Transform { props } => { - insert_wdgt_info(node, props, "Transform", vec![], id_to_props)?; + let id = hash_props_and_type(props, "Transform"); + insert_wdgt_info(node, props, "Transform", vec![], parent_id, id_to_props)?; } WidgetNode::Slider { props } => { - insert_wdgt_info(node, props, "Slider", vec![], id_to_props)?; + let id = hash_props_and_type(props, "Slider"); + insert_wdgt_info(node, props, "Slider", vec![], parent_id, id_to_props)?; } WidgetNode::Progress { props } => { - insert_wdgt_info(node, props, "Progress", vec![], id_to_props)?; + let id = hash_props_and_type(props, "Progress"); + insert_wdgt_info(node, props, "Progress", vec![], parent_id, id_to_props)?; } WidgetNode::Image { props } => { - insert_wdgt_info(node, props, "Image", vec![], id_to_props)?; + let id = hash_props_and_type(props, "Image"); + insert_wdgt_info(node, props, "Image", vec![], parent_id, id_to_props)?; } WidgetNode::Button { props } => { - insert_wdgt_info(node, props, "Button", vec![], id_to_props)?; + let id = hash_props_and_type(props, "Button"); + insert_wdgt_info(node, props, "Button", vec![], parent_id, id_to_props)?; } WidgetNode::Label { props } => { - insert_wdgt_info(node, props, "Label", vec![], id_to_props)?; + let id = hash_props_and_type(props, "Label"); + insert_wdgt_info(node, props, "Label", vec![], parent_id, id_to_props)?; } WidgetNode::Input { props } => { - insert_wdgt_info(node, props, "Input", vec![], id_to_props)?; + let id = hash_props_and_type(props, "Input"); + insert_wdgt_info(node, props, "Input", vec![], parent_id, id_to_props)?; } WidgetNode::Calendar { props } => { - insert_wdgt_info(node, props, "Calendar", vec![], id_to_props)?; + let id = hash_props_and_type(props, "Calendar"); + insert_wdgt_info(node, props, "Calendar", vec![], parent_id, id_to_props)?; } WidgetNode::ColorButton { props } => { - insert_wdgt_info(node, props, "ColorButton", vec![], id_to_props)?; + let id = hash_props_and_type(props, "ColorButton"); + insert_wdgt_info(node, props, "ColorButton", vec![], parent_id, id_to_props)?; } WidgetNode::Expander { props, children } => { - insert_wdgt_info(node, props, "Expander", children.clone(), id_to_props)?; + let id = hash_props_and_type(props, "Expander"); + insert_wdgt_info(node, props, "Expander", children.clone(), parent_id, id_to_props)?; for child in children { - get_id_to_widget_info(child, id_to_props)?; + get_id_to_widget_info(child, id_to_props, Some(id))?; } } WidgetNode::ToolTip { children } => { for child in children { - get_id_to_widget_info(child, id_to_props)?; + get_id_to_widget_info(child, id_to_props, parent_id)?; } } WidgetNode::ColorChooser { props } => { - insert_wdgt_info(node, props, "ColorChooser", vec![], id_to_props)?; + let id = hash_props_and_type(props, "ColorChooser"); + insert_wdgt_info(node, props, "ColorChooser", vec![], parent_id, id_to_props)?; } WidgetNode::ComboBoxText { props } => { - insert_wdgt_info(node, props, "ComboBoxText", vec![], id_to_props)?; + let id = hash_props_and_type(props, "ComboBoxText"); + insert_wdgt_info(node, props, "ComboBoxText", vec![], parent_id, id_to_props)?; } WidgetNode::Checkbox { props } => { - insert_wdgt_info(node, props, "Checkbox", vec![], id_to_props)?; + let id = hash_props_and_type(props, "Checkbox"); + insert_wdgt_info(node, props, "Checkbox", vec![], parent_id, id_to_props)?; } WidgetNode::Revealer { props, children } => { - insert_wdgt_info(node, props, "Revealer", children.clone(), id_to_props)?; + let id = hash_props_and_type(props, "Revealer"); + insert_wdgt_info(node, props, "Revealer", children.clone(), parent_id, id_to_props)?; for child in children { - get_id_to_widget_info(child, id_to_props)?; + get_id_to_widget_info(child, id_to_props, Some(id))?; } } WidgetNode::Scroll { props, children } => { - insert_wdgt_info(node, props, "Scroll", children.clone(), id_to_props)?; + let id = hash_props_and_type(props, "Scroll"); + insert_wdgt_info(node, props, "Scroll", children.clone(), parent_id, id_to_props)?; for child in children { - get_id_to_widget_info(child, id_to_props)?; + get_id_to_widget_info(child, id_to_props, Some(id))?; } } WidgetNode::OverLay { children } => { for child in children { - get_id_to_widget_info(child, id_to_props)?; + get_id_to_widget_info(child, id_to_props, parent_id)?; } } WidgetNode::Stack { props, children } => { - insert_wdgt_info(node, props, "Stack", children.clone(), id_to_props)?; + let id = hash_props_and_type(props, "Stack"); + insert_wdgt_info(node, props, "Stack", children.clone(), parent_id, id_to_props)?; for child in children { - get_id_to_widget_info(child, id_to_props)?; + get_id_to_widget_info(child, id_to_props, Some(id))?; } } - _ => { /* do nothinnng */ } + _ => { /* do nothing */ } } Ok(()) @@ -154,10 +180,17 @@ fn insert_wdgt_info( props: &Map, widget_type: &str, children: Vec, + parent_id: Option, id_to_info: &mut HashMap, ) -> Result<()> { let id = hash_props_and_type(props, widget_type); - let info = WidgetInfo { node: node.clone(), props: props.clone(), widget_type: widget_type.to_string(), children }; + let info = WidgetInfo { + node: node.clone(), + props: props.clone(), + widget_type: widget_type.to_string(), + children, + parent_id, + }; id_to_info.insert(id, info); Ok(()) } diff --git a/examples/data-structures/ewwii.rhai b/examples/data-structures/ewwii.rhai index 5bff634..09a8b62 100644 --- a/examples/data-structures/ewwii.rhai +++ b/examples/data-structures/ewwii.rhai @@ -16,9 +16,6 @@ let object = #{ // Widget: a single animal button fn animalButton(emoji, selected) { - print!(selected); - print!(emoji); - let class = "animal"; if selected == emoji {