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 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)
|
||||
});
|
||||
s.pop_layer();
|
||||
@ -53,7 +53,7 @@ fn add_name(s: &mut Cursive) {
|
||||
.title("Enter a new name")
|
||||
.button("Ok", |s| {
|
||||
let name =
|
||||
s.find_id("name", |view: &mut EditView| {
|
||||
s.call_on_id("name", |view: &mut EditView| {
|
||||
view.get_content().clone()
|
||||
}).unwrap();
|
||||
ok(s, &name);
|
||||
@ -62,16 +62,11 @@ fn add_name(s: &mut Cursive) {
|
||||
}
|
||||
|
||||
fn delete_name(s: &mut Cursive) {
|
||||
let selection = s.find_id("select", |view: &mut SelectView<String>| {
|
||||
view.selected_id()
|
||||
}).unwrap();
|
||||
|
||||
match selection {
|
||||
let mut select = s.find_id::<SelectView<String>>("select").unwrap();
|
||||
match select.selected_id() {
|
||||
None => s.add_layer(Dialog::info("No name to remove")),
|
||||
Some(focus) => {
|
||||
s.find_id("select", |view: &mut SelectView<String>| {
|
||||
view.remove_item(focus)
|
||||
});
|
||||
select.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!
|
||||
|
||||
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.
|
||||
|
||||
Here's what it looks like in action:
|
||||
@ -244,7 +239,7 @@ fn add_name(s: &mut Cursive) {
|
||||
.fixed_width(10))
|
||||
.title("Enter a new name")
|
||||
.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()
|
||||
}).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
|
||||
calling `find_id`.
|
||||
calling `call_on_id`.
|
||||
|
||||
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:
|
||||
@ -272,7 +267,7 @@ That way, we can update it with a new item:
|
||||
```rust,ignore
|
||||
fn add_name(s: &mut Cursive) {
|
||||
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);
|
||||
});
|
||||
s.pop_layer();
|
||||
@ -284,7 +279,7 @@ fn add_name(s: &mut Cursive) {
|
||||
.fixed_width(10))
|
||||
.title("Enter a new name")
|
||||
.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()
|
||||
}).unwrap();
|
||||
ok(s, &name);
|
||||
@ -298,27 +293,30 @@ complicated:
|
||||
|
||||
```rust,ignore
|
||||
fn delete_name(s: &mut Cursive) {
|
||||
match s.find_id("select", |v: &mut SelectView<String>| {
|
||||
v.selected_id()
|
||||
}).unwrap() {
|
||||
let mut select = s.find_id::<SelectView<String>>("select").unwrap();
|
||||
match select.selected_id() {
|
||||
None => s.add_layer(Dialog::info("No name to remove")),
|
||||
Some(focus) => s.find_id("select", |v: &mut SelectView<String>| {
|
||||
v.remove_item(focus)
|
||||
}),
|
||||
Some(focus) => {
|
||||
select.remove_item(focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We use [`SelectView::selected_id`] and [`SelectView::remove_item`] to remove
|
||||
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
|
||||
[`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
|
||||
[`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::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::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"));
|
||||
///
|
||||
/// 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");
|
||||
/// });
|
||||
/// });
|
||||
/// # }
|
||||
/// ```
|
||||
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>
|
||||
where V: View + Any,
|
||||
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.
|
||||
///
|
||||
/// Convenient method to use `find` with a `view::Selector::Id`.
|
||||
/// Convenient method to use `call_on` with a `view::Selector::Id`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -427,7 +427,7 @@ impl Cursive {
|
||||
where V: View + Any,
|
||||
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`].
|
||||
|
@ -116,14 +116,14 @@ pub trait View {
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// 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
|
||||
}
|
||||
|
||||
@ -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.
|
||||
///
|
||||
/// [`View::find_any`]: ./trait.View.html#method.find_any
|
||||
/// [`View::call_on_any`]: ./trait.View.html#method.call_on_any
|
||||
pub trait Finder {
|
||||
/// 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,
|
||||
/// 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,
|
||||
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>
|
||||
where V: View + Any,
|
||||
F: FnOnce(&mut V) -> R
|
||||
{
|
||||
self.find(&Selector::Id(id), callback)
|
||||
self.call_on(&Selector::Id(id), callback)
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
F: FnOnce(&mut V) -> R
|
||||
{
|
||||
@ -190,7 +190,7 @@ impl<T: View> Finder for T {
|
||||
.and_then(|v| v.with_view_mut(callback));
|
||||
}
|
||||
};
|
||||
self.find_any(sel, Box::new(callback));
|
||||
self.call_on_any(sel, Box::new(callback));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
@ -52,9 +52,9 @@ pub trait ViewWrapper {
|
||||
}
|
||||
|
||||
/// 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>) {
|
||||
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.
|
||||
@ -89,9 +89,9 @@ impl<T: ViewWrapper> View for T {
|
||||
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>) {
|
||||
self.wrap_find_any(selector, callback)
|
||||
self.wrap_call_on_any(selector, callback)
|
||||
}
|
||||
|
||||
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>) {
|
||||
self.content.find_any(selector, callback);
|
||||
self.content.call_on_any(selector, callback);
|
||||
}
|
||||
|
||||
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use owning_ref::{RcRef, OwningHandle};
|
||||
use std::any::Any;
|
||||
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::any::Any;
|
||||
use std::rc::Rc;
|
||||
use view::{Selector, View, ViewWrapper};
|
||||
|
||||
@ -12,6 +12,10 @@ pub struct IdView<V: 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>>;
|
||||
|
||||
impl<V: View> IdView<V> {
|
||||
@ -24,6 +28,8 @@ impl<V: View> IdView<V> {
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
// TODO: return a standalone item (not tied to our lifetime)
|
||||
// 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))
|
||||
}
|
||||
|
||||
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>) {
|
||||
let result = match selector {
|
||||
&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
|
||||
}
|
||||
|
@ -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>) {
|
||||
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
|
||||
}
|
||||
|
||||
fn find_any<'a>(&mut self, selector: &Selector,
|
||||
fn call_on_any<'a>(&mut self, selector: &Selector,
|
||||
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
||||
for view in self.children
|
||||
.iter_mut()
|
||||
.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>) {
|
||||
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