diff --git a/crates/ewwii/src/app.rs b/crates/ewwii/src/app.rs index 9797707..3752a75 100644 --- a/crates/ewwii/src/app.rs +++ b/crates/ewwii/src/app.rs @@ -321,10 +321,9 @@ impl App { let initiator = WindowInitiator::new(&window_def, window_args)?; - // Holds the id and the props of a widget - // It is crutual for supporting dynamic updates + // Should hold the id and the props of a widget + // It is critical for supporting dynamic updates let mut widget_reg_store = WidgetRegistry::new(); - // note for future me: ^ this might need cloning. let root_widget = build_gtk_widget(WidgetInput::Window(window_def), &mut widget_reg_store)?; diff --git a/crates/ewwii/src/widgets/build_widget.rs b/crates/ewwii/src/widgets/build_widget.rs index a58705b..d29225e 100644 --- a/crates/ewwii/src/widgets/build_widget.rs +++ b/crates/ewwii/src/widgets/build_widget.rs @@ -24,6 +24,14 @@ pub fn build_gtk_widget(input: WidgetInput, widget_reg: &mut WidgetRegistry) -> // TODO: implement the commented lines fn build_gtk_widget_from_node(root_node: WidgetNode, widget_reg: &mut WidgetRegistry) -> Result { let root_node2 = root_node.clone(); + + /* + When a a new widget is added to the build process, + make sure to update get_id_to_props_map() found in + `iirhai/widgetnode.rs`. It is crutial to presrve + dynamic update system in ewwii. + */ + let gtk_widget = match root_node { WidgetNode::Box { props, children } => build_gtk_box(props, children, widget_reg)?.upcast(), WidgetNode::CenterBox { props, children } => build_center_box(props, children, widget_reg)?.upcast(), diff --git a/crates/ewwii/src/widgets/widget_definitions.rs b/crates/ewwii/src/widgets/widget_definitions.rs index ed5a1ee..30e2bec 100644 --- a/crates/ewwii/src/widgets/widget_definitions.rs +++ b/crates/ewwii/src/widgets/widget_definitions.rs @@ -59,6 +59,13 @@ pub struct WidgetEntry { pub struct WidgetRegistry { widgets: HashMap, + stored_widget_node: Option, +} + +pub enum PatchGtkWidget { + Create(u64, Map), + Update(u64, Map), + Remove(u64), } impl WidgetRegistry { @@ -66,7 +73,28 @@ impl WidgetRegistry { Self { widgets: HashMap::new() } } - pub fn update_prop_changes(&self, id_to_props: HashMap) { + fn diff_trees(old: Option, new: WidgetNode) -> Vec { + let mut id_to_prop = HashMap::new(); + let _ = get_id_to_props_map(&new_widget, &mut id_to_prop); + } + + pub fn update_widget_tree(&mut self, new_tree: WidgetNode) { + let old_tree = self.stored_widget_node.take(); + + let patch = diff_trees(old_tree, new_tree.clone()); + + for op in patch { + match op { + PatchGtkWidget::Create(widget_id, props) => self.create_widget(widget_id, props), + PatchGtkWidget::Update(widget_id, new_props) => self.update_props(widget_id, new_props), + PatchGtkWidget::Remove(widget_id) => self.remove_widget(widget_id), + } + } + + self.stored_widget_node = Some(new_tree); + } + + pub fn update_props(&self, id_to_props: HashMap) { for (id, props) in id_to_props { if let Some(entry) = self.widgets.get(&id) { (entry.update_fn)(&props); diff --git a/crates/iirhai/src/widgetnode.rs b/crates/iirhai/src/widgetnode.rs index 2b5420e..5913ac5 100644 --- a/crates/iirhai/src/widgetnode.rs +++ b/crates/iirhai/src/widgetnode.rs @@ -39,7 +39,14 @@ pub enum WidgetNode { Enter(Vec), } -pub fn get_id_to_props_map(root_node: &WidgetNode, id_to_props: &mut HashMap) -> Result<()> { +// Get `HashMap` +// not exactly a get function as it mutates id_to_props +// instead of returning any value. +// it sounds misleading but i cant think of a better name. +pub fn get_id_to_props_map( + root_node: &WidgetNode, + id_to_props: &mut HashMap +) -> Result<()> { match root_node { WidgetNode::Box { props, children } => { insert_props(props, "Box", id_to_props)?;