diff --git a/src/lib.rs b/src/lib.rs index 061b31c..38436b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,7 @@ pub use with::With; pub use printer::Printer; use backend::{Backend, NcursesBackend}; +use view::Finder; use std::sync::mpsc; use std::any::Any; @@ -320,11 +321,6 @@ impl Cursive { self.active_screen = screen_id; } - fn find_any(&mut self, selector: &view::Selector) -> Option<&mut Any> { - // Internal find method that returns a Any object. - self.screen_mut().find(selector) - } - /// Tries to find the view pointed to by the given path. /// /// If the view is not found, or if it is not of the asked type, @@ -348,7 +344,7 @@ impl Cursive { /// # } /// ``` pub fn find(&mut self, sel: &view::Selector) -> Option<&mut V> { - self.find_any(sel).and_then(|b| b.downcast_mut::()) + self.screen_mut().find(sel) } /// Convenient method to use `find` with a `view::Selector::Id`. diff --git a/src/view/mod.rs b/src/view/mod.rs index 61484b2..6f26d9e 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -118,7 +118,7 @@ pub trait View { /// Returns None if the path doesn't lead to a view. /// /// Default implementation always return `None`. - fn find(&mut self, &Selector) -> Option<&mut Any> { + fn find_any(&mut self, &Selector) -> Option<&mut Any> { None } @@ -134,6 +134,19 @@ pub trait View { } } +/// Provides `find` to views. +pub trait Finder { + + /// Find a view + fn find(&mut self, sel: &Selector) -> Option<&mut V>; +} + +impl Finder for T { + fn find(&mut self, sel: &Selector) -> Option<&mut V> { + self.find_any(sel).and_then(|b| b.downcast_mut::()) + } +} + /// Selects a single view (if any) in the tree. pub enum Selector<'a> { /// Selects a view from its ID. diff --git a/src/view/view_wrapper.rs b/src/view/view_wrapper.rs index 986b05b..392f235 100644 --- a/src/view/view_wrapper.rs +++ b/src/view/view_wrapper.rs @@ -51,8 +51,8 @@ pub trait ViewWrapper { } /// Wraps the `find` method. - fn wrap_find(&mut self, selector: &Selector) -> Option<&mut Any> { - self.get_view_mut().find(selector) + fn wrap_find_any(&mut self, selector: &Selector) -> Option<&mut Any> { + self.get_view_mut().find_any(selector) } /// Wraps the `needs_relayout` method. @@ -82,8 +82,8 @@ impl View for T { self.wrap_take_focus(source) } - fn find(&mut self, selector: &Selector) -> Option<&mut Any> { - self.wrap_find(selector) + fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> { + self.wrap_find_any(selector) } fn needs_relayout(&self) -> bool { diff --git a/src/views/dialog.rs b/src/views/dialog.rs index 00e4d9e..3ee13f2 100644 --- a/src/views/dialog.rs +++ b/src/views/dialog.rs @@ -396,7 +396,7 @@ impl View for Dialog { } } - fn find(&mut self, selector: &Selector) -> Option<&mut Any> { - self.content.find(selector) + fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> { + self.content.find_any(selector) } } diff --git a/src/views/id_view.rs b/src/views/id_view.rs index 423986c..73ae6c2 100644 --- a/src/views/id_view.rs +++ b/src/views/id_view.rs @@ -21,10 +21,10 @@ impl IdView { impl ViewWrapper for IdView { wrap_impl!(self.view: T); - fn wrap_find(&mut self, selector: &Selector) -> Option<&mut Any> { + fn wrap_find_any(&mut self, selector: &Selector) -> Option<&mut Any> { match selector { &Selector::Id(id) if id == self.id => Some(&mut self.view), - s => self.view.find(s), + s => self.view.find_any(s), } } } diff --git a/src/views/linear_layout.rs b/src/views/linear_layout.rs index 61ee218..822cc5e 100644 --- a/src/views/linear_layout.rs +++ b/src/views/linear_layout.rs @@ -383,7 +383,10 @@ impl View for LinearLayout { } } - fn find(&mut self, selector: &Selector) -> Option<&mut Any> { - self.children.iter_mut().filter_map(|c| c.view.find(selector)).next() + fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> { + self.children + .iter_mut() + .filter_map(|c| c.view.find_any(selector)) + .next() } } diff --git a/src/views/list_view.rs b/src/views/list_view.rs index e51a57c..abe98e2 100644 --- a/src/views/list_view.rs +++ b/src/views/list_view.rs @@ -28,16 +28,6 @@ impl Child { _ => None, } } - - // Currently unused - // - // fn is_delimiter(&self) -> bool { - // match *self { - // Child::Row(_, _) => false, - // Child::Delimiter => true, - // } - // } - // } /// Displays a scrollable list of elements. @@ -270,11 +260,11 @@ impl View for ListView { true } - fn find(&mut self, selector: &Selector) -> Option<&mut Any> { + fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> { self.children .iter_mut() .filter_map(Child::view) - .filter_map(|v| v.find(selector)) + .filter_map(|v| v.find_any(selector)) .next() } } diff --git a/src/views/stack_view.rs b/src/views/stack_view.rs index 593e34c..6181b24 100644 --- a/src/views/stack_view.rs +++ b/src/views/stack_view.rs @@ -133,12 +133,10 @@ impl View for StackView { } } - fn find(&mut self, selector: &Selector) -> Option<&mut Any> { - for layer in &mut self.layers { - if let Some(any) = layer.view.find(selector) { - return Some(any); - } - } - None + fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> { + self.layers + .iter_mut() + .filter_map(|l| l.view.find_any(selector)) + .next() } }