diff --git a/src/align.rs b/src/align.rs index 8d80bd9..761b4c5 100644 --- a/src/align.rs +++ b/src/align.rs @@ -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, } diff --git a/src/event.rs b/src/event.rs index e7ed369..fc936db 100644 --- a/src/event.rs +++ b/src/event.rs @@ -18,6 +18,7 @@ pub enum EventResult { } impl EventResult { + /// Convenient method to create `Consumed(Some(f))` pub fn with_cb(f: F) -> Self { EventResult::Consumed(Some(Rc::new(f))) } diff --git a/src/lib.rs b/src/lib.rs index fa11cfc..ba64014 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,7 +20,7 @@ //! siv.run(); //! } //! ``` -//! #![deny(missing_docs)] +#![deny(missing_docs)] extern crate ncurses; extern crate toml; diff --git a/src/menu.rs b/src/menu.rs index f550b8f..55cac5a 100644 --- a/src/menu.rs +++ b/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, } +/// Node in the menu tree. pub enum MenuItem { + /// Actionnable button with a label. Leaf(String, Callback), + /// Sub-menu with a label. Subtree(String, Rc), + /// 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(&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(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(mut self, f: F) -> Self { f(&mut self); self diff --git a/src/printer.rs b/src/printer.rs index c530b4a..91d2b82 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -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(&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>(&self, start: T, len: usize) { let start = start.into(); self.print(start, "├"); diff --git a/src/theme.rs b/src/theme.rs index ca96e36..89bfbb4 100644 --- a/src/theme.rs +++ b/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), } diff --git a/src/view/box_view.rs b/src/view/box_view.rs index 3bdff25..40776ec 100644 --- a/src/view/box_view.rs +++ b/src/view/box_view.rs @@ -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 { width: Option, height: Option, @@ -11,21 +19,16 @@ pub struct BoxView { } impl BoxView { - /// 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>(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, height: Option, view: T) -> Self { BoxView { width: width, @@ -34,9 +37,15 @@ impl BoxView { } } + /// 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(a: T, b: Option) -> T { @@ -55,11 +64,11 @@ impl ViewWrapper for BoxView { 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)) } } } diff --git a/src/view/dialog.rs b/src/view/dialog.rs index cb7a413..ada169a 100644 --- a/src/view/dialog.rs +++ b/src/view/dialog.rs @@ -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") } diff --git a/src/view/full_view.rs b/src/view/full_view.rs index ffb0a28..8435458 100644 --- a/src/view/full_view.rs +++ b/src/view/full_view.rs @@ -8,15 +8,10 @@ pub struct FullView { orientation: Option, } -#[derive(Debug, PartialEq)] -enum Type { - FullWidth, - FullHeight, - FullScreen, -} - impl FullView { /// 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 FullView { } } + /// 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 FullView { } } + /// 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, diff --git a/src/view/menu_popup.rs b/src/view/menu_popup.rs index 521f972..4167a3a 100644 --- a/src/view/menu_popup.rs +++ b/src/view/menu_popup.rs @@ -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, 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) -> 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 ) pub fn on_dismiss(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(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() diff --git a/src/view/position.rs b/src/view/position.rs index c923dc5..8f18d35 100644 --- a/src/view/position.rs +++ b/src/view/position.rs @@ -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>(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>(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 { diff --git a/src/view/scroll.rs b/src/view/scroll.rs index 16111ae..bcd75e7 100644 --- a/src/view/scroll.rs +++ b/src/view/scroll.rs @@ -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 diff --git a/src/view/select_view.rs b/src/view/select_view.rs index f27e1a6..a5c4db9 100644 --- a/src/view/select_view.rs +++ b/src/view/select_view.rs @@ -49,15 +49,20 @@ impl SelectView { } } + /// Sets a callback to be used when an item is selected. + /// + /// (When ENTER is pressed on an item). pub fn set_on_select(&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(mut self, cb: F) -> Self where F: Fn(&mut Cursive, &T) + 'static { diff --git a/src/view/shadow_view.rs b/src/view/shadow_view.rs index 950f538..5b4d3fe 100644 --- a/src/view/shadow_view.rs +++ b/src/view/shadow_view.rs @@ -26,10 +26,17 @@ impl ShadowView { (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 diff --git a/src/view/tracked_view.rs b/src/view/tracked_view.rs index 344a5c0..e360f7a 100644 --- a/src/view/tracked_view.rs +++ b/src/view/tracked_view.rs @@ -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 { + /// Wrapped view. pub view: T, + /// Last position the view was located. pub offset: Vec2, } impl TrackedView { + /// Creates a new `TrackedView` around `view`. pub fn new(view: T) -> Self { TrackedView { view: view, @@ -15,6 +19,7 @@ impl TrackedView { } } + /// Wraps itself in a `IdView` for easy retrieval. pub fn with_id(self, id: &str) -> IdView { IdView::new(id, self) } diff --git a/src/view/view_wrapper.rs b/src/view/view_wrapper.rs index c3a74f4..96e9e76 100644 --- a/src/view/view_wrapper.rs +++ b/src/view/view_wrapper.rs @@ -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() }