mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +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)
|
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`.
|
/// Convenient method to use `find` with a `view::Selector::Id`.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
@ -417,6 +419,18 @@ impl Cursive {
|
|||||||
self.find(&view::Selector::Id(id))
|
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.
|
/// Adds a global callback.
|
||||||
///
|
///
|
||||||
/// Will be triggered on the given key press when no view catches it.
|
/// 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.
|
/// Draws the view with the given printer (includes bounds) and focus.
|
||||||
fn draw(&self, printer: &Printer);
|
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.
|
/// See [`Finder::find`] for a nicer interface, implemented for all views.
|
||||||
///
|
///
|
||||||
@ -126,6 +126,13 @@ pub trait View {
|
|||||||
None
|
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?
|
/// This view is offered focus. Will it take it?
|
||||||
///
|
///
|
||||||
/// `source` indicates where the focus comes from.
|
/// `source` indicates where the focus comes from.
|
||||||
|
@ -55,6 +55,11 @@ pub trait ViewWrapper {
|
|||||||
self.get_view_mut().find_any(selector)
|
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.
|
/// Wraps the `needs_relayout` method.
|
||||||
fn wrap_needs_relayout(&self) -> bool {
|
fn wrap_needs_relayout(&self) -> bool {
|
||||||
self.get_view().needs_relayout()
|
self.get_view().needs_relayout()
|
||||||
@ -89,6 +94,10 @@ impl<T: ViewWrapper> View for T {
|
|||||||
fn needs_relayout(&self) -> bool {
|
fn needs_relayout(&self) -> bool {
|
||||||
self.wrap_needs_relayout()
|
self.wrap_needs_relayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||||
|
self.wrap_focus_view(selector)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenient macro to implement the [`ViewWrapper`] trait.
|
/// 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> {
|
fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> {
|
||||||
self.content.find_any(selector)
|
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),
|
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))
|
.filter_map(|c| c.view.find_any(selector))
|
||||||
.next()
|
.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 => {
|
direction::Relative::Front => {
|
||||||
let start = if from_focus { self.focus } else { 0 };
|
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 => {
|
direction::Relative::Back => {
|
||||||
let end = if from_focus {
|
let end = if from_focus {
|
||||||
@ -296,10 +299,11 @@ impl View for ListView {
|
|||||||
|
|
||||||
fn take_focus(&mut self, source: direction::Direction) -> bool {
|
fn take_focus(&mut self, source: direction::Direction) -> bool {
|
||||||
let rel = source.relative(direction::Orientation::Vertical);
|
let rel = source.relative(direction::Orientation::Vertical);
|
||||||
let i = if let Some(i) = self.iter_mut(rel.is_none(),
|
let i = if let Some(i) =
|
||||||
rel.unwrap_or(direction::Relative::Front))
|
self.iter_mut(rel.is_none(),
|
||||||
.filter_map(|p| try_focus(p, source))
|
rel.unwrap_or(direction::Relative::Front))
|
||||||
.next() {
|
.filter_map(|p| try_focus(p, source))
|
||||||
|
.next() {
|
||||||
i
|
i
|
||||||
} else {
|
} else {
|
||||||
// No one wants to be in focus
|
// No one wants to be in focus
|
||||||
@ -317,4 +321,18 @@ impl View for ListView {
|
|||||||
.filter_map(|v| v.find_any(selector))
|
.filter_map(|v| v.find_any(selector))
|
||||||
.next()
|
.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))
|
.filter_map(|l| l.view.find_any(selector))
|
||||||
.next()
|
.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