#[cfg(declarative_view)]
fn main() {
use rust_widgets::core::{ObjectId, Rect};
use rust_widgets::view::{Node, Patch, View, ViewEngine};
use rust_widgets::widget::capability::CapabilityValue;
use rust_widgets::widget::{runtime, Widget, WidgetFactory};
struct Counter {
count: i64,
rows: Vec<&'static str>,
}
impl View for Counter {
fn build(&self) -> Node {
Node::new("group_box")
.key("root")
.child(
Node::new("label")
.key("count")
.prop("text", CapabilityValue::String(format!("Count: {}", self.count))),
)
.children_of(self.rows.iter().map(|row| {
Node::new("label")
.key(*row)
.prop("text", CapabilityValue::String((*row).to_string()))
}))
}
}
fn creator(factory: &WidgetFactory) -> impl Fn(&Node) -> Option<ObjectId> + '_ {
move |node: &Node| {
let widget: Box<dyn Widget> = factory.create(
&node.widget,
Rect::new(0, 0, 200, 28),
node.key_str().unwrap_or("anon"),
)?;
runtime::register(widget)
}
}
fn describe(patches: &[Patch]) -> String {
if patches.is_empty() {
return "no patches (the tree did not change)".to_string();
}
let names: Vec<String> = patches
.iter()
.map(|patch| match patch {
Patch::SetProperty { name, .. } => format!("SetProperty({name})"),
Patch::Remove { .. } => "Remove".to_string(),
Patch::Insert { .. } => "Insert".to_string(),
Patch::Move { .. } => "Move".to_string(),
Patch::Replace { .. } => "Replace".to_string(),
})
.collect();
format!("{} patch(es): {}", patches.len(), names.join(", "))
}
let factory = WidgetFactory::new_with_defaults();
let mut engine = ViewEngine::new();
let mut state = Counter { count: 0, rows: vec!["alpha", "beta"] };
let mounted = engine.mount(&state, &creator(&factory));
println!(
"initial mount : {} control(s) created, {} property write(s), {} error(s)",
mounted.widgets_created,
mounted.properties_written,
mounted.errors.len()
);
state.count = 1;
let report = engine.update(&state, &creator(&factory));
println!("bump counter : {}", describe(&report.patches));
println!(
" positional_matches={} replaced_subtrees={}",
report.positional_matches, report.replaced_subtrees
);
state.rows.push("gamma");
let report = engine.update(&state, &creator(&factory));
println!("append a row : {}", describe(&report.patches));
state.rows.remove(0);
let report = engine.update(&state, &creator(&factory));
println!("remove the first row : {}", describe(&report.patches));
println!("root control id : {:?} (stable across every update above)", engine.id_at(&[]));
println!(
"mounted tree size : {} node(s)",
engine.current().map(Node::node_count).unwrap_or(0)
);
}
#[cfg(not(declarative_view))]
fn main() {
println!(
"the declarative view layer is not compiled in this profile; \
run with --features desktop (or tablet/mobile) instead"
);
}