mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
View::find_any now takes a closure instead of returning reference
Also updated Finder::find and find_id.
This commit is contained in:
parent
57c1c1ad61
commit
b63762d441
@ -144,7 +144,7 @@ fn main() {
|
|||||||
siv.run();
|
siv.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_next(s: &mut Cursive) {
|
fn show_next(_: &mut Cursive) {
|
||||||
// Empty for now
|
// Empty for now
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -40,7 +40,9 @@ 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::<SelectView<String>>("select").unwrap().add_item_str(name);
|
s.find_id("select", |view: &mut SelectView<String>| {
|
||||||
|
view.add_item_str(name)
|
||||||
|
});
|
||||||
s.pop_layer();
|
s.pop_layer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,19 +53,25 @@ 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::<EditView>("name").unwrap().get_content().clone();
|
s.find_id("name", |view: &mut EditView| {
|
||||||
|
view.get_content().clone()
|
||||||
|
}).unwrap();
|
||||||
ok(s, &name);
|
ok(s, &name);
|
||||||
})
|
})
|
||||||
.button("Cancel", |s| s.pop_layer()));
|
.button("Cancel", |s| s.pop_layer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_name(s: &mut Cursive) {
|
fn delete_name(s: &mut Cursive) {
|
||||||
match s.find_id::<SelectView<String>>("select").unwrap().selected_id() {
|
let selection = s.find_id("select", |view: &mut SelectView<String>| {
|
||||||
|
view.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::<SelectView<String>>("select")
|
s.find_id("select", |view: &mut SelectView<String>| {
|
||||||
.unwrap()
|
view.remove_item(focus)
|
||||||
.remove_item(focus)
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,8 +232,8 @@ 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`] can then give you a mutable
|
the [`Identifiable`] trait. [`Cursive::find_id`] allows you to run a closure
|
||||||
reference to the view.
|
on the view.
|
||||||
|
|
||||||
Here's what it looks like in action:
|
Here's what it looks like in action:
|
||||||
|
|
||||||
@ -236,8 +244,9 @@ 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 =
|
let name = s.find_id("name", |view: &mut EditView| {
|
||||||
s.find_id::<EditView>("name").unwrap().get_content().clone();
|
view.get_content().clone()
|
||||||
|
}).unwrap();
|
||||||
})
|
})
|
||||||
.button("Cancel", |s| s.pop_layer()));
|
.button("Cancel", |s| s.pop_layer()));
|
||||||
}
|
}
|
||||||
@ -263,7 +272,9 @@ 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::<SelectView<String>>("select").unwrap().add_item_str(name);
|
s.find_id("select", |view: &mut SelectView<String>| {
|
||||||
|
view.add_item_str(name);
|
||||||
|
});
|
||||||
s.pop_layer();
|
s.pop_layer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,8 +284,9 @@ 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 =
|
let name = s.find_id("name", |v: &mut EditView| {
|
||||||
s.find_id::<EditView>("name").unwrap().get_content().clone();
|
v.get_content().clone()
|
||||||
|
}).unwrap();
|
||||||
ok(s, &name);
|
ok(s, &name);
|
||||||
})
|
})
|
||||||
.button("Cancel", |s| s.pop_layer()));
|
.button("Cancel", |s| s.pop_layer()));
|
||||||
@ -286,13 +298,13 @@ complicated:
|
|||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
fn delete_name(s: &mut Cursive) {
|
fn delete_name(s: &mut Cursive) {
|
||||||
match s.find_id::<SelectView<String>>("select").unwrap().selected_id() {
|
match s.find_id("select", |v: &mut SelectView<String>| {
|
||||||
|
v.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) => {
|
Some(focus) => s.find_id("select", |v: &mut SelectView<String>| {
|
||||||
s.find_id::<SelectView<String>>("select")
|
v.remove_item(focus)
|
||||||
.unwrap()
|
}),
|
||||||
.remove_item(focus)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
extern crate cursive;
|
extern crate cursive;
|
||||||
|
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
use cursive::views::{Dialog, EditView, TextView};
|
|
||||||
use cursive::traits::*;
|
use cursive::traits::*;
|
||||||
|
use cursive::views::{Dialog, EditView, TextView};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut siv = Cursive::new();
|
let mut siv = Cursive::new();
|
||||||
@ -18,9 +18,9 @@ fn main() {
|
|||||||
.with_id("name")
|
.with_id("name")
|
||||||
.fixed_width(20))
|
.fixed_width(20))
|
||||||
.button("Ok", |s| {
|
.button("Ok", |s| {
|
||||||
let name = s.find_id::<EditView>("name")
|
let name =
|
||||||
.unwrap()
|
s.find_id("name", |view: &mut EditView| view.get_content())
|
||||||
.get_content();
|
.unwrap();
|
||||||
show_popup(s, &name);
|
show_popup(s, &name);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
extern crate cursive;
|
extern crate cursive;
|
||||||
|
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
|
use cursive::traits::*;
|
||||||
use cursive::views::{Checkbox, Dialog, EditView, LinearLayout, ListView,
|
use cursive::views::{Checkbox, Dialog, EditView, LinearLayout, ListView,
|
||||||
SelectView, TextView};
|
SelectView, TextView};
|
||||||
use cursive::traits::*;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut siv = Cursive::new();
|
let mut siv = Cursive::new();
|
||||||
@ -25,11 +25,12 @@ fn main() {
|
|||||||
.with_id("email2")
|
.with_id("email2")
|
||||||
.fixed_width(10)))
|
.fixed_width(10)))
|
||||||
.child("Receive spam?",
|
.child("Receive spam?",
|
||||||
Checkbox::new().on_change(|s, checked| {
|
Checkbox::new()
|
||||||
for name in &["email1", "email2"] {
|
.on_change(|s, checked| for name in &["email1",
|
||||||
let view: &mut EditView = s.find_id(name).unwrap();
|
"email2"] {
|
||||||
view.set_enabled(checked);
|
s.find_id(name, |view: &mut EditView| {
|
||||||
}
|
view.set_enabled(checked)
|
||||||
|
});
|
||||||
}))
|
}))
|
||||||
.delimiter()
|
.delimiter()
|
||||||
.child("Age",
|
.child("Age",
|
||||||
@ -39,10 +40,8 @@ fn main() {
|
|||||||
.item_str("19-30")
|
.item_str("19-30")
|
||||||
.item_str("31-40")
|
.item_str("31-40")
|
||||||
.item_str("41+"))
|
.item_str("41+"))
|
||||||
.with(|list| {
|
.with(|list| for i in 0..50 {
|
||||||
for i in 0..50 {
|
|
||||||
list.add_child(&format!("Item {}", i), EditView::new());
|
list.add_child(&format!("Item {}", i), EditView::new());
|
||||||
}
|
|
||||||
})));
|
})));
|
||||||
|
|
||||||
siv.run();
|
siv.run();
|
||||||
|
@ -13,9 +13,10 @@ fn show_popup(siv: &mut Cursive) {
|
|||||||
Dialog::around(TextView::new("Tak!"))
|
Dialog::around(TextView::new("Tak!"))
|
||||||
.button("Change", |s| {
|
.button("Change", |s| {
|
||||||
// Look for a view tagged "text". We _know_ it's there, so unwrap it.
|
// Look for a view tagged "text". We _know_ it's there, so unwrap it.
|
||||||
let view = s.find_id::<TextView>("text").unwrap();
|
s.find_id("text", |view: &mut TextView| {
|
||||||
let content: String = view.get_content().chars().rev().collect();
|
let content: String = view.get_content().chars().rev().collect();
|
||||||
view.set_content(content);
|
view.set_content(content);
|
||||||
|
});
|
||||||
})
|
})
|
||||||
.dismiss_button("Ok"));
|
.dismiss_button("Ok"));
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
extern crate cursive;
|
extern crate cursive;
|
||||||
|
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
use cursive::views::{Dialog, SliderView};
|
|
||||||
use cursive::traits::*;
|
use cursive::traits::*;
|
||||||
|
use cursive::views::{Dialog, SliderView};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut siv = Cursive::new();
|
let mut siv = Cursive::new();
|
||||||
@ -14,7 +14,7 @@ fn main() {
|
|||||||
.value(7)
|
.value(7)
|
||||||
.on_change(|s, v| {
|
.on_change(|s, v| {
|
||||||
let title = format!("[ {} ]", v);
|
let title = format!("[ {} ]", v);
|
||||||
s.find_id::<Dialog>("dialog").unwrap().set_title(title);
|
s.find_id("dialog", |view: &mut Dialog| view.set_title(title));
|
||||||
})
|
})
|
||||||
.on_enter(|s, v| {
|
.on_enter(|s, v| {
|
||||||
s.pop_layer();
|
s.pop_layer();
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
extern crate bear_lib_terminal;
|
extern crate bear_lib_terminal;
|
||||||
|
|
||||||
use ::backend;
|
|
||||||
use ::event::{Event, Key};
|
|
||||||
use self::bear_lib_terminal::Color as BltColor;
|
use self::bear_lib_terminal::Color as BltColor;
|
||||||
use self::bear_lib_terminal::geometry::Size;
|
use self::bear_lib_terminal::geometry::Size;
|
||||||
use self::bear_lib_terminal::terminal::{self, Event as BltEvent, KeyCode};
|
use self::bear_lib_terminal::terminal::{self, Event as BltEvent, KeyCode};
|
||||||
|
use backend;
|
||||||
|
use event::{Event, Key};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use ::theme::{BaseColor, Color, ColorStyle, Effect};
|
use theme::{BaseColor, Color, ColorStyle, Effect};
|
||||||
|
|
||||||
pub struct Concrete {
|
pub struct Concrete {
|
||||||
colours: BTreeMap<i16, (BltColor, BltColor)>,
|
colours: BTreeMap<i16, (BltColor, BltColor)>,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
extern crate ncurses;
|
extern crate ncurses;
|
||||||
|
|
||||||
use backend;
|
|
||||||
use event::{Event, Key};
|
|
||||||
|
|
||||||
use self::super::find_closest;
|
use self::super::find_closest;
|
||||||
|
use backend;
|
||||||
|
use event::{Event, Key};
|
||||||
use theme::{Color, ColorStyle, Effect};
|
use theme::{Color, ColorStyle, Effect};
|
||||||
use utf8;
|
use utf8;
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
extern crate pancurses;
|
extern crate pancurses;
|
||||||
|
|
||||||
|
|
||||||
use backend;
|
|
||||||
use event::{Event, Key};
|
|
||||||
|
|
||||||
use self::super::find_closest;
|
use self::super::find_closest;
|
||||||
|
use backend;
|
||||||
|
use event::{Event, Key};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use theme::{Color, ColorStyle, Effect};
|
use theme::{Color, ColorStyle, Effect};
|
||||||
use utf8;
|
use utf8;
|
||||||
@ -23,7 +23,8 @@ impl backend::Backend for Concrete {
|
|||||||
pancurses::cbreak();
|
pancurses::cbreak();
|
||||||
pancurses::start_color();
|
pancurses::start_color();
|
||||||
pancurses::curs_set(0);
|
pancurses::curs_set(0);
|
||||||
window.bkgd(pancurses::COLOR_PAIR(ColorStyle::Background.id() as pancurses::chtype));
|
window.bkgd(pancurses::COLOR_PAIR(ColorStyle::Background.id() as
|
||||||
|
pancurses::chtype));
|
||||||
|
|
||||||
Concrete {
|
Concrete {
|
||||||
window: window,
|
window: window,
|
||||||
@ -66,7 +67,8 @@ impl backend::Backend for Concrete {
|
|||||||
self.current_style.set(current_style);
|
self.current_style.set(current_style);
|
||||||
|
|
||||||
// self.window.attroff(style);
|
// self.window.attroff(style);
|
||||||
self.window.attron(pancurses::COLOR_PAIR(current_style.id() as pancurses::chtype));
|
self.window.attron(pancurses::COLOR_PAIR(current_style.id() as
|
||||||
|
pancurses::chtype));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_effect<F: FnOnce()>(&self, effect: Effect, f: F) {
|
fn with_effect<F: FnOnce()>(&self, effect: Effect, f: F) {
|
||||||
@ -101,7 +103,9 @@ impl backend::Backend for Concrete {
|
|||||||
// TODO: wait for a very short delay. If more keys are
|
// TODO: wait for a very short delay. If more keys are
|
||||||
// pipelined, it may be an escape sequence.
|
// pipelined, it may be an escape sequence.
|
||||||
pancurses::Input::Character('\u{7f}') |
|
pancurses::Input::Character('\u{7f}') |
|
||||||
pancurses::Input::Character('\u{8}') => Event::Key(Key::Backspace),
|
pancurses::Input::Character('\u{8}') => {
|
||||||
|
Event::Key(Key::Backspace)
|
||||||
|
}
|
||||||
pancurses::Input::Character('\u{9}') => Event::Key(Key::Tab),
|
pancurses::Input::Character('\u{9}') => Event::Key(Key::Tab),
|
||||||
pancurses::Input::Character('\u{1b}') => Event::Key(Key::Esc),
|
pancurses::Input::Character('\u{1b}') => Event::Key(Key::Esc),
|
||||||
pancurses::Input::Character(c) if 32 <= (c as u32) &&
|
pancurses::Input::Character(c) if 32 <= (c as u32) &&
|
||||||
|
@ -8,12 +8,12 @@ mod blt;
|
|||||||
#[cfg(any(feature = "ncurses", feature = "pancurses"))]
|
#[cfg(any(feature = "ncurses", feature = "pancurses"))]
|
||||||
mod curses;
|
mod curses;
|
||||||
|
|
||||||
|
#[cfg(feature = "bear-lib-terminal")]
|
||||||
|
pub use self::blt::*;
|
||||||
#[cfg(any(feature = "ncurses", feature = "pancurses"))]
|
#[cfg(any(feature = "ncurses", feature = "pancurses"))]
|
||||||
pub use self::curses::*;
|
pub use self::curses::*;
|
||||||
#[cfg(feature = "termion")]
|
#[cfg(feature = "termion")]
|
||||||
pub use self::termion::*;
|
pub use self::termion::*;
|
||||||
#[cfg(feature = "bear-lib-terminal")]
|
|
||||||
pub use self::blt::*;
|
|
||||||
|
|
||||||
pub trait Backend {
|
pub trait Backend {
|
||||||
fn init() -> Self;
|
fn init() -> Self;
|
||||||
|
@ -2,14 +2,14 @@ extern crate termion;
|
|||||||
|
|
||||||
extern crate chan_signal;
|
extern crate chan_signal;
|
||||||
|
|
||||||
use ::backend;
|
|
||||||
use chan;
|
|
||||||
use ::event::{Event, Key};
|
|
||||||
use self::termion::color as tcolor;
|
use self::termion::color as tcolor;
|
||||||
use self::termion::event::Key as TKey;
|
use self::termion::event::Key as TKey;
|
||||||
use self::termion::input::TermRead;
|
use self::termion::input::TermRead;
|
||||||
use self::termion::raw::IntoRawMode;
|
use self::termion::raw::IntoRawMode;
|
||||||
use self::termion::style as tstyle;
|
use self::termion::style as tstyle;
|
||||||
|
use backend;
|
||||||
|
use chan;
|
||||||
|
use event::{Event, Key};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -17,7 +17,7 @@ use std::io::Write;
|
|||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time;
|
use std::time;
|
||||||
|
|
||||||
use ::theme;
|
use theme;
|
||||||
|
|
||||||
pub struct Concrete {
|
pub struct Concrete {
|
||||||
terminal: termion::raw::RawTerminal<::std::io::Stdout>,
|
terminal: termion::raw::RawTerminal<::std::io::Stdout>,
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
//! * Relative direction: front or back.
|
//! * Relative direction: front or back.
|
||||||
//! Its actual direction depends on the orientation.
|
//! Its actual direction depends on the orientation.
|
||||||
|
|
||||||
use vec::Vec2;
|
|
||||||
use XY;
|
use XY;
|
||||||
|
use vec::Vec2;
|
||||||
|
|
||||||
/// Describes a vertical or horizontal orientation for a view.
|
/// Describes a vertical or horizontal orientation for a view.
|
||||||
#[derive(Clone,Copy,Debug,PartialEq)]
|
#[derive(Clone,Copy,Debug,PartialEq)]
|
||||||
|
34
src/lib.rs
34
src/lib.rs
@ -68,6 +68,7 @@ extern crate num;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate chan;
|
extern crate chan;
|
||||||
|
|
||||||
|
|
||||||
macro_rules! println_stderr(
|
macro_rules! println_stderr(
|
||||||
($($arg:tt)*) => { {
|
($($arg:tt)*) => { {
|
||||||
use ::std::io::Write;
|
use ::std::io::Write;
|
||||||
@ -364,8 +365,11 @@ impl Cursive {
|
|||||||
|
|
||||||
/// Tries to find the view pointed to by the given selector.
|
/// Tries to find the view pointed to by the given selector.
|
||||||
///
|
///
|
||||||
|
/// Runs a closure on the view once it's found, and return the
|
||||||
|
/// result.
|
||||||
|
///
|
||||||
/// 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.
|
/// returns None.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
@ -380,15 +384,18 @@ impl Cursive {
|
|||||||
/// .with_id("text"));
|
/// .with_id("text"));
|
||||||
///
|
///
|
||||||
/// siv.add_global_callback('p', |s| {
|
/// siv.add_global_callback('p', |s| {
|
||||||
/// s.find::<views::TextView>(&view::Selector::Id("text"))
|
/// s.find(&view::Selector::Id("text"), |view: &mut views::TextView| {
|
||||||
/// .unwrap()
|
/// view.set_content("Text #2");
|
||||||
/// .set_content("Text #2");
|
/// });
|
||||||
/// });
|
/// });
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn find<V: View + Any>(&mut self, sel: &view::Selector)
|
pub fn find<V, F, R>(&mut self, sel: &view::Selector, callback: F)
|
||||||
-> Option<&mut V> {
|
-> Option<R>
|
||||||
self.screen_mut().find(sel)
|
where V: View + Any,
|
||||||
|
F: FnOnce(&mut V) -> R
|
||||||
|
{
|
||||||
|
self.screen_mut().find(sel, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenient method to use `find` with a `view::Selector::Id`.
|
/// Convenient method to use `find` with a `view::Selector::Id`.
|
||||||
@ -406,14 +413,17 @@ impl Cursive {
|
|||||||
/// .with_id("text"));
|
/// .with_id("text"));
|
||||||
///
|
///
|
||||||
/// siv.add_global_callback('p', |s| {
|
/// siv.add_global_callback('p', |s| {
|
||||||
/// s.find_id::<views::TextView>("text")
|
/// s.find_id("text", |view: &mut views::TextView| {
|
||||||
/// .unwrap()
|
/// view.set_content("Text #2");
|
||||||
/// .set_content("Text #2");
|
/// });
|
||||||
/// });
|
/// });
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn find_id<V: View + Any>(&mut self, id: &str) -> Option<&mut V> {
|
pub fn find_id<V, F, R>(&mut self, id: &str, callback: F) -> Option<R>
|
||||||
self.find(&view::Selector::Id(id))
|
where V: View + Any,
|
||||||
|
F: FnOnce(&mut V) -> R
|
||||||
|
{
|
||||||
|
self.find(&view::Selector::Id(id), callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a global callback.
|
/// Adds a global callback.
|
||||||
|
@ -165,12 +165,12 @@ impl MenuTree {
|
|||||||
/// Returns `None` if the given title was not found,
|
/// Returns `None` if the given title was not found,
|
||||||
/// or if it wasn't a subtree.
|
/// or if it wasn't a subtree.
|
||||||
pub fn find_subtree(&mut self, title: &str) -> Option<&mut MenuTree> {
|
pub fn find_subtree(&mut self, title: &str) -> Option<&mut MenuTree> {
|
||||||
self.find_item(title).and_then(|item| {
|
self.find_item(title)
|
||||||
if let MenuItem::Subtree(_, ref mut tree) = *item {
|
.and_then(|item| if let MenuItem::Subtree(_, ref mut tree) =
|
||||||
|
*item {
|
||||||
Some(Rc::make_mut(tree))
|
Some(Rc::make_mut(tree))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,5 +191,4 @@ impl MenuTree {
|
|||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.children.is_empty()
|
self.children.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,9 @@ impl<'a> Printer<'a> {
|
|||||||
///
|
///
|
||||||
/// But nobody needs to know that.
|
/// But nobody needs to know that.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn new<T: Into<Vec2>>(size: T, theme: Theme, backend: &'a backend::Concrete) -> Self {
|
pub fn new<T: Into<Vec2>>(size: T, theme: Theme,
|
||||||
|
backend: &'a backend::Concrete)
|
||||||
|
-> Self {
|
||||||
Printer {
|
Printer {
|
||||||
offset: Vec2::zero(),
|
offset: Vec2::zero(),
|
||||||
size: size.into(),
|
size: size.into(),
|
||||||
|
@ -14,7 +14,7 @@ pub struct Prefix {
|
|||||||
/// The length (in bytes) of the string.
|
/// The length (in bytes) of the string.
|
||||||
pub length: usize,
|
pub length: usize,
|
||||||
/// The unicode-width of the string.
|
/// The unicode-width of the string.
|
||||||
pub width: usize
|
pub width: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the length (number of bytes) and width of a prefix that fits in the given `width`.
|
/// Computes the length (number of bytes) and width of a prefix that fits in the given `width`.
|
||||||
@ -42,7 +42,8 @@ pub struct Prefix {
|
|||||||
/// prefix(my_text.graphemes(true), 5, "");
|
/// prefix(my_text.graphemes(true), 5, "");
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn prefix<'a, I>(iter: I, available_width: usize, delimiter: &str) -> Prefix
|
pub fn prefix<'a, I>(iter: I, available_width: usize, delimiter: &str)
|
||||||
|
-> Prefix
|
||||||
where I: Iterator<Item = &'a str>
|
where I: Iterator<Item = &'a str>
|
||||||
{
|
{
|
||||||
let delimiter_width = delimiter.width();
|
let delimiter_width = delimiter.width();
|
||||||
@ -70,7 +71,7 @@ pub fn prefix<'a, I>(iter: I, available_width: usize, delimiter: &str) -> Prefix
|
|||||||
|
|
||||||
Prefix {
|
Prefix {
|
||||||
length: length,
|
length: length,
|
||||||
width: current_width
|
width: current_width,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ impl<T: Zero + Clone> XY<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T: Into<XY<usize>>> From<T> for XY<isize> {
|
impl<T: Into<XY<usize>>> From<T> for XY<isize> {
|
||||||
fn from(t: T) -> Self {
|
fn from(t: T) -> Self {
|
||||||
let other = t.into();
|
let other = t.into();
|
||||||
Self::new(other.x as isize, other.y as isize)
|
Self::new(other.x as isize, other.y as isize)
|
||||||
@ -115,7 +115,7 @@ impl From<(u32, u32)> for XY<usize> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<T: Add<Output=T>, O: Into<XY<T>>> Add<O> for XY<T> {
|
impl<T: Add<Output = T>, O: Into<XY<T>>> Add<O> for XY<T> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn add(self, other: O) -> Self {
|
fn add(self, other: O) -> Self {
|
||||||
@ -123,7 +123,7 @@ impl<T: Add<Output=T>, O: Into<XY<T>>> Add<O> for XY<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Sub<Output=T>, O: Into<XY<T>>> Sub<O> for XY<T> {
|
impl<T: Sub<Output = T>, O: Into<XY<T>>> Sub<O> for XY<T> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn sub(self, other: O) -> Self {
|
fn sub(self, other: O) -> Self {
|
||||||
@ -131,7 +131,7 @@ impl<T: Sub<Output=T>, O: Into<XY<T>>> Sub<O> for XY<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T: Clone + Div<Output=T>> Div<T> for XY<T> {
|
impl<T: Clone + Div<Output = T>> Div<T> for XY<T> {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn div(self, other: T) -> Self {
|
fn div(self, other: T) -> Self {
|
||||||
|
@ -50,10 +50,6 @@ mod identifiable;
|
|||||||
mod boxable;
|
mod boxable;
|
||||||
|
|
||||||
|
|
||||||
use Printer;
|
|
||||||
|
|
||||||
use direction::Direction;
|
|
||||||
use event::{Event, EventResult};
|
|
||||||
pub use self::boxable::Boxable;
|
pub use self::boxable::Boxable;
|
||||||
pub use self::identifiable::Identifiable;
|
pub use self::identifiable::Identifiable;
|
||||||
|
|
||||||
@ -65,6 +61,10 @@ pub use self::size_cache::SizeCache;
|
|||||||
pub use self::size_constraint::SizeConstraint;
|
pub use self::size_constraint::SizeConstraint;
|
||||||
pub use self::view_path::ViewPath;
|
pub use self::view_path::ViewPath;
|
||||||
pub use self::view_wrapper::ViewWrapper;
|
pub use self::view_wrapper::ViewWrapper;
|
||||||
|
use Printer;
|
||||||
|
|
||||||
|
use direction::Direction;
|
||||||
|
use event::{Event, EventResult};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
|
|
||||||
@ -122,8 +122,9 @@ pub trait View {
|
|||||||
/// 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(&mut self, &Selector) -> Option<&mut Any> {
|
fn find_any<'a>(&mut self, _: &Selector,
|
||||||
None
|
_: Box<FnMut(&mut Any) + 'a>) {
|
||||||
|
// TODO: FnMut -> FnOnce once it works
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This view is offered focus. Will it take it?
|
/// This view is offered focus. Will it take it?
|
||||||
@ -150,17 +151,38 @@ pub trait Finder {
|
|||||||
///
|
///
|
||||||
/// 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: View + Any>(&mut self, sel: &Selector) -> Option<&mut V>;
|
fn find<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 `find` with a `view::Selector::Id`.
|
||||||
fn find_id<V: View + Any>(&mut self, id: &str) -> Option<&mut V> {
|
fn find_id<V, F, R>(&mut self, id: &str, callback: F) -> Option<R>
|
||||||
self.find(&Selector::Id(id))
|
where V: View + Any,
|
||||||
|
F: FnOnce(&mut V) -> R
|
||||||
|
{
|
||||||
|
self.find(&Selector::Id(id), callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: View> Finder for T {
|
impl<T: View> Finder for T {
|
||||||
fn find<V: View + Any>(&mut self, sel: &Selector) -> Option<&mut V> {
|
fn find<V, F, R>(&mut self, sel: &Selector, callback: F) -> Option<R>
|
||||||
self.find_any(sel).and_then(|b| b.downcast_mut::<V>())
|
where V: View + Any,
|
||||||
|
F: FnOnce(&mut V) -> R
|
||||||
|
{
|
||||||
|
let mut result = None;
|
||||||
|
{
|
||||||
|
let result_ref = &mut result;
|
||||||
|
|
||||||
|
let mut callback = Some(callback);
|
||||||
|
let callback = |v: &mut Any| if let Some(callback) =
|
||||||
|
callback.take() {
|
||||||
|
if let Some(v) = v.downcast_mut::<V>() {
|
||||||
|
*result_ref = Some(callback(v));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.find_any(sel, Box::new(callback));
|
||||||
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ use view::{Selector, View};
|
|||||||
/// Default implementation forwards all calls to the child view.
|
/// Default implementation forwards all calls to the child view.
|
||||||
/// Overrides some methods as desired.
|
/// Overrides some methods as desired.
|
||||||
///
|
///
|
||||||
/// You can use the [`wrap_impl!`] macro to define `get_view` and
|
/// You can use the [`wrap_impl!`] macro to define `with_view` and
|
||||||
/// `get_view_mut` for you.
|
/// `with_view_mut` for you.
|
||||||
///
|
///
|
||||||
/// [`wrap_impl!`]: ../macro.wrap_impl.html
|
/// [`wrap_impl!`]: ../macro.wrap_impl.html
|
||||||
pub trait ViewWrapper {
|
pub trait ViewWrapper {
|
||||||
@ -20,44 +20,46 @@ pub trait ViewWrapper {
|
|||||||
type V: View;
|
type V: View;
|
||||||
|
|
||||||
/// Get an immutable reference to the wrapped view.
|
/// Get an immutable reference to the wrapped view.
|
||||||
fn get_view(&self) -> &Self::V;
|
fn with_view<F, R>(&self, f: F) -> R where F: FnOnce(&Self::V) -> R;
|
||||||
|
|
||||||
/// Get a mutable reference to the wrapped view.
|
/// Get a mutable reference to the wrapped view.
|
||||||
fn get_view_mut(&mut self) -> &mut Self::V;
|
fn with_view_mut<F, R>(&mut self, f: F) -> R
|
||||||
|
where F: FnOnce(&mut Self::V) -> R;
|
||||||
|
|
||||||
/// Wraps the `draw` method.
|
/// Wraps the `draw` method.
|
||||||
fn wrap_draw(&self, printer: &Printer) {
|
fn wrap_draw(&self, printer: &Printer) {
|
||||||
self.get_view().draw(printer);
|
self.with_view(|v| v.draw(printer));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the `required_size` method.
|
/// Wraps the `required_size` method.
|
||||||
fn wrap_required_size(&mut self, req: Vec2) -> Vec2 {
|
fn wrap_required_size(&mut self, req: Vec2) -> Vec2 {
|
||||||
self.get_view_mut().required_size(req)
|
self.with_view_mut(|v| v.required_size(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the `on_event` method.
|
/// Wraps the `on_event` method.
|
||||||
fn wrap_on_event(&mut self, ch: Event) -> EventResult {
|
fn wrap_on_event(&mut self, ch: Event) -> EventResult {
|
||||||
self.get_view_mut().on_event(ch)
|
self.with_view_mut(|v| v.on_event(ch))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the `layout` method.
|
/// Wraps the `layout` method.
|
||||||
fn wrap_layout(&mut self, size: Vec2) {
|
fn wrap_layout(&mut self, size: Vec2) {
|
||||||
self.get_view_mut().layout(size);
|
self.with_view_mut(|v| v.layout(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the `take_focus` method.
|
/// Wraps the `take_focus` method.
|
||||||
fn wrap_take_focus(&mut self, source: Direction) -> bool {
|
fn wrap_take_focus(&mut self, source: Direction) -> bool {
|
||||||
self.get_view_mut().take_focus(source)
|
self.with_view_mut(|v| v.take_focus(source))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the `find` method.
|
/// Wraps the `find` method.
|
||||||
fn wrap_find_any(&mut self, selector: &Selector) -> Option<&mut Any> {
|
fn wrap_find_any<'a>(&mut self, selector: &Selector,
|
||||||
self.get_view_mut().find_any(selector)
|
callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
|
self.with_view_mut(|v| v.find_any(selector, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.with_view(|v| v.needs_relayout())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,8 +84,9 @@ impl<T: ViewWrapper> View for T {
|
|||||||
self.wrap_take_focus(source)
|
self.wrap_take_focus(source)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> {
|
fn find_any<'a>(&mut self, selector: &Selector,
|
||||||
self.wrap_find_any(selector)
|
callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
|
self.wrap_find_any(selector, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn needs_relayout(&self) -> bool {
|
fn needs_relayout(&self) -> bool {
|
||||||
@ -93,7 +96,7 @@ impl<T: ViewWrapper> View for T {
|
|||||||
|
|
||||||
/// Convenient macro to implement the [`ViewWrapper`] trait.
|
/// Convenient macro to implement the [`ViewWrapper`] trait.
|
||||||
///
|
///
|
||||||
/// It defines the `get_view` and `get_view_mut` implementations,
|
/// It defines the `with_view` and `with_view_mut` implementations,
|
||||||
/// as well as the `type V` declaration.
|
/// as well as the `type V` declaration.
|
||||||
///
|
///
|
||||||
/// [`ViewWrapper`]: view/trait.ViewWrapper.html
|
/// [`ViewWrapper`]: view/trait.ViewWrapper.html
|
||||||
@ -117,12 +120,14 @@ macro_rules! wrap_impl {
|
|||||||
(self.$v:ident: $t:ty) => {
|
(self.$v:ident: $t:ty) => {
|
||||||
type V = $t;
|
type V = $t;
|
||||||
|
|
||||||
fn get_view(&self) -> &Self::V {
|
fn with_view<F, R>(&self, f: F) -> R where F: FnOnce(&Self::V) -> R {
|
||||||
&self.$v
|
f(&self.$v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_view_mut(&mut self) -> &mut Self::V {
|
fn with_view_mut<F, R>(&mut self, f: F) -> R
|
||||||
&mut self.$v
|
where F: FnOnce(&mut Self::V) -> R
|
||||||
|
{
|
||||||
|
f(&mut self.$v)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -61,9 +61,7 @@ impl Checkbox {
|
|||||||
///
|
///
|
||||||
/// Chainable variant.
|
/// Chainable variant.
|
||||||
pub fn checked(self) -> Self {
|
pub fn checked(self) -> Self {
|
||||||
self.with(|s| {
|
self.with(|s| { s.check(); })
|
||||||
s.check();
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the checkbox is checked.
|
/// Returns `true` if the checkbox is checked.
|
||||||
@ -80,9 +78,7 @@ impl Checkbox {
|
|||||||
///
|
///
|
||||||
/// Chainable variant.
|
/// Chainable variant.
|
||||||
pub fn unchecked(self) -> Self {
|
pub fn unchecked(self) -> Self {
|
||||||
self.with(|s| {
|
self.with(|s| { s.uncheck(); })
|
||||||
s.uncheck();
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the checkbox state.
|
/// Sets the checkbox state.
|
||||||
|
@ -399,7 +399,8 @@ impl View for Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> {
|
fn find_any<'a>(&mut self, selector: &Selector,
|
||||||
self.content.find_any(selector)
|
callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
|
self.content.find_any(selector, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,8 @@ use view::View;
|
|||||||
/// .with_id("name")
|
/// .with_id("name")
|
||||||
/// .fixed_width(20))
|
/// .fixed_width(20))
|
||||||
/// .button("Ok", |s| {
|
/// .button("Ok", |s| {
|
||||||
/// let name = s.find_id::<EditView>("name")
|
/// let name = s.find_id("name", |view: &mut EditView| view.get_content())
|
||||||
/// .unwrap()
|
/// .unwrap();
|
||||||
/// .get_content();
|
|
||||||
/// show_popup(s, &name);
|
/// show_popup(s, &name);
|
||||||
/// }));
|
/// }));
|
||||||
///
|
///
|
||||||
@ -239,9 +238,10 @@ impl EditView {
|
|||||||
// Look at the content before the cursor (we will print its tail).
|
// Look at the content before the cursor (we will print its tail).
|
||||||
// From the end, count the length until we reach `available`.
|
// From the end, count the length until we reach `available`.
|
||||||
// Then sum the byte lengths.
|
// Then sum the byte lengths.
|
||||||
let suffix_length =
|
let suffix_length = simple_suffix(&self.content[self.offset..
|
||||||
simple_suffix(&self.content[self.offset..self.cursor],
|
self.cursor],
|
||||||
available).length;
|
available)
|
||||||
|
.length;
|
||||||
self.offset = self.cursor - suffix_length;
|
self.offset = self.cursor - suffix_length;
|
||||||
// Make sure the cursor is in view
|
// Make sure the cursor is in view
|
||||||
assert!(self.cursor >= self.offset);
|
assert!(self.cursor >= self.offset);
|
||||||
@ -250,8 +250,8 @@ impl EditView {
|
|||||||
|
|
||||||
// If we have too much space
|
// If we have too much space
|
||||||
if self.content[self.offset..].width() < self.last_length {
|
if self.content[self.offset..].width() < self.last_length {
|
||||||
let suffix_length = simple_suffix(&self.content,
|
let suffix_length =
|
||||||
self.last_length - 1).length;
|
simple_suffix(&self.content, self.last_length - 1).length;
|
||||||
self.offset = self.content.len() - suffix_length;
|
self.offset = self.content.len() - suffix_length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -392,9 +392,7 @@ impl View for EditView {
|
|||||||
Event::Key(Key::Enter) if self.on_submit.is_some() => {
|
Event::Key(Key::Enter) if self.on_submit.is_some() => {
|
||||||
let cb = self.on_submit.clone().unwrap();
|
let cb = self.on_submit.clone().unwrap();
|
||||||
let content = self.content.clone();
|
let content = self.content.clone();
|
||||||
return EventResult::with_cb(move |s| {
|
return EventResult::with_cb(move |s| { cb(s, &content); });
|
||||||
cb(s, &content);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
_ => return EventResult::Ignored,
|
_ => return EventResult::Ignored,
|
||||||
}
|
}
|
||||||
@ -407,9 +405,7 @@ impl View for EditView {
|
|||||||
let content = self.content.clone();
|
let content = self.content.clone();
|
||||||
let cursor = self.cursor;
|
let cursor = self.cursor;
|
||||||
|
|
||||||
Callback::from_fn(move |s| {
|
Callback::from_fn(move |s| { cb(s, &content, cursor); })
|
||||||
cb(s, &content, cursor);
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
EventResult::Consumed(cb)
|
EventResult::Consumed(cb)
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,11 @@ impl<T: View> IdView<T> {
|
|||||||
impl<T: View + Any> ViewWrapper for IdView<T> {
|
impl<T: View + Any> ViewWrapper for IdView<T> {
|
||||||
wrap_impl!(self.view: T);
|
wrap_impl!(self.view: T);
|
||||||
|
|
||||||
fn wrap_find_any(&mut self, selector: &Selector) -> Option<&mut Any> {
|
fn wrap_find_any<'a>(&mut self, selector: &Selector,
|
||||||
|
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
match selector {
|
match selector {
|
||||||
&Selector::Id(id) if id == self.id => Some(&mut self.view),
|
&Selector::Id(id) if id == self.id => callback(&mut self.view),
|
||||||
s => self.view.find_any(s),
|
s => self.view.find_any(s, callback),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,10 @@ pub struct Layer<T: View> {
|
|||||||
view: T,
|
view: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T: View> Layer<T> {
|
impl<T: View> Layer<T> {
|
||||||
/// Wraps the given view.
|
/// Wraps the given view.
|
||||||
pub fn new(view: T) -> Self {
|
pub fn new(view: T) -> Self {
|
||||||
Layer {
|
Layer { view: view }
|
||||||
view: view,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,10 +375,10 @@ impl View for LinearLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> {
|
fn find_any<'a>(&mut self, selector: &Selector,
|
||||||
self.children
|
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
.iter_mut()
|
for child in &mut self.children {
|
||||||
.filter_map(|c| c.view.find_any(selector))
|
child.view.find_any(selector, Box::new(|any| callback(any)));
|
||||||
.next()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,14 +185,12 @@ impl View for ListView {
|
|||||||
.max()
|
.max()
|
||||||
.unwrap_or(0) + 1;
|
.unwrap_or(0) + 1;
|
||||||
|
|
||||||
self.scrollbase.draw(printer, |printer, i| {
|
self.scrollbase.draw(printer, |printer, i| match self.children[i] {
|
||||||
match self.children[i] {
|
|
||||||
Child::Row(ref label, ref view) => {
|
Child::Row(ref label, ref view) => {
|
||||||
printer.print((0, 0), label);
|
printer.print((0, 0), label);
|
||||||
view.draw(&printer.offset((offset, 0), i == self.focus));
|
view.draw(&printer.offset((offset, 0), i == self.focus));
|
||||||
}
|
}
|
||||||
Child::Delimiter => (),
|
Child::Delimiter => (),
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,11 +296,12 @@ impl View for ListView {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> {
|
fn find_any<'a>(&mut self, selector: &Selector,
|
||||||
self.children
|
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
|
for view in self.children
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.filter_map(Child::view)
|
.filter_map(Child::view) {
|
||||||
.filter_map(|v| v.find_any(selector))
|
view.find_any(selector, Box::new(|any| callback(any)));
|
||||||
.next()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,12 +228,9 @@ impl View for MenuPopup {
|
|||||||
Event::Key(Key::PageDown) => self.scroll_down(5, false),
|
Event::Key(Key::PageDown) => self.scroll_down(5, false),
|
||||||
|
|
||||||
Event::Key(Key::Home) => self.focus = 0,
|
Event::Key(Key::Home) => self.focus = 0,
|
||||||
Event::Key(Key::End) => {
|
Event::Key(Key::End) => self.focus = self.menu.children.len() - 1,
|
||||||
self.focus = self.menu.children.len() - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
Event::Key(Key::Right) if self.menu.children
|
Event::Key(Key::Right) if self.menu.children[self.focus]
|
||||||
[self.focus]
|
|
||||||
.is_subtree() => {
|
.is_subtree() => {
|
||||||
return match self.menu.children[self.focus] {
|
return match self.menu.children[self.focus] {
|
||||||
MenuItem::Subtree(_, ref tree) => {
|
MenuItem::Subtree(_, ref tree) => {
|
||||||
@ -243,8 +240,7 @@ impl View for MenuPopup {
|
|||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Event::Key(Key::Enter) if !self.menu.children
|
Event::Key(Key::Enter) if !self.menu.children[self.focus]
|
||||||
[self.focus]
|
|
||||||
.is_delimiter() => {
|
.is_delimiter() => {
|
||||||
return match self.menu.children[self.focus] {
|
return match self.menu.children[self.focus] {
|
||||||
MenuItem::Leaf(_, ref cb) => {
|
MenuItem::Leaf(_, ref cb) => {
|
||||||
|
@ -118,9 +118,7 @@ impl ProgressBar {
|
|||||||
pub fn start<F: FnOnce(Counter) + Send + 'static>(&mut self, f: F) {
|
pub fn start<F: FnOnce(Counter) + Send + 'static>(&mut self, f: F) {
|
||||||
let counter: Counter = self.value.clone();
|
let counter: Counter = self.value.clone();
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || { f(counter); });
|
||||||
f(counter);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts a function in a separate thread, and monitor the progress.
|
/// Starts a function in a separate thread, and monitor the progress.
|
||||||
|
@ -55,9 +55,7 @@ impl SliderView {
|
|||||||
///
|
///
|
||||||
/// Chainable variant.
|
/// Chainable variant.
|
||||||
pub fn value(self, value: usize) -> Self {
|
pub fn value(self, value: usize) -> Self {
|
||||||
self.with(|s| {
|
self.with(|s| { s.set_value(value); })
|
||||||
s.set_value(value);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a callback to be called when the slider is moved.
|
/// Sets a callback to be called when the slider is moved.
|
||||||
@ -79,9 +77,7 @@ impl SliderView {
|
|||||||
fn get_change_result(&self) -> EventResult {
|
fn get_change_result(&self) -> EventResult {
|
||||||
EventResult::Consumed(self.on_change.clone().map(|cb| {
|
EventResult::Consumed(self.on_change.clone().map(|cb| {
|
||||||
let value = self.value;
|
let value = self.value;
|
||||||
Callback::from_fn(move |s| {
|
Callback::from_fn(move |s| { cb(s, value); })
|
||||||
cb(s, value);
|
|
||||||
})
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,9 +144,7 @@ impl View for SliderView {
|
|||||||
Event::Key(Key::Enter) if self.on_enter.is_some() => {
|
Event::Key(Key::Enter) if self.on_enter.is_some() => {
|
||||||
let value = self.value;
|
let value = self.value;
|
||||||
let cb = self.on_enter.clone().unwrap();
|
let cb = self.on_enter.clone().unwrap();
|
||||||
EventResult::with_cb(move |s| {
|
EventResult::with_cb(move |s| { cb(s, value); })
|
||||||
cb(s, value);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
_ => EventResult::Ignored,
|
_ => EventResult::Ignored,
|
||||||
}
|
}
|
||||||
|
@ -180,10 +180,10 @@ impl View for StackView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_any(&mut self, selector: &Selector) -> Option<&mut Any> {
|
fn find_any<'a>(&mut self, selector: &Selector,
|
||||||
self.layers
|
mut callback: Box<FnMut(&mut Any) + 'a>) {
|
||||||
.iter_mut()
|
for layer in &mut self.layers {
|
||||||
.filter_map(|l| l.view.find_any(selector))
|
layer.view.find_any(selector, Box::new(|any| callback(any)));
|
||||||
.next()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,10 +375,9 @@ impl View for TextArea {
|
|||||||
} else {
|
} else {
|
||||||
printer.size.x
|
printer.size.x
|
||||||
};
|
};
|
||||||
printer.with_effect(effect, |printer| {
|
printer.with_effect(effect,
|
||||||
for y in 0..printer.size.y {
|
|printer| for y in 0..printer.size.y {
|
||||||
printer.print_hline((0, y), w, " ");
|
printer.print_hline((0, y), w, " ");
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// println_stderr!("Content: `{}`", &self.content);
|
// println_stderr!("Content: `{}`", &self.content);
|
||||||
|
@ -56,7 +56,7 @@ impl<T> XY<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T: Clone> XY<T> {
|
impl<T: Clone> XY<T> {
|
||||||
/// Returns a new `XY` with the axis `o` set to `value`.
|
/// Returns a new `XY` with the axis `o` set to `value`.
|
||||||
pub fn with_axis(&self, o: Orientation, value: T) -> Self {
|
pub fn with_axis(&self, o: Orientation, value: T) -> Self {
|
||||||
let mut new = self.clone();
|
let mut new = self.clone();
|
||||||
|
Loading…
Reference in New Issue
Block a user