use rdom_core::{Event, NodeId};
use crate::TuiDom;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ControlFlow {
#[default]
Continue,
Quit,
}
pub(super) enum StylesheetIntent {
Set(super::StylesheetId, crate::style::Stylesheet),
Push(super::StylesheetId, crate::style::Stylesheet),
Remove(super::StylesheetId),
}
pub struct AppContext<'a> {
pub dom: &'a mut TuiDom,
pub(super) redraw_requested: bool,
pub(super) quit_requested: bool,
pub(super) queued_dispatches: Vec<(NodeId, Event)>,
pub(super) stylesheet_intents: Vec<StylesheetIntent>,
stylesheet_ids: &'a mut super::stylesheets::StylesheetIdAllocator,
}
impl<'a> AppContext<'a> {
pub(super) fn new(
dom: &'a mut TuiDom,
stylesheet_ids: &'a mut super::stylesheets::StylesheetIdAllocator,
) -> Self {
Self {
dom,
redraw_requested: false,
quit_requested: false,
queued_dispatches: Vec::new(),
stylesheet_intents: Vec::new(),
stylesheet_ids,
}
}
pub fn set_stylesheet(&mut self, sheet: crate::style::Stylesheet) -> super::StylesheetId {
let id = self.stylesheet_ids.allocate();
self.stylesheet_intents
.push(StylesheetIntent::Set(id, sheet));
id
}
pub fn push_stylesheet(&mut self, sheet: crate::style::Stylesheet) -> super::StylesheetId {
let id = self.stylesheet_ids.allocate();
self.stylesheet_intents
.push(StylesheetIntent::Push(id, sheet));
id
}
pub fn remove_stylesheet(&mut self, id: super::StylesheetId) {
self.stylesheet_intents.push(StylesheetIntent::Remove(id));
}
pub fn request_redraw(&mut self) {
self.redraw_requested = true;
}
pub fn quit(&mut self) {
self.quit_requested = true;
}
pub fn dispatch(&mut self, target: NodeId, event: &mut Event) -> rdom_core::Result<()> {
self.dom.dispatch_event(target, event)
}
pub fn queue_dispatch(&mut self, target: NodeId, event: Event) {
self.queued_dispatches.push((target, event));
}
}
pub(super) fn run_queued_dispatches(dom: &mut TuiDom, queued: Vec<(NodeId, Event)>) {
for (target, mut event) in queued {
match dom.dispatch_event(target, &mut event) {
Ok(()) | Err(rdom_core::DomError::InvalidNode(_)) => {}
Err(rdom_core::DomError::InvalidState(_)) => {
let mut fresh = event.clone();
crate::tui_event::dispatch_event_to_live(dom, target, &mut fresh);
}
Err(e) => panic!(
"dispatching a queued `{}` event failed: {e:?}",
event.event_type
),
}
}
}