Add #![deny(missing_docs)]

And fill the appropriate missing ones
This commit is contained in:
Alexandre Bury 2016-07-11 20:26:33 -07:00
parent c597c262fe
commit 309c471a63
16 changed files with 175 additions and 29 deletions

View File

@ -2,7 +2,9 @@
/// Specifies the alignment along both horizontal and vertical directions. /// Specifies the alignment along both horizontal and vertical directions.
pub struct Align { pub struct Align {
/// Horizontal alignment policy
pub h: HAlign, pub h: HAlign,
/// Vertical alignment policy
pub v: VAlign, pub v: VAlign,
} }
@ -40,15 +42,21 @@ impl Align {
/// Horizontal alignment /// Horizontal alignment
pub enum HAlign { pub enum HAlign {
/// Place the element to the left of available space
Left, Left,
/// Place the element horizontally in the center of available space
Center, Center,
/// Place the element to the right of available space
Right, Right,
} }
/// Vertical alignment /// Vertical alignment
pub enum VAlign { pub enum VAlign {
/// Place the element at the top of available space
Top, Top,
/// Place the element vertically in the center of available space
Center, Center,
/// Place the element at the bottom of available space
Bottom, Bottom,
} }

View File

@ -18,6 +18,7 @@ pub enum EventResult {
} }
impl EventResult { impl EventResult {
/// Convenient method to create `Consumed(Some(f))`
pub fn with_cb<F: 'static + Fn(&mut Cursive)>(f: F) -> Self { pub fn with_cb<F: 'static + Fn(&mut Cursive)>(f: F) -> Self {
EventResult::Consumed(Some(Rc::new(f))) EventResult::Consumed(Some(Rc::new(f)))
} }

View File

@ -20,7 +20,7 @@
//! siv.run(); //! siv.run();
//! } //! }
//! ``` //! ```
//! #![deny(missing_docs)] #![deny(missing_docs)]
extern crate ncurses; extern crate ncurses;
extern crate toml; extern crate toml;

View File

@ -1,19 +1,30 @@
//! Module to build menus.
use Cursive; use Cursive;
use std::rc::Rc; use std::rc::Rc;
use event::Callback; use event::Callback;
/// Root of a menu tree.
#[derive(Default)] #[derive(Default)]
pub struct MenuTree { pub struct MenuTree {
/// Menu items
pub children: Vec<MenuItem>, pub children: Vec<MenuItem>,
} }
/// Node in the menu tree.
pub enum MenuItem { pub enum MenuItem {
/// Actionnable button with a label.
Leaf(String, Callback), Leaf(String, Callback),
/// Sub-menu with a label.
Subtree(String, Rc<MenuTree>), Subtree(String, Rc<MenuTree>),
/// Delimiter without a label.
Delimiter, Delimiter,
} }
impl MenuItem { impl MenuItem {
/// Returns the label for this item.
///
/// Returns an empty string if `self` is a delimiter.
pub fn label(&self) -> &str { pub fn label(&self) -> &str {
match *self { match *self {
MenuItem::Delimiter => "", MenuItem::Delimiter => "",
@ -22,6 +33,7 @@ impl MenuItem {
} }
} }
/// Returns `true` if `self` is a delimiter.
pub fn is_delimiter(&self) -> bool { pub fn is_delimiter(&self) -> bool {
match *self { match *self {
MenuItem::Delimiter => true, MenuItem::Delimiter => true,
@ -29,6 +41,7 @@ impl MenuItem {
} }
} }
/// Returns `true` if `self` is a subtree.
pub fn is_subtree(&self) -> bool { pub fn is_subtree(&self) -> bool {
match *self { match *self {
MenuItem::Subtree(_, _) => true, MenuItem::Subtree(_, _) => true,
@ -38,49 +51,62 @@ impl MenuItem {
} }
impl MenuTree { impl MenuTree {
/// Creates a new, empty tree.
pub fn new() -> Self { pub fn new() -> Self {
Self::default() Self::default()
} }
/// Returns the number of children, including delimiters.
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.children.len() self.children.len()
} }
/// Remove every children from this tree.
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.children.clear(); self.children.clear();
} }
/// Returns `true` if this tree has no children.
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.children.is_empty() self.children.is_empty()
} }
/// Adds a delimiter to the end of this tree.
pub fn add_delimiter(&mut self) { pub fn add_delimiter(&mut self) {
self.children.push(MenuItem::Delimiter); self.children.push(MenuItem::Delimiter);
} }
/// Adds a delimiter to the end of this tree - chainable variant.
pub fn delimiter(self) -> Self { pub fn delimiter(self) -> Self {
self.with(|menu| menu.add_delimiter()) 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, pub fn add_leaf<F: 'static + Fn(&mut Cursive)>(&mut self, title: &str,
cb: F) { cb: F) {
self.children self.children
.push(MenuItem::Leaf(title.to_string(), Rc::new(cb))); .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 { pub fn leaf<F: 'static + Fn(&mut Cursive)>(self, title: &str, cb: F) -> Self {
self.with(|menu| menu.add_leaf(title, cb)) 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) { pub fn add_subtree(&mut self, title: &str, tree: MenuTree) {
self.children self.children
.push(MenuItem::Subtree(title.to_string(), Rc::new(tree))); .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 { pub fn subtree(self, title: &str, tree: MenuTree) -> Self {
self.with(|menu| menu.add_subtree(title, tree)) 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 { pub fn with<F: FnOnce(&mut Self)>(mut self, f: F) -> Self {
f(&mut self); f(&mut self);
self self

View File

@ -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) { pub fn with_selection<F: FnOnce(&Printer)>(&self, selection: bool, f: F) {
self.with_color(if selection { self.with_color(if selection {
if self.focused { if self.focused {
@ -157,6 +164,7 @@ impl Printer {
f); f);
} }
/// Prints a horizontal delimiter with side border `├` and `┤`.
pub fn print_hdelim<T: Into<Vec2>>(&self, start: T, len: usize) { pub fn print_hdelim<T: Into<Vec2>>(&self, start: T, len: usize) {
let start = start.into(); let start = start.into();
self.print(start, ""); self.print(start, "");

View File

@ -11,8 +11,11 @@ use toml;
use B; use B;
/// Text effect
pub enum Effect { pub enum Effect {
/// No effect
Simple, Simple,
/// Reverses foreground and background colors
Reverse, Reverse,
} }
@ -236,17 +239,45 @@ fn load_color(target: &mut Color, value: Option<&toml::Value>) -> bool {
/// Represents a color used by the theme. /// Represents a color used by the theme.
#[derive(Clone,Debug)] #[derive(Clone,Debug)]
pub enum Color { pub enum Color {
/// Color ID used by ncurses. /// Black color
///
/// Color #0
Black, Black,
/// Red color
///
/// Color #1
Red, Red,
/// Green color
///
/// Color #2
Green, Green,
/// Yellow color (Red + Green)
///
/// Color #3
Yellow, Yellow,
/// Blue color
///
/// Color #4
Blue, Blue,
/// Magenta color (Red + Blue)
///
/// Color #5
Magenta, Magenta,
/// Cyan color (Green + Blue)
///
/// Color #6
Cyan, Cyan,
/// White color (Red + Green + Blue)
///
/// Color #7
White, White,
// 24-bit color /// True-color, 24-bit.
Rgb(u8, u8, u8), 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), RgbLowRes(u8, u8, u8),
} }

View File

@ -4,14 +4,6 @@ use vec::Vec2;
use super::{View, ViewWrapper}; use super::{View, ViewWrapper};
/// `BoxView` is a wrapper around an other view, with a given minimum size. /// `BoxView` is a wrapper around an other view, with a given minimum size.
pub struct BoxView<T: View> {
width: Option<usize>,
height: Option<usize>,
view: T,
}
impl<T: View> BoxView<T> {
/// Creates a new `BoxView` with the given minimum size and content
/// ///
/// # Example /// # Example
/// ///
@ -20,12 +12,23 @@ impl<T: View> BoxView<T> {
/// // Creates a 20x4 BoxView with a TextView content. /// // Creates a 20x4 BoxView with a TextView content.
/// let view = BoxView::fixed_size((20,4), TextView::new("Hello!")); /// let view = BoxView::fixed_size((20,4), TextView::new("Hello!"));
/// ``` /// ```
pub struct BoxView<T: View> {
width: Option<usize>,
height: Option<usize>,
view: T,
}
impl<T: View> BoxView<T> {
/// Wraps `view` in a neww `BoxView` with the given size.
pub fn fixed_size<S: Into<Vec2>>(size: S, view: T) -> Self { pub fn fixed_size<S: Into<Vec2>>(size: S, view: T) -> Self {
let size = size.into(); let size = size.into();
BoxView::new(Some(size.x), Some(size.y), view) 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 { pub fn new(width: Option<usize>, height: Option<usize>, view: T) -> Self {
BoxView { BoxView {
width: width, 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 { pub fn fixed_width(width: usize, view: T) -> Self {
BoxView::new(Some(width), None, view) 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 { fn min<T: Ord>(a: T, b: Option<T>) -> T {

View File

@ -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 { pub fn info(text: &str) -> Self {
Self::new(TextView::new(text)).dismiss_button("Ok") Self::new(TextView::new(text)).dismiss_button("Ok")
} }

View File

@ -8,15 +8,10 @@ pub struct FullView<T: View> {
orientation: Option<Orientation>, orientation: Option<Orientation>,
} }
#[derive(Debug, PartialEq)]
enum Type {
FullWidth,
FullHeight,
FullScreen,
}
impl<T: View> FullView<T> { impl<T: View> FullView<T> {
/// Wraps the given view into a new FullView. /// Wraps the given view into a new FullView.
///
/// It will always take the entire space available.
pub fn new(view: T) -> Self { pub fn new(view: T) -> Self {
FullView { FullView {
view: view, 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 { pub fn full_width(view: T) -> Self {
FullView { FullView {
view: view, 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 { pub fn full_height(view: T) -> Self {
FullView { FullView {
view: view, view: view,

View File

@ -13,7 +13,7 @@ use align::Align;
use vec::Vec2; use vec::Vec2;
use event::{Callback, Event, EventResult, Key}; use event::{Callback, Event, EventResult, Key};
/// fd /// Popup that shows a list of items.
pub struct MenuPopup { pub struct MenuPopup {
menu: Rc<MenuTree>, menu: Rc<MenuTree>,
focus: usize, focus: usize,
@ -24,6 +24,7 @@ pub struct MenuPopup {
} }
impl MenuPopup { impl MenuPopup {
/// Creates a new `MenuPopup` using the given menu tree.
pub fn new(menu: Rc<MenuTree>) -> Self { pub fn new(menu: Rc<MenuTree>) -> Self {
MenuPopup { MenuPopup {
menu: menu, menu: menu,
@ -82,11 +83,19 @@ impl MenuPopup {
self 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 { pub fn on_dismiss<F: 'static + Fn(&mut Cursive)>(mut self, f: F) -> Self {
self.on_dismiss = Some(Rc::new(f)); self.on_dismiss = Some(Rc::new(f));
self 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 { pub fn on_action<F: 'static + Fn(&mut Cursive)>(mut self, f: F) -> Self {
self.on_action = Some(Rc::new(f)); self.on_action = Some(Rc::new(f));
self self
@ -103,6 +112,7 @@ impl MenuPopup {
.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();
EventResult::with_cb(move |s| { EventResult::with_cb(move |s| {
let action_cb = action_cb.clone(); let action_cb = action_cb.clone();
s.screen_mut() s.screen_mut()

View File

@ -4,29 +4,41 @@ use vec::Vec2;
/// Location of the view on screen /// Location of the view on screen
#[derive(PartialEq,Debug,Clone)] #[derive(PartialEq,Debug,Clone)]
pub struct Position { pub struct Position {
/// Horizontal offset
pub x: Offset, pub x: Offset,
/// Vertical offset
pub y: Offset, pub y: Offset,
} }
impl Position { impl Position {
/// Creates a new position with the given offsets.
pub fn new(x: Offset, y: Offset) -> Self { pub fn new(x: Offset, y: Offset) -> Self {
Position { x: x, y: y } Position { x: x, y: y }
} }
/// Returns a position centered on both axis.
pub fn center() -> Self { pub fn center() -> Self {
Position::new(Offset::Center, Offset::Center) Position::new(Offset::Center, Offset::Center)
} }
/// Returns a position absolute on both axis.
pub fn absolute<T: Into<Vec2>>(offset: T) -> Self { pub fn absolute<T: Into<Vec2>>(offset: T) -> Self {
let offset = offset.into(); let offset = offset.into();
Position::new(Offset::Absolute(offset.x), Offset::Absolute(offset.y)) 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 { pub fn parent<T: Into<Vec2>>(offset: T) -> Self {
let offset = offset.into(); let offset = offset.into();
Position::new(Offset::Parent(offset.x), Offset::Parent(offset.y)) 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) pub fn compute_offset(&self, size: Vec2, available: Vec2, parent: Vec2)
-> Vec2 { -> Vec2 {
Vec2::new(self.x.compute_offset(size.x, available.x, parent.x), 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)] #[derive(PartialEq,Debug,Clone)]
pub enum Offset { pub enum Offset {
/// In the center of the screen /// In the center of the screen
@ -48,6 +61,7 @@ pub enum Offset {
} }
impl Offset { impl Offset {
/// Computes a single-dimension offset requred to draw a view.
pub fn compute_offset(&self, size: usize, available: usize, parent: usize) pub fn compute_offset(&self, size: usize, available: usize, parent: usize)
-> usize { -> usize {
match *self { match *self {

View File

@ -7,13 +7,24 @@ use printer::Printer;
/// Provide scrolling functionalities to a view. /// Provide scrolling functionalities to a view.
#[derive(Default)] #[derive(Default)]
pub struct ScrollBase { pub struct ScrollBase {
/// First line visible
pub start_line: usize, pub start_line: usize,
/// Content height
pub content_height: usize, pub content_height: usize,
/// Number of lines displayed
pub view_height: usize, 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, pub scrollbar_padding: usize,
} }
impl ScrollBase { impl ScrollBase {
/// Creates a new, uninitialized scrollbar.
pub fn new() -> Self { pub fn new() -> Self {
ScrollBase { ScrollBase {
start_line: 0, 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 { pub fn bar_padding(mut self, padding: usize) -> Self {
self.scrollbar_padding = padding; self.scrollbar_padding = padding;
self self

View File

@ -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) pub fn set_on_select<F>(&mut self, cb: F)
where F: Fn(&mut Cursive, &T) + 'static where F: Fn(&mut Cursive, &T) + 'static
{ {
self.select_cb = Some(Rc::new(cb)); 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 pub fn on_select<F>(mut self, cb: F) -> Self
where F: Fn(&mut Cursive, &T) + 'static where F: Fn(&mut Cursive, &T) + 'static
{ {

View File

@ -26,10 +26,17 @@ impl<T: View> ShadowView<T> {
(1 + self.left_padding as usize, 1 + self.top_padding as usize) (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 { pub fn left_padding(mut self, value: bool) -> Self {
self.left_padding = value; self.left_padding = value;
self 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 { pub fn top_padding(mut self, value: bool) -> Self {
self.top_padding = value; self.top_padding = value;
self self

View File

@ -2,12 +2,16 @@ use view::{IdView, View, ViewWrapper};
use printer::Printer; use printer::Printer;
use vec::Vec2; use vec::Vec2;
/// Wrapper around a view that remembers its position.
pub struct TrackedView<T: View> { pub struct TrackedView<T: View> {
/// Wrapped view.
pub view: T, pub view: T,
/// Last position the view was located.
pub offset: Vec2, pub offset: Vec2,
} }
impl<T: View> TrackedView<T> { impl<T: View> TrackedView<T> {
/// Creates a new `TrackedView` around `view`.
pub fn new(view: T) -> Self { pub fn new(view: T) -> Self {
TrackedView { TrackedView {
view: view, 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> { pub fn with_id(self, id: &str) -> IdView<Self> {
IdView::new(id, self) IdView::new(id, self)
} }

View File

@ -16,35 +16,37 @@ pub trait ViewWrapper {
/// Get a mutable reference to the wrapped view. /// Get a mutable reference to the wrapped view.
fn get_view_mut(&mut self) -> &mut View; fn get_view_mut(&mut self) -> &mut View;
/// Wraps the draw method. /// Wraps the `draw` method.
fn wrap_draw(&mut self, printer: &Printer) { fn wrap_draw(&mut self, printer: &Printer) {
self.get_view_mut().draw(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 { fn wrap_get_min_size(&mut self, req: Vec2) -> Vec2 {
self.get_view_mut().get_min_size(req) 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 { fn wrap_on_event(&mut self, ch: Event) -> EventResult {
self.get_view_mut().on_event(ch) self.get_view_mut().on_event(ch)
} }
/// Wraps the layout method /// Wraps the `layout` method.
fn wrap_layout(&mut self, size: Vec2) { fn wrap_layout(&mut self, size: Vec2) {
self.get_view_mut().layout(size); self.get_view_mut().layout(size);
} }
/// Wraps the take_focus method /// Wraps the `take_focus` method.
fn wrap_take_focus(&mut self) -> bool { fn wrap_take_focus(&mut self) -> bool {
self.get_view_mut().take_focus() self.get_view_mut().take_focus()
} }
/// Wraps the `find` method.
fn wrap_find(&mut self, selector: &Selector) -> Option<&mut Any> { fn wrap_find(&mut self, selector: &Selector) -> Option<&mut Any> {
self.get_view_mut().find(selector) self.get_view_mut().find(selector)
} }
/// Wraps the `needs_relayout` method.
fn wrap_needs_relayout(&self) -> bool { fn wrap_needs_relayout(&self) -> bool {
self.get_view().needs_relayout() self.get_view().needs_relayout()
} }