Split non-backend code into cursive-core

This commit is contained in:
Alexandre Bury 2020-04-15 12:20:50 -07:00
parent 0a6368d681
commit 4154f99b44
159 changed files with 865 additions and 635 deletions

View File

@ -10,6 +10,6 @@ jobs:
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: Build - name: Build
run: cargo build --no-default-features --verbose run: cd cursive && cargo build --no-default-features --verbose
- name: Run tests - name: Run tests
run: cargo test --no-default-features --verbose run: cd cursive && cargo test --no-default-features --verbose

View File

@ -4,6 +4,7 @@ rust:
- stable - stable
- nightly - nightly
script: script:
- cd cursive
- cargo check --all-features - cargo check --all-features
- cargo build --verbose --features "markdown pancurses-backend termion-backend crossterm-backend" - cargo build --verbose --features "markdown pancurses-backend termion-backend crossterm-backend"
- cargo test --verbose --features "markdown pancurses-backend termion-backend crossterm-backend" - cargo test --verbose --features "markdown pancurses-backend termion-backend crossterm-backend"

View File

@ -1,5 +1,33 @@
# Changelog # Changelog
## Next version (0.15.0)
### Breaking changes
- Split library into a backend-agnostic `cursive-core` and a user-facing `cursive`.
- `Cursive::default` now needs the `cursive::CursiveExt` trait to be in scope.
- Update dependencies:
- crossterm to 0.17.
- enumset to 1.0
- ahash to 0.3
- pulldown-cmark to 0.7
- Add `PaletteColor::HighlightText`
- `AnyCb` now takes a `&mut dyn View` rather than a `&mut dyn Any`.
### API updates
- Added `cursive::{default,ncurses,pancurses,termion,crossterm,blt,dummy}` functions.
- Add `Cursive::debug_name`
- Add `ScreensView` to move some code away from the `Cursive` root
- Reworked global callbacks configuration
- Ctrl-C can be rewired to no longer exit the application
### Bugfixes
- Fix Ctrl-Z binding for ncurses
- Fix potential crash with empty `SelectView`
- Add `toml` and `markdown` features to docs.rs
## 0.14.0 ## 0.14.0
### Breaking changes ### Breaking changes

View File

@ -1,98 +1,3 @@
[package] [workspace]
authors = ["Alexandre Bury <alexandre.bury@gmail.com>"]
categories = ["command-line-interface", "gui"]
description = "A TUI (Text User Interface) library focused on ease-of-use."
documentation = "https://docs.rs/cursive"
exclude = ["doc/**", "assets/**", "examples/**"]
keywords = ["ncurses", "TUI", "UI"]
license = "MIT"
name = "cursive"
readme = "Readme.md"
repository = "https://github.com/gyscos/cursive"
version = "0.14.1-alpha.0"
edition = "2018"
[package.metadata.docs.rs] members = ["cursive-core", "cursive"]
features = ["unstable_scroll", "scroll", "markdown"]
[badges.travis-ci]
repository = "gyscos/cursive"
[badges.appveyor]
repository = "gyscos/cursive"
[dependencies]
enum-map = "0.6.0"
enumset = "1.0.0"
log = "0.4.8"
owning_ref = "0.4.0"
unicode-segmentation = "1.3.0"
unicode-width = "0.1.5"
xi-unicode = "0.2.0"
libc = "0.2.60"
term_size = { version = "0.3.1", optional = true }
crossbeam-channel = "0.4.0"
lazy_static = "1"
chrono = "0.4.7"
cfg-if = "0.1.9"
ahash = "0.3"
[dependencies.toml]
optional = true
version = "0.5.1"
[dependencies.num]
default-features = false
version = "0.2.0"
[dependencies.maplit]
optional = true
version = "1.0.1"
[dependencies.bear-lib-terminal]
optional = true
version = "2.0.0"
[dependencies.ncurses]
features = ["wide"]
optional = true
version = "5.99.0"
[dependencies.pancurses]
features = ["wide"]
optional = true
version = "0.16.1"
[dependencies.pulldown-cmark]
default-features = false
optional = true
version = "0.7.0"
[dependencies.termion]
optional = true
version = "1.5.3"
[dependencies.crossterm]
optional = true
version = "0.17"
[target.'cfg(unix)'.dependencies]
signal-hook = "0.1"
[dev-dependencies]
rand = "0.7.0"
pretty-bytes = "0.2.2"
atty = "0.2.13"
[features]
blt-backend = ["bear-lib-terminal"]
default = ["ncurses-backend"]
markdown = ["pulldown-cmark"]
ncurses-backend = ["ncurses", "maplit", "term_size"]
pancurses-backend = ["pancurses", "maplit", "term_size"]
termion-backend = ["termion"]
crossterm-backend = ["crossterm"]
unstable_scroll = []
[lib]
name = "cursive"

View File

