use orbtk::prelude::*; use std::collections::VecDeque; #[derive(Debug)] pub enum Event { Create(Entity), Delete(Entity), } #[derive(AsAny, Default)] pub struct AppState { events: VecDeque, pub notes: Entity, count: u32, } impl AppState { fn append_note(&self, ctx: &mut Context, copy: String) { let id = ctx.entity; let bctx = &mut ctx.build_context(); let text = TextBox::create().text(copy); let container = Stack::create() .orientation(Orientation::Horizontal) .vertical_alignment(Alignment::Start) .child(text.build(bctx)) .build(bctx); let button = Button::create() .horizontal_alignment(Alignment::End) .text("Delete") .on_click(move |ctxt, _| { ctxt.get_mut::(id) .events .push_back(Event::Delete(container)); true }) .build(bctx); bctx.append_child(container, button); bctx.append_child(self.notes, container); } fn fetch_text(ctx: &mut Context, entity: Entity) -> Option { let mut widget = ctx.get_widget(entity); let entry = widget.get_mut::("text"); if entry.is_empty() { return None; } let copy = entry.to_string(); entry.clear(); Some(copy) } pub fn send(&mut self, event: Event) { self.events.push_back(event); } } impl State for AppState { fn update(&mut self, _: &mut Registry, ctx: &mut Context) { if let Some(event) = self.events.pop_front() { match event { // Create and append the note to the UI. Event::Create(entity) => { if let Some(copy) = Self::fetch_text(ctx, entity) { self.append_note(ctx, copy); let count = self.count + 1; self.count = count; if count == 1 { ctx.widget().set::("spacing", 12.0); } } } // Delete the note of the given ID from the UI. Event::Delete(id) => { ctx.remove_child_from(id, self.notes); let count = self.count - 1; self.count = count; if count == 0 { ctx.widget().set::("spacing", 0.0); } } } } } }