diff --git a/src/view/mod.rs b/src/view/mod.rs index 928f123..8cbed6f 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -148,42 +148,6 @@ pub trait View { } } -use std::ops::{Deref, DerefMut}; -impl View for Box { - fn draw(&self, printer: &Printer) { - self.deref().draw(printer) - } - - fn required_size(&mut self, req: Vec2) -> Vec2 { - self.deref_mut().required_size(req) - } - - fn on_event(&mut self, ch: Event) -> EventResult { - self.deref_mut().on_event(ch) - } - - fn layout(&mut self, size: Vec2) { - self.deref_mut().layout(size); - } - - fn take_focus(&mut self, source: Direction) -> bool { - self.deref_mut().take_focus(source) - } - - fn call_on_any<'a>(&mut self, selector: &Selector, - callback: Box) { - self.deref_mut().call_on_any(selector, callback) - } - - fn needs_relayout(&self) -> bool { - self.deref().needs_relayout() - } - - fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> { - self.deref_mut().focus_view(selector) - } -} - /// Provides `call_on` to views. /// /// This trait is mostly a wrapper around [`View::call_on_any`]. diff --git a/src/view/view_wrapper.rs b/src/view/view_wrapper.rs index fc0ddca..7d850d8 100644 --- a/src/view/view_wrapper.rs +++ b/src/view/view_wrapper.rs @@ -17,14 +17,21 @@ use view::{Selector, View}; /// [`wrap_impl!`]: ../macro.wrap_impl.html pub trait ViewWrapper { /// Type that this view wraps. - type V: View; + type V: View + ?Sized; /// Get an immutable reference to the wrapped view. - fn with_view(&self, f: F) -> Option where F: FnOnce(&Self::V) -> R; + /// + /// Returns `None` if the inner view is unavailable. + fn with_view(&self, f: F) -> Option + where + F: FnOnce(&Self::V) -> R; /// Get a mutable reference to the wrapped view. + /// + /// Returns `None` if the inner view is unavailable. fn with_view_mut(&mut self, f: F) -> Option - where F: FnOnce(&mut Self::V) -> R; + where + F: FnOnce(&mut Self::V) -> R; /// Wraps the `draw` method. fn wrap_draw(&self, printer: &Printer) { @@ -33,12 +40,15 @@ pub trait ViewWrapper { /// Wraps the `required_size` method. fn wrap_required_size(&mut self, req: Vec2) -> Vec2 { - self.with_view_mut(|v| v.required_size(req)).unwrap_or_else(Vec2::zero) + self.with_view_mut(|v| v.required_size(req)) + .unwrap_or_else(Vec2::zero) } /// Wraps the `on_event` method. fn wrap_on_event(&mut self, ch: Event) -> EventResult { - self.with_view_mut(|v| v.on_event(ch)).unwrap_or(EventResult::Ignored) + self.with_view_mut(|v| v.on_event(ch)).unwrap_or( + EventResult::Ignored, + ) } /// Wraps the `layout` method. @@ -48,18 +58,21 @@ pub trait ViewWrapper { /// Wraps the `take_focus` method. fn wrap_take_focus(&mut self, source: Direction) -> bool { - self.with_view_mut(|v| v.take_focus(source)).unwrap_or(false) + self.with_view_mut(|v| v.take_focus(source)).unwrap_or( + false, + ) } /// Wraps the `find` method. - fn wrap_call_on_any<'a>(&mut self, selector: &Selector, - callback: Box) { + fn wrap_call_on_any<'a>(&mut self, selector: &Selector, callback: Box) { self.with_view_mut(|v| v.call_on_any(selector, callback)); } /// Wraps the `focus_view` method. fn wrap_focus_view(&mut self, selector: &Selector) -> Result<(), ()> { - self.with_view_mut(|v| v.focus_view(selector)).unwrap_or(Err(())) + self.with_view_mut(|v| v.focus_view(selector)).unwrap_or( + Err(()), + ) } /// Wraps the `needs_relayout` method. @@ -68,6 +81,27 @@ pub trait ViewWrapper { } } +use std::ops::{Deref, DerefMut}; +impl + DerefMut> ViewWrapper for T { + type V = U; + + /// Get an immutable reference to the wrapped view. + fn with_view(&self, f: F) -> Option + where + F: FnOnce(&Self::V) -> R, + { + Some(f(self.deref())) + } + + /// Get a mutable reference to the wrapped view. + fn with_view_mut(&mut self, f: F) -> Option + where + F: FnOnce(&mut Self::V) -> R, + { + Some(f(self.deref_mut())) + } +} + impl View for T { fn draw(&self, printer: &Printer) { self.wrap_draw(printer); @@ -89,8 +123,7 @@ impl View for T { self.wrap_take_focus(source) } - fn call_on_any<'a>(&mut self, selector: &Selector, - callback: Box) { + fn call_on_any<'a>(&mut self, selector: &Selector, callback: Box) { self.wrap_call_on_any(selector, callback) }