mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Rename find
-> call_on
And update tutorials
This commit is contained in:
parent
c3c69e7892
commit
c300e0628d
@ -40,7 +40,7 @@ fn main() {
|
|||||||
|
|
||||||
fn add_name(s: &mut Cursive) {
|
fn add_name(s: &mut Cursive) {
|
||||||
fn ok(s: &mut Cursive, name: &str) {
|
fn ok(s: &mut Cursive, name: &str) {
|
||||||
s.find_id("select", |view: &mut SelectView<String>| {
|
s.call_on_id("select", |view: &mut SelectView<String>| {
|
||||||
view.add_item_str(name)
|
view.add_item_str(name)
|
||||||
});
|
});
|
||||||
s.pop_layer();
|
s.pop_layer();
|
||||||
@ -53,7 +53,7 @@ fn add_name(s: &mut Cursive) {
|
|||||||
.title("Enter a new name")
|
.title("Enter a new name")
|
||||||
.button("Ok", |s| {
|
.button("Ok", |s| {
|
||||||
let name =
|
let name =
|
||||||
s.find_id("name", |view: &mut EditView| {
|
s.call_on_id("name", |view: &mut EditView| {
|
||||||
view.get_content().clone()
|
view.get_content().clone()
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
ok(s, &name);
|
ok(s, &name);
|
||||||
@ -62,16 +62,11 @@ fn add_name(s: &mut Cursive) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn delete_name(s: &mut Cursive) {
|
fn delete_name(s: &mut Cursive) {
|
||||||
let selection = s.find_id("select", |view: &mut SelectView<String>| {
|
let mut select = s.find_id::<SelectView<String>>("select").unwrap();
|
||||||
view.selected_id()
|
match select.selected_id() {
|
||||||
}).unwrap();
|
|
||||||
|
|
||||||
match selection {
|
|
||||||
None => s.add_layer(Dialog::info("No name to remove")),
|
None => s.add_layer(Dialog::info("No name to remove")),
|
||||||
Some(focus) => {
|
Some(focus) => {
|
||||||
s.find_id("select", |view: &mut SelectView<String>| {
|
select.remove_item(focus);
|
||||||
view.remove_item(focus)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,7 +227,7 @@ Later, you can ask the Cursive root for this ID and get access to the view.
|
|||||||
Just what we need!
|
Just what we need!
|
||||||
|
|
||||||
Like `BoxView`, `IdView` can be used directly with [`IdView::new`], or through
|
Like `BoxView`, `IdView` can be used directly with [`IdView::new`], or through
|
||||||
the [`Identifiable`] trait. [`Cursive::find_id`] allows you to run a closure
|
the [`Identifiable`] trait. [`Cursive::call_on_id`] allows you to run a closure
|
||||||
on the view.
|
on the view.
|
||||||
|
|
||||||
Here's what it looks like in action:
|
Here's what it looks like in action:
|
||||||
@ -244,7 +239,7 @@ fn add_name(s: &mut Cursive) {
|
|||||||
.fixed_width(10))
|
.fixed_width(10))
|
||||||
.title("Enter a new name")
|
.title("Enter a new name")
|
||||||
.button("Ok", |s| {
|
.button("Ok", |s| {
|
||||||
let name = s.find_id("name", |view: &mut EditView| {
|
let name = s.call_on_id("name", |view: &mut EditView| {
|
||||||
view.get_content().clone()
|
view.get_content().clone()
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
})
|
})
|
||||||
@ -253,7 +248,7 @@ fn add_name(s: &mut Cursive) {
|
|||||||
```
|
```
|
||||||
|
|
||||||
We create the `EditView` with the id `"name"`, and we use `"name"` again when
|
We create the `EditView` with the id `"name"`, and we use `"name"` again when
|
||||||
calling `find_id`.
|
calling `call_on_id`.
|
||||||
|
|
||||||
Now we just need to do something with this name: add it to the list!
|
Now we just need to do something with this name: add it to the list!
|
||||||
Remember the `SelectView` we created? Let's give it an ID too:
|
Remember the `SelectView` we created? Let's give it an ID too:
|
||||||
@ -272,7 +267,7 @@ That way, we can update it with a new item:
|
|||||||
```rust,ignore
|
```rust,ignore
|
||||||
fn add_name(s: &mut Cursive) {
|
fn add_name(s: &mut Cursive) {
|
||||||
fn ok(s: &mut Cursive, name: &str) {
|
fn ok(s: &mut Cursive, name: &str) {
|
||||||
s.find_id("select", |view: &mut SelectView<String>| {
|
s.call_on_id("select", |view: &mut SelectView<String>| {
|
||||||
view.add_item_str(name);
|
view.add_item_str(name);
|
||||||
});
|
});
|
||||||
s.pop_layer();
|
s.pop_layer();
|
||||||
@ -284,7 +279,7 @@ fn add_name(s: &mut Cursive) {
|
|||||||
.fixed_width(10))
|
.fixed_width(10))
|
||||||
.title("Enter a new name")
|
.title("Enter a new name")
|
||||||
.button("Ok", |s| {
|
.button("Ok", |s| {
|
||||||
let name = s.find_id("name", |v: &mut EditView| {
|
let name = s.call_on_id("name", |v: &mut EditView| {
|
||||||
v.get_content().clone()
|
v.get_content().clone()
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
ok(s, &name);
|
ok(s, &name);
|
||||||
@ -298,27 +293,30 @@ complicated:
|
|||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
fn delete_name(s: &mut Cursive) {
|
fn delete_name(s: &mut Cursive) {
|
||||||
match s.find_id("select", |v: &mut SelectView<String>| {
|
let mut select = s.find_id::<SelectView<String>>("select").unwrap();
|
||||||
v.selected_id()
|
match select.selected_id() {
|
||||||
}).unwrap() {
|
|
||||||
None => s.add_layer(Dialog::info("No name to remove")),
|
None => s.add_layer(Dialog::info("No name to remove")),
|
||||||
Some(focus) => s.find_id("select", |v: &mut SelectView<String>| {
|
Some(focus) => {
|
||||||
v.remove_item(focus)
|
select.remove_item(focus);
|
||||||
}),
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
We use [`SelectView::selected_id`] and [`SelectView::remove_item`] to remove
|
We use [`SelectView::selected_id`] and [`SelectView::remove_item`] to remove
|
||||||
the item currently selected, nothing too surprising.
|
the item currently selected, nothing too surprising.
|
||||||
We have to find the `SelectView` twice, otherwise we're still borrowing `s`
|
|
||||||
when we try to add a new layer - one of the quirks of the borrow checker.
|
But this time, instead of using `call_on_id`, we use `Cursive::find_id`:
|
||||||
|
this method returns a handle, through which we can mutate the view.
|
||||||
|
It uses `Rc` and `RefCell` under the hood to provide mutable access to the
|
||||||
|
view without borrowing the `Cursive` root, leaving us free to pop layers.
|
||||||
|
|
||||||
[`EditView`]: http://gyscos.github.io/Cursive/cursive/views/struct.EditView.html
|
[`EditView`]: http://gyscos.github.io/Cursive/cursive/views/struct.EditView.html
|
||||||
[`IdView`]: http://gyscos.github.io/Cursive/cursive/views/struct.IdView.html
|
[`IdView`]: http://gyscos.github.io/Cursive/cursive/views/struct.IdView.html
|
||||||
[`IdView::new`]: http://gyscos.github.io/Cursive/cursive/prelude/struct.IdView.html#method.around
|
[`IdView::new`]: http://gyscos.github.io/Cursive/cursive/prelude/struct.IdView.html#method.around
|
||||||
[`Identifiable`]: http://gyscos.github.io/Cursive/cursive/view/trait.Identifiable.html
|
[`Identifiable`]: http://gyscos.github.io/Cursive/cursive/view/trait.Identifiable.html
|
||||||
[`Cursive::find_id`]: http://gyscos.github.io/Cursive/cursive/struct.Cursive.html#method.find_id
|
[`Cursive::find_id`]: http://gyscos.github.io/Cursive/cursive/struct.Cursive.html#method.find_id
|
||||||
|
[`Cursive::call_on_id`]: http://gyscos.github.io/Cursive/cursive/struct.Cursive.html#method.call_on_id
|
||||||
[`SelectView::selected_id`]: http://gyscos.github.io/Cursive/cursive/views/struct.SelectView.html#method.selected_id
|
[`SelectView::selected_id`]: http://gyscos.github.io/Cursive/cursive/views/struct.SelectView.html#method.selected_id
|
||||||
[`SelectView::remove_item`]: http://gyscos.github.io/Cursive/cursive/views/struct.SelectView.html#method.remove_item
|
[`SelectView::remove_item`]: http://gyscos.github.io/Cursive/cursive/views/struct.SelectView.html#method.remove_item
|
||||||
|
|
||||||
|
10
src/lib.rs
10
src/lib.rs
@ -386,23 +386,23 @@ impl Cursive {
|
|||||||
/// .with_id("text"));
|
/// .with_id("text"));
|
||||||
///
|
///
|
||||||
/// siv.add_global_callback('p', |s| {
|
/// siv.add_global_callback('p', |s| {
|
||||||
/// s.find(&view::Selector::Id("text"), |view: &mut views::TextView| {
|
/// s.call_on(&view::Selector::Id("text"), |view: &mut views::TextView| {
|
||||||
/// view.set_content("Text #2");
|
/// view.set_content("Text #2");
|
||||||
/// });
|
/// });
|
||||||
/// });
|
/// });
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn find<V, F, R>(&mut self, sel: &view::Selector, callback: F)
|
pub fn call_on<V, F, R>(&mut self, sel: &view::Selector, callback: F)
|
||||||
-> Option<R>
|
-> Option<R>
|
||||||
where V: View + Any,
|
where V: View + Any,
|
||||||
F: FnOnce(&mut V) -> R
|
F: FnOnce(&mut V) -> R
|
||||||
{
|
{
|
||||||
self.screen_mut().find(sel, callback)
|
self.screen_mut().call_on(sel, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to find the view identified by the given id.
|
/// Tries to find the view identified by the given id.
|
||||||
///
|
///
|
||||||
/// Convenient method to use `find` with a `view::Selector::Id`.
|
/// Convenient method to use `call_on` with a `view::Selector::Id`.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -427,7 +427,7 @@ impl Cursive {
|
|||||||
where V: View + Any,
|
where V: View + Any,
|
||||||
F: FnOnce(&mut V) -> R
|
F: FnOnce(&mut V) -> R
|
||||||
{
|
{
|
||||||
self.find(&view::Selector::Id(id), callback)
|
self.call_on(&view::Selector::Id(id), callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenient method to find a view wrapped in [`IdView`].
|
/// Convenient method to find a view wrapped in [`IdView`].
|
||||||
|
@ -116,14 +116,14 @@ pub trait View {
|
|||||||
|
|
||||||
/// Finds the view identified by the given selector.
|
/// Finds the view identified by the given selector.
|
||||||
///
|
///
|
||||||
/// See [`Finder::find`] for a nicer interface, implemented for all views.
|
/// See [`Finder::call_on`] for a nicer interface, implemented for all views.
|
||||||
///
|
///
|
||||||
/// [`Finder::find`]: trait.Finder.html#method.find
|
/// [`Finder::call_on`]: trait.Finder.html#method.call_on
|
||||||
///
|
///
|
||||||
/// Returns None if the path doesn't lead to a view.
|
/// Returns None if the path doesn't lead to a view.
|
||||||
///
|
///
|
||||||
/// Default implementation always return `None`.
|
/// Default implementation always return `None`.
|
||||||
fn find_any<'a>(&mut self, _: &Selector, _: Box<FnMut(&mut Any) + 'a>) {
|
fn call_on_any<'a>(&mut self, _: &Selector, _: Box<FnMut(&mut Any) + 'a>) {
|
||||||
// TODO: FnMut -> FnOnce once it works
|
// TODO: FnMut -> FnOnce once it works
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,33 +146,33 @@ pub trait View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Provides `find<V: View>` to views.
|
/// Provides `call_on<V: View>` to views.
|
||||||
///
|
///
|
||||||
/// This trait is mostly a wrapper around [`View::find_any`].
|
/// This trait is mostly a wrapper around [`View::call_on_any`].
|
||||||
///
|
///
|
||||||
/// It provides a nicer interface to find a view when you know its type.
|
/// It provides a nicer interface to find a view when you know its type.
|
||||||
///
|
///
|
||||||
/// [`View::find_any`]: ./trait.View.html#method.find_any
|
/// [`View::call_on_any`]: ./trait.View.html#method.call_on_any
|
||||||
pub trait Finder {
|
pub trait Finder {
|
||||||
/// Tries to find the view pointed to by the given selector.
|
/// Tries to find the view pointed to by the given selector.
|
||||||
///
|
///
|
||||||
/// If the view is not found, or if it is not of the asked type,
|
/// If the view is not found, or if it is not of the asked type,
|
||||||
/// it returns None.
|
/// it returns None.
|
||||||
fn find<V, F, R>(&mut self, sel: &Selector, callback: F) -> Option<R>
|
fn call_on<V, F, R>(&mut self, sel: &Selector, callback: F) -> Option<R>
|
||||||
where V: View + Any,
|
where V: View + Any,
|
||||||
F: FnOnce(&mut V) -> R;
|
F: FnOnce(&mut V) -> R;
|
||||||
|
|
||||||
/// Convenient method to use `find` with a `view::Selector::Id`.
|
/// Convenient method to use `call_on` with a `view::Selector::Id`.
|
||||||
fn find_id<V, F, R>(&mut self, id: &str, callback: F) -> Option<R>
|
fn find_id<V, F, R>(&mut self, id: &str, callback: F) -> Option<R>
|
||||||
where V: View + Any,
|
where V: View + Any,
|
||||||
F: FnOnce(&mut V) -> R
|
F: FnOnce(&mut V) -> R
|
||||||
{
|
{
|
||||||
self.find(&Selector::Id(id), callback)
|
self.call_on(&Selector::Id(id), callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: View> Finder for T {
|
impl<T: View> Finder for T {
|
||||||
fn find<V, F, R>(&mut self, sel: &Selector, callback: F) -> Option<R>
|
fn call_on<V, F, R>(&mut self, sel: &Selector, callback: F) -> Option<R>
|
||||||
where V: View + Any,
|
where V: View + Any,
|
||||||
F: FnOnce(&mut V) -> R
|
F: FnOnce(&mut V) -> R
|
||||||
{
|
{
|
||||||
@ -190,7 +190,7 @@ impl<T: View> Finder for T {
|
|||||||
.and_then(|v| v.with_view_mut(callback));
|
.and_then(|v| v.with_view_mut(callback));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.find_any(sel, Box::new(callback));
|
self.call_on_any(sel, Box::new(callback));
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,9 @@ pub trait ViewWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the `find` method.
|
/// Wraps the `find` method.
|
||||||
fn wrap_find_any<'a>(&mut self, selector: &Selector,
|
fn wrap_call_on_any<'a>(&mut self, selector: &Selector,
|
||||||
callback: Box<FnMut(&mut Any) + 'a>) {
|
callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
self.with_view_mut(|v| v.find_any(selector, callback));
|
self.with_view_mut(|v| v.call_on_any(selector, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the `focus_view` method.
|
/// Wraps the `focus_view` method.
|
||||||
@ -89,9 +89,9 @@ impl<T: ViewWrapper> View for T {
|
|||||||
self.wrap_take_focus(source)
|
self.wrap_take_focus(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_any<'a>(&mut self, selector: &Selector,
|
fn call_on_any<'a>(&mut self, selector: &Selector,
|
||||||
callback: Box<FnMut(&mut Any) + 'a>) {
|
callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
self.wrap_find_any(selector, callback)
|
self.wrap_call_on_any(selector, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn needs_relayout(&self) -> bool {
|
fn needs_relayout(&self) -> bool {
|
||||||
|
@ -399,9 +399,9 @@ impl View for Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_any<'a>(&mut self, selector: &Selector,
|
fn call_on_any<'a>(&mut self, selector: &Selector,
|
||||||
callback: Box<FnMut(&mut Any) + 'a>) {
|
callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
self.content.find_any(selector, callback);
|
self.content.call_on_any(selector, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use owning_ref::{RcRef, OwningHandle};
|
use owning_ref::{RcRef, OwningHandle};
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::{RefCell, RefMut};
|
||||||
use std::any::Any;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use view::{Selector, View, ViewWrapper};
|
use view::{Selector, View, ViewWrapper};
|
||||||
|
|
||||||
@ -12,6 +12,10 @@ pub struct IdView<V: View> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Mutable reference to a view.
|
/// Mutable reference to a view.
|
||||||
|
///
|
||||||
|
/// This behaves like a [`RefMut`], but without being tied to a lifetime.
|
||||||
|
///
|
||||||
|
/// [`RefMut`]: https://doc.rust-lang.org/std/cell/struct.RefMut.html
|
||||||
pub type ViewRef<V> = OwningHandle<RcRef<RefCell<V>>, RefMut<'static, V>>;
|
pub type ViewRef<V> = OwningHandle<RcRef<RefCell<V>>, RefMut<'static, V>>;
|
||||||
|
|
||||||
impl<V: View> IdView<V> {
|
impl<V: View> IdView<V> {
|
||||||
@ -24,6 +28,8 @@ impl<V: View> IdView<V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets mutable access to the inner view.
|
/// Gets mutable access to the inner view.
|
||||||
|
///
|
||||||
|
/// This returns a `ViewRef<V>`, which implement `DerefMut<Target = V>`.
|
||||||
pub fn get_mut(&mut self) -> ViewRef<V> {
|
pub fn get_mut(&mut self) -> ViewRef<V> {
|
||||||
// TODO: return a standalone item (not tied to our lifetime)
|
// TODO: return a standalone item (not tied to our lifetime)
|
||||||
// that bundles `self.view.clone()` and allow mutable reference to
|
// that bundles `self.view.clone()` and allow mutable reference to
|
||||||
@ -56,11 +62,11 @@ impl<T: View + 'static> ViewWrapper for IdView<T> {
|
|||||||
.map(|mut v| f(&mut *v))
|
.map(|mut v| f(&mut *v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_find_any<'a>(&mut self, selector: &Selector,
|
fn wrap_call_on_any<'a>(&mut self, selector: &Selector,
|
||||||
mut callback: Box<for<'b> FnMut(&'b mut Any) + 'a>) {
|
mut callback: Box<for<'b> FnMut(&'b mut Any) + 'a>) {
|
||||||
let result = match selector {
|
let result = match selector {
|
||||||
&Selector::Id(id) if id == self.id => callback(self),
|
&Selector::Id(id) if id == self.id => callback(self),
|
||||||
s => self.view.borrow_mut().find_any(s, callback),
|
s => self.view.borrow_mut().call_on_any(s, callback),
|
||||||
};
|
};
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
@ -395,10 +395,10 @@ impl View for LinearLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_any<'a>(&mut self, selector: &Selector,
|
fn call_on_any<'a>(&mut self, selector: &Selector,
|
||||||
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
for child in &mut self.children {
|
for child in &mut self.children {
|
||||||
child.view.find_any(selector, Box::new(|any| callback(any)));
|
child.view.call_on_any(selector, Box::new(|any| callback(any)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,12 +313,12 @@ impl View for ListView {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_any<'a>(&mut self, selector: &Selector,
|
fn call_on_any<'a>(&mut self, selector: &Selector,
|
||||||
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
for view in self.children
|
for view in self.children
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.filter_map(Child::view) {
|
.filter_map(Child::view) {
|
||||||
view.find_any(selector, Box::new(|any| callback(any)));
|
view.call_on_any(selector, Box::new(|any| callback(any)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,10 +180,10 @@ impl View for StackView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_any<'a>(&mut self, selector: &Selector,
|
fn call_on_any<'a>(&mut self, selector: &Selector,
|
||||||
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
for layer in &mut self.layers {
|
for layer in &mut self.layers {
|
||||||
layer.view.find_any(selector, Box::new(|any| callback(any)));
|
layer.view.call_on_any(selector, Box::new(|any| callback(any)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user