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.
|
/// 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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)))
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
26
src/menu.rs
26
src/menu.rs
@ -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
|
||||||
|
@ -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, "├");
|
||||||
|
35
src/theme.rs
35
src/theme.rs
@ -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),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,14 @@ 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.
|
||||||
|
///
|
||||||
|
/// # 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> {
|
pub struct BoxView<T: View> {
|
||||||
width: Option<usize>,
|
width: Option<usize>,
|
||||||
height: Option<usize>,
|
height: Option<usize>,
|
||||||
@ -11,21 +19,16 @@ pub struct BoxView<T: View> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: View> BoxView<T> {
|
impl<T: View> BoxView<T> {
|
||||||
/// Creates a new `BoxView` with the given minimum size and content
|
/// Wraps `view` in a neww `BoxView` with the given 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 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 {
|
||||||
@ -55,11 +64,11 @@ impl<T: View> ViewWrapper for BoxView<T> {
|
|||||||
Vec2::new(w, h)
|
Vec2::new(w, h)
|
||||||
} else {
|
} else {
|
||||||
let req = Vec2::new(min(req.x, self.width),
|
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);
|
let child_size = self.view.get_min_size(req);
|
||||||
|
|
||||||
Vec2::new(self.width.unwrap_or(child_size.x),
|
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 {
|
pub fn info(text: &str) -> Self {
|
||||||
Self::new(TextView::new(text)).dismiss_button("Ok")
|
Self::new(TextView::new(text)).dismiss_button("Ok")
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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()
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user