This commit is contained in:
Alexandre Bury 2018-06-10 23:29:10 -07:00
parent 017e100b1b
commit 8acc08f340
83 changed files with 378 additions and 356 deletions

View File

@ -1,9 +1,9 @@
extern crate cursive; extern crate cursive;
use cursive::{Cursive, Printer};
use cursive::theme::{Color, ColorStyle}; use cursive::theme::{Color, ColorStyle};
use cursive::view::Boxable; use cursive::view::Boxable;
use cursive::views::Canvas; use cursive::views::Canvas;
use cursive::{Cursive, Printer};
// This example will draw a colored square with a gradient. // This example will draw a colored square with a gradient.
// //

View File

@ -1,7 +1,7 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::views::{Dialog, TextView}; use cursive::views::{Dialog, TextView};
use cursive::Cursive;
fn main() { fn main() {
// Creates the cursive root - required for every application. // Creates the cursive root - required for every application.

View File

@ -1,8 +1,8 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::traits::*; use cursive::traits::*;
use cursive::views::{Dialog, EditView, TextView}; use cursive::views::{Dialog, EditView, TextView};
use cursive::Cursive;
fn main() { fn main() {
let mut siv = Cursive::default(); let mut siv = Cursive::default();

View File

@ -1,7 +1,7 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::views::TextView; use cursive::views::TextView;
use cursive::Cursive;
fn main() { fn main() {
let mut siv = Cursive::default(); let mut siv = Cursive::default();

View File

@ -1,8 +1,8 @@
extern crate cursive; extern crate cursive;
use cursive::{Cursive, Printer};
use cursive::event::{Event, EventResult}; use cursive::event::{Event, EventResult};
use cursive::traits::*; use cursive::traits::*;
use cursive::{Cursive, Printer};
// This example define a custom view that prints any event it receives. // This example define a custom view that prints any event it receives.
// This is a handy way to check the input received by cursive. // This is a handy way to check the input received by cursive.

View File

@ -1,9 +1,9 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::align::HAlign; use cursive::align::HAlign;
use cursive::traits::*; use cursive::traits::*;
use cursive::views::{Dialog, DummyView, LinearLayout, TextView}; use cursive::views::{Dialog, DummyView, LinearLayout, TextView};
use cursive::Cursive;
// This example uses a LinearLayout to stick multiple views next to each other. // This example uses a LinearLayout to stick multiple views next to each other.

View File

@ -1,9 +1,10 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::traits::*; use cursive::traits::*;
use cursive::views::{Checkbox, Dialog, EditView, LinearLayout, ListView, use cursive::views::{
SelectView, TextView}; Checkbox, Dialog, EditView, LinearLayout, ListView, SelectView, TextView,
};
use cursive::Cursive;
// This example uses a ListView. // This example uses a ListView.
// //

View File

@ -1,8 +1,8 @@
extern crate cursive; extern crate cursive;
use cursive::{Cursive, Printer};
use cursive::traits::*; use cursive::traits::*;
use cursive::vec::Vec2; use cursive::vec::Vec2;
use cursive::{Cursive, Printer};
use std::collections::VecDeque; use std::collections::VecDeque;
use std::sync::mpsc; use std::sync::mpsc;
use std::thread; use std::thread;

View File

@ -1,12 +1,12 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::theme::BaseColor; use cursive::theme::BaseColor;
use cursive::theme::Color; use cursive::theme::Color;
use cursive::theme::Effect; use cursive::theme::Effect;
use cursive::theme::Style; use cursive::theme::Style;
use cursive::utils::markup::StyledString; use cursive::utils::markup::StyledString;
use cursive::views::{Dialog, TextView}; use cursive::views::{Dialog, TextView};
use cursive::Cursive;
fn main() { fn main() {
let mut siv = Cursive::default(); let mut siv = Cursive::default();

View File

@ -1,10 +1,10 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::event::Key; use cursive::event::Key;
use cursive::menu::MenuTree; use cursive::menu::MenuTree;
use cursive::traits::*; use cursive::traits::*;
use cursive::views::Dialog; use cursive::views::Dialog;
use cursive::Cursive;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
// This examples shows how to configure and use a menubar at the top of the // This examples shows how to configure and use a menubar at the top of the

View File

@ -3,13 +3,13 @@ extern crate rand;
mod game; mod game;
use cursive::Cursive;
use cursive::Printer;
use cursive::direction::Direction; use cursive::direction::Direction;
use cursive::event::{Event, EventResult, MouseButton, MouseEvent}; use cursive::event::{Event, EventResult, MouseButton, MouseEvent};
use cursive::theme::{BaseColor, Color, ColorStyle}; use cursive::theme::{BaseColor, Color, ColorStyle};
use cursive::vec::Vec2; use cursive::vec::Vec2;
use cursive::views::{Button, Dialog, LinearLayout, Panel, SelectView}; use cursive::views::{Button, Dialog, LinearLayout, Panel, SelectView};
use cursive::Cursive;
use cursive::Printer;
fn main() { fn main() {
let mut siv = Cursive::default(); let mut siv = Cursive::default();

View File

@ -1,9 +1,9 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::traits::*; use cursive::traits::*;
use cursive::view::{Offset, Position}; use cursive::view::{Offset, Position};
use cursive::views::{Dialog, OnEventView, TextView}; use cursive::views::{Dialog, OnEventView, TextView};
use cursive::Cursive;
// This example modifies a view after creation. // This example modifies a view after creation.

View File

@ -1,9 +1,9 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::view::Position; use cursive::view::Position;
use cursive::views::LayerPosition; use cursive::views::LayerPosition;
use cursive::views::TextView; use cursive::views::TextView;
use cursive::Cursive;
/// Moves top layer by the specified amount /// Moves top layer by the specified amount
fn move_top(c: &mut Cursive, x_in: isize, y_in: isize) { fn move_top(c: &mut Cursive, x_in: isize, y_in: isize) {

View File

@ -1,10 +1,10 @@
extern crate cursive; extern crate cursive;
extern crate rand; extern crate rand;
use cursive::Cursive;
use cursive::traits::*; use cursive::traits::*;
use cursive::views::{Button, Dialog, LinearLayout, ProgressBar, TextView};
use cursive::utils::Counter; use cursive::utils::Counter;
use cursive::views::{Button, Dialog, LinearLayout, ProgressBar, TextView};
use cursive::Cursive;
use rand::Rng; use rand::Rng;
use std::cmp::min; use std::cmp::min;
use std::thread; use std::thread;

View File

@ -1,7 +1,7 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::views::{Dialog, DummyView, LinearLayout, RadioGroup}; use cursive::views::{Dialog, DummyView, LinearLayout, RadioGroup};
use cursive::Cursive;
// This example uses radio buttons. // This example uses radio buttons.

View File

@ -1,8 +1,8 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::view::{Boxable, Identifiable}; use cursive::view::{Boxable, Identifiable};
use cursive::views::{Dialog, EditView, LinearLayout, TextView}; use cursive::views::{Dialog, EditView, LinearLayout, TextView};
use cursive::Cursive;
// This example shows a way to access multiple views at the same time. // This example shows a way to access multiple views at the same time.

View File

@ -1,10 +1,10 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::align::HAlign; use cursive::align::HAlign;
use cursive::event::EventResult; use cursive::event::EventResult;
use cursive::traits::*; use cursive::traits::*;
use cursive::views::{Dialog, OnEventView, SelectView, TextView}; use cursive::views::{Dialog, OnEventView, SelectView, TextView};
use cursive::Cursive;
// We'll use a SelectView here. // We'll use a SelectView here.
// //

View File

@ -1,8 +1,8 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::traits::*; use cursive::traits::*;
use cursive::views::{Dialog, SliderView}; use cursive::views::{Dialog, SliderView};
use cursive::Cursive;
fn main() { fn main() {
let mut siv = Cursive::default(); let mut siv = Cursive::default();

View File

@ -1,8 +1,8 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::theme::{Color, PaletteColor, Theme}; use cursive::theme::{Color, PaletteColor, Theme};
use cursive::views::TextView; use cursive::views::TextView;
use cursive::Cursive;
// This example sets the background color to the terminal default. // This example sets the background color to the terminal default.
// //

View File

@ -1,9 +1,9 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::event::{Event, Key}; use cursive::event::{Event, Key};
use cursive::traits::*; use cursive::traits::*;
use cursive::views::{Dialog, EditView, OnEventView, TextArea}; use cursive::views::{Dialog, EditView, OnEventView, TextArea};
use cursive::Cursive;
fn main() { fn main() {
let mut siv = Cursive::default(); let mut siv = Cursive::default();
@ -35,10 +35,10 @@ fn main() {
.min_width(10), .min_width(10),
) )
.button("Ok", |s| { .button("Ok", |s| {
let text = s.call_on_id( let text =
"edit", s.call_on_id("edit", |view: &mut EditView| {
|view: &mut EditView| view.get_content(), view.get_content()
).unwrap(); }).unwrap();
find(s, &text); find(s, &text);
}) })
.dismiss_button("Cancel"), .dismiss_button("Cancel"),

View File

@ -1,7 +1,7 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::views::{Dialog, TextView}; use cursive::views::{Dialog, TextView};
use cursive::Cursive;
fn main() { fn main() {
let mut siv = Cursive::default(); let mut siv = Cursive::default();

View File

@ -1,8 +1,8 @@
extern crate cursive; extern crate cursive;
use cursive::Cursive;
use cursive::theme::{BaseColor, BorderStyle, Color, ColorStyle}; use cursive::theme::{BaseColor, BorderStyle, Color, ColorStyle};
use cursive::views::{Dialog, EditView, LinearLayout, TextView}; use cursive::views::{Dialog, EditView, LinearLayout, TextView};
use cursive::Cursive;
fn main() { fn main() {
let mut siv = Cursive::default(); let mut siv = Cursive::default();

View File

@ -3,10 +3,10 @@ extern crate pretty_bytes;
use std::io; use std::io;
use cursive::Cursive;
use cursive::traits::{Boxable, With}; use cursive::traits::{Boxable, With};
use cursive::utils; use cursive::utils;
use cursive::views::{Canvas, Dialog, LinearLayout, ProgressBar}; use cursive::views::{Canvas, Dialog, LinearLayout, ProgressBar};
use cursive::Cursive;
use pretty_bytes::converter::convert; use pretty_bytes::converter::convert;
use std::thread; use std::thread;
use std::time; use std::time;
@ -31,10 +31,7 @@ fn main() {
let meta = std::fs::metadata(&source).unwrap(); let meta = std::fs::metadata(&source).unwrap();
// If possible, read the file size to have a progress bar. // If possible, read the file size to have a progress bar.
let len = meta.len(); let len = meta.len();
( (Some(source), if len > 0 { Some(len) } else { None })
Some(source),
if len > 0 { Some(len) } else { None },
)
} }
None => (None, None), None => (None, None),
}; };
@ -68,9 +65,7 @@ fn main() {
} }
// When we're done, shut down the application // When we're done, shut down the application
cb_sink cb_sink.send(Box::new(|s: &mut Cursive| s.quit())).unwrap();
.send(Box::new(|s: &mut Cursive| s.quit()))
.unwrap();
}); });
// Add a single view: progress status // Add a single view: progress status

View File

@ -5,10 +5,11 @@
extern crate bear_lib_terminal; extern crate bear_lib_terminal;
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, state, Event as BltEvent, use self::bear_lib_terminal::terminal::{
KeyCode}; self, state, Event as BltEvent, KeyCode,
};
use self::bear_lib_terminal::Color as BltColor;
use backend; use backend;
use event::{Event, Key, MouseButton, MouseEvent}; use event::{Event, Key, MouseButton, MouseEvent};
use std::collections::HashSet; use std::collections::HashSet;
@ -49,7 +50,7 @@ impl Backend {
} }
fn blt_keycode_to_ev( fn blt_keycode_to_ev(
&mut self, kc: KeyCode, shift: bool, ctrl: bool &mut self, kc: KeyCode, shift: bool, ctrl: bool,
) -> Event { ) -> Event {
match kc { match kc {
KeyCode::F1 KeyCode::F1
@ -179,12 +180,12 @@ impl backend::Backend for Backend {
fn set_color(&self, color: ColorPair) -> ColorPair { fn set_color(&self, color: ColorPair) -> ColorPair {
let current = ColorPair { let current = ColorPair {
front: blt_colour_to_colour(state::foreground()), front: blt_colour_to_colour(state::foreground()),
back: blt_colour_to_colour(state::background()) back: blt_colour_to_colour(state::background()),
}; };
let fg = colour_to_blt_colour(color.front, ColorRole::Foreground); let fg = colour_to_blt_colour(color.front, ColorRole::Foreground);
let bg = colour_to_blt_colour(color.back, ColorRole::Background); let bg = colour_to_blt_colour(color.back, ColorRole::Background);
terminal::set_colors(fg, bg); terminal::set_colors(fg, bg);
current current
@ -196,14 +197,14 @@ impl backend::Backend for Backend {
Effect::Bold Effect::Bold
| Effect::Italic | Effect::Italic
| Effect::Underline | Effect::Underline
| Effect::Simple => {}, | Effect::Simple => {}
// TODO: how to do this correctly?` // TODO: how to do this correctly?`
// BLT itself doesn't do this kind of thing, // BLT itself doesn't do this kind of thing,
// we'd need the colours in our position, // we'd need the colours in our position,
// but `f()` can do whatever // but `f()` can do whatever
Effect::Reverse => terminal::set_colors( Effect::Reverse => {
state::background(), state::foreground() terminal::set_colors(state::background(), state::foreground())
), }
} }
} }
@ -213,11 +214,11 @@ impl backend::Backend for Backend {
Effect::Bold Effect::Bold
| Effect::Italic | Effect::Italic
| Effect::Underline | Effect::Underline
| Effect::Simple => {}, | Effect::Simple => {}
// The process of reversing is the same as unreversing // The process of reversing is the same as unreversing
Effect::Reverse => terminal::set_colors( Effect::Reverse => {
state::background(), state::foreground() terminal::set_colors(state::background(), state::foreground())
), }
} }
} }

View File

@ -63,7 +63,7 @@ where
fn find_closest_pair(pair: &ColorPair, max_colors: i16) -> (i16, i16) { fn find_closest_pair(pair: &ColorPair, max_colors: i16) -> (i16, i16) {
( (
find_closest(&pair.front,max_colors), find_closest(&pair.front, max_colors),
find_closest(&pair.back, max_colors), find_closest(&pair.back, max_colors),
) )
} }

View File

@ -1,7 +1,7 @@
extern crate ncurses; extern crate ncurses;
use self::ncurses::mmask_t;
use self::super::split_i32; use self::super::split_i32;
use self::ncurses::mmask_t;
use backend; use backend;
use event::{Event, Key, MouseButton, MouseEvent}; use event::{Event, Key, MouseButton, MouseEvent};
use libc; use libc;
@ -10,7 +10,7 @@ use std::collections::HashMap;
use std::ffi::CString; use std::ffi::CString;
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::io::{Write}; use std::io::Write;
use theme::{Color, ColorPair, Effect}; use theme::{Color, ColorPair, Effect};
use utf8; use utf8;
use vec::Vec2; use vec::Vec2;
@ -95,10 +95,9 @@ impl Backend {
Box::new(c) Box::new(c)
} }
/// Save a new color pair. /// Save a new color pair.
fn insert_color( fn insert_color(
&self, pairs: &mut HashMap<(i16, i16), i16>, (front, back): (i16, i16) &self, pairs: &mut HashMap<(i16, i16), i16>, (front, back): (i16, i16),
) -> i16 { ) -> i16 {
let n = 1 + pairs.len() as i16; let n = 1 + pairs.len() as i16;
@ -157,7 +156,8 @@ impl Backend {
let _alt = (mevent.bstate & ncurses::BUTTON_ALT as mmask_t) != 0; let _alt = (mevent.bstate & ncurses::BUTTON_ALT as mmask_t) != 0;
let _ctrl = (mevent.bstate & ncurses::BUTTON_CTRL as mmask_t) != 0; let _ctrl = (mevent.bstate & ncurses::BUTTON_CTRL as mmask_t) != 0;
mevent.bstate &= !(ncurses::BUTTON_SHIFT | ncurses::BUTTON_ALT mevent.bstate &= !(ncurses::BUTTON_SHIFT
| ncurses::BUTTON_ALT
| ncurses::BUTTON_CTRL) | ncurses::BUTTON_CTRL)
as mmask_t; as mmask_t;

View File

@ -1,7 +1,7 @@
extern crate pancurses; extern crate pancurses;
use self::pancurses::mmask_t;
use self::super::split_i32; use self::super::split_i32;
use self::pancurses::mmask_t;
use backend; use backend;
use event::{Event, Key, MouseButton, MouseEvent}; use event::{Event, Key, MouseButton, MouseEvent};
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
@ -65,9 +65,7 @@ impl Backend {
/// Save a new color pair. /// Save a new color pair.
fn insert_color( fn insert_color(
&self, &self, pairs: &mut HashMap<(i16, i16), i32>, (front, back): (i16, i16),
pairs: &mut HashMap<(i16,i16), i32>,
(front, back): (i16, i16),
) -> i32 { ) -> i32 {
let n = 1 + pairs.len() as i32; let n = 1 + pairs.len() as i32;
@ -119,7 +117,8 @@ impl Backend {
let _alt = (mevent.bstate & pancurses::BUTTON_ALT as mmask_t) != 0; let _alt = (mevent.bstate & pancurses::BUTTON_ALT as mmask_t) != 0;
let _ctrl = (mevent.bstate & pancurses::BUTTON_CTRL as mmask_t) != 0; let _ctrl = (mevent.bstate & pancurses::BUTTON_CTRL as mmask_t) != 0;
mevent.bstate &= !(pancurses::BUTTON_SHIFT | pancurses::BUTTON_ALT mevent.bstate &= !(pancurses::BUTTON_SHIFT
| pancurses::BUTTON_ALT
| pancurses::BUTTON_CTRL) as mmask_t; | pancurses::BUTTON_CTRL) as mmask_t;
let make_event = |event| Event::Mouse { let make_event = |event| Event::Mouse {

View File

@ -1,7 +1,7 @@
//! Dummy backend //! Dummy backend
use backend; use backend;
use theme;
use event; use event;
use theme;
use vec::Vec2; use vec::Vec2;
pub struct Backend; pub struct Backend;

View File

@ -4,7 +4,7 @@
//! backend library, which handles all actual input and output. //! backend library, which handles all actual input and output.
//! //!
//! This module defines the `Backend` trait, as well as a few implementations //! This module defines the `Backend` trait, as well as a few implementations
//! using some common libraries. Each of those included backends needs a //! using some common libraries. Each of those included backends needs a
//! corresonding feature to be enabled. //! corresonding feature to be enabled.
use event; use event;
@ -14,9 +14,9 @@ use vec::Vec2;
pub mod dummy; pub mod dummy;
pub mod termion;
pub mod blt; pub mod blt;
pub mod curses; pub mod curses;
pub mod termion;
/// Trait defining the required methods to be a backend. /// Trait defining the required methods to be a backend.
pub trait Backend { pub trait Backend {
@ -58,7 +58,6 @@ pub trait Backend {
/// Enables the given effect. /// Enables the given effect.
fn set_effect(&self, effect: theme::Effect); fn set_effect(&self, effect: theme::Effect);
/// Disables the given effect. /// Disables the given effect.
fn unset_effect(&self, effect: theme::Effect); fn unset_effect(&self, effect: theme::Effect);
} }

View File

@ -46,14 +46,27 @@ impl Default for Cursive {
} }
} }
#[cfg(all(not(feature = "termion"), not(feature = "pancurses"), feature = "bear-lib-terminal"))] #[cfg(
all(
not(feature = "termion"),
not(feature = "pancurses"),
feature = "bear-lib-terminal"
)
)]
impl Default for Cursive { impl Default for Cursive {
fn default() -> Self { fn default() -> Self {
Self::blt() Self::blt()
} }
} }
#[cfg(all(not(feature = "termion"), not(feature = "pancurses"), not(feature = "bear-lib-terminal"), feature = "ncurses"))] #[cfg(
all(
not(feature = "termion"),
not(feature = "pancurses"),
not(feature = "bear-lib-terminal"),
feature = "ncurses"
)
)]
impl Default for Cursive { impl Default for Cursive {
fn default() -> Self { fn default() -> Self {
Self::ncurses() Self::ncurses()
@ -261,7 +274,7 @@ impl Cursive {
/// ///
/// `filename` must point to a valid toml file. /// `filename` must point to a valid toml file.
pub fn load_theme_file<P: AsRef<Path>>( pub fn load_theme_file<P: AsRef<Path>>(
&mut self, filename: P &mut self, filename: P,
) -> Result<(), theme::Error> { ) -> Result<(), theme::Error> {
self.set_theme(try!(theme::load_theme_file(filename))); self.set_theme(try!(theme::load_theme_file(filename)));
Ok(()) Ok(())
@ -366,7 +379,7 @@ impl Cursive {
/// # } /// # }
/// ``` /// ```
pub fn call_on<V, F, R>( pub fn call_on<V, F, R>(
&mut self, sel: &view::Selector, callback: F &mut self, sel: &view::Selector, callback: F,
) -> Option<R> ) -> Option<R>
where where
V: View + Any, V: View + Any,
@ -532,7 +545,7 @@ impl Cursive {
/// Convenient stub forwarding layer repositioning. /// Convenient stub forwarding layer repositioning.
pub fn reposition_layer( pub fn reposition_layer(
&mut self, layer: LayerPosition, position: Position &mut self, layer: LayerPosition, position: Position,
) { ) {
self.screen_mut().reposition_layer(layer, position); self.screen_mut().reposition_layer(layer, position);
} }
@ -661,7 +674,8 @@ impl Cursive {
event, position, .. event, position, ..
} = event } = event
{ {
if event.grabs_focus() && !self.menubar.autohide if event.grabs_focus()
&& !self.menubar.autohide
&& !self.menubar.has_submenu() && !self.menubar.has_submenu()
&& position.y == 0 && position.y == 0
{ {

View File

@ -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 XY;
use vec::Vec2; use vec::Vec2;
use XY;
/// 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)]

View File

@ -13,10 +13,10 @@
//! [global callback](../struct.Cursive.html#method.add_global_callback) //! [global callback](../struct.Cursive.html#method.add_global_callback)
//! table is checked. //! table is checked.
use Cursive;
use std::ops::Deref; use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use vec::Vec2; use vec::Vec2;
use Cursive;
/// Callback is a function that can be triggered by an event. /// Callback is a function that can be triggered by an event.
/// It has a mutable access to the cursive root. /// It has a mutable access to the cursive root.

View File

@ -72,8 +72,8 @@ extern crate log;
#[macro_use] #[macro_use]
extern crate maplit; extern crate maplit;
extern crate num;
extern crate libc; extern crate libc;
extern crate num;
extern crate owning_ref; extern crate owning_ref;
extern crate toml; extern crate toml;
extern crate unicode_segmentation; extern crate unicode_segmentation;
@ -100,20 +100,20 @@ pub mod event;
#[macro_use] #[macro_use]
pub mod view; pub mod view;
pub mod views; pub mod align;
pub mod vec; pub mod direction;
pub mod menu;
pub mod rect; pub mod rect;
pub mod theme; pub mod theme;
pub mod align;
pub mod menu;
pub mod direction;
pub mod utils; pub mod utils;
pub mod vec;
pub mod views;
// This probably doesn't need to be public? // This probably doesn't need to be public?
mod cursive; mod cursive;
mod printer; mod printer;
mod xy;
mod with; mod with;
mod xy;
mod div; mod div;
mod utf8; mod utf8;

View File

@ -12,10 +12,10 @@
//! //!
//! [menubar]: ../struct.Cursive.html#method.menubar //! [menubar]: ../struct.Cursive.html#method.menubar
use Cursive;
use With;
use event::Callback; use event::Callback;
use std::rc::Rc; use std::rc::Rc;
use Cursive;
use With;
/// Root of a menu tree. /// Root of a menu tree.
#[derive(Default, Clone)] #[derive(Default, Clone)]

View File

@ -33,7 +33,7 @@ impl<'a, 'b> Printer<'a, 'b> {
/// But nobody needs to know that. /// But nobody needs to know that.
#[doc(hidden)] #[doc(hidden)]
pub fn new<T: Into<Vec2>>( pub fn new<T: Into<Vec2>>(
size: T, theme: &'a Theme, backend: &'b Backend size: T, theme: &'a Theme, backend: &'b Backend,
) -> Self { ) -> Self {
Printer { Printer {
offset: Vec2::zero(), offset: Vec2::zero(),
@ -93,7 +93,7 @@ impl<'a, 'b> Printer<'a, 'b> {
let p = p + self.offset; let p = p + self.offset;
for y in 0..len { for y in 0..len {
self.backend.print_at(p + (0,y), c); self.backend.print_at(p + (0, y), c);
} }
} }
@ -178,12 +178,12 @@ impl<'a, 'b> Printer<'a, 'b> {
F: FnOnce(&Printer), F: FnOnce(&Printer),
{ {
let new_printer = Printer { let new_printer = Printer {
offset: self.offset, offset: self.offset,
size: self.size, size: self.size,
focused: self.focused, focused: self.focused,
theme : theme, theme: theme,
new: self.new.clone(), new: self.new.clone(),
backend : self.backend backend: self.backend,
}; };
f(&new_printer); f(&new_printer);
} }
@ -222,7 +222,7 @@ impl<'a, 'b> Printer<'a, 'b> {
/// printer.print_box((0,0), (6,4), false); /// printer.print_box((0,0), (6,4), false);
/// ``` /// ```
pub fn print_box<T: Into<Vec2>, S: Into<Vec2>>( pub fn print_box<T: Into<Vec2>, S: Into<Vec2>>(
&self, start: T, size: S, invert: bool &self, start: T, size: S, invert: bool,
) { ) {
self.new.set(false); self.new.set(false);
@ -319,7 +319,7 @@ impl<'a, 'b> Printer<'a, 'b> {
/// Returns a printer on a subset of this one's area. /// Returns a printer on a subset of this one's area.
pub fn sub_printer<S: Into<Vec2>, T: Into<Vec2>>( pub fn sub_printer<S: Into<Vec2>, T: Into<Vec2>>(
&self, offset: S, size: T, focused: bool &self, offset: S, size: T, focused: bool,
) -> Printer<'a, 'b> { ) -> Printer<'a, 'b> {
let size = size.into(); let size = size.into();
let offset = offset.into().or_min(self.size); let offset = offset.into().or_min(self.size);

View File

@ -80,7 +80,10 @@ impl Rect {
} }
/// Adds the given offset to this rectangle. /// Adds the given offset to this rectangle.
pub fn offset<V>(&mut self, offset: V) where V: Into<Vec2> { pub fn offset<V>(&mut self, offset: V)
where
V: Into<Vec2>,
{
let offset = offset.into(); let offset = offset.into();
self.top_left = self.top_left + offset; self.top_left = self.top_left + offset;
self.bottom_right = self.bottom_right + offset; self.bottom_right = self.bottom_right + offset;

View File

@ -156,13 +156,13 @@
//! highlight = "#F00" //! highlight = "#F00"
//! highlight_inactive = "#5555FF" //! highlight_inactive = "#5555FF"
//! ``` //! ```
mod style; mod border_style;
mod effect;
mod color; mod color;
mod color_pair; mod color_pair;
mod color_style; mod color_style;
mod border_style; mod effect;
mod palette; mod palette;
mod style;
pub use self::border_style::BorderStyle; pub use self::border_style::BorderStyle;
pub use self::color::{BaseColor, Color}; pub use self::color::{BaseColor, Color};

View File

@ -82,8 +82,9 @@ impl Palette {
for (key, value) in palette.iter() { for (key, value) in palette.iter() {
match *value { match *value {
PaletteNode::Color(color) => result.set_color(key, color), PaletteNode::Color(color) => result.set_color(key, color),
PaletteNode::Namespace(ref map) => PaletteNode::Namespace(ref map) => {
result.add_namespace(key, map.clone()), result.add_namespace(key, map.clone())
}
} }
} }
} }
@ -116,8 +117,11 @@ impl Palette {
} }
/// Adds a color namespace to this palette. /// Adds a color namespace to this palette.
fn add_namespace(&mut self, key: &str, namespace: HashMap<String, PaletteNode>) { fn add_namespace(
self.custom.insert(key.to_string(), PaletteNode::Namespace(namespace)); &mut self, key: &str, namespace: HashMap<String, PaletteNode>,
) {
self.custom
.insert(key.to_string(), PaletteNode::Namespace(namespace));
} }
} }
@ -158,14 +162,18 @@ impl Default for Palette {
} }
// Iterate over a toml // Iterate over a toml
fn iterate_toml<'a>(table: &'a toml::value::Table) -> impl Iterator<Item=(&'a str, PaletteNode)> + 'a { fn iterate_toml<'a>(
table: &'a toml::value::Table,
) -> impl Iterator<Item = (&'a str, PaletteNode)> + 'a {
table.iter().flat_map(|(key, value)| { table.iter().flat_map(|(key, value)| {
let node = match value { let node = match value {
toml::Value::Table(table) => { toml::Value::Table(table) => {
// This should define a new namespace // This should define a new namespace
// Treat basic colors as simple string. // Treat basic colors as simple string.
// We'll convert them back in the merge method. // We'll convert them back in the merge method.
let map = iterate_toml(table).map(|(key, value)| (key.to_string(), value)).collect(); let map = iterate_toml(table)
.map(|(key, value)| (key.to_string(), value))
.collect();
// Should we only return something if it's non-empty? // Should we only return something if it's non-empty?
Some(PaletteNode::Namespace(map)) Some(PaletteNode::Namespace(map))
} }
@ -184,7 +192,10 @@ fn iterate_toml<'a>(table: &'a toml::value::Table) -> impl Iterator<Item=(&'a st
} }
other => { other => {
// Other - error? // Other - error?
debug!("Found unexpected value in theme: {} = {:?}", key, other); debug!(
"Found unexpected value in theme: {} = {:?}",
key, other
);
None None
} }
}; };

View File

@ -8,7 +8,7 @@
//! use cursive::traits::*; //! use cursive::traits::*;
//! ``` //! ```
#[doc(no_inline)]
pub use With;
#[doc(no_inline)] #[doc(no_inline)]
pub use view::{Boxable, Finder, Identifiable, View}; pub use view::{Boxable, Finder, Identifiable, View};
#[doc(no_inline)]
pub use With;

View File

@ -1,5 +1,5 @@
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
/// Atomic counter used by [`ProgressBar`]. /// Atomic counter used by [`ProgressBar`].
/// ///

View File

@ -70,10 +70,6 @@ impl<'a> Iterator for LinesIterator<'a> {
let width = row.width; let width = row.width;
Some(Row { Some(Row { start, end, width })
start,
end,
width,
})
} }
} }

View File

@ -61,18 +61,19 @@ where
// `current_width` is the width of everything // `current_width` is the width of everything
// before the next token, including any space. // before the next token, including any space.
let mut current_width = 0; let mut current_width = 0;
let sum: usize = iter.take_while(|token| { let sum: usize =
let width = token.width(); iter.take_while(|token| {
if current_width + width > available_width { let width = token.width();
false if current_width + width > available_width {
} else { false
// Include the delimiter after this token. } else {
current_width += width; // Include the delimiter after this token.
current_width += delimiter_width; current_width += width;
true current_width += delimiter_width;
} true
}).map(|token| token.len() + delimiter_len) }
.sum(); }).map(|token| token.len() + delimiter_len)
.sum();
// We counted delimiter once too many times, // We counted delimiter once too many times,
// but only if the iterator was non empty. // but only if the iterator was non empty.

View File

@ -47,10 +47,7 @@ where
} }
// Skip empty spans // Skip empty spans
if self.source.spans()[self.current_span] if self.source.spans()[self.current_span].as_ref().is_empty() {
.as_ref()
.is_empty()
{
self.current_span += 1; self.current_span += 1;
return self.next(); return self.next();
} }
@ -123,13 +120,9 @@ where
self.current_span += 1; self.current_span += 1;
// Skip empty spans // Skip empty spans
while let Some(true) = self.source while let Some(true) =
.spans() self.source.spans().get(self.current_span).map(|span| {
.get(self.current_span) span.as_ref().resolve(self.source.source()).is_empty()
.map(|span| {
span.as_ref()
.resolve(self.source.source())
.is_empty()
}) { }) {
self.current_span += 1; self.current_span += 1;
} }

View File

@ -76,11 +76,8 @@ where
self.width self.width
}; };
let mut chunks = prefix( let mut chunks =
&mut self.iter, prefix(&mut self.iter, allowed_width, &mut self.chunk_offset);
allowed_width,
&mut self.chunk_offset,
);
// println!("Chunks..: {:?}", chunks); // println!("Chunks..: {:?}", chunks);
@ -152,10 +149,7 @@ where
// We can know text was wrapped if the stop was optional, // We can know text was wrapped if the stop was optional,
// and there's more coming. // and there's more coming.
let text_wrap = !chunks let text_wrap = !chunks.last().map(|c| c.hard_stop).unwrap_or(true)
.last()
.map(|c| c.hard_stop)
.unwrap_or(true)
&& self.iter.peek().is_some(); && self.iter.peek().is_some();
// If we had to break a line in two, then at least pretent we're // If we had to break a line in two, then at least pretent we're
@ -178,9 +172,6 @@ where
// TODO: merge consecutive segments of the same span // TODO: merge consecutive segments of the same span
Some(Row { Some(Row { segments, width })
segments,
width,
})
} }
} }

View File

@ -3,7 +3,7 @@ use std::iter::Peekable;
/// Concatenates chunks as long as they fit in the given width. /// Concatenates chunks as long as they fit in the given width.
pub fn prefix<I>( pub fn prefix<I>(
tokens: &mut Peekable<I>, width: usize, offset: &mut ChunkPart tokens: &mut Peekable<I>, width: usize, offset: &mut ChunkPart,
) -> Vec<Chunk> ) -> Vec<Chunk>
where where
I: Iterator<Item = Chunk>, I: Iterator<Item = Chunk>,

View File

@ -8,9 +8,7 @@ fn input() -> StyledString {
text.append(StyledString::styled("didn't", Effect::Bold)); text.append(StyledString::styled("didn't", Effect::Bold));
text.append(StyledString::plain(" say ")); text.append(StyledString::plain(" say "));
text.append(StyledString::styled("half", Effect::Italic)); text.append(StyledString::styled("half", Effect::Italic));
text.append(StyledString::plain( text.append(StyledString::plain(" the things people say I did."));
" the things people say I did.",
));
text.append(StyledString::plain("\n")); text.append(StyledString::plain("\n"));
text.append(StyledString::plain("\n")); text.append(StyledString::plain("\n"));
text.append(StyledString::plain(" - A. Einstein")); text.append(StyledString::plain(" - A. Einstein"));
@ -49,25 +47,19 @@ fn test_line_breaks() {
attr: &Style::from(Effect::Italic), attr: &Style::from(Effect::Italic),
}, },
], ],
vec![ vec![Span {
Span { content: "the things people",
content: "the things people", attr: &Style::none(),
attr: &Style::none(), }],
}, vec![Span {
], content: "say I did.",
vec![ attr: &Style::none(),
Span { }],
content: "say I did.",
attr: &Style::none(),
},
],
vec![], vec![],
vec![ vec![Span {
Span { content: " - A. Einstein",
content: " - A. Einstein", attr: &Style::none(),
attr: &Style::none(), }],
},
],
] ]
); );
} }

View File

@ -73,10 +73,12 @@ impl<'a> Iterator for Parser<'a> {
self.stack.push(Style::from(Effect::Italic)) self.stack.push(Style::from(Effect::Italic))
} }
Tag::Header(level) => { Tag::Header(level) => {
return Some(self.literal(format!( return Some(
"{} ", self.literal(format!(
header(level as usize) "{} ",
))) header(level as usize)
)),
)
} }
Tag::Rule => return Some(self.literal("---")), Tag::Rule => return Some(self.literal("---")),
Tag::BlockQuote => return Some(self.literal("> ")), Tag::BlockQuote => return Some(self.literal("> ")),
@ -139,10 +141,8 @@ Attention
==== ====
I *really* love __Cursive__!"; I *really* love __Cursive__!";
let spans = parse_spans(input); let spans = parse_spans(input);
let spans: Vec<_> = spans let spans: Vec<_> =
.iter() spans.iter().map(|span| span.resolve(input)).collect();
.map(|span| span.resolve(input))
.collect();
// println!("{:?}", spans); // println!("{:?}", spans);
assert_eq!( assert_eq!(

View File

@ -195,15 +195,13 @@ impl<T> SpannedString<T> {
{ {
let source = source.into(); let source = source.into();
let spans = vec![ let spans = vec![IndexedSpan {
IndexedSpan { content: IndexedCow::Borrowed {
content: IndexedCow::Borrowed { start: 0,
start: 0, end: source.len(),
end: source.len(),
},
attr,
}, },
]; attr,
}];
Self::with_spans(source, spans) Self::with_spans(source, spans)
} }

View File

@ -1,9 +1,9 @@
//! Points on the 2D character grid. //! Points on the 2D character grid.
use XY;
use num::traits::Zero; use num::traits::Zero;
use std::cmp::{max, min, Ordering}; use std::cmp::{max, min, Ordering};
use std::ops::{Add, Div, Mul, Sub}; use std::ops::{Add, Div, Mul, Sub};
use XY;
/// Simple 2D size, in cells. /// Simple 2D size, in cells.
/// ///

View File

@ -8,7 +8,7 @@ use views::BoxView;
pub trait Boxable: View + Sized { pub trait Boxable: View + Sized {
/// Wraps `self` in a `BoxView` with the given size constraints. /// Wraps `self` in a `BoxView` with the given size constraints.
fn boxed( fn boxed(
self, width: SizeConstraint, height: SizeConstraint self, width: SizeConstraint, height: SizeConstraint,
) -> BoxView<Self> { ) -> BoxView<Self> {
BoxView::new(width, height, self) BoxView::new(width, height, self)
} }

View File

@ -46,7 +46,8 @@ impl<T: View> Finder for T {
*result_ref = *result_ref =
v.downcast_mut::<V>().map(|v| callback(v)); v.downcast_mut::<V>().map(|v| callback(v));
} else if v.is::<IdView<V>>() { } else if v.is::<IdView<V>>() {
*result_ref = v.downcast_mut::<IdView<V>>() *result_ref = v
.downcast_mut::<IdView<V>>()
.and_then(|v| v.with_view_mut(callback)); .and_then(|v| v.with_view_mut(callback));
} }
} }

View File

@ -61,12 +61,7 @@ impl From<(usize, usize, usize, usize)> for Margins {
impl From<(i32, i32, i32, i32)> for Margins { impl From<(i32, i32, i32, i32)> for Margins {
fn from((left, right, top, bottom): (i32, i32, i32, i32)) -> Margins { fn from((left, right, top, bottom): (i32, i32, i32, i32)) -> Margins {
( (left as usize, right as usize, top as usize, bottom as usize).into()
left as usize,
right as usize,
top as usize,
bottom as usize,
).into()
} }
} }

View File

@ -41,17 +41,17 @@ mod view_wrapper;
// Essentials components // Essentials components
mod any; mod any;
mod finder; mod finder;
mod position;
mod margins; mod margins;
mod position;
mod size_cache; mod size_cache;
mod size_constraint; mod size_constraint;
mod view_path;
mod view; mod view;
mod view_path;
// Helper bases // Helper bases
mod scroll;
mod identifiable;
mod boxable; mod boxable;
mod identifiable;
mod scroll;
mod into_boxed_view; mod into_boxed_view;

View File

@ -1,6 +1,6 @@
use XY;
use std::cmp::min; use std::cmp::min;
use vec::Vec2; use vec::Vec2;
use XY;
/// Location of the view on screen /// Location of the view on screen
pub type Position = XY<Offset>; pub type Position = XY<Offset>;
@ -30,7 +30,7 @@ impl Position {
/// child with its top-left corner at the returned coordinates will /// child with its top-left corner at the returned coordinates will
/// position him appropriately. /// position him appropriately.
pub fn compute_offset<S, A, P>( pub fn compute_offset<S, A, P>(
&self, size: S, available: A, parent: P &self, size: S, available: A, parent: P,
) -> Vec2 ) -> Vec2
where where
S: Into<Vec2>, S: Into<Vec2>,
@ -65,7 +65,7 @@ pub enum Offset {
impl Offset { impl Offset {
/// Computes a single-dimension offset requred to draw a view. /// Computes a single-dimension offset requred to draw a view.
pub fn compute_offset( pub fn compute_offset(
&self, size: usize, available: usize, parent: usize &self, size: usize, available: usize, parent: usize,
) -> usize { ) -> usize {
if size > available { if size > available {
0 0

View File

@ -1,8 +1,8 @@
use Printer;
use div::div_up; use div::div_up;
use std::cmp::{max, min}; use std::cmp::{max, min};
use theme::ColorStyle; use theme::ColorStyle;
use vec::Vec2; use vec::Vec2;
use Printer;
/// Provide scrolling functionalities to a view. /// Provide scrolling functionalities to a view.
/// ///

View File

@ -18,10 +18,7 @@ pub struct SizeCache {
impl SizeCache { impl SizeCache {
/// Creates a new sized cache /// Creates a new sized cache
pub fn new(value: usize, constrained: bool) -> Self { pub fn new(value: usize, constrained: bool) -> Self {
SizeCache { SizeCache { value, constrained }
value,
constrained,
}
} }
/// Returns `true` if `self` is still valid for the given `request`. /// Returns `true` if `self` is still valid for the given `request`.

View File

@ -1,15 +1,14 @@
use Printer;
use direction::Direction; use direction::Direction;
use event::{Event, EventResult}; use event::{Event, EventResult};
use std::any::Any; use std::any::Any;
use vec::Vec2; use vec::Vec2;
use view::{AnyView, Selector}; use view::{AnyView, Selector};
use Printer;
/// Main trait defining a view behaviour. /// Main trait defining a view behaviour.
/// ///
/// This is what you should implement to define a custom View. /// This is what you should implement to define a custom View.
pub trait View: Any + AnyView { pub trait View: Any + AnyView {
/// Draws the view with the given printer (includes bounds) and focus. /// Draws the view with the given printer (includes bounds) and focus.
/// ///
/// This is the only *required* method to implement. /// This is the only *required* method to implement.
@ -63,7 +62,6 @@ pub trait View: Any + AnyView {
EventResult::Ignored EventResult::Ignored
} }
/// Runs a closure on the view identified by the given selector. /// Runs a closure on the view identified by the given selector.
/// ///
/// See [`Finder::call_on`] for a nicer interface, implemented for all /// See [`Finder::call_on`] for a nicer interface, implemented for all

View File

@ -1,9 +1,9 @@
use Printer;
use direction::Direction; use direction::Direction;
use event::{Event, EventResult}; use event::{Event, EventResult};
use std::any::Any; use std::any::Any;
use vec::Vec2; use vec::Vec2;
use view::{Selector, View}; use view::{Selector, View};
use Printer;
/// Generic wrapper around a view. /// Generic wrapper around a view.
/// ///
@ -78,7 +78,7 @@ pub trait ViewWrapper: 'static {
/// Wraps the `find` method. /// Wraps the `find` method.
fn wrap_call_on_any<'a>( fn wrap_call_on_any<'a>(
&mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a> &mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>,
) { ) {
self.with_view_mut(|v| v.call_on_any(selector, callback)); self.with_view_mut(|v| v.call_on_any(selector, callback));
} }
@ -118,7 +118,7 @@ impl<T: ViewWrapper> View for T {
} }
fn call_on_any<'a>( fn call_on_any<'a>(
&mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a> &mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>,
) { ) {
self.wrap_call_on_any(selector, callback) self.wrap_call_on_any(selector, callback)
} }

View File

@ -1,6 +1,6 @@
use XY;
use vec::Vec2; use vec::Vec2;
use view::{SizeConstraint, View, ViewWrapper}; use view::{SizeConstraint, View, ViewWrapper};
use XY;
/// Wrapper around another view, with a controlled size. /// Wrapper around another view, with a controlled size.
/// ///
@ -39,7 +39,7 @@ impl<T: View> BoxView<T> {
/// ///
/// `None` values will use the wrapped view's preferences. /// `None` values will use the wrapped view's preferences.
pub fn new( pub fn new(
width: SizeConstraint, height: SizeConstraint, view: T width: SizeConstraint, height: SizeConstraint, view: T,
) -> Self { ) -> Self {
BoxView { BoxView {
size: (width, height).into(), size: (width, height).into(),
@ -50,7 +50,7 @@ impl<T: View> BoxView<T> {
/// Sets the size constraints for this view. /// Sets the size constraints for this view.
pub fn set_constraints( pub fn set_constraints(
&mut self, width: SizeConstraint, height: SizeConstraint &mut self, width: SizeConstraint, height: SizeConstraint,
) { ) {
self.set_width(width); self.set_width(width);
self.set_height(height); self.set_height(height);
@ -195,7 +195,8 @@ impl<T: View> ViewWrapper for BoxView<T> {
let req = self.size.zip_map(req, SizeConstraint::available); let req = self.size.zip_map(req, SizeConstraint::available);
let child_size = self.view.required_size(req); let child_size = self.view.required_size(req);
let result = self.size let result = self
.size
.zip_map(child_size.zip(req), SizeConstraint::result); .zip_map(child_size.zip(req), SizeConstraint::result);
debug!("{:?}", result); debug!("{:?}", result);

View File

@ -1,4 +1,3 @@
use {Cursive, Printer, With};
use align::HAlign; use align::HAlign;
use direction::Direction; use direction::Direction;
use event::*; use event::*;
@ -6,6 +5,7 @@ use theme::ColorStyle;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use vec::Vec2; use vec::Vec2;
use view::View; use view::View;
use {Cursive, Printer, With};
/// Simple text label with a callback when <Enter> is pressed. /// Simple text label with a callback when <Enter> is pressed.
/// ///

View File

@ -1,9 +1,9 @@
use Printer;
use With;
use direction::Direction; use direction::Direction;
use event::{Event, EventResult}; use event::{Event, EventResult};
use vec::Vec2; use vec::Vec2;
use view::View; use view::View;
use Printer;
use With;
/// A blank view that forwards calls to closures. /// A blank view that forwards calls to closures.
/// ///

View File

@ -1,12 +1,12 @@
use Cursive;
use Printer;
use With;
use direction::Direction; use direction::Direction;
use event::{Event, EventResult, Key, MouseButton, MouseEvent}; use event::{Event, EventResult, Key, MouseButton, MouseEvent};
use std::rc::Rc; use std::rc::Rc;
use theme::ColorStyle; use theme::ColorStyle;
use vec::Vec2; use vec::Vec2;
use view::View; use view::View;
use Cursive;
use Printer;
use With;
/// Checkable box. /// Checkable box.
pub struct Checkbox { pub struct Checkbox {
@ -32,7 +32,7 @@ impl Checkbox {
/// Sets a callback to be used when the state changes. /// Sets a callback to be used when the state changes.
pub fn set_on_change<F: 'static + Fn(&mut Cursive, bool)>( pub fn set_on_change<F: 'static + Fn(&mut Cursive, bool)>(
&mut self, on_change: F &mut self, on_change: F,
) { ) {
self.on_change = Some(Rc::new(on_change)); self.on_change = Some(Rc::new(on_change));
} }
@ -41,7 +41,7 @@ impl Checkbox {
/// ///
/// Chainable variant. /// Chainable variant.
pub fn on_change<F: 'static + Fn(&mut Cursive, bool)>( pub fn on_change<F: 'static + Fn(&mut Cursive, bool)>(
self, on_change: F self, on_change: F,
) -> Self { ) -> Self {
self.with(|s| s.set_on_change(on_change)) self.with(|s| s.set_on_change(on_change))
} }

View File

@ -1,6 +1,3 @@
use Cursive;
use Printer;
use With;
use align::*; use align::*;
use direction::Direction; use direction::Direction;
use event::*; use event::*;
@ -12,6 +9,9 @@ use unicode_width::UnicodeWidthStr;
use vec::Vec2; use vec::Vec2;
use view::{Margins, Selector, View}; use view::{Margins, Selector, View};
use views::{Button, DummyView, SizedView, TextView, ViewBox}; use views::{Button, DummyView, SizedView, TextView, ViewBox};
use Cursive;
use Printer;
use With;
/// Identifies currently focused element in [`Dialog`]. /// Identifies currently focused element in [`Dialog`].
/// ///
@ -246,7 +246,7 @@ impl Dialog {
/// Returns an iterator on this buttons for this dialog. /// Returns an iterator on this buttons for this dialog.
pub fn buttons_mut<'a>( pub fn buttons_mut<'a>(
&'a mut self &'a mut self,
) -> Box<'a + Iterator<Item = &'a mut Button>> { ) -> Box<'a + Iterator<Item = &'a mut Button>> {
Box::new(self.buttons.iter_mut().map(|b| &mut b.button.view)) Box::new(self.buttons.iter_mut().map(|b| &mut b.button.view))
} }
@ -281,7 +281,7 @@ impl Dialog {
// An event is received while a button is in focus // An event is received while a button is in focus
fn on_event_button( fn on_event_button(
&mut self, event: Event, button_id: usize &mut self, event: Event, button_id: usize,
) -> EventResult { ) -> EventResult {
let result = { let result = {
let button = &mut self.buttons[button_id]; let button = &mut self.buttons[button_id];
@ -340,7 +340,8 @@ impl Dialog {
// Current horizontal position of the next button we'll draw. // Current horizontal position of the next button we'll draw.
// Sum of the sizes + len-1 for margins // Sum of the sizes + len-1 for margins
let width = self.buttons let width = self
.buttons
.iter() .iter()
.map(|button| button.button.size.x) .map(|button| button.button.size.x)
.sum::<usize>() .sum::<usize>()
@ -350,7 +351,8 @@ impl Dialog {
return None; return None;
} }
let mut offset = overhead.left let mut offset = overhead.left
+ self.align + self
.align
.h .h
.get_offset(width, printer.size.x - overhead.horizontal()); .get_offset(width, printer.size.x - overhead.horizontal());
@ -382,7 +384,8 @@ impl Dialog {
fn draw_content(&self, printer: &Printer, buttons_height: usize) { fn draw_content(&self, printer: &Printer, buttons_height: usize) {
// What do we have left? // What do we have left?
let taken = Vec2::new(0, buttons_height) + self.borders.combined() let taken = Vec2::new(0, buttons_height)
+ self.borders.combined()
+ self.padding.combined(); + self.padding.combined();
let inner_size = match printer.size.checked_sub(taken) { let inner_size = match printer.size.checked_sub(taken) {
@ -405,7 +408,8 @@ impl Dialog {
} }
let spacing = 3; //minimum distance to borders let spacing = 3; //minimum distance to borders
let x = spacing let x = spacing
+ self.title_position + self
.title_position
.get_offset(len, printer.size.x - 2 * spacing); .get_offset(len, printer.size.x - 2 * spacing);
printer.with_high_border(false, |printer| { printer.with_high_border(false, |printer| {
printer.print((x - 2, 0), ""); printer.print((x - 2, 0), "");
@ -564,7 +568,7 @@ impl View for Dialog {
} }
fn call_on_any<'a>( fn call_on_any<'a>(
&mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a> &mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>,
) { ) {
self.content.call_on_any(selector, callback); self.content.call_on_any(selector, callback);
} }

View File

@ -1,5 +1,5 @@
use Printer;
use view::View; use view::View;
use Printer;
/// Dummy view. /// Dummy view.
/// ///

View File

@ -367,8 +367,7 @@ impl EditView {
self.offset = 0; self.offset = 0;
self.set_cursor(len); self.set_cursor(len);
self.make_edit_cb() self.make_edit_cb().unwrap_or_else(Callback::dummy)
.unwrap_or_else(Callback::dummy)
} }
/// Get the current text. /// Get the current text.
@ -420,8 +419,7 @@ impl EditView {
self.keep_cursor_in_view(); self.keep_cursor_in_view();
self.make_edit_cb() self.make_edit_cb().unwrap_or_else(Callback::dummy)
.unwrap_or_else(Callback::dummy)
} }
/// Remove the character at the current cursor position. /// Remove the character at the current cursor position.
@ -436,8 +434,7 @@ impl EditView {
self.keep_cursor_in_view(); self.keep_cursor_in_view();
self.make_edit_cb() self.make_edit_cb().unwrap_or_else(Callback::dummy)
.unwrap_or_else(Callback::dummy)
} }
fn make_edit_cb(&self) -> Option<Callback> { fn make_edit_cb(&self) -> Option<Callback> {

View File

@ -77,7 +77,7 @@ impl<T: View + 'static> ViewWrapper for IdView<T> {
// Some for<'b> weirdness here to please the borrow checker gods... // Some for<'b> weirdness here to please the borrow checker gods...
fn wrap_call_on_any<'a>( fn wrap_call_on_any<'a>(
&mut self, selector: &Selector, mut callback: BoxedCallback<'a> &mut self, selector: &Selector, mut callback: BoxedCallback<'a>,
) { ) {
match selector { match selector {
&Selector::Id(id) if id == self.id => callback(self), &Selector::Id(id) if id == self.id => callback(self),
@ -93,7 +93,8 @@ impl<T: View + 'static> ViewWrapper for IdView<T> {
fn wrap_focus_view(&mut self, selector: &Selector) -> Result<(), ()> { fn wrap_focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
match selector { match selector {
&Selector::Id(id) if id == self.id => Ok(()), &Selector::Id(id) if id == self.id => Ok(()),
s => self.view s => self
.view
.try_borrow_mut() .try_borrow_mut()
.map_err(|_| ()) .map_err(|_| ())
.and_then(|mut v| v.deref_mut().focus_view(s)), .and_then(|mut v| v.deref_mut().focus_view(s)),

View File

@ -1,5 +1,5 @@
use Printer;
use view::{View, ViewWrapper}; use view::{View, ViewWrapper};
use Printer;
/// Wrapper view that fills the background. /// Wrapper view that fills the background.
/// ///

View File

@ -1,6 +1,3 @@
use Printer;
use With;
use XY;
use direction; use direction;
use event::{Event, EventResult, Key}; use event::{Event, EventResult, Key};
use std::any::Any; use std::any::Any;
@ -8,6 +5,9 @@ use std::cmp::min;
use std::ops::Deref; use std::ops::Deref;
use vec::Vec2; use vec::Vec2;
use view::{Selector, SizeCache, View}; use view::{Selector, SizeCache, View};
use Printer;
use With;
use XY;
/// Arranges its children linearly according to its orientation. /// Arranges its children linearly according to its orientation.
pub struct LinearLayout { pub struct LinearLayout {
@ -57,7 +57,7 @@ struct ChildItem<T> {
impl<T> ChildIterator<T> { impl<T> ChildIterator<T> {
fn new( fn new(
inner: T, orientation: direction::Orientation, available: usize inner: T, orientation: direction::Orientation, available: usize,
) -> Self { ) -> Self {
ChildIterator { ChildIterator {
inner, inner,
@ -195,7 +195,8 @@ impl LinearLayout {
} }
fn children_are_sleeping(&self) -> bool { fn children_are_sleeping(&self) -> bool {
!self.children !self
.children
.iter() .iter()
.map(Child::as_view) .map(Child::as_view)
.any(View::needs_relayout) .any(View::needs_relayout)
@ -203,7 +204,7 @@ impl LinearLayout {
/// Returns a cyclic mutable iterator starting with the child in focus /// Returns a cyclic mutable iterator starting with the child in focus
fn iter_mut<'a>( fn iter_mut<'a>(
&'a mut self, from_focus: bool, source: direction::Relative &'a mut self, from_focus: bool, source: direction::Relative,
) -> Box<Iterator<Item = (usize, &mut Child)> + 'a> { ) -> Box<Iterator<Item = (usize, &mut Child)> + 'a> {
match source { match source {
direction::Relative::Front => { direction::Relative::Front => {
@ -292,7 +293,7 @@ impl LinearLayout {
} }
fn try_focus( fn try_focus(
(i, child): (usize, &mut Child), source: direction::Direction (i, child): (usize, &mut Child), source: direction::Direction,
) -> Option<usize> { ) -> Option<usize> {
if child.view.take_focus(source) { if child.view.take_focus(source) {
Some(i) Some(i)
@ -358,7 +359,8 @@ impl View for LinearLayout {
} }
// First, make a naive scenario: everything will work fine. // First, make a naive scenario: everything will work fine.
let ideal_sizes: Vec<Vec2> = self.children let ideal_sizes: Vec<Vec2> = self
.children
.iter_mut() .iter_mut()
.map(|c| c.required_size(req)) .map(|c| c.required_size(req))
.collect(); .collect();
@ -382,7 +384,8 @@ impl View for LinearLayout {
// See how they like it that way. // See how they like it that way.
// This is, hopefully, the absolute minimum these views will accept. // This is, hopefully, the absolute minimum these views will accept.
let min_sizes: Vec<Vec2> = self.children let min_sizes: Vec<Vec2> = self
.children
.iter_mut() .iter_mut()
.map(|c| c.required_size(budget_req)) .map(|c| c.required_size(budget_req))
.collect(); .collect();
@ -462,7 +465,8 @@ impl View for LinearLayout {
// Let's ask everyone one last time. Everyone should be happy. // Let's ask everyone one last time. Everyone should be happy.
// (But they may ask more on the other axis.) // (But they may ask more on the other axis.)
let final_sizes: Vec<Vec2> = self.children let final_sizes: Vec<Vec2> = self
.children
.iter_mut() .iter_mut()
.enumerate() .enumerate()
.map(|(i, c)| c.required_size(final_lengths[i])) .map(|(i, c)| c.required_size(final_lengths[i]))
@ -482,10 +486,9 @@ impl View for LinearLayout {
// In what order will we iterate on the children? // In what order will we iterate on the children?
let rel = source.relative(self.orientation); let rel = source.relative(self.orientation);
// We activate from_focus only if coming from the "sides". // We activate from_focus only if coming from the "sides".
let i = if let Some(i) = self.iter_mut( let i = if let Some(i) = self
rel.is_none(), .iter_mut(rel.is_none(), rel.unwrap_or(direction::Relative::Front))
rel.unwrap_or(direction::Relative::Front), .filter_map(|p| try_focus(p, source))
).filter_map(|p| try_focus(p, source))
.next() .next()
{ {
// ... we can't update `self.focus` here, // ... we can't update `self.focus` here,

View File

@ -1,6 +1,3 @@
use Cursive;
use Printer;
use With;
use direction; use direction;
use event::{Callback, Event, EventResult, Key, MouseButton, MouseEvent}; use event::{Callback, Event, EventResult, Key, MouseButton, MouseEvent};
use std::any::Any; use std::any::Any;
@ -8,6 +5,9 @@ use std::rc::Rc;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use vec::Vec2; use vec::Vec2;
use view::{ScrollBase, Selector, View}; use view::{ScrollBase, Selector, View};
use Cursive;
use Printer;
use With;
/// Represents a child from a [`ListView`]. /// Represents a child from a [`ListView`].
/// ///
@ -148,7 +148,7 @@ impl ListView {
} }
fn iter_mut<'a>( fn iter_mut<'a>(
&'a mut self, from_focus: bool, source: direction::Relative &'a mut self, from_focus: bool, source: direction::Relative,
) -> Box<Iterator<Item = (usize, &mut ListChild)> + 'a> { ) -> Box<Iterator<Item = (usize, &mut ListChild)> + 'a> {
match source { match source {
direction::Relative::Front => { direction::Relative::Front => {
@ -172,7 +172,7 @@ impl ListView {
} }
fn move_focus( fn move_focus(
&mut self, n: usize, source: direction::Direction &mut self, n: usize, source: direction::Direction,
) -> EventResult { ) -> EventResult {
let i = if let Some(i) = source let i = if let Some(i) = source
.relative(direction::Orientation::Vertical) .relative(direction::Orientation::Vertical)
@ -246,7 +246,7 @@ impl ListView {
} }
fn try_focus( fn try_focus(
(i, child): (usize, &mut ListChild), source: direction::Direction (i, child): (usize, &mut ListChild), source: direction::Direction,
) -> Option<usize> { ) -> Option<usize> {
match *child { match *child {
ListChild::Delimiter => None, ListChild::Delimiter => None,
@ -279,14 +279,16 @@ impl View for ListView {
fn required_size(&mut self, req: Vec2) -> Vec2 { fn required_size(&mut self, req: Vec2) -> Vec2 {
// We'll show 2 columns: the labels, and the views. // We'll show 2 columns: the labels, and the views.
let label_width = self.children let label_width = self
.children
.iter() .iter()
.map(ListChild::label) .map(ListChild::label)
.map(UnicodeWidthStr::width) .map(UnicodeWidthStr::width)
.max() .max()
.unwrap_or(0); .unwrap_or(0);
let view_size = self.children let view_size = self
.children
.iter_mut() .iter_mut()
.filter_map(ListChild::view) .filter_map(ListChild::view)
.map(|v| v.required_size(req).x) .map(|v| v.required_size(req).x)
@ -306,7 +308,8 @@ impl View for ListView {
self.scrollbase.set_heights(size.y, self.children.len()); self.scrollbase.set_heights(size.y, self.children.len());
// We'll show 2 columns: the labels, and the views. // We'll show 2 columns: the labels, and the views.
let label_width = self.children let label_width = self
.children
.iter() .iter()
.map(ListChild::label) .map(ListChild::label)
.map(UnicodeWidthStr::width) .map(UnicodeWidthStr::width)
@ -316,7 +319,8 @@ impl View for ListView {
let spacing = 1; let spacing = 1;
let scrollbar_width = if self.children.len() > size.y { 2 } else { 0 }; let scrollbar_width = if self.children.len() > size.y { 2 } else { 0 };
let available = size.x let available = size
.x
.saturating_sub(label_width + spacing + scrollbar_width); .saturating_sub(label_width + spacing + scrollbar_width);
debug!("Available: {}", available); debug!("Available: {}", available);
@ -399,16 +403,10 @@ impl View for ListView {
Event::Key(Key::PageDown) => { Event::Key(Key::PageDown) => {
self.move_focus(10, direction::Direction::up()) self.move_focus(10, direction::Direction::up())
} }
Event::Key(Key::Home) | Event::Ctrl(Key::Home) => { Event::Key(Key::Home) | Event::Ctrl(Key::Home) => self
self.move_focus( .move_focus(usize::max_value(), direction::Direction::back()),
usize::max_value(), Event::Key(Key::End) | Event::Ctrl(Key::End) => self
direction::Direction::back(), .move_focus(usize::max_value(), direction::Direction::front()),
)
}
Event::Key(Key::End) | Event::Ctrl(Key::End) => self.move_focus(
usize::max_value(),
direction::Direction::front(),
),
Event::Key(Key::Tab) => { Event::Key(Key::Tab) => {
self.move_focus(1, direction::Direction::front()) self.move_focus(1, direction::Direction::front())
} }
@ -437,10 +435,9 @@ 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( let i = if let Some(i) = self
rel.is_none(), .iter_mut(rel.is_none(), rel.unwrap_or(direction::Relative::Front))
rel.unwrap_or(direction::Relative::Front), .filter_map(|p| try_focus(p, source))
).filter_map(|p| try_focus(p, source))
.next() .next()
{ {
i i
@ -463,7 +460,8 @@ impl View for ListView {
} }
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> { fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
if let Some(i) = self.children if let Some(i) = self
.children
.iter_mut() .iter_mut()
.enumerate() .enumerate()
.filter_map(|(i, v)| v.view().map(|v| (i, v))) .filter_map(|(i, v)| v.view().map(|v| (i, v)))

View File

@ -1,6 +1,3 @@
use Cursive;
use Printer;
use With;
use align::Align; use align::Align;
use event::{Callback, Event, EventResult, Key, MouseButton, MouseEvent}; use event::{Callback, Event, EventResult, Key, MouseButton, MouseEvent};
use menu::{MenuItem, MenuTree}; use menu::{MenuItem, MenuTree};
@ -10,6 +7,9 @@ use unicode_width::UnicodeWidthStr;
use vec::Vec2; use vec::Vec2;
use view::{Position, ScrollBase, View}; use view::{Position, ScrollBase, View};
use views::OnEventView; use views::OnEventView;
use Cursive;
use Printer;
use With;
/// Popup that shows a list of items. /// Popup that shows a list of items.
pub struct MenuPopup { pub struct MenuPopup {
@ -137,13 +137,13 @@ impl MenuPopup {
fn make_subtree_cb(&self, tree: &Rc<MenuTree>) -> EventResult { fn make_subtree_cb(&self, tree: &Rc<MenuTree>) -> EventResult {
let tree = Rc::clone(tree); let tree = Rc::clone(tree);
let max_width = 4 let max_width = 4 + self
+ self.menu .menu
.children .children
.iter() .iter()
.map(Self::item_width) .map(Self::item_width)
.max() .max()
.unwrap_or(1); .unwrap_or(1);
let offset = Vec2::new(max_width, self.focus); let offset = Vec2::new(max_width, self.focus);
let action_cb = self.on_action.clone(); let action_cb = self.on_action.clone();
@ -250,13 +250,13 @@ impl View for MenuPopup {
fn required_size(&mut self, req: Vec2) -> Vec2 { fn required_size(&mut self, req: Vec2) -> Vec2 {
// We can't really shrink our items here, so it's not flexible. // We can't really shrink our items here, so it's not flexible.
let w = 4 let w = 4 + self
+ self.menu .menu
.children .children
.iter() .iter()
.map(Self::item_width) .map(Self::item_width)
.max() .max()
.unwrap_or(1); .unwrap_or(1);
let h = 2 + self.menu.children.len(); let h = 2 + self.menu.children.len();
let scrolling = req.y < h; let scrolling = req.y < h;

View File

@ -1,5 +1,3 @@
use Cursive;
use Printer;
use direction; use direction;
use event::*; use event::*;
use menu::{MenuItem, MenuTree}; use menu::{MenuItem, MenuTree};
@ -9,6 +7,8 @@ use unicode_width::UnicodeWidthStr;
use vec::Vec2; use vec::Vec2;
use view::{Position, View}; use view::{Position, View};
use views::{MenuPopup, OnEventView}; use views::{MenuPopup, OnEventView};
use Cursive;
use Printer;
/// Current state of the menubar /// Current state of the menubar
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
@ -106,7 +106,7 @@ impl Menubar {
/// Insert a new item at the given position. /// Insert a new item at the given position.
pub fn insert_subtree<S>( pub fn insert_subtree<S>(
&mut self, i: usize, title: S, menu: MenuTree &mut self, i: usize, title: S, menu: MenuTree,
) -> &mut Self ) -> &mut Self
where where
S: Into<String>, S: Into<String>,
@ -341,7 +341,8 @@ impl View for Menubar {
.checked_sub(offset) .checked_sub(offset)
.and_then(|pos| self.child_at(pos.x)) .and_then(|pos| self.child_at(pos.x))
{ {
if self.focus == child && btn == MouseButton::Left if self.focus == child
&& btn == MouseButton::Left
&& self.root.children[child].is_leaf() && self.root.children[child].is_leaf()
{ {
return self.select_child(false); return self.select_child(false);
@ -371,7 +372,8 @@ impl View for Menubar {
// We add 2 to the length of every label for marin. // We add 2 to the length of every label for marin.
// Also, we add 1 at the beginning. // Also, we add 1 at the beginning.
// (See the `draw()` method) // (See the `draw()` method)
let width = self.root let width = self
.root
.children .children
.iter() .iter()
.map(|item| item.label().len() + 2) .map(|item| item.label().len() + 2)

View File

@ -35,7 +35,6 @@ macro_rules! impl_enabled {
} }
} }
mod view_box;
mod box_view; mod box_view;
mod button; mod button;
mod canvas; mod canvas;
@ -44,23 +43,24 @@ mod dialog;
mod dummy; mod dummy;
mod edit_view; mod edit_view;
mod id_view; mod id_view;
mod on_event_view;
mod layer; mod layer;
mod linear_layout; mod linear_layout;
mod list_view; mod list_view;
mod menubar;
mod menu_popup; mod menu_popup;
mod menubar;
mod on_event_view;
mod panel; mod panel;
mod progress_bar; mod progress_bar;
mod radio; mod radio;
mod select_view; mod select_view;
mod slider_view;
mod shadow_view; mod shadow_view;
mod sized_view; mod sized_view;
mod slider_view;
mod stack_view; mod stack_view;
mod text_area; mod text_area;
mod text_view; mod text_view;
mod tracked_view; mod tracked_view;
mod view_box;
pub use self::box_view::BoxView; pub use self::box_view::BoxView;
pub use self::button::Button; pub use self::button::Button;

View File

@ -1,9 +1,9 @@
use Cursive;
use With;
use event::{Callback, Event, EventResult}; use event::{Callback, Event, EventResult};
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use view::{View, ViewWrapper}; use view::{View, ViewWrapper};
use Cursive;
use With;
/// A wrapper view that can react to events. /// A wrapper view that can react to events.
/// ///

View File

@ -1,7 +1,7 @@
use Printer;
use event::{Event, EventResult}; use event::{Event, EventResult};
use vec::Vec2; use vec::Vec2;
use view::{View, ViewWrapper}; use view::{View, ViewWrapper};
use Printer;
/// Draws a border around a wrapped view. /// Draws a border around a wrapped view.
#[derive(Debug)] #[derive(Debug)]

View File

@ -1,10 +1,10 @@
use Printer;
use align::HAlign; use align::HAlign;
use std::cmp; use std::cmp;
use std::thread; use std::thread;
use theme::{ColorStyle, Effect}; use theme::{ColorStyle, Effect};
use utils::Counter; use utils::Counter;
use view::View; use view::View;
use Printer;
// pub type CbPromise = Option<Box<Fn(&mut Cursive) + Send>>; // pub type CbPromise = Option<Box<Fn(&mut Cursive) + Send>>;
@ -96,7 +96,7 @@ impl ProgressBar {
/// ///
/// Chainable variant. /// Chainable variant.
pub fn with_task<F: FnOnce(Counter) + Send + 'static>( pub fn with_task<F: FnOnce(Counter) + Send + 'static>(
mut self, task: F mut self, task: F,
) -> Self { ) -> Self {
self.start(task); self.start(task);
self self
@ -116,7 +116,7 @@ impl ProgressBar {
/// } /// }
/// ``` /// ```
pub fn with_label<F: Fn(usize, (usize, usize)) -> String + 'static>( pub fn with_label<F: Fn(usize, (usize, usize)) -> String + 'static>(
mut self, label_maker: F mut self, label_maker: F,
) -> Self { ) -> Self {
self.label_maker = Box::new(label_maker); self.label_maker = Box::new(label_maker);
self self

View File

@ -1,4 +1,3 @@
use {Printer, With};
use direction::Direction; use direction::Direction;
use event::{Event, EventResult, Key, MouseButton, MouseEvent}; use event::{Event, EventResult, Key, MouseButton, MouseEvent};
use std::cell::RefCell; use std::cell::RefCell;
@ -6,6 +5,7 @@ use std::rc::Rc;
use theme::ColorStyle; use theme::ColorStyle;
use vec::Vec2; use vec::Vec2;
use view::View; use view::View;
use {Printer, With};
struct SharedState<T> { struct SharedState<T> {
selection: usize, selection: usize,
@ -52,7 +52,7 @@ impl<T> RadioGroup<T> {
/// ///
/// The button will display `label` next to it, and will embed `value`. /// The button will display `label` next to it, and will embed `value`.
pub fn button<S: Into<String>>( pub fn button<S: Into<String>>(
&mut self, value: T, label: S &mut self, value: T, label: S,
) -> RadioButton<T> { ) -> RadioButton<T> {
let count = self.state.borrow().values.len(); let count = self.state.borrow().values.len();
self.state.borrow_mut().values.push(Rc::new(value)); self.state.borrow_mut().values.push(Rc::new(value));
@ -75,7 +75,7 @@ impl<T> RadioGroup<T> {
impl RadioGroup<String> { impl RadioGroup<String> {
/// Adds a button, using the label itself as value. /// Adds a button, using the label itself as value.
pub fn button_str<S: Into<String>>( pub fn button_str<S: Into<String>>(
&mut self, text: S &mut self, text: S,
) -> RadioButton<String> { ) -> RadioButton<String> {
let text = text.into(); let text = text.into();
self.button(text.clone(), text) self.button(text.clone(), text)
@ -104,7 +104,7 @@ impl<T> RadioButton<T> {
impl_enabled!(self.enabled); impl_enabled!(self.enabled);
fn new( fn new(
state: Rc<RefCell<SharedState<T>>>, id: usize, label: String state: Rc<RefCell<SharedState<T>>>, id: usize, label: String,
) -> Self { ) -> Self {
RadioButton { RadioButton {
state, state,

View File

@ -1,6 +1,3 @@
use Cursive;
use Printer;
use With;
use align::{Align, HAlign, VAlign}; use align::{Align, HAlign, VAlign};
use direction::Direction; use direction::Direction;
use event::{Callback, Event, EventResult, Key, MouseButton, MouseEvent}; use event::{Callback, Event, EventResult, Key, MouseButton, MouseEvent};
@ -14,6 +11,9 @@ use unicode_width::UnicodeWidthStr;
use vec::Vec2; use vec::Vec2;
use view::{Position, ScrollBase, View}; use view::{Position, ScrollBase, View};
use views::MenuPopup; use views::MenuPopup;
use Cursive;
use Printer;
use With;
/// View to select an item among a list. /// View to select an item among a list.
/// ///
@ -526,7 +526,8 @@ impl<T: 'static> SelectView<T> {
// the list when we reach the end. // the list when we reach the end.
// This is achieved by chaining twice the iterator // This is achieved by chaining twice the iterator
let iter = self.items.iter().chain(self.items.iter()); let iter = self.items.iter().chain(self.items.iter());
if let Some((i, _)) = iter.enumerate() if let Some((i, _)) = iter
.enumerate()
.skip(self.focus() + 1) .skip(self.focus() + 1)
.find(|&(_, item)| item.label.starts_with(c)) .find(|&(_, item)| item.label.starts_with(c))
{ {
@ -640,7 +641,10 @@ impl SelectView<String> {
} }
/// Convenient method to use the label as value. /// Convenient method to use the label as value.
pub fn insert_item_str<S>(&mut self, index: usize, label: S) where S: Into<String> { pub fn insert_item_str<S>(&mut self, index: usize, label: S)
where
S: Into<String>,
{
let label = label.into(); let label = label.into();
self.insert_item(index, label.clone(), label); self.insert_item(index, label.clone(), label);
} }
@ -732,7 +736,8 @@ impl<T: 'static> View for SelectView<T> {
// Items here are not compressible. // Items here are not compressible.
// So no matter what the horizontal requirements are, // So no matter what the horizontal requirements are,
// we'll still return our longest item. // we'll still return our longest item.
let w = self.items let w = self
.items
.iter() .iter()
.map(|item| item.label.width()) .map(|item| item.label.width())
.max() .max()

View File

@ -1,8 +1,8 @@
use Printer;
use event::{Event, EventResult}; use event::{Event, EventResult};
use theme::ColorStyle; use theme::ColorStyle;
use vec::Vec2; use vec::Vec2;
use view::{View, ViewWrapper}; use view::{View, ViewWrapper};
use Printer;
/// Wrapper view that adds a shadow. /// Wrapper view that adds a shadow.
/// ///

View File

@ -1,11 +1,11 @@
use {Cursive, Printer};
use With;
use direction::{Direction, Orientation}; use direction::{Direction, Orientation};
use event::{Callback, Event, EventResult, Key, MouseButton, MouseEvent}; use event::{Callback, Event, EventResult, Key, MouseButton, MouseEvent};
use std::rc::Rc; use std::rc::Rc;
use theme::ColorStyle; use theme::ColorStyle;
use vec::Vec2; use vec::Vec2;
use view::View; use view::View;
use With;
use {Cursive, Printer};
/// A horizontal or vertical slider. /// A horizontal or vertical slider.
pub struct SliderView { pub struct SliderView {

View File

@ -1,5 +1,3 @@
use Printer;
use With;
use direction::Direction; use direction::Direction;
use event::{Event, EventResult}; use event::{Event, EventResult};
use std::any::Any; use std::any::Any;
@ -9,6 +7,8 @@ use theme::ColorStyle;
use vec::Vec2; use vec::Vec2;
use view::{IntoBoxedView, Offset, Position, Selector, View, ViewWrapper}; use view::{IntoBoxedView, Offset, Position, Selector, View, ViewWrapper};
use views::{Layer, ShadowView, ViewBox}; use views::{Layer, ShadowView, ViewBox};
use Printer;
use With;
/// Simple stack of views. /// Simple stack of views.
/// Only the top-most view is active and can receive input. /// Only the top-most view is active and can receive input.
@ -37,7 +37,7 @@ pub enum LayerPosition {
impl Placement { impl Placement {
pub fn compute_offset<S, A, P>( pub fn compute_offset<S, A, P>(
&self, size: S, available: A, parent: P &self, size: S, available: A, parent: P,
) -> Vec2 ) -> Vec2
where where
S: Into<Vec2>, S: Into<Vec2>,
@ -146,7 +146,7 @@ impl<T: View> View for ChildWrapper<T> {
} }
fn call_on_any<'a>( fn call_on_any<'a>(
&mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a> &mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>,
) { ) {
match *self { match *self {
ChildWrapper::Shadow(ref mut v) => { ChildWrapper::Shadow(ref mut v) => {
@ -415,7 +415,7 @@ impl StackView {
/// Has no effect on fullscreen layers /// Has no effect on fullscreen layers
/// Has no effect if layer is not found /// Has no effect if layer is not found
pub fn reposition_layer( pub fn reposition_layer(
&mut self, layer: LayerPosition, position: Position &mut self, layer: LayerPosition, position: Position,
) { ) {
let i = self.get_index(layer); let i = self.get_index(layer);
let child = match self.layers.get_mut(i) { let child = match self.layers.get_mut(i) {
@ -675,21 +675,45 @@ mod tests {
.layer(TextView::new("1")) .layer(TextView::new("1"))
.layer(TextView::new("2")); .layer(TextView::new("2"));
assert!(stack.get(LayerPosition::FromFront(0)).unwrap() assert!(
.as_any().downcast_ref::<ViewBox>().unwrap() stack
.with_view(|v| v.as_any().is::<TextView>()).unwrap() .get(LayerPosition::FromFront(0))
.unwrap()
.as_any()
.downcast_ref::<ViewBox>()
.unwrap()
.with_view(|v| v.as_any().is::<TextView>())
.unwrap()
); );
assert!(stack.get(LayerPosition::FromBack(0)).unwrap() assert!(
.as_any().downcast_ref::<ViewBox>().unwrap() stack
.with_view(|v| v.as_any().is::<TextView>()).unwrap() .get(LayerPosition::FromBack(0))
.unwrap()
.as_any()
.downcast_ref::<ViewBox>()
.unwrap()
.with_view(|v| v.as_any().is::<TextView>())
.unwrap()
); );
assert!(stack.get_mut(LayerPosition::FromFront(0)).unwrap() assert!(
.as_any_mut().downcast_mut::<ViewBox>().unwrap() stack
.with_view_mut(|v| v.as_any_mut().is::<TextView>()).unwrap() .get_mut(LayerPosition::FromFront(0))
.unwrap()
.as_any_mut()
.downcast_mut::<ViewBox>()
.unwrap()
.with_view_mut(|v| v.as_any_mut().is::<TextView>())
.unwrap()
); );
assert!(stack.get_mut(LayerPosition::FromBack(0)).unwrap() assert!(
.as_any_mut().downcast_mut::<ViewBox>().unwrap() stack
.with_view_mut(|v| v.as_any_mut().is::<TextView>()).unwrap() .get_mut(LayerPosition::FromBack(0))
.unwrap()
.as_any_mut()
.downcast_mut::<ViewBox>()
.unwrap()
.with_view_mut(|v| v.as_any_mut().is::<TextView>())
.unwrap()
); );
} }
} }

View File

@ -1,4 +1,3 @@
use {Printer, With, XY};
use direction::Direction; use direction::Direction;
use event::{Event, EventResult, Key, MouseButton, MouseEvent}; use event::{Event, EventResult, Key, MouseButton, MouseEvent};
use std::cmp::min; use std::cmp::min;
@ -8,6 +7,7 @@ use unicode_width::UnicodeWidthStr;
use utils::lines::simple::{prefix, simple_prefix, LinesIterator, Row}; use utils::lines::simple::{prefix, simple_prefix, LinesIterator, Row};
use vec::Vec2; use vec::Vec2;
use view::{ScrollBase, SizeCache, View}; use view::{ScrollBase, SizeCache, View};
use {Printer, With, XY};
/// Multi-lines text editor. /// Multi-lines text editor.
/// ///
@ -437,7 +437,8 @@ impl View for TextArea {
debug!("{:?}", self.rows); debug!("{:?}", self.rows);
let scroll_width = if self.rows.len() > constraint.y { 1 } else { 0 }; let scroll_width = if self.rows.len() > constraint.y { 1 } else { 0 };
Vec2::new( Vec2::new(
scroll_width + 1 scroll_width
+ 1
+ self.rows.iter().map(|r| r.width).max().unwrap_or(1), + self.rows.iter().map(|r| r.width).max().unwrap_or(1),
self.rows.len(), self.rows.len(),
) )

View File

@ -1,19 +1,19 @@
use Printer;
use With;
use XY;
use align::*; use align::*;
use direction::Direction; use direction::Direction;
use event::*; use event::*;
use owning_ref::{ArcRef, OwningHandle}; use owning_ref::{ArcRef, OwningHandle};
use std::ops::Deref; use std::ops::Deref;
use std::sync::{Mutex, MutexGuard};
use std::sync::Arc; use std::sync::Arc;
use std::sync::{Mutex, MutexGuard};
use theme::Effect; use theme::Effect;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use utils::lines::spans::{LinesIterator, Row}; use utils::lines::spans::{LinesIterator, Row};
use utils::markup::StyledString; use utils::markup::StyledString;
use vec::Vec2; use vec::Vec2;
use view::{ScrollBase, ScrollStrategy, SizeCache, View}; use view::{ScrollBase, ScrollStrategy, SizeCache, View};
use Printer;
use With;
use XY;
/// Provides access to the content of a [`TextView`]. /// Provides access to the content of a [`TextView`].
/// ///
@ -421,7 +421,8 @@ impl TextView {
} }
// Desired width, including the scrollbar_width. // Desired width, including the scrollbar_width.
self.width = self.rows self.width = self
.rows
.iter() .iter()
.map(|row| row.width) .map(|row| row.width)
.max() .max()

View File

@ -1,8 +1,8 @@
use Printer;
use std::cell::Cell; use std::cell::Cell;
use vec::Vec2; use vec::Vec2;
use view::{View, ViewWrapper}; use view::{View, ViewWrapper};
use views::IdView; use views::IdView;
use Printer;
/// Wrapper around a view that remembers its position. /// Wrapper around a view that remembers its position.
pub struct TrackedView<T: View> { pub struct TrackedView<T: View> {