use cursive_core::{
View, Printer, Vec2,
event::{Event, EventResult, AnyCb},
direction::Direction,
view::{
CannotFocus,
Selector,
ViewNotFound
},
Rect
};
pub struct LazyView<V: View> {
view_thunk: Option<Box<dyn FnOnce() -> V + Send + Sync>>,
final_view: Option<V>,
auto_init: bool
}
impl<V: View> LazyView<V> {
pub fn new<F: FnOnce() -> V + Send + Sync + 'static>(view_thunk: F) -> Self {
LazyView {
view_thunk: Some(Box::new(view_thunk)),
final_view: None,
auto_init: true
}
}
pub fn initialize(&mut self) {
if self.final_view.is_none() {
let view_thunk = self.view_thunk.take().unwrap();
self.final_view = Some(view_thunk());
}
}
pub fn is_initialized(&self) -> bool {
self.get_view().is_some()
}
pub fn get_view(&self) -> Option<&V> {
self.final_view.as_ref()
}
pub fn get_view_mut(&mut self) -> Option<&mut V> {
self.initialize();
self.final_view.as_mut()
}
pub fn set_auto_init(&mut self, auto_init: bool) {
self.auto_init = auto_init;
}
pub fn auto_init(mut self, auto_init: bool) -> Self {
self.set_auto_init(auto_init);
self
}
}
impl<V: View> View for LazyView<V> {
fn draw(&self, printer: &Printer) {
if let Some(ref view) = self.final_view {
view.draw(printer);
}
}
fn layout(&mut self, size: Vec2) {
if let Some(ref mut view) = self.final_view {
view.layout(size);
}
else if self.auto_init {
self.initialize();
}
}
fn required_size(&mut self, constraint: Vec2) -> Vec2 {
if let Some(ref mut view) = self.final_view {
view.required_size(constraint)
}
else { Vec2::new(0, 0) }
}
fn on_event(&mut self, event: Event) -> EventResult {
if let Some(ref mut view) = self.final_view {
view.on_event(event)
}
else { EventResult::Ignored }
}
fn take_focus(&mut self, dir: Direction) -> Result<EventResult, CannotFocus> {
if let Some(ref mut view) = self.final_view {
view.take_focus(dir)
}
else {
Err(CannotFocus)
}
}
fn call_on_any(&mut self, sel: &Selector, cb: AnyCb) {
if let Some(ref mut view) = self.final_view {
view.call_on_any(sel, cb);
}
}
fn focus_view(&mut self, sel: &Selector) -> Result<EventResult, ViewNotFound> {
if let Some(ref mut view) = self.final_view {
view.focus_view(sel)
}
else { Err(ViewNotFound) }
}
fn needs_relayout(&self) -> bool {
if let Some(ref view) = self.final_view {
view.needs_relayout()
}
else { true }
}
fn important_area(&self, size: Vec2) -> Rect {
if let Some(ref view) = self.final_view {
view.important_area(size)
}
else { Rect::from_point((1, 1)) }
}
}