feat: make wc add eval rhai code instead of .ui

This commit is contained in:
Byson94
2025-11-08 18:47:09 +05:30
parent b821d8bb6a
commit 6a6856192c
5 changed files with 36 additions and 25 deletions

View File

@@ -86,7 +86,7 @@ pub enum DaemonCommand {
ListActiveWindows(DaemonResponseSender),
WidgetControl {
action: crate::opts::WidgetControlAction,
sender: DaemonResponseSender
sender: DaemonResponseSender,
},
TriggerUpdateUI {
inject_vars: Option<HashMap<String, String>>,
@@ -759,7 +759,10 @@ impl<B: DisplayBackend> App<B> {
}
/// Perform widget control based on the action
pub fn perform_widget_control(&mut self, action: crate::opts::WidgetControlAction) -> Result<()> {
pub fn perform_widget_control(
&mut self,
action: crate::opts::WidgetControlAction,
) -> Result<()> {
match action {
crate::opts::WidgetControlAction::Remove { name } => {
if let Ok(mut maybe_registry) = self.widget_reg_store.lock() {
@@ -772,13 +775,12 @@ impl<B: DisplayBackend> App<B> {
log::error!("Failed to acquire lock on widget registry");
}
}
crate::opts::WidgetControlAction::Create { ui_file, widget_id, parent_name } => {
let mut props = rhai::Map::new();
props.insert("file".into(), ui_file.into());
props.insert("id".into(), widget_id.into());
let wid = rhai_impl::ast::hash_props(&props);
let widget_node = rhai_impl::ast::WidgetNode::GtkUI { props };
crate::opts::WidgetControlAction::Create { rhai_code, parent_name } => {
let mut parser = self.config_parser.borrow_mut();
let widget_node = parser.eval_code_snippet(&rhai_code)?;
let wid = rhai_impl::ast::hash_props(widget_node.props().ok_or_else(|| {
anyhow::anyhow!("Failed to retreive the properties of this widget.")
})?);
if let Ok(mut maybe_registry) = self.widget_reg_store.lock() {
if let Some(widget_registry) = maybe_registry.as_mut() {

View File

@@ -187,7 +187,6 @@ pub enum ActionWithServer {
// /// Print out the scope graph structure in graphviz dot format.
// #[command(name = "graph")]
// ShowGraph,
/// Control widgets through CLI.
#[command(name = "widget-control", alias = "wc")]
WidgetControl {
@@ -253,17 +252,13 @@ pub enum WidgetControlAction {
/// Create a widget
Create {
/// Path of .ui file to get widget from.
ui_file: String,
/// ID of the widget to use as child.
#[arg(long = "id", short = 'i')]
widget_id: String,
/// Rhai code to create widget from.
rhai_code: String,
/// Name of the widget to add this widget as a child to.
#[arg(long = "parent", short = 'p')]
parent_name: String,
}
},
}
impl Opt {

View File

@@ -56,9 +56,7 @@ fn build_gtk_widget_from_node(
WidgetNode::CircularProgress { props } => {
build_circular_progress_bar(props, widget_reg)?.upcast()
}
WidgetNode::GtkUI { props } => {
build_gtk_ui_file(props)?.upcast()
}
WidgetNode::GtkUI { props } => build_gtk_ui_file(props)?.upcast(),
// WidgetNode::Graph { props } => build_graph(props, widget_reg)?.upcast(),
// WidgetNode::Transform { props } => build_transform(props, widget_reg)?.upcast(),
WidgetNode::Slider { props } => build_gtk_scale(props, widget_reg)?.upcast(),

View File

@@ -215,8 +215,8 @@ impl WidgetRegistry {
}
pub fn remove_widget_by_name(&mut self, name: &str) -> bool {
if let Some((&id, _)) = self.widgets.iter()
.find(|(_, entry)| entry.widget.widget_name().as_str() == name)
if let Some((&id, _)) =
self.widgets.iter().find(|(_, entry)| entry.widget.widget_name().as_str() == name)
{
if let Some(entry) = self.widgets.remove(&id) {
entry.widget.unparent();
@@ -1993,9 +1993,7 @@ pub(super) fn build_gtk_combo_box_text(
Ok(gtk_widget)
}
pub(super) fn build_gtk_ui_file(
props: &Map,
) -> Result<gtk4::Widget> {
pub(super) fn build_gtk_ui_file(props: &Map) -> Result<gtk4::Widget> {
let path = get_string_prop(&props, "file", None)?;
let main_id = get_string_prop(&props, "id", None)?;

View File

@@ -95,6 +95,24 @@ impl ParseConfig {
Ok(merged_node.setup_dyn_ids("root"))
}
pub fn eval_code_snippet(&mut self, code: &str) -> Result<WidgetNode> {
let mut scope = Scope::new();
// Just eval as node will be in `all_nodes`
let node = self
.engine
.eval_with_scope::<WidgetNode>(&mut scope, code)
.map_err(|e| anyhow!(format_eval_error(&e, code, &self.engine, Some("<dyn eval>"))))?;
// Retain signals
crate::updates::retain_signals(&self.keep_signal.borrow());
// Clear all nodes
self.all_nodes.borrow_mut().clear();
Ok(node)
}
pub fn code_from_file<P: AsRef<Path>>(&mut self, file_path: P) -> Result<String> {
Ok(fs::read_to_string(&file_path)
.map_err(|e| anyhow!("Failed to read {:?}: {}", file_path.as_ref(), e))?)