Skip to content

Commit

Permalink
Handle multiple children in let
Browse files Browse the repository at this point in the history
  • Loading branch information
elkowar committed Apr 27, 2022
1 parent bc994c2 commit 9f3ba90
Showing 1 changed file with 68 additions and 34 deletions.
102 changes: 68 additions & 34 deletions crates/eww/src/widgets/build_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ pub fn build_gtk_widget(
WidgetUse::Basic(widget_use) => {
build_basic_gtk_widget(graph, widget_defs, calling_scope, widget_use, custom_widget_invocation)
}
WidgetUse::Let(let_use) => build_let_special_widget(graph, widget_defs, calling_scope, let_use, custom_widget_invocation),
WidgetUse::Let(let_use) => {
build_let_special_widget_single_child(graph, widget_defs, calling_scope, let_use, custom_widget_invocation)
}
WidgetUse::Loop(_) | WidgetUse::Children(_) => Err(anyhow::anyhow!(DiagError::new(gen_diagnostic! {
msg = "This widget can only be used as a child of some container widget such as box",
label = widget_use.span(),
Expand Down Expand Up @@ -112,20 +114,12 @@ fn build_basic_gtk_widget(
}
}

fn build_let_special_widget(
graph: &mut ScopeGraph,
widget_defs: Rc<HashMap<String, WidgetDefinition>>,
calling_scope: ScopeIndex,
widget_use: LetWidgetUse,
custom_widget_invocation: Option<Rc<CustomWidgetInvocation>>,
) -> Result<gtk::Widget> {
let child = widget_use.body.first().expect("no child in let");

fn init_let_widget_scope(graph: &mut ScopeGraph, calling_scope: ScopeIndex, widget_use: &LetWidgetUse) -> Result<ScopeIndex> {
// Evaluate explicitly here, so we don't keep linking the state changes here.
// If that was desired, it'd suffice to just pass the simplexprs as attributes to register_new_scope,
// rather than converting them into literals explicitly.
let mut defined_vars = HashMap::new();
for (name, expr) in widget_use.defined_vars.into_iter() {
for (name, expr) in widget_use.defined_vars.clone().into_iter() {
let mut needed_vars = graph.lookup_variables_in_scope(calling_scope, &expr.collect_var_refs())?;
needed_vars.extend(defined_vars.clone().into_iter());
let value = expr.eval(&needed_vars)?;
Expand All @@ -138,13 +132,48 @@ fn build_let_special_widget(
calling_scope,
defined_vars.into_iter().map(|(k, v)| (AttrName(k.to_string()), SimplExpr::Literal(v))).collect(),
)?;
let gtk_widget = build_gtk_widget(graph, widget_defs, let_scope, child.clone(), custom_widget_invocation)?;
Ok(let_scope)
}

fn build_let_special_widget_single_child(
graph: &mut ScopeGraph,
widget_defs: Rc<HashMap<String, WidgetDefinition>>,
calling_scope: ScopeIndex,
widget_use: LetWidgetUse,
custom_widget_invocation: Option<Rc<CustomWidgetInvocation>>,
) -> Result<gtk::Widget> {
assert!(widget_use.body.len() == 1, "build_let_special_widget_single_child called with let with more than one child");
let child = widget_use.body.first().cloned().expect("no child in let");
let let_scope = init_let_widget_scope(graph, calling_scope, &widget_use)?;
let child_widget = build_gtk_widget(graph, widget_defs, let_scope, child.clone(), custom_widget_invocation)?;
let scope_graph_sender = graph.event_sender.clone();
child_widget.connect_destroy(move |_| {
let _ = scope_graph_sender.send(ScopeGraphEvent::RemoveScope(let_scope));
});
Ok(child_widget)
}

gtk_widget.connect_destroy(move |_| {
fn build_let_special_widget_multiple_children(
graph: &mut ScopeGraph,
widget_defs: Rc<HashMap<String, WidgetDefinition>>,
calling_scope: ScopeIndex,
widget_use: LetWidgetUse,
gtk_container: &gtk::Container,
custom_widget_invocation: Option<Rc<CustomWidgetInvocation>>,
) -> Result<()> {
let let_scope = init_let_widget_scope(graph, calling_scope, &widget_use)?;
let scope_graph_sender = graph.event_sender.clone();

for child in &widget_use.body {
let child_widget =
build_gtk_widget(graph, widget_defs.clone(), let_scope, child.clone(), custom_widget_invocation.clone())?;
gtk_container.add(&child_widget);
}

gtk_container.connect_destroy(move |_| {
let _ = scope_graph_sender.send(ScopeGraphEvent::RemoveScope(let_scope));
});
Ok(gtk_widget)
Ok(())
}

/// build a [`gtk::Widget`] out of a [`WidgetUse`] that uses a
Expand Down Expand Up @@ -220,26 +249,31 @@ fn populate_widget_children(
) -> Result<()> {
for child in widget_use_children {
match child {
WidgetUse::Children(child) => {
build_children_special_widget(
tree,
widget_defs.clone(),
calling_scope,
child,
gtk_container,
custom_widget_invocation.clone().context("Not in a custom widget invocation")?,
)?;
}
WidgetUse::Loop(child) => {
build_loop_special_widget(
tree,
widget_defs.clone(),
calling_scope,
child,
gtk_container,
custom_widget_invocation.clone(),
)?;
}
WidgetUse::Children(child) => build_children_special_widget(
tree,
widget_defs.clone(),
calling_scope,
child,
gtk_container,
custom_widget_invocation.clone().context("Not in a custom widget invocation")?,
)?,

WidgetUse::Let(child) => build_let_special_widget_multiple_children(
tree,
widget_defs.clone(),
calling_scope,
child,
gtk_container,
custom_widget_invocation.clone(),
)?,
WidgetUse::Loop(child) => build_loop_special_widget(
tree,
widget_defs.clone(),
calling_scope,
child,
gtk_container,
custom_widget_invocation.clone(),
)?,
_ => {
let child_widget =
build_gtk_widget(tree, widget_defs.clone(), calling_scope, child, custom_widget_invocation.clone())?;
Expand Down

0 comments on commit 9f3ba90

Please sign in to comment.