@ -30,12 +30,11 @@ cursive = { git = "https://github.com/gyscos/cursive" }
([You will also need ncurses installed.](https://github.com/gyscos/cursive/wiki/Install-ncurses)) ([You will also need ncurses installed.](https://github.com/gyscos/cursive/wiki/Install-ncurses))
```rust,no_run ```rust,no_run
use cursive::Cursive;
use cursive::views::{Dialog, TextView}; use cursive::views::{Dialog, TextView};
fn main() { fn main() {
// Creates the cursive root - required for every application. // Creates the cursive root - required for every application.
let mut siv = Cursive::default(); let mut siv = cursive::default();
// Creates a dialog with a single "Quit" button // Creates a dialog with a single "Quit" button
siv.add_layer(Dialog::around(TextView::new("Hello Dialog!")) siv.add_layer(Dialog::around(TextView::new("Hello Dialog!"))

View File

@ -33,4 +33,4 @@ build: false
# Equivalent to Travis' `script` phase # Equivalent to Travis' `script` phase
# TODO modify this phase as you see fit # TODO modify this phase as you see fit
test_script: test_script:
- cargo test --verbose --all --no-default-features --features pancurses-backend - cd cursive && cargo test --verbose --all --no-default-features --features pancurses-backend

64
cursive-core/Cargo.toml Normal file
View File

@ -0,0 +1,64 @@
[package]
authors = ["Alexandre Bury <alexandre.bury@gmail.com>"]
categories = ["command-line-interface", "gui"]
description = "Core components for the Cursive TUI"
documentation = "https://docs.rs/cursive"
exclude = ["doc/**", "assets/**", "examples/**"]
keywords = ["ncurses", "TUI", "UI"]
license = "MIT"
name = "cursive_core"
readme = "Readme.md"
repository = "https://github.com/gyscos/cursive"
version = "0.1.0"
edition = "2018"
[package.metadata.docs.rs]
features = ["unstable_scroll", "scroll", "markdown"]
[badges.travis-ci]
repository = "gyscos/cursive"
[badges.appveyor]
repository = "gyscos/cursive"
[dependencies]
enum-map = "0.6.0"
enumset = "1.0.0"
log = "0.4.8"
owning_ref = "0.4.0"
unicode-segmentation = "1.3.0"
unicode-width = "0.1.5"
xi-unicode = "0.2.0"
libc = "0.2.60"
crossbeam-channel = "0.4.0"
lazy_static = "1"
chrono = "0.4.7"
ahash = "0.3"
[dependencies.toml]
optional = true
version = "0.5.1"
[dependencies.num]
default-features = false
version = "0.2.0"
[dependencies.pulldown-cmark]
default-features = false
optional = true
version = "0.7.0"
[target.'cfg(unix)'.dependencies]
signal-hook = "0.1"
[dev-dependencies]
rand = "0.7.0"
pretty-bytes = "0.2.2"
atty = "0.2.13"
[features]
markdown = ["pulldown-cmark"]
unstable_scroll = []
[lib]
name = "cursive_core"

View File

@ -12,17 +12,6 @@ use crate::theme;
use crate::Vec2; use crate::Vec2;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
#[cfg(unix)]
mod resize;
pub mod dummy;
pub mod blt;
pub mod crossterm;
pub mod curses;
pub mod puppet;
pub mod termion;
/// Trait defining the required methods to be a backend. /// Trait defining the required methods to be a backend.
/// ///
/// A backend is the interface between the abstract view tree and the actual /// A backend is the interface between the abstract view tree and the actual
@ -40,11 +29,14 @@ pub mod termion;
pub trait Backend { pub trait Backend {
/// Polls the backend for any input. /// Polls the backend for any input.
/// ///
/// Should return immediately. /// Should return immediately:
/// * `None` if no event is currently available.
/// * `Some(event)` for each event to process.
fn poll_event(&mut self) -> Option<Event>; fn poll_event(&mut self) -> Option<Event>;
// TODO: take `self` by value? // TODO: take `self` by value?
// Or implement Drop? // Or implement Drop?
// Will change when implementing resumable backends
/// Prepares to close the backend. /// Prepares to close the backend.
/// ///
/// This should clear any state in the terminal. /// This should clear any state in the terminal.
@ -67,8 +59,11 @@ pub trait Backend {
/// Main method used for printing /// Main method used for printing
fn print_at(&self, pos: Vec2, text: &str); fn print_at(&self, pos: Vec2, text: &str);
/// First positions the cursor, similar to `print_at`, and then prints the given number of /// Efficient method to print repetitions of the same text.
/// `repetitions` of `text`. ///
/// Usually used to draw horizontal lines/borders.
///
/// It is a small optimization to avoid moving the cursor after each step.
fn print_at_rep(&self, pos: Vec2, repetitions: usize, text: &str) { fn print_at_rep(&self, pos: Vec2, repetitions: usize, text: &str) {
if repetitions > 0 { if repetitions > 0 {
self.print_at(pos, text); self.print_at(pos, text);
@ -110,3 +105,55 @@ pub trait Backend {
"unknown" "unknown"
} }
} }
/// Dummy backend that does nothing and immediately exits.
///
/// Mostly used for testing.
pub struct Dummy;
impl Dummy {
/// Creates a new dummy backend.
pub fn init() -> Box<dyn Backend>
where
Self: Sized,
{
Box::new(Dummy)
}
}
impl Backend for Dummy {
fn name(&self) -> &str {
"dummy"
}
fn finish(&mut self) {}
fn refresh(&mut self) {}
fn has_colors(&self) -> bool {
false
}
fn screen_size(&self) -> Vec2 {
(1, 1).into()
}
fn poll_event(&mut self) -> Option<Event> {
Some(Event::Exit)
}
fn print_at(&self, _: Vec2, _: &str) {}
fn print_at_rep(&self, _pos: Vec2, _repetitions: usize, _text: &str) {}
fn clear(&self, _: theme::Color) {}
// This sets the Colours and returns the previous colours
// to allow you to set them back when you're done.
fn set_color(&self, colors: theme::ColorPair) -> theme::ColorPair {
// TODO: actually save a stack of colors?
colors
}
fn set_effect(&self, _: theme::Effect) {}
fn unset_effect(&self, _: theme::Effect) {}
}

View File

@ -69,53 +69,18 @@ pub type ScreenId = usize;
/// [`send_wrapper`]: https://crates.io/crates/send_wrapper /// [`send_wrapper`]: https://crates.io/crates/send_wrapper
pub type CbSink = Sender<Box<dyn FnOnce(&mut Cursive) + Send>>; pub type CbSink = Sender<Box<dyn FnOnce(&mut Cursive) + Send>>;
cfg_if::cfg_if! {
if #[cfg(feature = "blt-backend")] {
impl Default for Cursive {
fn default() -> Self {
Self::blt()
}
}
} else if #[cfg(feature = "termion-backend")] {
impl Default for Cursive {
fn default() -> Self {
Self::termion().unwrap()
}
}
} else if #[cfg(feature = "crossterm-backend")] {
impl Default for Cursive {
fn default() -> Self {
Self::crossterm().unwrap()
}
}
} else if #[cfg(feature = "pancurses-backend")] {
impl Default for Cursive {
fn default() -> Self {
Self::pancurses().unwrap()
}
}
} else if #[cfg(feature = "ncurses-backend")] {
impl Default for Cursive {
fn default() -> Self {
Self::ncurses().unwrap()
}
}
} else {
impl Default for Cursive {
fn default() -> Self {
log::warn!("No built-it backend, falling back to Cursive::dummy().");
Self::dummy()
}
}
}
}
impl Cursive { impl Cursive {
/// Shortcut for `Cursive::try_new` with non-failible init function. /// Shortcut for `Cursive::try_new` with non-failible init function.
/// ///
/// You probably don't want to use this function directly. Instead, /// You probably don't want to use this function directly, unless you're
/// `Cursive::default()` or `Cursive::ncurses()` may be what you're /// using a non-standard backend. Built-in backends have dedicated functions.
/// looking for. ///
/// # Examples
///
/// ```rust,no_run
/// # use cursive_core::{Cursive, backend};
/// let siv = Cursive::new(backend::Dummy::init);
/// ```
pub fn new<F>(backend_init: F) -> Self pub fn new<F>(backend_init: F) -> Self
where where
F: FnOnce() -> Box<dyn backend::Backend>, F: FnOnce() -> Box<dyn backend::Backend>,
@ -125,23 +90,11 @@ impl Cursive {
/// Creates a new Cursive root, and initialize the back-end. /// Creates a new Cursive root, and initialize the back-end.
/// ///
/// * If you just want a cursive instance, use `Cursive::default()`. /// You probably don't want to use this function directly, unless you're
/// * If you want a specific backend, then: /// using a non-standard backend. Built-in backends have dedicated functions in the
/// * `Cursive::ncurses()` if the `ncurses-backend` feature is enabled (it is by default). /// [`CursiveExt`] trait.
/// * `Cursive::pancurses()` if the `pancurses-backend` feature is enabled.
/// * `Cursive::termion()` if the `termion-backend` feature is enabled.
/// * `Cursive::crossterm()` if the `crossterm-backend` feature is enabled.
/// * `Cursive::blt()` if the `blt-backend` feature is enabled.
/// * `Cursive::dummy()` for a dummy backend, mostly useful for tests.
/// * If you want to use a third-party backend, then `Cursive::new` is indeed the way to go:
/// * `Cursive::new(bring::your::own::Backend::new)`
/// ///
/// Examples: /// [`CursiveExt`]: https://docs.rs/cursive/0/cursive/trait.CursiveExt.html
///
/// ```rust,no_run
/// # use cursive::{Cursive, backend};
/// let siv = Cursive::new(backend::dummy::Backend::init); // equivalent to Cursive::dummy()
/// ```
pub fn try_new<F, E>(backend_init: F) -> Result<Self, E> pub fn try_new<F, E>(backend_init: F) -> Result<Self, E>
where where
F: FnOnce() -> Result<Box<dyn backend::Backend>, E>, F: FnOnce() -> Result<Box<dyn backend::Backend>, E>,
@ -171,6 +124,7 @@ impl Cursive {
Ok(cursive) Ok(cursive)
} }
/*
/// Creates a new Cursive root using a ncurses backend. /// Creates a new Cursive root using a ncurses backend.
#[cfg(feature = "ncurses-backend")] #[cfg(feature = "ncurses-backend")]
pub fn ncurses() -> std::io::Result<Self> { pub fn ncurses() -> std::io::Result<Self> {
@ -200,12 +154,15 @@ impl Cursive {
pub fn blt() -> Self { pub fn blt() -> Self {
Self::new(backend::blt::Backend::init) Self::new(backend::blt::Backend::init)
} }
*/
/// Creates a new Cursive root using a dummy backend. /// Creates a new Cursive root using a [dummy backend].
/// ///
/// Nothing will be output. This is mostly here for tests. /// Nothing will be output. This is mostly here for tests.
///
/// [dummy backend]: backend::Dummy
pub fn dummy() -> Self { pub fn dummy() -> Self {
Self::new(backend::dummy::Backend::init) Self::new(backend::Dummy::init)
} }
/// Sets some data to be stored in Cursive. /// Sets some data to be stored in Cursive.
@ -236,7 +193,7 @@ impl Cursive {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// let mut siv = cursive::Cursive::dummy(); /// let mut siv = cursive_core::Cursive::dummy();
/// ///
/// // Start with a simple `Vec<i32>` as user data. /// // Start with a simple `Vec<i32>` as user data.
/// siv.set_user_data(vec![1i32, 2, 3]); /// siv.set_user_data(vec![1i32, 2, 3]);
@ -304,7 +261,7 @@ impl Cursive {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Cursive; /// # use cursive_core::Cursive;
/// # let mut siv = Cursive::dummy(); /// # let mut siv = Cursive::dummy();
/// siv.add_global_callback('~', Cursive::toggle_debug_console); /// siv.add_global_callback('~', Cursive::toggle_debug_console);
/// ``` /// ```
@ -337,7 +294,7 @@ impl Cursive {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::*; /// # use cursive_core::*;
/// let mut siv = Cursive::dummy(); /// let mut siv = Cursive::dummy();
/// ///
/// // quit() will be called during the next event cycle /// // quit() will be called during the next event cycle
@ -367,10 +324,10 @@ impl Cursive {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::{Cursive, event}; /// # use cursive_core::{Cursive, event};
/// # use cursive::views::{Dialog}; /// # use cursive_core::views::{Dialog};
/// # use cursive::traits::*; /// # use cursive_core::traits::*;
/// # use cursive::menu::*; /// # use cursive_core::menu::*;
/// # /// #
/// let mut siv = Cursive::dummy(); /// let mut siv = Cursive::dummy();
/// ///
@ -524,8 +481,8 @@ impl Cursive {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::{Cursive, views, view}; /// # use cursive_core::{Cursive, views, view};
/// # use cursive::traits::*; /// # use cursive_core::traits::*;
/// let mut siv = Cursive::dummy(); /// let mut siv = Cursive::dummy();
/// ///
/// siv.add_layer(views::TextView::new("Text #1").with_name("text")); /// siv.add_layer(views::TextView::new("Text #1").with_name("text"));
@ -558,8 +515,8 @@ impl Cursive {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::{Cursive, views}; /// # use cursive_core::{Cursive, views};
/// # use cursive::traits::*; /// # use cursive_core::traits::*;
/// let mut siv = Cursive::dummy(); /// let mut siv = Cursive::dummy();
/// ///
/// siv.add_layer(views::TextView::new("Text #1") /// siv.add_layer(views::TextView::new("Text #1")
@ -602,10 +559,10 @@ impl Cursive {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Cursive; /// # use cursive_core::Cursive;
/// # use cursive::views::{TextView, ViewRef}; /// # use cursive_core::views::{TextView, ViewRef};
/// # let mut siv = Cursive::dummy(); /// # let mut siv = Cursive::dummy();
/// use cursive::traits::Identifiable; /// use cursive_core::traits::Identifiable;
/// ///
/// siv.add_layer(TextView::new("foo").with_name("id")); /// siv.add_layer(TextView::new("foo").with_name("id"));
/// ///
@ -618,10 +575,10 @@ impl Cursive {
/// wrong item type in a `SelectView` will not find anything: /// wrong item type in a `SelectView` will not find anything:
/// ///
/// ```rust /// ```rust
/// # use cursive::Cursive; /// # use cursive_core::Cursive;
/// # use cursive::views::{SelectView}; /// # use cursive_core::views::{SelectView};
/// # let mut siv = Cursive::dummy(); /// # let mut siv = Cursive::dummy();
/// use cursive::traits::Identifiable; /// use cursive_core::traits::Identifiable;
/// ///
/// let select = SelectView::new().item("zero", 0u32).item("one", 1u32); /// let select = SelectView::new().item("zero", 0u32).item("one", 1u32);
/// siv.add_layer(select.with_name("select")); /// siv.add_layer(select.with_name("select"));
@ -679,7 +636,7 @@ impl Cursive {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::*; /// # use cursive_core::*;
/// let mut siv = Cursive::dummy(); /// let mut siv = Cursive::dummy();
/// ///
/// siv.add_global_callback('q', |s| s.quit()); /// siv.add_global_callback('q', |s| s.quit());
@ -775,7 +732,7 @@ impl Cursive {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// use cursive::Cursive; /// use cursive_core::Cursive;
/// let mut siv = Cursive::dummy(); /// let mut siv = Cursive::dummy();
/// ///
/// siv.add_global_callback('q', |s| s.quit()); /// siv.add_global_callback('q', |s| s.quit());
@ -804,7 +761,7 @@ impl Cursive {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// use cursive::{Cursive, views}; /// use cursive_core::{Cursive, views};
/// let mut siv = Cursive::dummy(); /// let mut siv = Cursive::dummy();
/// ///
/// siv.add_layer(views::TextView::new("Hello world!")); /// siv.add_layer(views::TextView::new("Hello world!"));

View File

@ -62,8 +62,8 @@ impl Orientation {
/// ///
/// # Examples /// # Examples
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// # use cursive::direction::Orientation; /// # use cursive_core::direction::Orientation;
/// let o = Orientation::Horizontal; /// let o = Orientation::Horizontal;
/// let mut xy = XY::new(1, 2); /// let mut xy = XY::new(1, 2);
/// *o.get_ref(&mut xy) = 42; /// *o.get_ref(&mut xy) = 42;
@ -99,8 +99,8 @@ impl Orientation {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::direction::Orientation; /// # use cursive_core::direction::Orientation;
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let o = Orientation::Horizontal; /// let o = Orientation::Horizontal;
/// let vec = o.make_vec(1, 2); /// let vec = o.make_vec(1, 2);
/// ///

View File

@ -23,7 +23,7 @@ use std::rc::Rc;
/// ///
/// It is meant to be stored in views. /// It is meant to be stored in views.
#[derive(Clone)] #[derive(Clone)]
pub struct Callback(Rc<Box<dyn Fn(&mut Cursive)>>); pub struct Callback(Rc<dyn Fn(&mut Cursive)>);
// TODO: remove the Box when Box<T: Sized> -> Rc<T> is possible // TODO: remove the Box when Box<T: Sized> -> Rc<T> is possible
/// A callback that can be run on `&mut dyn View`. /// A callback that can be run on `&mut dyn View`.
@ -162,9 +162,9 @@ impl Callback {
where where
F: 'static + Fn(&mut Cursive), F: 'static + Fn(&mut Cursive),
{ {
Callback(Rc::new(Box::new(move |siv| { Callback(Rc::new(move |siv| {
f(siv); f(siv);
}))) }))
} }
/// Wrap a `FnMut` into a `Callback` object. /// Wrap a `FnMut` into a `Callback` object.
@ -184,27 +184,22 @@ impl Callback {
} }
impl Deref for Callback { impl Deref for Callback {
type Target = Box<dyn Fn(&mut Cursive)>; type Target = dyn Fn(&mut Cursive) + 'static;
fn deref<'a>(&'a self) -> &'a Box<dyn Fn(&mut Cursive)> {
&self.0 fn deref(&self) -> &Self::Target {
&*self.0
} }
} }
impl From<Rc<Box<dyn Fn(&mut Cursive)>>> for Callback { impl From<Rc<dyn Fn(&mut Cursive)>> for Callback {
fn from(f: Rc<Box<dyn Fn(&mut Cursive)>>) -> Self { fn from(f: Rc<dyn Fn(&mut Cursive)>) -> Self {
Callback(f) Callback(f)
} }
} }
impl From<Box<dyn Fn(&mut Cursive) + Send>> for Callback {
fn from(f: Box<dyn Fn(&mut Cursive) + Send>) -> Self {
Callback(Rc::new(f))
}
}
impl From<Box<dyn Fn(&mut Cursive)>> for Callback { impl From<Box<dyn Fn(&mut Cursive)>> for Callback {
fn from(f: Box<dyn Fn(&mut Cursive)>) -> Self { fn from(f: Box<dyn Fn(&mut Cursive)>) -> Self {
Callback(Rc::new(f)) Callback(Rc::from(f))
} }
} }

58
cursive-core/src/lib.rs Normal file
View File

@ -0,0 +1,58 @@
//! # Cursive-core
//!
//! This library defines the core components for the Cursive TUI.
//!
//! The main purpose of `cursive-core` is to write third-party libraries to work with Cursive.
//!
//! If you are building an end-user application, then `cursive` is probably what you want.
#![deny(missing_docs)]
macro_rules! new_default(
($c:ident<$t:ident>) => {
impl<$t> Default for $c<$t> {
fn default() -> Self {
Self::new()
}
}
};
($c:ty) => {
impl Default for $c {
fn default() -> Self {
Self::new()
}
}
}
);
#[macro_use]
pub mod utils;
#[macro_use]
pub mod view;
#[macro_use]
pub mod views;
pub mod align;
pub mod backend;
pub mod direction;
pub mod event;
pub mod logger;
pub mod menu;
pub mod theme;
pub mod traits;
pub mod vec;
mod cursive;
mod printer;
mod rect;
mod with;
mod xy;
mod div;
pub use self::cursive::{CbSink, Cursive, ScreenId};
pub use self::printer::Printer;
pub use self::rect::Rect;
pub use self::vec::Vec2;
pub use self::view::View;
pub use self::with::With;
pub use self::xy::XY;

View File

@ -290,10 +290,10 @@ impl<'a, 'b> Printer<'a, 'b> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Printer; /// # use cursive_core::Printer;
/// # use cursive::theme; /// # use cursive_core::theme;
/// # use cursive::backend; /// # use cursive_core::backend;
/// # let b = backend::dummy::Backend::init(); /// # let b = backend::Dummy::init();
/// # let t = theme::load_default(); /// # let t = theme::load_default();
/// # let printer = Printer::new((6,4), &t, &*b); /// # let printer = Printer::new((6,4), &t, &*b);
/// printer.with_color(theme::ColorStyle::highlight(), |printer| { /// printer.with_color(theme::ColorStyle::highlight(), |printer| {
@ -386,10 +386,10 @@ impl<'a, 'b> Printer<'a, 'b> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Printer; /// # use cursive_core::Printer;
/// # use cursive::theme; /// # use cursive_core::theme;
/// # use cursive::backend; /// # use cursive_core::backend;
/// # let b = backend::dummy::Backend::init(); /// # let b = backend::Dummy::init();
/// # let t = theme::load_default(); /// # let t = theme::load_default();
/// # let printer = Printer::new((6,4), &t, &*b); /// # let printer = Printer::new((6,4), &t, &*b);
/// printer.print_box((0,0), (6,4), false); /// printer.print_box((0,0), (6,4), false);

View File

@ -21,8 +21,8 @@ type HashMap<K, V> = std::collections::HashMap<K, V, ahash::RandomState>;
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # use cursive::theme::Palette; /// # use cursive_core::theme::Palette;
/// use cursive::theme::{BaseColor::*, Color::*, PaletteColor::*}; /// use cursive_core::theme::{BaseColor::*, Color::*, PaletteColor::*};
/// ///
/// let mut palette = Palette::default(); /// let mut palette = Palette::default();
/// ///

View File

@ -5,7 +5,7 @@
//! # Examples //! # Examples
//! //!
//! ``` //! ```
//! use cursive::traits::*; //! use cursive_core::traits::*;
//! ``` //! ```
#[doc(no_inline)] #[doc(no_inline)]

View File

@ -52,7 +52,7 @@ pub fn immutify<F: FnMut(&mut Cursive)>(
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::{Cursive, immut1}; /// # use cursive_core::{Cursive, immut1};
/// # fn main() { /// # fn main() {
/// # let mut siv = Cursive::dummy(); /// # let mut siv = Cursive::dummy();
/// let mut i = 0; /// let mut i = 0;

View File

@ -41,7 +41,7 @@ pub fn make_lines(content: &str, width: usize) -> Vec<Row> {
/// ``` /// ```
/// use unicode_segmentation::UnicodeSegmentation; /// use unicode_segmentation::UnicodeSegmentation;
/// ///
/// # use cursive::utils::lines::simple::prefix; /// # use cursive_core::utils::lines::simple::prefix;
/// let my_text = "blah..."; /// let my_text = "blah...";
/// // This returns the number of bytes for a prefix of `my_text` that /// // This returns the number of bytes for a prefix of `my_text` that
/// // fits within 5 cells. /// // fits within 5 cells.

View File

@ -10,7 +10,7 @@ use std::io::{self, Read};
/// ///
/// ```rust,no_run /// ```rust,no_run
/// use std::io::Read; /// use std::io::Read;
/// use cursive::utils::{Counter, ProgressReader}; /// use cursive_core::utils::{Counter, ProgressReader};
/// ///
/// // Read a file and report the progress /// // Read a file and report the progress
/// let file = std::fs::File::open("large_file").unwrap(); /// let file = std::fs::File::open("large_file").unwrap();

View File

@ -38,7 +38,7 @@ impl XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// assert!(Vec2::new(9999, 9999) < Vec2::max_value()); /// assert!(Vec2::new(9999, 9999) < Vec2::max_value());
/// ``` /// ```
pub fn max_value() -> Self { pub fn max_value() -> Self {
@ -52,7 +52,7 @@ impl XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let u = Vec2::new(1, 2); /// let u = Vec2::new(1, 2);
/// let v = Vec2::new(2, 1); /// let v = Vec2::new(2, 1);
/// assert_eq!(u.saturating_sub(v), Vec2::new(0, 1)); /// assert_eq!(u.saturating_sub(v), Vec2::new(0, 1));
@ -69,8 +69,8 @@ impl XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// # use cursive::XY; /// # use cursive_core::XY;
/// let u = Vec2::new(1, 2); /// let u = Vec2::new(1, 2);
/// let v = XY::<isize>::new(-2, 1); /// let v = XY::<isize>::new(-2, 1);
/// assert_eq!(u.saturating_add(v), Vec2::new(0, 3)); /// assert_eq!(u.saturating_add(v), Vec2::new(0, 3));
@ -92,7 +92,7 @@ impl XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let u = Vec2::new(1, 6); /// let u = Vec2::new(1, 6);
/// let v = Vec2::new(2, 3); /// let v = Vec2::new(2, 3);
/// assert_eq!(u.div_up(v), Vec2::new(1, 2)); /// assert_eq!(u.div_up(v), Vec2::new(1, 2));
@ -113,7 +113,7 @@ impl XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let xy = Vec2::new(1, 2); /// let xy = Vec2::new(1, 2);
/// assert_eq!(xy.checked_sub((1, 1)), Some(Vec2::new(0, 1))); /// assert_eq!(xy.checked_sub((1, 1)), Some(Vec2::new(0, 1)));
/// assert_eq!(xy.checked_sub((2, 2)), None); /// assert_eq!(xy.checked_sub((2, 2)), None);
@ -132,8 +132,8 @@ impl XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// # use cursive::XY; /// # use cursive_core::XY;
/// let v: XY<isize> = Vec2::new(1, 2).signed().map(|i| i - 5); /// let v: XY<isize> = Vec2::new(1, 2).signed().map(|i| i - 5);
/// assert_eq!(v, XY::new(-4, -3)); /// assert_eq!(v, XY::new(-4, -3));
/// ///
@ -155,7 +155,7 @@ impl<T: Ord> XY<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let v = Vec2::new(1, 2); /// let v = Vec2::new(1, 2);
/// assert!(v.fits_in((1, 2))); /// assert!(v.fits_in((1, 2)));
/// assert!(v.fits_in((3, 3))); /// assert!(v.fits_in((3, 3)));
@ -175,7 +175,7 @@ impl<T: Ord> XY<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let v = Vec2::new(1, 2); /// let v = Vec2::new(1, 2);
/// assert!(v.fits((1, 2))); /// assert!(v.fits((1, 2)));
/// assert!(v.fits((0, 0))); /// assert!(v.fits((0, 0)));
@ -203,7 +203,7 @@ impl<T: Ord> XY<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// assert_eq!(Vec2::max((1, 2), (3, 1)), Vec2::new(3, 2)); /// assert_eq!(Vec2::max((1, 2), (3, 1)), Vec2::new(3, 2));
/// ``` /// ```
pub fn max<A: Into<XY<T>>, B: Into<XY<T>>>(a: A, b: B) -> Self { pub fn max<A: Into<XY<T>>, B: Into<XY<T>>>(a: A, b: B) -> Self {
@ -217,7 +217,7 @@ impl<T: Ord> XY<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// assert_eq!(Vec2::min((1, 2), (3, 1)), Vec2::new(1, 1)); /// assert_eq!(Vec2::min((1, 2), (3, 1)), Vec2::new(1, 1));
/// ``` /// ```
pub fn min<A: Into<XY<T>>, B: Into<XY<T>>>(a: A, b: B) -> Self { pub fn min<A: Into<XY<T>>, B: Into<XY<T>>>(a: A, b: B) -> Self {
@ -289,7 +289,7 @@ impl<T: Zero + Clone> XY<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// let xy = XY::new(1, 2); /// let xy = XY::new(1, 2);
/// assert_eq!(xy.keep_x(), XY::new(1, 0)); /// assert_eq!(xy.keep_x(), XY::new(1, 0));
/// ``` /// ```
@ -302,7 +302,7 @@ impl<T: Zero + Clone> XY<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// let xy = XY::new(1, 2); /// let xy = XY::new(1, 2);
/// assert_eq!(xy.keep_y(), XY::new(0, 2)); /// assert_eq!(xy.keep_y(), XY::new(0, 2));
/// ``` /// ```
@ -315,7 +315,7 @@ impl<T: Zero + Clone> XY<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// assert_eq!(Vec2::zero(), Vec2::new(0, 0)); /// assert_eq!(Vec2::zero(), Vec2::new(0, 0));
/// ``` /// ```
pub fn zero() -> Self { pub fn zero() -> Self {
@ -332,7 +332,7 @@ where
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// let xy = XY::new(String::from("a"), String::from("ab")); /// let xy = XY::new(String::from("a"), String::from("ab"));
/// assert_eq!(XY::from(&xy), xy); /// assert_eq!(XY::from(&xy), xy);
/// ``` /// ```
@ -349,8 +349,8 @@ where
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let u = Vec2::new(1, 2); /// let u = Vec2::new(1, 2);
/// let v: XY<isize> = XY::from(u); /// let v: XY<isize> = XY::from(u);
/// assert_eq!(v, XY::new(1, 2)); /// assert_eq!(v, XY::new(1, 2));
@ -365,7 +365,7 @@ impl From<(i32, i32)> for XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// let xy: XY<isize> = XY::from((-1i32, -2i32)); /// let xy: XY<isize> = XY::from((-1i32, -2i32));
/// assert_eq!(xy, XY::new(-1, -2)); /// assert_eq!(xy, XY::new(-1, -2));
/// ``` /// ```
@ -378,7 +378,7 @@ impl From<(u32, u32)> for XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let v = Vec2::from((1u32, 2u32)); /// let v = Vec2::from((1u32, 2u32));
/// assert_eq!(v, Vec2::new(1, 2)); /// assert_eq!(v, Vec2::new(1, 2));
/// ``` /// ```
@ -391,7 +391,7 @@ impl From<(u8, u8)> for XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let v = Vec2::from((1u8, 2u8)); /// let v = Vec2::from((1u8, 2u8));
/// assert_eq!(v, Vec2::new(1, 2)); /// assert_eq!(v, Vec2::new(1, 2));
/// ``` /// ```
@ -404,7 +404,7 @@ impl From<(u16, u16)> for XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let v = Vec2::from((1u16, 2u16)); /// let v = Vec2::from((1u16, 2u16));
/// assert_eq!(v, Vec2::new(1, 2)); /// assert_eq!(v, Vec2::new(1, 2));
/// ``` /// ```
@ -424,7 +424,7 @@ where
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// let xy = XY::new(1, 2); /// let xy = XY::new(1, 2);
/// assert_eq!(xy + (2, 3), XY::new(3, 5)); /// assert_eq!(xy + (2, 3), XY::new(3, 5));
/// ``` /// ```
@ -443,7 +443,7 @@ where
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// let xy = XY::new(1, 2); /// let xy = XY::new(1, 2);
/// assert_eq!(xy - (1, 0), XY::new(0, 2)); /// assert_eq!(xy - (1, 0), XY::new(0, 2));
/// ``` /// ```
@ -458,7 +458,7 @@ impl<T: Clone + Div<Output = T>> Div<T> for XY<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// let xy = XY::new(1, 4); /// let xy = XY::new(1, 4);
/// assert_eq!(xy / 2, XY::new(0, 2)); /// assert_eq!(xy / 2, XY::new(0, 2));
/// ``` /// ```
@ -473,7 +473,7 @@ impl Mul<usize> for XY<usize> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Vec2; /// # use cursive_core::Vec2;
/// let v = Vec2::new(1, 2); /// let v = Vec2::new(1, 2);
/// assert_eq!(v * 2, Vec2::new(2, 4)); /// assert_eq!(v * 2, Vec2::new(2, 4));
/// ``` /// ```
@ -491,7 +491,7 @@ where
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// let u = XY::new(1, 2); /// let u = XY::new(1, 2);
/// let v = XY::new(2, 3); /// let v = XY::new(2, 3);
/// assert_eq!(u * v, XY::new(2, 6)); /// assert_eq!(u * v, XY::new(2, 6));
@ -509,7 +509,7 @@ where
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::XY; /// # use cursive_core::XY;
/// let u = XY::new(2, 3); /// let u = XY::new(2, 3);
/// let v = XY::new(1, 2); /// let v = XY::new(1, 2);
/// assert_eq!(u / v, XY::new(2, 1)); /// assert_eq!(u / v, XY::new(2, 1));

View File

@ -18,8 +18,8 @@ pub trait AnyView {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::views::TextView; /// # use cursive_core::views::TextView;
/// # use cursive::view::View; /// # use cursive_core::view::View;
/// let boxed: Box<View> = Box::new(TextView::new("text")); /// let boxed: Box<View> = Box::new(TextView::new("text"));
/// let text: Box<TextView> = boxed.as_boxed_any().downcast().unwrap(); /// let text: Box<TextView> = boxed.as_boxed_any().downcast().unwrap();
/// ``` /// ```

View File

@ -12,10 +12,10 @@ pub trait Nameable: View + Sized {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Cursive; /// # use cursive_core::Cursive;
/// # use cursive::views::TextView; /// # use cursive_core::views::TextView;
/// # use cursive::view::Resizable; /// # use cursive_core::view::Resizable;
/// use cursive::view::Nameable; /// use cursive_core::view::Nameable;
/// ///
/// let mut siv = Cursive::dummy(); /// let mut siv = Cursive::dummy();
/// siv.add_layer( /// siv.add_layer(

View File

@ -50,15 +50,15 @@ impl Default for ScrollStrategy {
/// Example: /// Example:
/// ///
/// ``` /// ```
/// use cursive::{Printer, Vec2, Rect}; /// use cursive_core::{Printer, Vec2, Rect};
/// use cursive::event::{Event, EventResult}; /// use cursive_core::event::{Event, EventResult};
/// use cursive::view::{View, scroll}; /// use cursive_core::view::{View, scroll};
/// ///
/// struct MyView { /// struct MyView {
/// core: scroll::Core, /// core: scroll::Core,
/// } /// }
/// ///
/// cursive::impl_scroller!(MyView::core); /// cursive_core::impl_scroller!(MyView::core);
/// ///
/// impl MyView { /// impl MyView {
/// fn inner_on_event(&mut self, event: Event) -> EventResult { /// fn inner_on_event(&mut self, event: Event) -> EventResult {

View File

@ -210,14 +210,10 @@ impl ScrollBase {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::view::ScrollBase; /// # let scrollbase = cursive_core::view::ScrollBase::new();
/// # use cursive::Printer; /// # let b = cursive_core::backend::Dummy::init();
/// # use cursive::theme; /// # let t = cursive_core::theme::load_default();
/// # use cursive::backend; /// # let printer = &cursive_core::Printer::new((5,1), &t, &*b);
/// # let scrollbase = ScrollBase::new();
/// # let b = backend::dummy::Backend::init();
/// # let t = theme::load_default();
/// # let printer = Printer::new((5,1), &t, &*b);
/// # let printer = &printer; /// # let printer = &printer;
/// let lines = ["Line 1", "Line number 2"]; /// let lines = ["Line 1", "Line number 2"];
/// scrollbase.draw(printer, |printer, i| { /// scrollbase.draw(printer, |printer, i| {

View File

@ -154,13 +154,13 @@ impl<T: ViewWrapper> View for T {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::view::{View,ViewWrapper}; /// # use cursive_core::view::{View,ViewWrapper};
/// struct FooView<T: View> { /// struct FooView<T: View> {
/// view: T, /// view: T,
/// } /// }
/// ///
/// impl <T: View> ViewWrapper for FooView<T> { /// impl <T: View> ViewWrapper for FooView<T> {
/// cursive::wrap_impl!(self.view: T); /// cursive_core::wrap_impl!(self.view: T);
/// } /// }
/// # fn main() { } /// # fn main() { }
/// ``` /// ```
@ -170,18 +170,23 @@ macro_rules! wrap_impl {
type V = $t; type V = $t;
fn with_view<F, R>(&self, f: F) -> Option<R> fn with_view<F, R>(&self, f: F) -> Option<R>
where F: FnOnce(&Self::V) -> R where
F: FnOnce(&Self::V) -> R,
{ {
Some(f(&self.$v)) Some(f(&self.$v))
} }
fn with_view_mut<F, R>(&mut self, f: F) -> Option<R> fn with_view_mut<F, R>(&mut self, f: F) -> Option<R>
where F: FnOnce(&mut Self::V) -> R where
F: FnOnce(&mut Self::V) -> R,
{ {
Some(f(&mut self.$v)) Some(f(&mut self.$v))
} }
fn into_inner(self) -> Result<Self::V, Self> where Self::V: Sized { fn into_inner(self) -> Result<Self::V, Self>
where
Self::V: Sized,
{
Ok(self.$v) Ok(self.$v)
} }
}; };
@ -198,17 +203,17 @@ macro_rules! wrap_impl {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::view::{View, ViewWrapper}; /// # use cursive_core::view::{View, ViewWrapper};
/// struct FooView<T: View> { /// struct FooView<T: View> {
/// view: T, /// view: T,
/// } /// }
/// ///
/// impl<T: View> FooView<T> { /// impl<T: View> FooView<T> {
/// cursive::inner_getters!(self.view: T); /// cursive_core::inner_getters!(self.view: T);
/// } /// }
/// ///
/// impl <T: View> ViewWrapper for FooView<T> { /// impl <T: View> ViewWrapper for FooView<T> {
/// cursive::wrap_impl!(self.view: T); /// cursive_core::wrap_impl!(self.view: T);
/// } /// }
/// # fn main() { } /// # fn main() { }
/// ``` /// ```
@ -223,5 +228,5 @@ macro_rules! inner_getters {
pub fn get_inner_mut(&mut self) -> &mut $t { pub fn get_inner_mut(&mut self) -> &mut $t {
&mut self.$v &mut self.$v
} }
} };
} }

View File

@ -15,7 +15,7 @@ use unicode_width::UnicodeWidthStr;
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::Button; /// use cursive_core::views::Button;
/// ///
/// let quit_button = Button::new("Quit", |s| s.quit()); /// let quit_button = Button::new("Quit", |s| s.quit());
/// ``` /// ```
@ -44,7 +44,7 @@ impl Button {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::Button; /// use cursive_core::views::Button;
/// ///
/// let button = Button::new_raw("[ Quit ]", |s| s.quit()); /// let button = Button::new_raw("[ Quit ]", |s| s.quit());
/// ``` /// ```
@ -107,7 +107,7 @@ impl Button {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::views::Button; /// # use cursive_core::views::Button;
/// let button = Button::new("Quit", |s| s.quit()); /// let button = Button::new("Quit", |s| s.quit());
/// assert_eq!(button.label(), "<Quit>"); /// assert_eq!(button.label(), "<Quit>");
/// ``` /// ```
@ -122,7 +122,7 @@ impl Button {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::Button; /// use cursive_core::views::Button;
/// ///
/// let mut button = Button::new("Quit", |s| s.quit()); /// let mut button = Button::new("Quit", |s| s.quit());
/// button.set_label("Escape"); /// button.set_label("Escape");

View File

@ -16,8 +16,8 @@ type CallOnAny<T> = Box<dyn for<'a> FnMut(&mut T, &Selector, AnyCb<'a>)>;
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// use cursive::views::{Canvas, Dialog}; /// use cursive_core::views::{Canvas, Dialog};
/// use cursive::event::{Event, EventResult, Key}; /// use cursive_core::event::{Event, EventResult, Key};
/// use unicode_width::UnicodeWidthStr; // To get the width of some text. /// use unicode_width::UnicodeWidthStr; // To get the width of some text.
/// ///
/// // Build a canvas around a string. /// // Build a canvas around a string.

View File

@ -13,8 +13,8 @@ use std::rc::Rc;
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::Checkbox; /// use cursive_core::views::Checkbox;
/// use cursive::traits::Identifiable; /// use cursive_core::traits::Identifiable;
/// ///
/// let checkbox = Checkbox::new().checked().with_name("check"); /// let checkbox = Checkbox::new().checked().with_name("check");
/// ``` /// ```
@ -82,7 +82,7 @@ impl Checkbox {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::Checkbox; /// use cursive_core::views::Checkbox;
/// ///
/// let mut checkbox = Checkbox::new().checked(); /// let mut checkbox = Checkbox::new().checked();
/// assert!(checkbox.is_checked()); /// assert!(checkbox.is_checked());

View File

@ -44,7 +44,7 @@ impl ChildButton {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # use cursive::views::{Dialog,TextView}; /// # use cursive_core::views::{Dialog,TextView};
/// let dialog = Dialog::around(TextView::new("Hello!")) /// let dialog = Dialog::around(TextView::new("Hello!"))
/// .button("Ok", |s| s.quit()); /// .button("Ok", |s| s.quit());
/// ``` /// ```
@ -110,7 +110,7 @@ impl Dialog {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::{Dialog, TextView}; /// use cursive_core::views::{Dialog, TextView};
/// ///
/// let dialog = Dialog::new() /// let dialog = Dialog::new()
/// .content(TextView::new("Hello!")) /// .content(TextView::new("Hello!"))
@ -123,7 +123,7 @@ impl Dialog {
/// Gets the content of this dialog. /// Gets the content of this dialog.
/// ///
/// ``` /// ```
/// use cursive::views::{Dialog, TextView}; /// use cursive_core::views::{Dialog, TextView};
/// let dialog = Dialog::around(TextView::new("Hello!")); /// let dialog = Dialog::around(TextView::new("Hello!"));
/// let text_view: &TextView = dialog /// let text_view: &TextView = dialog
/// .get_content() /// .get_content()
@ -154,7 +154,7 @@ impl Dialog {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::Dialog; /// use cursive_core::views::Dialog;
/// ///
/// let dialog = Dialog::text("Hello!") /// let dialog = Dialog::text("Hello!")
/// .button("Quit", |s| s.quit()); /// .button("Quit", |s| s.quit());
@ -170,7 +170,7 @@ impl Dialog {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::Dialog; /// use cursive_core::views::Dialog;
/// ///
/// let dialog = Dialog::info("Some very important information!"); /// let dialog = Dialog::info("Some very important information!");
/// ``` /// ```
@ -245,7 +245,7 @@ impl Dialog {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::Dialog; /// use cursive_core::views::Dialog;
/// ///
/// let dialog = Dialog::text("Hello!") /// let dialog = Dialog::text("Hello!")
/// .dismiss_button("Close"); /// .dismiss_button("Close");
@ -263,7 +263,7 @@ impl Dialog {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::Dialog; /// use cursive_core::views::Dialog;
/// ///
/// let dialog = Dialog::info("Some info") /// let dialog = Dialog::info("Some info")
/// .title("Read me!"); /// .title("Read me!");
@ -294,8 +294,8 @@ impl Dialog {
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use cursive::views::Dialog; /// use cursive_core::views::Dialog;
/// use cursive::view::Margins; /// use cursive_core::view::Margins;
/// ///
/// let dialog = Dialog::info("Hello!") /// let dialog = Dialog::info("Hello!")
/// .padding(Margins::lrtb(1, 1, 0, 0)); // (Left, Right, Top, Bottom) /// .padding(Margins::lrtb(1, 1, 0, 0)); // (Left, Right, Top, Bottom)

View File

@ -31,9 +31,9 @@ pub type OnSubmit = dyn Fn(&mut Cursive, &str);
/// [1]: https://github.com/gyscos/cursive/blob/master/examples/edit.rs /// [1]: https://github.com/gyscos/cursive/blob/master/examples/edit.rs
/// ///
/// ```rust /// ```rust
/// # use cursive::Cursive; /// # use cursive_core::Cursive;
/// # use cursive::traits::*; /// # use cursive_core::traits::*;
/// # use cursive::views::{Dialog, EditView, TextView}; /// # use cursive_core::views::{Dialog, EditView, TextView};
/// let mut siv = Cursive::dummy(); /// let mut siv = Cursive::dummy();
/// ///
/// // Create a dialog with an edit text and a button. /// // Create a dialog with an edit text and a button.
@ -174,7 +174,7 @@ impl EditView {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::views::EditView; /// # use cursive_core::views::EditView;
/// let edit = EditView::new().filler(" "); /// let edit = EditView::new().filler(" ");
/// ``` /// ```
pub fn filler<S: Into<String>>(self, filler: S) -> Self { pub fn filler<S: Into<String>>(self, filler: S) -> Self {
@ -269,7 +269,7 @@ impl EditView {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::{TextContent, TextView, EditView}; /// use cursive_core::views::{TextContent, TextView, EditView};
/// // Keep the length of the text in a separate view. /// // Keep the length of the text in a separate view.
/// let mut content = TextContent::new("0"); /// let mut content = TextContent::new("0");
/// let text_view = TextView::new_with_content(content.clone()); /// let text_view = TextView::new_with_content(content.clone());
@ -343,7 +343,7 @@ impl EditView {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::{Dialog, EditView}; /// use cursive_core::views::{Dialog, EditView};
/// ///
/// let edit_view = EditView::new() /// let edit_view = EditView::new()
/// .on_submit(|s, text| { /// .on_submit(|s, text| {

View File

@ -9,9 +9,9 @@ use crate::Printer;
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::Cursive; /// use cursive_core::Cursive;
/// use cursive::views::{Button, EnableableView, Checkbox, LinearLayout}; /// use cursive_core::views::{Button, EnableableView, Checkbox, LinearLayout};
/// use cursive::traits::Identifiable; /// use cursive_core::traits::Identifiable;
/// ///
/// let mut siv = Cursive::dummy(); /// let mut siv = Cursive::dummy();
/// ///

View File

@ -15,8 +15,8 @@ use std::ops::Deref;
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::{Button, LinearLayout, TextView, TextArea}; /// use cursive_core::views::{Button, LinearLayout, TextView, TextArea};
/// use cursive::traits::Boxable; /// use cursive_core::traits::Boxable;
/// ///
/// let linear_layout = LinearLayout::horizontal() /// let linear_layout = LinearLayout::horizontal()
/// .child(TextView::new("Top of the page")) /// .child(TextView::new("Top of the page"))

View File

@ -10,7 +10,7 @@
/// } /// }
/// ///
/// impl MyView { /// impl MyView {
/// cursive::impl_enabled!(self.enabled); /// cursive_core::impl_enabled!(self.enabled);
/// } /// }
/// ///
/// let view = MyView { enabled: true }; /// let view = MyView { enabled: true };
@ -19,7 +19,6 @@
#[macro_export] #[macro_export]
macro_rules! impl_enabled { macro_rules! impl_enabled {
(self.$x:ident) => { (self.$x:ident) => {
/// Disables this view. /// Disables this view.
/// ///
/// A disabled view cannot be selected. /// A disabled view cannot be selected.
@ -49,7 +48,7 @@ macro_rules! impl_enabled {
pub fn is_enabled(&self) -> bool { pub fn is_enabled(&self) -> bool {
self.$x self.$x
} }
} };
} }
mod boxed_view; mod boxed_view;

View File

@ -32,8 +32,8 @@ use std::rc::Rc;
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # use cursive::event;; /// # use cursive_core::event;;
/// # use cursive::views::{OnEventView, TextView}; /// # use cursive_core::views::{OnEventView, TextView};
/// let view = OnEventView::new(TextView::new("This view has an event!")) /// let view = OnEventView::new(TextView::new("This view has an event!"))
/// .on_event('q', |s| s.quit()) /// .on_event('q', |s| s.quit())
/// .on_event(event::Key::Esc, |s| s.quit()); /// .on_event(event::Key::Esc, |s| s.quit());
@ -92,8 +92,8 @@ impl<T: View> OnEventView<T> {
/// ///
/// ///
/// ```rust /// ```rust
/// # use cursive::views::{OnEventView, DummyView}; /// # use cursive_core::views::{OnEventView, DummyView};
/// # use cursive::event::{Key, EventTrigger}; /// # use cursive_core::event::{Key, EventTrigger};
/// let view = OnEventView::new(DummyView) /// let view = OnEventView::new(DummyView)
/// .on_event('q', |s| s.quit()) /// .on_event('q', |s| s.quit())
/// .on_event(Key::Esc, |s| { /// .on_event(Key::Esc, |s| {
@ -158,8 +158,8 @@ impl<T: View> OnEventView<T> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::views::{DummyView, OnEventView}; /// # use cursive_core::views::{DummyView, OnEventView};
/// # use cursive::event::{Event, EventTrigger, MouseEvent, EventResult}; /// # use cursive_core::event::{Event, EventTrigger, MouseEvent, EventResult};
/// let view = OnEventView::new(DummyView) /// let view = OnEventView::new(DummyView)
/// .on_event_inner( /// .on_event_inner(
/// EventTrigger::mouse(), /// EventTrigger::mouse(),

View File

@ -12,7 +12,7 @@ use crate::Vec2;
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::views::{TextView, PaddedView}; /// # use cursive_core::views::{TextView, PaddedView};
/// // Adds 2 columns of padding to the left and to the right. /// // Adds 2 columns of padding to the left and to the right.
/// let view = PaddedView::lrtb( /// let view = PaddedView::lrtb(
/// 2,2,0,0, // Left, Right, Top, Bottom /// 2,2,0,0, // Left, Right, Top, Bottom

View File

@ -23,7 +23,7 @@ use std::thread;
/// # Example /// # Example
/// ///
/// ``` /// ```
/// # use cursive::views::ProgressBar; /// # use cursive_core::views::ProgressBar;
/// let bar = ProgressBar::new() /// let bar = ProgressBar::new()
/// .with_task(|counter| { /// .with_task(|counter| {
/// // This closure is called in parallel. /// // This closure is called in parallel.

View File

@ -16,7 +16,7 @@ use crate::XY;
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::{ResizedView, TextView}; /// use cursive_core::views::{ResizedView, TextView};
/// ///
/// // Creates a 20x4 ResizedView with a TextView content. /// // Creates a 20x4 ResizedView with a TextView content.
/// let view = ResizedView::with_fixed_size((20,4), TextView::new("Hello!")); /// let view = ResizedView::with_fixed_size((20,4), TextView::new("Hello!"));

View File

@ -25,9 +25,9 @@ use std::rc::Rc;
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::Cursive; /// # use cursive_core::Cursive;
/// # use cursive::views::{SelectView, Dialog, TextView}; /// # use cursive_core::views::{SelectView, Dialog, TextView};
/// # use cursive::align::HAlign; /// # use cursive_core::align::HAlign;
/// let mut time_select = SelectView::new().h_align(HAlign::Center); /// let mut time_select = SelectView::new().h_align(HAlign::Center);
/// time_select.add_item("Short", 1); /// time_select.add_item("Short", 1);
/// time_select.add_item("Medium", 5); /// time_select.add_item("Medium", 5);
@ -175,8 +175,8 @@ impl<T: 'static> SelectView<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::traits::Identifiable; /// use cursive_core::traits::Identifiable;
/// use cursive::views::{TextView, SelectView}; /// use cursive_core::views::{TextView, SelectView};
/// ///
/// let text_view = TextView::new("").with_name("text"); /// let text_view = TextView::new("").with_name("text");
/// ///
@ -231,7 +231,7 @@ impl<T: 'static> SelectView<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::{Dialog, SelectView}; /// use cursive_core::views::{Dialog, SelectView};
/// ///
/// let select_view = SelectView::new() /// let select_view = SelectView::new()
/// .item("One", 1) /// .item("One", 1)
@ -260,8 +260,8 @@ impl<T: 'static> SelectView<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::align; /// use cursive_core::align;
/// use cursive::views::SelectView; /// use cursive_core::views::SelectView;
/// ///
/// let select_view = SelectView::new() /// let select_view = SelectView::new()
/// .item("One", 1) /// .item("One", 1)
@ -311,7 +311,7 @@ impl<T: 'static> SelectView<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::SelectView; /// use cursive_core::views::SelectView;
/// ///
/// let mut select_view = SelectView::new(); /// let mut select_view = SelectView::new();
/// ///
@ -325,8 +325,8 @@ impl<T: 'static> SelectView<T> {
/// Gets an item at given idx or None. /// Gets an item at given idx or None.
/// ///
/// ``` /// ```
/// use cursive::Cursive; /// use cursive_core::Cursive;
/// use cursive::views::{SelectView, TextView}; /// use cursive_core::views::{SelectView, TextView};
/// let select = SelectView::new() /// let select = SelectView::new()
/// .item("Short", 1); /// .item("Short", 1);
/// assert_eq!(select.get_item(0), Some(("Short", &1))); /// assert_eq!(select.get_item(0), Some(("Short", &1)));
@ -391,7 +391,7 @@ impl<T: 'static> SelectView<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::SelectView; /// use cursive_core::views::SelectView;
/// ///
/// let select_view = SelectView::new() /// let select_view = SelectView::new()
/// .item("Item 1", 1) /// .item("Item 1", 1)
@ -420,7 +420,7 @@ impl<T: 'static> SelectView<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::SelectView; /// use cursive_core::views::SelectView;
/// ///
/// // Create a SelectView with 100 items /// // Create a SelectView with 100 items
/// let select_view = SelectView::new() /// let select_view = SelectView::new()
@ -463,7 +463,7 @@ impl<T: 'static> SelectView<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::SelectView; /// use cursive_core::views::SelectView;
/// ///
/// let select_view = SelectView::new() /// let select_view = SelectView::new()
/// .item("Item 1", 1) /// .item("Item 1", 1)
@ -481,7 +481,7 @@ impl<T: 'static> SelectView<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::SelectView; /// use cursive_core::views::SelectView;
/// ///
/// let mut select_view = SelectView::new(); /// let mut select_view = SelectView::new();
/// assert!(select_view.is_empty()); /// assert!(select_view.is_empty());
@ -581,8 +581,8 @@ impl<T: 'static> SelectView<T> {
/// You should run this callback with a `&mut Cursive`: /// You should run this callback with a `&mut Cursive`:
/// ///
/// ```rust /// ```rust
/// # use cursive::Cursive; /// # use cursive_core::Cursive;
/// # use cursive::views::SelectView; /// # use cursive_core::views::SelectView;
/// fn select_up(siv: &mut Cursive, view: &mut SelectView<()>) { /// fn select_up(siv: &mut Cursive, view: &mut SelectView<()>) {
/// let cb = view.select_up(1); /// let cb = view.select_up(1);
/// cb(siv); /// cb(siv);
@ -789,7 +789,7 @@ impl SelectView<String> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::SelectView; /// use cursive_core::views::SelectView;
/// ///
/// let select_view = SelectView::new() /// let select_view = SelectView::new()
/// .item_str("Paris") /// .item_str("Paris")
@ -814,7 +814,7 @@ impl SelectView<String> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # use cursive::views::SelectView; /// # use cursive_core::views::SelectView;
/// let mut select_view = SelectView::new(); /// let mut select_view = SelectView::new();
/// select_view.add_all_str(vec!["a", "b", "c"]); /// select_view.add_all_str(vec!["a", "b", "c"]);
/// ``` /// ```
@ -835,7 +835,7 @@ impl SelectView<String> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::SelectView; /// use cursive_core::views::SelectView;
/// ///
/// let text = "..."; // Maybe read some config file /// let text = "..."; // Maybe read some config file
/// ///

View File

@ -14,7 +14,7 @@ use std::rc::Rc;
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::views::{Dialog, SliderView}; /// use cursive_core::views::{Dialog, SliderView};
/// ///
/// let slider_view = SliderView::horizontal(10) /// let slider_view = SliderView::horizontal(10)
/// .on_change(|s, n| if n == 5 { /// .on_change(|s, n| if n == 5 {

View File

@ -308,8 +308,8 @@ impl StackView {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use cursive::views::{TextView, StackView, Dialog, LayerPosition}; /// # use cursive_core::views::{TextView, StackView, Dialog, LayerPosition};
/// # use cursive::view::Identifiable; /// # use cursive_core::view::Identifiable;
/// let mut stack = StackView::new(); /// let mut stack = StackView::new();
/// stack.add_layer(TextView::new("Back")); /// stack.add_layer(TextView::new("Back"));
/// stack.add_layer(Dialog::around(TextView::new("Middle").with_name("text"))); /// stack.add_layer(Dialog::around(TextView::new("Middle").with_name("text")));

View File

@ -20,8 +20,8 @@ use unicode_width::UnicodeWidthStr;
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use cursive::traits::{Resizable, Identifiable}; /// use cursive_core::traits::{Resizable, Identifiable};
/// use cursive::views::TextArea; /// use cursive_core::views::TextArea;
/// ///
/// let text_area = TextArea::new() /// let text_area = TextArea::new()
/// .content("Write description here...") /// .content("Write description here...")

Some files were not shown because too many files have changed in this diff Show More