use Printer; use With; use direction::Direction; use event::{AnyCb, Event, EventResult}; use rect::Rect; use vec::Vec2; use view::{Selector, View}; /// A blank view that forwards calls to closures. /// /// You can use this view to easily draw your own interface. pub struct Canvas { state: T, draw: Box, on_event: Box EventResult>, required_size: Box Vec2>, layout: Box, take_focus: Box bool>, needs_relayout: Box bool>, focus_view: Box Result<(), ()>>, call_on_any: Box FnMut(&mut T, &Selector, AnyCb<'a>)>, important_area: Box Rect>, } impl Canvas { /// Creates a new Canvas around the given view. /// /// By default, forwards all calls to the inner view. pub fn wrap(view: T) -> Self { Canvas::new(view) .with_draw(T::draw) .with_on_event(T::on_event) .with_required_size(T::required_size) .with_layout(T::layout) .with_take_focus(T::take_focus) .with_needs_relayout(T::needs_relayout) .with_focus_view(T::focus_view) .with_call_on_any(T::call_on_any) .with_important_area(T::important_area) } } impl Canvas { /// Creates a new, empty Canvas. /// /// # Examples /// /// ```rust /// # use cursive::views::Canvas; /// let canvas = Canvas::new(()) /// .with_draw(|printer, _| { /// // Print the view /// }); /// ``` pub fn new(state: T) -> Self { Canvas { state, draw: Box::new(|_, _| ()), on_event: Box::new(|_, _| EventResult::Ignored), required_size: Box::new(|_, _| Vec2::new(1, 1)), layout: Box::new(|_, _| ()), take_focus: Box::new(|_, _| false), needs_relayout: Box::new(|_| true), focus_view: Box::new(|_, _| Err(())), call_on_any: Box::new(|_, _, _| ()), important_area: Box::new(|_, size| { Rect::from_corners((0, 0), size) }), } } /// Gets a mutable reference to the inner state. pub fn state_mut(&mut self) -> &mut T { &mut self.state } /// Sets the closure for `draw(&Printer)`. pub fn set_draw(&mut self, f: F) where F: 'static + Fn(&T, &Printer), { self.draw = Box::new(f); } /// Sets the closure for `draw(&Printer)`. /// /// Chainable variant. pub fn with_draw(self, f: F) -> Self where F: 'static + Fn(&T, &Printer), { self.with(|s| s.set_draw(f)) } /// Sets the closure for `on_event(Event)`. pub fn set_on_event(&mut self, f: F) where F: 'static + FnMut(&mut T, Event) -> EventResult, { self.on_event = Box::new(f); } /// Sets the closure for `on_event(Event)`. /// /// Chainable variant. pub fn with_on_event(self, f: F) -> Self where F: 'static + FnMut(&mut T, Event) -> EventResult, { self.with(|s| s.set_on_event(f)) } /// Sets the closure for `required_size(Vec2)`. pub fn set_required_size(&mut self, f: F) where F: 'static + FnMut(&mut T, Vec2) -> Vec2, { self.required_size = Box::new(f); } /// Sets the closure for `required_size(Vec2)`. /// /// Chainable variant. pub fn with_required_size(self, f: F) -> Self where F: 'static + FnMut(&mut T, Vec2) -> Vec2, { self.with(|s| s.set_required_size(f)) } /// Sets the closure for `layout(Vec2)`. pub fn set_layout(&mut self, f: F) where F: 'static + FnMut(&mut T, Vec2), { self.layout = Box::new(f); } /// Sets the closure for `layout(Vec2)`. /// /// Chainable variant. pub fn with_layout(self, f: F) -> Self where F: 'static + FnMut(&mut T, Vec2), { self.with(|s| s.set_layout(f)) } /// Sets the closure for `take_focus(Direction)`. pub fn set_take_focus(&mut self, f: F) where F: 'static + FnMut(&mut T, Direction) -> bool, { self.take_focus = Box::new(f); } /// Sets the closure for `take_focus(Direction)`. /// /// Chainable variant. pub fn with_take_focus(self, f: F) -> Self where F: 'static + FnMut(&mut T, Direction) -> bool, { self.with(|s| s.set_take_focus(f)) } /// Sets the closure for `needs_relayout()`. pub fn set_needs_relayout(&mut self, f: F) where F: 'static + Fn(&T) -> bool, { self.needs_relayout = Box::new(f); } /// Sets the closure for `needs_relayout()`. /// /// Chainable variant. pub fn with_needs_relayout(self, f: F) -> Self where F: 'static + Fn(&T) -> bool, { self.with(|s| s.set_needs_relayout(f)) } /// Sets the closure for `call_on_any()`. pub fn set_call_on_any(&mut self, f: F) where F: 'static + for<'a> FnMut(&mut T, &Selector, AnyCb<'a>), { self.call_on_any = Box::new(f); } /// Sets the closure for `call_on_any()`. /// /// Chainable variant. pub fn with_call_on_any(self, f: F) -> Self where F: 'static + for<'a> FnMut(&mut T, &Selector, AnyCb<'a>), { self.with(|s| s.set_call_on_any(f)) } /// Sets the closure for `important_area()`. pub fn set_important_area(&mut self, f: F) where F: 'static + Fn(&T, Vec2) -> Rect, { self.important_area = Box::new(f); } /// Sets the closure for `important_area()`. /// /// Chainable variant. pub fn with_important_area(self, f: F) -> Self where F: 'static + Fn(&T, Vec2) -> Rect, { self.with(|s| s.set_important_area(f)) } /// Sets the closure for `focus_view()`. pub fn set_focus_view(&mut self, f: F) where F: 'static + FnMut(&mut T, &Selector) -> Result<(), ()>, { self.focus_view = Box::new(f); } /// Sets the closure for `focus_view()`. /// /// Chainable variant. pub fn with_focus_view(self, f: F) -> Self where F: 'static + FnMut(&mut T, &Selector) -> Result<(), ()>, { self.with(|s| s.set_focus_view(f)) } } impl View for Canvas { fn draw(&self, printer: &Printer) { (self.draw)(&self.state, printer); } fn on_event(&mut self, event: Event) -> EventResult { (self.on_event)(&mut self.state, event) } fn required_size(&mut self, constraint: Vec2) -> Vec2 { (self.required_size)(&mut self.state, constraint) } fn layout(&mut self, size: Vec2) { (self.layout)(&mut self.state, size); } fn take_focus(&mut self, source: Direction) -> bool { (self.take_focus)(&mut self.state, source) } fn needs_relayout(&self) -> bool { (self.needs_relayout)(&self.state) } fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> { (self.focus_view)(&mut self.state, selector) } fn important_area(&self, view_size: Vec2) -> Rect { (self.important_area)(&self.state, view_size) } fn call_on_any<'a>(&mut self, selector: &Selector, cb: AnyCb<'a>) { (self.call_on_any)(&mut self.state, selector, cb); } }