#[macro_use]
mod view_wrapper;
mod position;
mod size_cache;
mod size_constraint;
mod view_path;
mod scroll;
mod identifiable;
mod boxable;
pub use self::boxable::Boxable;
pub use self::identifiable::Identifiable;
pub use self::position::{Offset, Position};
pub use self::scroll::{ScrollBase, ScrollStrategy};
pub use self::size_cache::SizeCache;
pub use self::size_constraint::SizeConstraint;
pub use self::view_path::ViewPath;
pub use self::view_wrapper::ViewWrapper;
use Printer;
use direction::Direction;
use event::{Event, EventResult};
use vec::Vec2;
use views::IdView;
use std::any::Any;
pub trait View {
fn on_event(&mut self, Event) -> EventResult {
EventResult::Ignored
}
fn required_size(&mut self, constraint: Vec2) -> Vec2 {
let _ = constraint;
Vec2::new(1, 1)
}
fn needs_relayout(&self) -> bool {
true
}
fn layout(&mut self, Vec2) {}
fn draw(&self, printer: &Printer);
fn call_on_any<'a>(&mut self, _: &Selector, _: Box<FnMut(&mut Any) + 'a>) {
}
fn focus_view(&mut self, &Selector) -> Result<(), ()> {
Err(())
}
fn take_focus(&mut self, source: Direction) -> bool {
let _ = source;
false
}
}
pub trait Finder {
fn call_on<V, F, R>(&mut self, sel: &Selector, callback: F) -> Option<R>
where V: View + Any,
F: FnOnce(&mut V) -> R;
fn find_id<V, F, R>(&mut self, id: &str, callback: F) -> Option<R>
where V: View + Any,
F: FnOnce(&mut V) -> R
{
self.call_on(&Selector::Id(id), callback)
}
}
impl<T: View> Finder for T {
fn call_on<V, F, R>(&mut self, sel: &Selector, callback: F) -> Option<R>
where V: View + Any,
F: FnOnce(&mut V) -> R
{
let mut result = None;
{
let result_ref = &mut result;
let mut callback = Some(callback);
let callback = |v: &mut Any| if let Some(callback) =
callback.take() {
if v.is::<V>() {
*result_ref = v.downcast_mut::<V>().map(|v| callback(v));
} else if v.is::<IdView<V>>() {
*result_ref = v.downcast_mut::<IdView<V>>()
.and_then(|v| v.with_view_mut(callback));
}
};
self.call_on_any(sel, Box::new(callback));
}
result
}
}
pub enum Selector<'a> {
Id(&'a str),
Path(&'a ViewPath),
}