mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-09 19:00:46 +00:00
Add View::focus_view
This commit is contained in:
parent
2cd2787119
commit
017bb21710
14
src/lib.rs
14
src/lib.rs
@ -392,6 +392,8 @@ impl Cursive {
|
||||
self.screen_mut().find(sel)
|
||||
}
|
||||
|
||||
/// Tries to find the view identified by the given id.
|
||||
///
|
||||
/// Convenient method to use `find` with a `view::Selector::Id`.
|
||||
///
|
||||
/// # Examples
|
||||
@ -417,6 +419,18 @@ impl Cursive {
|
||||
self.find(&view::Selector::Id(id))
|
||||
}
|
||||
|
||||
/// Moves the focus to the view identified by `id`.
|
||||
///
|
||||
/// Convenient method to call `focus` with a `view::Selector::Id`.
|
||||
pub fn focus_id(&mut self, id: &str) -> Result<(), ()> {
|
||||
self.focus(&view::Selector::Id(id))
|
||||
}
|
||||
|
||||
/// Moves the focus to the view identified by `sel`.
|
||||
pub fn focus(&mut self, sel: &view::Selector) -> Result<(), ()> {
|
||||
self.screen_mut().focus_view(sel)
|
||||
}
|
||||
|
||||
/// Adds a global callback.
|
||||
///
|
||||
/// Will be triggered on the given key press when no view catches it.
|
||||
|
@ -113,7 +113,7 @@ pub trait View {
|
||||
/// Draws the view with the given printer (includes bounds) and focus.
|
||||
fn draw(&self, printer: &Printer);
|
||||
|
||||
/// Finds the view pointed to by the given path.
|
||||
/// Finds the view identified by the given selector.
|
||||
///
|
||||
/// See [`Finder::find`] for a nicer interface, implemented for all views.
|
||||
///
|
||||
@ -126,6 +126,13 @@ pub trait View {
|
||||
None
|
||||
}
|
||||
|
||||
/// Moves the focus to the view identified by the given selector.
|
||||
///
|
||||
/// Returns `Ok(())` if the view was found and selected.
|
||||
fn focus_view(&mut self, &Selector) -> Result<(), ()> {
|
||||
Err(())
|
||||
}
|
||||
|
||||
/// This view is offered focus. Will it take it?
|
||||
///
|
||||
/// `source` indicates where the focus comes from.
|
||||
|
@ -55,6 +55,11 @@ pub trait ViewWrapper {
|
||||
self.get_view_mut().find_any(selector)
|
||||
}
|
||||
|
||||
/// Wraps the `focus_view` method.
|
||||
fn wrap_focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||
self.get_view_mut().focus_view(selector)
|
||||
}
|
||||
|
||||
/// Wraps the `needs_relayout` method.
|
||||
fn wrap_needs_relayout(&self) -> bool {
|
||||
self.get_view().needs_relayout()
|
||||
@ -89,6 +94,10 @@ impl<T: ViewWrapper> View for T {
|
||||
fn needs_relayout(&self) -> bool {
|
||||
self.wrap_needs_relayout()
|
||||
}
|
||||
|
||||
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||
self.wrap_focus_view(selector)
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenient macro to implement the [`ViewWrapper`] trait.
|
||||
|
@ -402,4 +402,8 @@ impl View for Dialog {
|
||||
fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> {
|
||||
self.content.find_any(selector)
|
||||
}
|
||||
|
||||
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||
self.content.focus_view(selector)
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,11 @@ impl<T: View + Any> ViewWrapper for IdView<T> {
|
||||
s => self.view.find_any(s),
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap_focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||
match selector {
|
||||
&Selector::Id(id) if id == self.id => Ok(()),
|
||||
s => self.view.focus_view(s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -401,4 +401,15 @@ impl View for LinearLayout {
|
||||
.filter_map(|c| c.view.find_any(selector))
|
||||
.next()
|
||||
}
|
||||
|
||||
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||
for (i, child) in self.children.iter_mut().enumerate() {
|
||||
if child.view.focus_view(selector).is_ok() {
|
||||
self.focus = i;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,10 @@ impl ListView {
|
||||
direction::Relative::Front => {
|
||||
let start = if from_focus { self.focus } else { 0 };
|
||||
|
||||
Box::new(self.children.iter_mut().enumerate().skip(start))
|
||||
Box::new(self.children
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.skip(start))
|
||||
}
|
||||
direction::Relative::Back => {
|
||||
let end = if from_focus {
|
||||
@ -296,10 +299,11 @@ impl View for ListView {
|
||||
|
||||
fn take_focus(&mut self, source: direction::Direction) -> bool {
|
||||
let rel = source.relative(direction::Orientation::Vertical);
|
||||
let i = if let Some(i) = self.iter_mut(rel.is_none(),
|
||||
rel.unwrap_or(direction::Relative::Front))
|
||||
.filter_map(|p| try_focus(p, source))
|
||||
.next() {
|
||||
let i = if let Some(i) =
|
||||
self.iter_mut(rel.is_none(),
|
||||
rel.unwrap_or(direction::Relative::Front))
|
||||
.filter_map(|p| try_focus(p, source))
|
||||
.next() {
|
||||
i
|
||||
} else {
|
||||
// No one wants to be in focus
|
||||
@ -317,4 +321,18 @@ impl View for ListView {
|
||||
.filter_map(|v| v.find_any(selector))
|
||||
.next()
|
||||
}
|
||||
|
||||
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||
if let Some(i) = self.children
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.filter_map(|(i, v)| v.view().map(|v| (i, v)))
|
||||
.filter_map(|(i, v)| v.focus_view(selector).ok().map(|_| i))
|
||||
.next() {
|
||||
self.focus = i;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,4 +186,14 @@ impl View for StackView {
|
||||
.filter_map(|l| l.view.find_any(selector))
|
||||
.next()
|
||||
}
|
||||
|
||||
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||
for layer in &mut self.layers {
|
||||
if layer.view.focus_view(selector).is_ok() {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user