feat: moving all localsignal into a localbind wrapper

This commit is contained in:
Byson94
2025-10-30 14:59:56 +05:30
parent 425ef5020b
commit 98e370ac60
5 changed files with 89 additions and 0 deletions

View File

@@ -50,6 +50,9 @@ fn build_gtk_widget_from_node(
WidgetNode::ToolTip { props, children } => {
build_tooltip(props, children, widget_reg)?.upcast()
}
WidgetNode::LocalBind { props, children } => {
build_localbind(props, children, widget_reg)?.upcast()
}
WidgetNode::CircularProgress { props } => {
build_circular_progress_bar(props, widget_reg)?.upcast()
}

View File

@@ -13,6 +13,7 @@ use gtk4::{
};
use rhai::Map;
use rhai_impl::ast::{get_id_to_widget_info, hash_props_and_type, WidgetNode};
use rhai_impl::updates::LocalSignal;
use super::widget_definitions_helper::*;
use shared_utils::extract_props::*;
@@ -418,6 +419,78 @@ pub(super) fn build_tooltip(
Ok(gtk_widget)
}
pub(super) fn build_localbind(
props: &Map,
children: &Vec<WidgetNode>,
widget_registry: &mut WidgetRegistry,
) -> Result<gtk4::Box> {
let gtk_widget = gtk4::Box::new(gtk4::Orientation::Horizontal, 0);
let count = children.len();
if count < 1 {
bail!("localbind must contain exactly 1 child");
} else if count > 1 {
bail!("localbind must contain exactly 1 child, but got more");
}
let child_node = children.get(0).cloned().ok_or_else(|| anyhow!("missing child"))?;
let child_widget = build_gtk_widget(&WidgetInput::Node(child_node), widget_registry)?;
gtk_widget.append(&child_widget);
let bindings_variant = props.get("bindings");
if bindings_variant.is_none() {
bail!("No 'bindings' map found in props.");
}
let bindings = match bindings_variant.and_then(|v| v.clone().try_cast::<rhai::Map>()) {
Some(map) => map,
None => {
bail!("'bindings' is not a valid map.");
}
};
for (prop_name, localsignal_val) in bindings {
let prop_name = prop_name.clone();
let localsignal = match localsignal_val.clone().try_cast::<LocalSignal>() {
Some(sig) => sig,
None => {
bail!("Invalid localsignal for property '{}'", prop_name);
}
};
let data_obj: glib::Object = localsignal.data.as_ref().clone().upcast();
data_obj
.bind_property("value", &child_widget, &prop_name)
.flags(glib::BindingFlags::SYNC_CREATE)
.build();
}
let gtk_widget_clone = gtk_widget.clone();
let update_fn: UpdateFn = Box::new(move |props: &Map| {
// now re-apply generic widget attrs
if let Err(err) =
resolve_rhai_widget_attrs(&gtk_widget_clone.clone().upcast::<gtk4::Widget>(), &props)
{
eprintln!("Failed to update widget attrs: {:?}", err);
}
});
let id = hash_props_and_type(&props, "LocalBind");
widget_registry
.widgets
.insert(id, WidgetEntry { widget: gtk_widget.clone().upcast(), update_fn });
resolve_rhai_widget_attrs(&gtk_widget.clone().upcast::<gtk4::Widget>(), &props)?;
Ok(gtk_widget)
}
struct EventBoxCtrlData {
// hover controller data
onhover_cmd: String,

View File

@@ -32,6 +32,7 @@ pub enum WidgetNode {
Transform { props: Map },
EventBox { props: Map, children: Vec<WidgetNode> },
ToolTip { props: Map, children: Vec<WidgetNode> },
LocalBind { props: Map, children: Vec<WidgetNode> },
// Top-level macros
DefWindow { name: String, props: Map, node: Box<WidgetNode> },
@@ -151,6 +152,13 @@ pub fn get_id_to_widget_info<'a>(
get_id_to_widget_info(child, id_to_props, Some(id))?;
}
}
WidgetNode::LocalBind { props, children } => {
let id = hash_props_and_type(props, "LocalBind");
insert_wdgt_info(node, props, "LocalBind", children.as_slice(), parent_id, id_to_props)?;
for child in children {
get_id_to_widget_info(child, id_to_props, Some(id))?;
}
}
WidgetNode::ColorChooser { props } => {
// let id = hash_props_and_type(props, "ColorChooser");
insert_wdgt_info(node, props, "ColorChooser", &[], parent_id, id_to_props)?;

View File

@@ -78,6 +78,7 @@ pub fn register_all_widgets(engine: &mut Engine, all_nodes: &Rc<RefCell<Vec<Widg
register_with_children!("stack", Stack);
register_with_children!("eventbox", EventBox);
register_with_children!("tooltip", ToolTip);
register_with_children!("localbind", LocalBind);
// == Special signal
engine.register_fn("localsignal", |props: Map| -> Result<LocalSignal, Box<EvalAltResult>> {

View File

@@ -71,6 +71,10 @@ impl WidgetNode {
props: with_dyn_id(props.clone(), parent_path),
children: process_children(children, parent_path, "tooltip"),
},
WidgetNode::LocalBind { props, children } => WidgetNode::LocalBind {
props: with_dyn_id(props.clone(), parent_path),
children: process_children(children, parent_path, "localbind"),
},
// == Top-level container for multiple widgets ==
WidgetNode::Enter(children) => {