mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add #![deny(missing_docs)]
And fill the appropriate missing ones
This commit is contained in:
parent
c597c262fe
commit
309c471a63
@ -2,7 +2,9 @@
|
||||
|
||||
/// Specifies the alignment along both horizontal and vertical directions.
|
||||
pub struct Align {
|
||||
/// Horizontal alignment policy
|
||||
pub h: HAlign,
|
||||
/// Vertical alignment policy
|
||||
pub v: VAlign,
|
||||
}
|
||||
|
||||
@ -40,15 +42,21 @@ impl Align {
|
||||
|
||||
/// Horizontal alignment
|
||||
pub enum HAlign {
|
||||
/// Place the element to the left of available space
|
||||
Left,
|
||||
/// Place the element horizontally in the center of available space
|
||||
Center,
|
||||
/// Place the element to the right of available space
|
||||
Right,
|
||||
}
|
||||
|
||||
/// Vertical alignment
|
||||
pub enum VAlign {
|
||||
/// Place the element at the top of available space
|
||||
Top,
|
||||
/// Place the element vertically in the center of available space
|
||||
Center,
|
||||
/// Place the element at the bottom of available space
|
||||
Bottom,
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ pub enum EventResult {
|
||||
}
|
||||
|
||||
impl EventResult {
|
||||
/// Convenient method to create `Consumed(Some(f))`
|
||||
pub fn with_cb<F: 'static + Fn(&mut Cursive)>(f: F) -> Self {
|
||||
EventResult::Consumed(Some(Rc::new(f)))
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
//! siv.run();
|
||||
//! }
|
||||
//! ```
|
||||
//! #![deny(missing_docs)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
extern crate ncurses;
|
||||
extern crate toml;
|
||||
|
26
src/menu.rs
26
src/menu.rs
@ -1,19 +1,30 @@
|
||||
//! Module to build menus.
|
||||
|
||||
use Cursive;
|
||||
use std::rc::Rc;
|
||||
use event::Callback;
|
||||
|
||||
/// Root of a menu tree.
|
||||
#[derive(Default)]
|
||||
pub struct MenuTree {
|
||||
/// Menu items
|
||||
pub children: Vec<MenuItem>,
|
||||
}
|
||||
|
||||
/// Node in the menu tree.
|
||||
pub enum MenuItem {
|
||||
/// Actionnable button with a label.
|
||||
Leaf(String, Callback),
|
||||
/// Sub-menu with a label.
|
||||
Subtree(String, Rc<MenuTree>),
|
||||
/// Delimiter without a label.
|
||||
Delimiter,
|
||||
}
|
||||
|
||||
impl MenuItem {
|
||||
/// Returns the label for this item.
|
||||
///
|
||||
/// Returns an empty string if `self` is a delimiter.
|
||||
pub fn label(&self) -> &str {
|
||||
match *self {
|
||||
MenuItem::Delimiter => "",
|
||||
@ -22,6 +33,7 @@ impl MenuItem {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is a delimiter.
|
||||
pub fn is_delimiter(&self) -> bool {
|
||||
match *self {
|
||||
MenuItem::Delimiter => true,
|
||||
@ -29,6 +41,7 @@ impl MenuItem {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` is a subtree.
|
||||
pub fn is_subtree(&self) -> bool {
|
||||
match *self {
|
||||
MenuItem::Subtree(_, _) => true,
|
||||
@ -38,49 +51,62 @@ impl MenuItem {
|
||||
}
|
||||
|
||||
impl MenuTree {
|
||||
/// Creates a new, empty tree.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Returns the number of children, including delimiters.
|
||||
pub fn len(&self) -> usize {
|
||||
self.children.len()
|
||||
}
|
||||
|
||||
/// Remove every children from this tree.
|
||||
pub fn clear(&mut self) {
|
||||
self.children.clear();
|
||||
}
|
||||
|
||||
/// Returns `true` if this tree has no children.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.children.is_empty()
|
||||
}
|
||||
|
||||
/// Adds a delimiter to the end of this tree.
|
||||
pub fn add_delimiter(&mut self) {
|
||||
self.children.push(MenuItem::Delimiter);
|
||||
}
|
||||
|
||||
/// Adds a delimiter to the end of this tree - chainable variant.
|
||||
pub fn delimiter(self) -> Self {
|
||||
self.with(|menu| menu.add_delimiter())
|
||||
}
|
||||
|
||||
/// Adds a actionnable leaf to the end of this tree.
|
||||
pub fn add_leaf<F: 'static + Fn(&mut Cursive)>(&mut self, title: &str,
|
||||
cb: F) {
|
||||
self.children
|
||||
.push(MenuItem::Leaf(title.to_string(), Rc::new(cb)));
|
||||
}
|
||||
|
||||
/// Adds a actionnable leaf to the end of this tree - chainable variant.
|
||||
pub fn leaf<F: 'static + Fn(&mut Cursive)>(self, title: &str, cb: F) -> Self {
|
||||
self.with(|menu| menu.add_leaf(title, cb))
|
||||
}
|
||||
|
||||
/// Adds a submenu to the end of this tree.
|
||||
pub fn add_subtree(&mut self, title: &str, tree: MenuTree) {
|
||||
self.children
|
||||
.push(MenuItem::Subtree(title.to_string(), Rc::new(tree)));
|
||||
}
|
||||
|
||||
/// Adds a submenu to the end of this tree - chainable variant.
|
||||
pub fn subtree(self, title: &str, tree: MenuTree) -> Self {
|
||||
self.with(|menu| menu.add_subtree(title, tree))
|
||||
}
|
||||
|
||||
/// Calls the given closure on `self`.
|
||||
///
|
||||
/// Useful in a function chain.
|
||||
pub fn with<F: FnOnce(&mut Self)>(mut self, f: F) -> Self {
|
||||
f(&mut self);
|
||||
self
|
||||
|
@ -144,6 +144,13 @@ impl Printer {
|
||||
"│");
|
||||
}
|
||||
|
||||
/// Apply a selection style and call the given function.
|
||||
///
|
||||
/// * If `selection` is `false`, simply uses `ColorStyle::Primary`.
|
||||
/// * If `selection` is `true`:
|
||||
/// * If the printer currently has the focus,
|
||||
/// uses `ColorStyle::Highlight`.
|
||||
/// * Otherwise, uses `ColorStyle::HighlightInactive`.
|
||||
pub fn with_selection<F: FnOnce(&Printer)>(&self, selection: bool, f: F) {
|
||||
self.with_color(if selection {
|
||||
if self.focused {
|
||||
@ -157,6 +164,7 @@ impl Printer {
|
||||
f);
|
||||
}
|
||||
|
||||
/// Prints a horizontal delimiter with side border `├` and `┤`.
|
||||
pub fn print_hdelim<T: Into<Vec2>>(&self, start: T, len: usize) {
|
||||
let start = start.into();
|
||||
self.print(start, "├");
|
||||
|
35
src/theme.rs
35
src/theme.rs
@ -11,8 +11,11 @@ use toml;
|
||||
|
||||
use B;
|
||||
|
||||
/// Text effect
|
||||
pub enum Effect {
|
||||
/// No effect
|
||||
Simple,
|
||||
/// Reverses foreground and background colors
|
||||
Reverse,
|
||||
}
|
||||
|
||||
@ -236,17 +239,45 @@ fn load_color(target: &mut Color, value: Option<&toml::Value>) -> bool {
|
||||
/// Represents a color used by the theme.
|
||||
#[derive(Clone,Debug)]
|
||||
pub enum Color {
|
||||
/// Color ID used by ncurses.
|
||||
/// Black color
|
||||
///
|
||||
/// Color #0
|
||||
Black,
|
||||
/// Red color
|
||||
///
|
||||
/// Color #1
|
||||
Red,
|
||||
/// Green color
|
||||
///
|
||||
/// Color #2
|
||||
Green,
|
||||
/// Yellow color (Red + Green)
|
||||
///
|
||||
/// Color #3
|
||||
Yellow,
|
||||
/// Blue color
|
||||
///
|
||||
/// Color #4
|
||||
Blue,
|
||||
/// Magenta color (Red + Blue)
|
||||
///
|
||||
/// Color #5
|
||||
Magenta,
|
||||
/// Cyan color (Green + Blue)
|
||||
///
|
||||
/// Color #6
|
||||
Cyan,
|
||||
/// White color (Red + Green + Blue)
|
||||
///
|
||||
/// Color #7
|
||||
White,
|
||||
// 24-bit color
|
||||
/// True-color, 24-bit.
|
||||
Rgb(u8, u8, u8),
|
||||
/// Low-resolution
|
||||
///
|
||||
/// Each value should be `<= 5` (you'll get panics otherwise).
|
||||
///
|
||||
/// These 216 possible colors are part of the default color palette.
|
||||
RgbLowRes(u8, u8, u8),
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,14 @@ use vec::Vec2;
|
||||
use super::{View, ViewWrapper};
|
||||
|
||||
/// `BoxView` is a wrapper around an other view, with a given minimum size.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use cursive::view::{BoxView,TextView};
|
||||
/// // Creates a 20x4 BoxView with a TextView content.
|
||||
/// let view = BoxView::fixed_size((20,4), TextView::new("Hello!"));
|
||||
/// ```
|
||||
pub struct BoxView<T: View> {
|
||||
width: Option<usize>,
|
||||
height: Option<usize>,
|
||||
@ -11,21 +19,16 @@ pub struct BoxView<T: View> {
|
||||
}
|
||||
|
||||
impl<T: View> BoxView<T> {
|
||||
/// Creates a new `BoxView` with the given minimum size and content
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use cursive::view::{BoxView,TextView};
|
||||
/// // Creates a 20x4 BoxView with a TextView content.
|
||||
/// let view = BoxView::fixed_size((20,4), TextView::new("Hello!"));
|
||||
/// ```
|
||||
/// Wraps `view` in a neww `BoxView` with the given size.
|
||||
pub fn fixed_size<S: Into<Vec2>>(size: S, view: T) -> Self {
|
||||
let size = size.into();
|
||||
|
||||
BoxView::new(Some(size.x), Some(size.y), view)
|
||||
}
|
||||
|
||||
/// Creates a new `BoxView` with the given width and height requirements.
|
||||
///
|
||||
/// `None` values will use the wrapped view's preferences.
|
||||
pub fn new(width: Option<usize>, height: Option<usize>, view: T) -> Self {
|
||||
BoxView {
|
||||
width: width,
|
||||
@ -34,9 +37,15 @@ impl<T: View> BoxView<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps `view` in a new `BoxView` with fixed width.
|
||||
pub fn fixed_width(width: usize, view: T) -> Self {
|
||||
BoxView::new(Some(width), None, view)
|
||||
}
|
||||
|
||||
/// Wraps `view` in a new `BoxView` with fixed height.
|
||||
pub fn fixed_height(height: usize, view: T) -> Self {
|
||||
BoxView::new(None, Some(height), view)
|
||||
}
|
||||
}
|
||||
|
||||
fn min<T: Ord>(a: T, b: Option<T>) -> T {
|
||||
@ -55,11 +64,11 @@ impl<T: View> ViewWrapper for BoxView<T> {
|
||||
Vec2::new(w, h)
|
||||
} else {
|
||||
let req = Vec2::new(min(req.x, self.width),
|
||||
min(req.y, self.height));
|
||||
min(req.y, self.height));
|
||||
let child_size = self.view.get_min_size(req);
|
||||
|
||||
Vec2::new(self.width.unwrap_or(child_size.x),
|
||||
self.height.unwrap_or(child_size.y))
|
||||
self.height.unwrap_or(child_size.y))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,9 @@ impl Dialog {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenient method to create an infobox.
|
||||
///
|
||||
/// It will contain the given text and a `Ok` dismiss button.
|
||||
pub fn info(text: &str) -> Self {
|
||||
Self::new(TextView::new(text)).dismiss_button("Ok")
|
||||
}
|
||||
|
@ -8,15 +8,10 @@ pub struct FullView<T: View> {
|
||||
orientation: Option<Orientation>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum Type {
|
||||
FullWidth,
|
||||
FullHeight,
|
||||
FullScreen,
|
||||
}
|
||||
|
||||
impl<T: View> FullView<T> {
|
||||
/// Wraps the given view into a new FullView.
|
||||
///
|
||||
/// It will always take the entire space available.
|
||||
pub fn new(view: T) -> Self {
|
||||
FullView {
|
||||
view: view,
|
||||
@ -24,6 +19,9 @@ impl<T: View> FullView<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new wrapper around `view` with full width.
|
||||
///
|
||||
/// It will always take the maximum width available.
|
||||
pub fn full_width(view: T) -> Self {
|
||||
FullView {
|
||||
view: view,
|
||||
@ -31,6 +29,9 @@ impl<T: View> FullView<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new wrapper around `view` with full height.
|
||||
///
|
||||
/// It will always take the maximum height available.
|
||||
pub fn full_height(view: T) -> Self {
|
||||
FullView {
|
||||
view: view,
|
||||
|
@ -13,7 +13,7 @@ use align::Align;
|
||||
use vec::Vec2;
|
||||
use event::{Callback, Event, EventResult, Key};
|
||||
|
||||
/// fd
|
||||
/// Popup that shows a list of items.
|
||||
pub struct MenuPopup {
|
||||
menu: Rc<MenuTree>,
|
||||
focus: usize,
|
||||
@ -24,6 +24,7 @@ pub struct MenuPopup {
|
||||
}
|
||||
|
||||
impl MenuPopup {
|
||||
/// Creates a new `MenuPopup` using the given menu tree.
|
||||
pub fn new(menu: Rc<MenuTree>) -> Self {
|
||||
MenuPopup {
|
||||
menu: menu,
|
||||
@ -82,11 +83,19 @@ impl MenuPopup {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a callback to be used when this view is actively dismissed.
|
||||
///
|
||||
/// (When the user hits <ESC>)
|
||||
pub fn on_dismiss<F: 'static + Fn(&mut Cursive)>(mut self, f: F) -> Self {
|
||||
self.on_dismiss = Some(Rc::new(f));
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a callback to be used when a leaf is activated.
|
||||
///
|
||||
/// Will also be called if a leaf from a subtree is activated.
|
||||
///
|
||||
/// Usually used to hide the parent view.
|
||||
pub fn on_action<F: 'static + Fn(&mut Cursive)>(mut self, f: F) -> Self {
|
||||
self.on_action = Some(Rc::new(f));
|
||||
self
|
||||
@ -103,6 +112,7 @@ impl MenuPopup {
|
||||
.unwrap_or(1);
|
||||
let offset = Vec2::new(max_width, self.focus);
|
||||
let action_cb = self.on_action.clone();
|
||||
|
||||
EventResult::with_cb(move |s| {
|
||||
let action_cb = action_cb.clone();
|
||||
s.screen_mut()
|
||||
|
@ -4,29 +4,41 @@ use vec::Vec2;
|
||||
/// Location of the view on screen
|
||||
#[derive(PartialEq,Debug,Clone)]
|
||||
pub struct Position {
|
||||
/// Horizontal offset
|
||||
pub x: Offset,
|
||||
/// Vertical offset
|
||||
pub y: Offset,
|
||||
}
|
||||
|
||||
impl Position {
|
||||
/// Creates a new position with the given offsets.
|
||||
pub fn new(x: Offset, y: Offset) -> Self {
|
||||
Position { x: x, y: y }
|
||||
}
|
||||
|
||||
/// Returns a position centered on both axis.
|
||||
pub fn center() -> Self {
|
||||
Position::new(Offset::Center, Offset::Center)
|
||||
}
|
||||
|
||||
/// Returns a position absolute on both axis.
|
||||
pub fn absolute<T: Into<Vec2>>(offset: T) -> Self {
|
||||
let offset = offset.into();
|
||||
Position::new(Offset::Absolute(offset.x), Offset::Absolute(offset.y))
|
||||
}
|
||||
|
||||
/// Returns a position relative to the parent on both axis.
|
||||
pub fn parent<T: Into<Vec2>>(offset: T) -> Self {
|
||||
let offset = offset.into();
|
||||
Position::new(Offset::Parent(offset.x), Offset::Parent(offset.y))
|
||||
}
|
||||
|
||||
/// Computes the offset required to draw a view.
|
||||
///
|
||||
/// When drawing a view with `size` in a container with `available`,
|
||||
/// and a parent with the absolute coordinates `parent`, drawing the
|
||||
/// child with its top-left corner at the returned coordinates will
|
||||
/// position him appropriately.
|
||||
pub fn compute_offset(&self, size: Vec2, available: Vec2, parent: Vec2)
|
||||
-> Vec2 {
|
||||
Vec2::new(self.x.compute_offset(size.x, available.x, parent.x),
|
||||
@ -34,6 +46,7 @@ impl Position {
|
||||
}
|
||||
}
|
||||
|
||||
/// Single-dimensional offset policy.
|
||||
#[derive(PartialEq,Debug,Clone)]
|
||||
pub enum Offset {
|
||||
/// In the center of the screen
|
||||
@ -48,6 +61,7 @@ pub enum Offset {
|
||||
}
|
||||
|
||||
impl Offset {
|
||||
/// Computes a single-dimension offset requred to draw a view.
|
||||
pub fn compute_offset(&self, size: usize, available: usize, parent: usize)
|
||||
-> usize {
|
||||
match *self {
|
||||
|
@ -7,13 +7,24 @@ use printer::Printer;
|
||||
/// Provide scrolling functionalities to a view.
|
||||
#[derive(Default)]
|
||||
pub struct ScrollBase {
|
||||
/// First line visible
|
||||
pub start_line: usize,
|
||||
/// Content height
|
||||
pub content_height: usize,
|
||||
/// Number of lines displayed
|
||||
pub view_height: usize,
|
||||
/// Padding for the scrollbar
|
||||
///
|
||||
/// If present, the scrollbar will be shifted
|
||||
/// `scrollbar_padding` columns to the left.
|
||||
///
|
||||
/// (Useful when each item includes its own side borders,
|
||||
/// to draw the scrollbar inside.)
|
||||
pub scrollbar_padding: usize,
|
||||
}
|
||||
|
||||
impl ScrollBase {
|
||||
/// Creates a new, uninitialized scrollbar.
|
||||
pub fn new() -> Self {
|
||||
ScrollBase {
|
||||
start_line: 0,
|
||||
@ -23,6 +34,11 @@ impl ScrollBase {
|
||||
}
|
||||
}
|
||||
|
||||
/// Shifts the scrollbar toward the inside of the view.
|
||||
///
|
||||
/// Used by views that draw their side borders in the children.
|
||||
/// Pushing the scrollbar to the left allows it to stay inside
|
||||
/// the borders.
|
||||
pub fn bar_padding(mut self, padding: usize) -> Self {
|
||||
self.scrollbar_padding = padding;
|
||||
self
|
||||
|
@ -49,15 +49,20 @@ impl<T: 'static> SelectView<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets a callback to be used when an item is selected.
|
||||
///
|
||||
/// (When ENTER is pressed on an item).
|
||||
pub fn set_on_select<F>(&mut self, cb: F)
|
||||
where F: Fn(&mut Cursive, &T) + 'static
|
||||
{
|
||||
self.select_cb = Some(Rc::new(cb));
|
||||
}
|
||||
|
||||
/// Sets a function to be called when an item is selected.
|
||||
/// Sets a callback to be used when an item is selected.
|
||||
///
|
||||
/// (When ENTER is pressed).
|
||||
/// (When ENTER is pressed on an item).
|
||||
///
|
||||
/// Chainable variant.
|
||||
pub fn on_select<F>(mut self, cb: F) -> Self
|
||||
where F: Fn(&mut Cursive, &T) + 'static
|
||||
{
|
||||
|
@ -26,10 +26,17 @@ impl<T: View> ShadowView<T> {
|
||||
(1 + self.left_padding as usize, 1 + self.top_padding as usize)
|
||||
}
|
||||
|
||||
/// If set, adds an empty column to the left of the view.
|
||||
///
|
||||
/// Default to true.
|
||||
pub fn left_padding(mut self, value: bool) -> Self {
|
||||
self.left_padding = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// If set, adds an empty row at the top of the view.
|
||||
///
|
||||
/// Default to true.
|
||||
pub fn top_padding(mut self, value: bool) -> Self {
|
||||
self.top_padding = value;
|
||||
self
|
||||
|
@ -2,12 +2,16 @@ use view::{IdView, View, ViewWrapper};
|
||||
use printer::Printer;
|
||||
use vec::Vec2;
|
||||
|
||||
/// Wrapper around a view that remembers its position.
|
||||
pub struct TrackedView<T: View> {
|
||||
/// Wrapped view.
|
||||
pub view: T,
|
||||
/// Last position the view was located.
|
||||
pub offset: Vec2,
|
||||
}
|
||||
|
||||
impl<T: View> TrackedView<T> {
|
||||
/// Creates a new `TrackedView` around `view`.
|
||||
pub fn new(view: T) -> Self {
|
||||
TrackedView {
|
||||
view: view,
|
||||
@ -15,6 +19,7 @@ impl<T: View> TrackedView<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps itself in a `IdView` for easy retrieval.
|
||||
pub fn with_id(self, id: &str) -> IdView<Self> {
|
||||
IdView::new(id, self)
|
||||
}
|
||||
|
@ -16,35 +16,37 @@ pub trait ViewWrapper {
|
||||
/// Get a mutable reference to the wrapped view.
|
||||
fn get_view_mut(&mut self) -> &mut View;
|
||||
|
||||
/// Wraps the draw method.
|
||||
/// Wraps the `draw` method.
|
||||
fn wrap_draw(&mut self, printer: &Printer) {
|
||||
self.get_view_mut().draw(printer);
|
||||
}
|
||||
|
||||
/// Wraps the get_min_size method.
|
||||
/// Wraps the `get_min_size` method.
|
||||
fn wrap_get_min_size(&mut self, req: Vec2) -> Vec2 {
|
||||
self.get_view_mut().get_min_size(req)
|
||||
}
|
||||
|
||||
/// Wraps the on_event method.
|
||||
/// Wraps the `on_event` method.
|
||||
fn wrap_on_event(&mut self, ch: Event) -> EventResult {
|
||||
self.get_view_mut().on_event(ch)
|
||||
}
|
||||
|
||||
/// Wraps the layout method
|
||||
/// Wraps the `layout` method.
|
||||
fn wrap_layout(&mut self, size: Vec2) {
|
||||
self.get_view_mut().layout(size);
|
||||
}
|
||||
|
||||
/// Wraps the take_focus method
|
||||
/// Wraps the `take_focus` method.
|
||||
fn wrap_take_focus(&mut self) -> bool {
|
||||
self.get_view_mut().take_focus()
|
||||
}
|
||||
|
||||
/// Wraps the `find` method.
|
||||
fn wrap_find(&mut self, selector: &Selector) -> Option<&mut Any> {
|
||||
self.get_view_mut().find(selector)
|
||||
}
|
||||
|
||||
/// Wraps the `needs_relayout` method.
|
||||
fn wrap_needs_relayout(&self) -> bool {
|
||||
self.get_view().needs_relayout()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user