cursive_extras/views/
lazy_view.rs1use cursive_core::{
2 View, Printer, Vec2,
3 event::{Event, EventResult, AnyCb},
4 direction::Direction,
5 view::{
6 CannotFocus,
7 Selector,
8 ViewNotFound
9 },
10 Rect
11};
12
13pub struct LazyView<V: View> {
15 view_thunk: Option<Box<dyn FnOnce() -> V + Send + Sync>>,
16 final_view: Option<V>,
17 auto_init: bool
18}
19
20impl<V: View> LazyView<V> {
21 pub fn new<F: FnOnce() -> V + Send + Sync + 'static>(view_thunk: F) -> Self {
23 LazyView {
24 view_thunk: Some(Box::new(view_thunk)),
25 final_view: None,
26 auto_init: true
27 }
28 }
29
30 pub fn initialize(&mut self) {
32 if self.final_view.is_none() {
33 let view_thunk = self.view_thunk.take().unwrap();
34 self.final_view = Some(view_thunk());
35 }
36 }
37
38 pub fn is_initialized(&self) -> bool {
40 self.get_view().is_some()
41 }
42
43 pub fn get_view(&self) -> Option<&V> {
47 self.final_view.as_ref()
48 }
49
50 pub fn get_view_mut(&mut self) -> Option<&mut V> {
54 self.initialize();
55 self.final_view.as_mut()
56 }
57
58 pub fn set_auto_init(&mut self, auto_init: bool) {
60 self.auto_init = auto_init;
61 }
62
63 pub fn auto_init(mut self, auto_init: bool) -> Self {
67 self.set_auto_init(auto_init);
68 self
69 }
70}
71
72impl<V: View> View for LazyView<V> {
73 fn draw(&self, printer: &Printer) {
74 if let Some(ref view) = self.final_view {
75 view.draw(printer);
76 }
77 }
78
79 fn layout(&mut self, size: Vec2) {
80 if let Some(ref mut view) = self.final_view {
81 view.layout(size);
82 }
83 else if self.auto_init {
84 self.initialize();
85 }
86 }
87
88 fn required_size(&mut self, constraint: Vec2) -> Vec2 {
89 if let Some(ref mut view) = self.final_view {
90 view.required_size(constraint)
91 }
92 else { Vec2::new(0, 0) }
93 }
94
95 fn on_event(&mut self, event: Event) -> EventResult {
96 if let Some(ref mut view) = self.final_view {
97 view.on_event(event)
98 }
99 else { EventResult::Ignored }
100 }
101
102 fn take_focus(&mut self, dir: Direction) -> Result<EventResult, CannotFocus> {
103 if let Some(ref mut view) = self.final_view {
104 view.take_focus(dir)
105 }
106 else {
107 Err(CannotFocus)
108 }
109 }
110
111 fn call_on_any(&mut self, sel: &Selector, cb: AnyCb) {
112 if let Some(ref mut view) = self.final_view {
113 view.call_on_any(sel, cb);
114 }
115 }
116
117 fn focus_view(&mut self, sel: &Selector) -> Result<EventResult, ViewNotFound> {
118 if let Some(ref mut view) = self.final_view {
119 view.focus_view(sel)
120 }
121 else { Err(ViewNotFound) }
122 }
123
124 fn needs_relayout(&self) -> bool {
125 if let Some(ref view) = self.final_view {
126 view.needs_relayout()
127 }
128 else { true }
129 }
130
131 fn important_area(&self, size: Vec2) -> Rect {
132 if let Some(ref view) = self.final_view {
133 view.important_area(size)
134 }
135 else { Rect::from_point((1, 1)) }
136 }
137}