diff --git a/src/widgets/block.rs b/src/widgets/block.rs index b8880211..a6df2fe2 100644 --- a/src/widgets/block.rs +++ b/src/widgets/block.rs @@ -6,18 +6,20 @@ //! In its simplest form, a `Block` is a [border](Borders) around another widget. It can have a //! [title](Block::title) and [padding](Block::padding). -#[path = "../title.rs"] -pub mod title; - use strum::{Display, EnumString}; -pub use self::title::{Position, Title}; use crate::{ prelude::*, symbols::border, widgets::{Borders, Widget}, }; +mod padding; +pub mod title; + +pub use padding::Padding; +pub use title::{Position, Title}; + /// The type of border of a [`Block`]. /// /// See the [`borders`](Block::borders) method of `Block` to configure its borders. @@ -110,171 +112,6 @@ impl BorderType { } } -/// Defines the padding of a [`Block`]. -/// -/// See the [`padding`](Block::padding) method of [`Block`] to configure its padding. -/// -/// This concept is similar to [CSS padding](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_box_model/Introduction_to_the_CSS_box_model#padding_area). -/// -/// **NOTE**: Terminal cells are often taller than they are wide, so to make horizontal and vertical -/// padding seem equal, doubling the horizontal padding is usually pretty good. -/// -/// # Example -/// -/// ``` -/// use ratatui::{prelude::*, widgets::*}; -/// -/// Padding::uniform(1); -/// Padding::horizontal(2); -/// Padding::left(3); -/// Padding::proportional(4); -/// Padding::symmetric(5, 6); -/// ``` -#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] -pub struct Padding { - /// Left padding - pub left: u16, - /// Right padding - pub right: u16, - /// Top padding - pub top: u16, - /// Bottom padding - pub bottom: u16, -} - -impl Padding { - /// Creates a new `Padding` by specifying every field individually. - pub const fn new(left: u16, right: u16, top: u16, bottom: u16) -> Self { - Padding { - left, - right, - top, - bottom, - } - } - - /// Creates a `Padding` of 0. - /// - /// This is also the default. - pub const fn zero() -> Self { - Padding { - left: 0, - right: 0, - top: 0, - bottom: 0, - } - } - - /// Defines the [`left`](Padding::left) and [`right`](Padding::right) padding. - /// - /// This leaves [`top`](Padding::top) and [`bottom`](Padding::bottom) to `0`. - pub const fn horizontal(value: u16) -> Self { - Padding { - left: value, - right: value, - top: 0, - bottom: 0, - } - } - - /// Defines the [`top`](Padding::top) and [`bottom`](Padding::bottom) padding. - /// - /// This leaves [`left`](Padding::left) and [`right`](Padding::right) at `0`. - pub const fn vertical(value: u16) -> Self { - Padding { - left: 0, - right: 0, - top: value, - bottom: value, - } - } - - /// Applies the same value to every `Padding` field. - pub const fn uniform(value: u16) -> Self { - Padding { - left: value, - right: value, - top: value, - bottom: value, - } - } - - /// To make horizontal and vertical padding seem equal - /// - /// Defines the [`top`](Padding::top) and [`bottom`](Padding::bottom) padding. - /// - /// Doubles the value then - /// defines [`left`](Padding::left) and [`right`](Padding::right) padding. - pub const fn proportional(value: u16) -> Self { - Padding { - left: 2 * value, - right: 2 * value, - top: value, - bottom: value, - } - } - - /// Defines the [`left`](Padding::left) and [`right`](Padding::right) padding with x value. - /// - /// defines [`top`](Padding::top) and [`bottom`](Padding::bottom) padding with y value. - pub const fn symmetric(x: u16, y: u16) -> Self { - Padding { - left: x, - right: x, - top: y, - bottom: y, - } - } - - /// Defines the [`left`](Padding::left) padding. - /// - /// This leaves others to `0`. - pub const fn left(value: u16) -> Self { - Padding { - left: value, - right: 0, - top: 0, - bottom: 0, - } - } - - /// Defines the [`right`](Padding::right) padding. - /// - /// This leaves others to `0`. - pub const fn right(value: u16) -> Self { - Padding { - left: 0, - right: value, - top: 0, - bottom: 0, - } - } - - /// Defines the [`top`](Padding::top) padding. - /// - /// This leaves others to `0`. - pub const fn top(value: u16) -> Self { - Padding { - left: 0, - right: 0, - top: value, - bottom: 0, - } - } - - /// Defines the [`bottom`](Padding::bottom) padding. - /// - /// This leaves others to `0`. - pub const fn bottom(value: u16) -> Self { - Padding { - left: 0, - right: 0, - top: 0, - bottom: value, - } - } -} - /// Base widget to be used to display a box border around all [upper level ones](crate::widgets). /// /// The borders can be configured with [`Block::borders`] and others. A block can have multiple @@ -1139,48 +976,6 @@ mod tests { const _PLAIN: border::Set = BorderType::border_symbols(BorderType::Plain); } - #[test] - fn padding_new() { - assert_eq!( - Padding::new(1, 2, 3, 4), - Padding { - left: 1, - right: 2, - top: 3, - bottom: 4 - } - ) - } - - #[test] - fn padding_constructors() { - assert_eq!(Padding::zero(), Padding::new(0, 0, 0, 0)); - assert_eq!(Padding::horizontal(1), Padding::new(1, 1, 0, 0)); - assert_eq!(Padding::vertical(1), Padding::new(0, 0, 1, 1)); - assert_eq!(Padding::uniform(1), Padding::new(1, 1, 1, 1)); - assert_eq!(Padding::proportional(1), Padding::new(2, 2, 1, 1)); - assert_eq!(Padding::symmetric(1, 2), Padding::new(1, 1, 2, 2)); - assert_eq!(Padding::left(1), Padding::new(1, 0, 0, 0)); - assert_eq!(Padding::right(1), Padding::new(0, 1, 0, 0)); - assert_eq!(Padding::top(1), Padding::new(0, 0, 1, 0)); - assert_eq!(Padding::bottom(1), Padding::new(0, 0, 0, 1)); - } - - #[test] - fn padding_can_be_const() { - const _PADDING: Padding = Padding::new(1, 1, 1, 1); - const _UNI_PADDING: Padding = Padding::uniform(1); - const _NO_PADDING: Padding = Padding::zero(); - const _HORIZONTAL: Padding = Padding::horizontal(1); - const _VERTICAL: Padding = Padding::vertical(1); - const _PROPORTIONAL: Padding = Padding::proportional(1); - const _SYMMETRIC: Padding = Padding::symmetric(1, 1); - const _LEFT: Padding = Padding::left(1); - const _RIGHT: Padding = Padding::right(1); - const _TOP: Padding = Padding::top(1); - const _BOTTOM: Padding = Padding::bottom(1); - } - #[test] fn block_new() { assert_eq!( diff --git a/src/widgets/block/padding.rs b/src/widgets/block/padding.rs new file mode 100644 index 00000000..5b4ae282 --- /dev/null +++ b/src/widgets/block/padding.rs @@ -0,0 +1,202 @@ +/// Defines the padding for a [`Block`]. +/// +/// See the [`padding`] method of [`Block`] to configure its padding. +/// +/// This concept is similar to [CSS padding]. +/// +/// **NOTE**: Terminal cells are often taller than they are wide, so to make horizontal and vertical +/// padding seem equal, doubling the horizontal padding is usually pretty good. +/// +/// # Example +/// +/// ``` +/// use ratatui::{prelude::*, widgets::*}; +/// +/// Padding::uniform(1); +/// Padding::horizontal(2); +/// Padding::left(3); +/// Padding::proportional(4); +/// Padding::symmetric(5, 6); +/// ``` +/// +/// [`Block`]: crate::widgets::Block +/// [`padding`]: crate::widgets::Block::padding +/// [CSS padding]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding +#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub struct Padding { + /// Left padding + pub left: u16, + /// Right padding + pub right: u16, + /// Top padding + pub top: u16, + /// Bottom padding + pub bottom: u16, +} + +impl Padding { + /// Creates a new `Padding` by specifying every field individually. + /// + /// Note: the order of the fields does not match the order of the CSS properties. + pub const fn new(left: u16, right: u16, top: u16, bottom: u16) -> Self { + Padding { + left, + right, + top, + bottom, + } + } + + /// Creates a `Padding` with all fields set to `0`. + pub const fn zero() -> Self { + Padding { + left: 0, + right: 0, + top: 0, + bottom: 0, + } + } + + /// Creates a `Padding` with the same value for `left` and `right`. + pub const fn horizontal(value: u16) -> Self { + Padding { + left: value, + right: value, + top: 0, + bottom: 0, + } + } + + /// Creates a `Padding` with the same value for `top` and `bottom`. + pub const fn vertical(value: u16) -> Self { + Padding { + left: 0, + right: 0, + top: value, + bottom: value, + } + } + + /// Creates a `Padding` with the same value for all fields. + pub const fn uniform(value: u16) -> Self { + Padding { + left: value, + right: value, + top: value, + bottom: value, + } + } + + /// Creates a `Padding` that is visually proportional to the terminal. + /// + /// This represents a padding of 2x the value for `left` and `right` and 1x the value for + /// `top` and `bottom`. + pub const fn proportional(value: u16) -> Self { + Padding { + left: 2 * value, + right: 2 * value, + top: value, + bottom: value, + } + } + + /// Creates a `Padding` that is symmetric. + /// + /// The `x` value is used for `left` and `right` and the `y` value is used for `top` and + /// `bottom`. + pub const fn symmetric(x: u16, y: u16) -> Self { + Padding { + left: x, + right: x, + top: y, + bottom: y, + } + } + + /// Creates a `Padding` that only sets the `left` padding. + pub const fn left(value: u16) -> Self { + Padding { + left: value, + right: 0, + top: 0, + bottom: 0, + } + } + + /// Creates a `Padding` that only sets the `right` padding. + pub const fn right(value: u16) -> Self { + Padding { + left: 0, + right: value, + top: 0, + bottom: 0, + } + } + + /// Creates a `Padding` that only sets the `top` padding. + pub const fn top(value: u16) -> Self { + Padding { + left: 0, + right: 0, + top: value, + bottom: 0, + } + } + + /// Creates a `Padding` that only sets the `bottom` padding. + pub const fn bottom(value: u16) -> Self { + Padding { + left: 0, + right: 0, + top: 0, + bottom: value, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn new() { + assert_eq!( + Padding::new(1, 2, 3, 4), + Padding { + left: 1, + right: 2, + top: 3, + bottom: 4 + } + ) + } + + #[test] + fn constructors() { + assert_eq!(Padding::zero(), Padding::new(0, 0, 0, 0)); + assert_eq!(Padding::horizontal(1), Padding::new(1, 1, 0, 0)); + assert_eq!(Padding::vertical(1), Padding::new(0, 0, 1, 1)); + assert_eq!(Padding::uniform(1), Padding::new(1, 1, 1, 1)); + assert_eq!(Padding::proportional(1), Padding::new(2, 2, 1, 1)); + assert_eq!(Padding::symmetric(1, 2), Padding::new(1, 1, 2, 2)); + assert_eq!(Padding::left(1), Padding::new(1, 0, 0, 0)); + assert_eq!(Padding::right(1), Padding::new(0, 1, 0, 0)); + assert_eq!(Padding::top(1), Padding::new(0, 0, 1, 0)); + assert_eq!(Padding::bottom(1), Padding::new(0, 0, 0, 1)); + } + + #[test] + fn can_be_const() { + const _PADDING: Padding = Padding::new(1, 1, 1, 1); + const _UNI_PADDING: Padding = Padding::uniform(1); + const _NO_PADDING: Padding = Padding::zero(); + const _HORIZONTAL: Padding = Padding::horizontal(1); + const _VERTICAL: Padding = Padding::vertical(1); + const _PROPORTIONAL: Padding = Padding::proportional(1); + const _SYMMETRIC: Padding = Padding::symmetric(1, 1); + const _LEFT: Padding = Padding::left(1); + const _RIGHT: Padding = Padding::right(1); + const _TOP: Padding = Padding::top(1); + const _BOTTOM: Padding = Padding::bottom(1); + } +} diff --git a/src/title.rs b/src/widgets/block/title.rs similarity index 100% rename from src/title.rs rename to src/widgets/block/title.rs