View
A view exposes event handling and passes any internal state to the runtime.
Any type that implements the anathema::core::View
trait is a view.
This trait has no required methods, however note that
without implementing the fn state(&self) -> &dyn State
method, no internal
state will be exposed to the template even if the view has a state.
See State for more information about state.
Example
#![allow(unused)] fn main() { use anathema::core::{Event, KeyCode, Nodes, View}; impl View for MyView { fn on_event(&mut self, event: Event, _: &mut Nodes<'_>) -> Event { match event { Event::KeyPress(KeyCode::Char(c), ..) => { } Event::KeyPress(KeyCode::Backspace, ..) => { } _ => {} } event } fn state(&self) -> &dyn State { &self.state } fn tick(&mut self) { *self.state.counter += 1; } fn focus(&mut self) { *self.state.color = Color::Reset; } fn blur(&mut self) { *self.state.color = Color::Magenta; } } }
Root view
The runtime needs at least one view, however since the View
trait is
implemented for the unit type it is possible to pass ()
as an argument
instead of your own defined view:
#![allow(unused)] fn main() { let view = (); let template = read_to_string("templates/index.aml").unwrap(); // Pass associate the template with the root view: let mut templates = Templates::new(template, view); let templates = templates.compile().unwrap(); let runtime = Runtime::new(&templates).unwrap(); }
This is suitable if no event handling or no internal state is required.
One or many views
Singular instance of a view
If the number of instances are known at compile time, for instance the view is not
created inside a for-loop, then use add_view
to register a view with a
template.
#![allow(unused)] fn main() { let items_view = ItemsView::new(); let items_template = read_to_string("templates/index.aml").unwrap(); templates.add_view( "items", // Name of the view in the template items_template, // Template items_view // A view instance ); }
This is then accessible in the template with the view syntax:
@items
Multiple / dynamic instances of a view
If a view is used inside a for-loop or is otherwise generated as requested by
the runtime use add_prototype
:
#![allow(unused)] fn main() { let item_view = ; let item_template = read_to_string("templates/index.aml").unwrap(); templates.add_prototype( "item", // Name of the view in the template item_template, // Template || ItemView::new() // A closure creating a view instance when called ); }
This makes it possible to create views on the fly:
for item in items
@item item