diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-01-26 15:51:13 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-01-26 15:51:13 +0100 |
| commit | 20fb4e7c379b79b84d9884d5f2c89d781c5793e2 (patch) | |
| tree | a1eef90680afa2b43cb1ce0a687c837fd78810e7 /src/layout/mod.rs | |
| parent | 0a087cd28bbee5fcdffbb9d49b0ba9f413ad7f92 (diff) | |
Document everything 📜
Diffstat (limited to 'src/layout/mod.rs')
| -rw-r--r-- | src/layout/mod.rs | 231 |
1 files changed, 134 insertions, 97 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs index f8074524..bcabf7f3 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -1,4 +1,4 @@ -//! The core layouting engine. +//! Layouting types and engines. use std::io::{self, Write}; use std::fmt::{self, Display, Formatter}; @@ -6,7 +6,7 @@ use smallvec::SmallVec; use toddle::query::FontIndex; use crate::size::{Size, Size2D, SizeBox}; -use self::{GenericAxis::*, SpecificAxis::*, Direction::*, Alignment::*}; +use self::prelude::*; pub mod line; pub mod stack; @@ -15,8 +15,13 @@ pub mod text; pub_use_mod!(actions); pub_use_mod!(model); +/// Basic types used across the layouting engine. pub mod prelude { - pub use super::{LayoutSpace, LayoutExpansion, LayoutAxes, LayoutAlignment}; + pub use super::{ + LayoutContext, layout, LayoutSpace, + Layouted, Commands, + LayoutAxes, LayoutAlignment, LayoutExpansion + }; pub use super::GenericAxis::{self, *}; pub use super::SpecificAxis::{self, *}; pub use super::Direction::{self, *}; @@ -27,7 +32,7 @@ pub mod prelude { /// A collection of layouts. pub type MultiLayout = Vec<Layout>; -/// A sequence of layouting actions inside a box. +/// A finished box with content at fixed positions. #[derive(Debug, Clone)] pub struct Layout { /// The size of the box. @@ -81,10 +86,11 @@ impl Serialize for MultiLayout { } } -/// A possibly stack-allocated vector of layout spaces. +/// A vector of layout spaces, that is stack allocated as long as it only +/// contains at most 2 spaces. pub type LayoutSpaces = SmallVec<[LayoutSpace; 2]>; -/// Spacial layouting constraints. +/// The space into which content is laid out. #[derive(Debug, Copy, Clone)] pub struct LayoutSpace { /// The maximum size of the box to layout in. @@ -92,8 +98,7 @@ pub struct LayoutSpace { /// Padding that should be respected on each side. pub padding: SizeBox, /// Whether to expand the dimensions of the resulting layout to the full - /// dimensions of this space or to shrink them to fit the content for the - /// horizontal and vertical axis. + /// dimensions of this space or to shrink them to fit the content. pub expansion: LayoutExpansion, } @@ -119,70 +124,12 @@ impl LayoutSpace { } } -/// Whether to fit to content or expand to the space's size. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub struct LayoutExpansion { - pub horizontal: bool, - pub vertical: bool, -} - -impl LayoutExpansion { - pub fn new(horizontal: bool, vertical: bool) -> LayoutExpansion { - LayoutExpansion { horizontal, vertical } - } - - /// Borrow the specified component mutably. - pub fn get_mut(&mut self, axis: SpecificAxis) -> &mut bool { - match axis { - Horizontal => &mut self.horizontal, - Vertical => &mut self.vertical, - } - } -} - -/// The axes along which the content is laid out. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] -pub struct LayoutAxes { - pub primary: Direction, - pub secondary: Direction, -} - -impl LayoutAxes { - pub fn new(primary: Direction, secondary: Direction) -> LayoutAxes { - if primary.axis() == secondary.axis() { - panic!("LayoutAxes::new: invalid aligned axes {:?} and {:?}", - primary, secondary); - } - - LayoutAxes { primary, secondary } - } - - /// Return the direction of the specified generic axis. - pub fn get(self, axis: GenericAxis) -> Direction { - match axis { - Primary => self.primary, - Secondary => self.secondary, - } - } - - /// Borrow the direction of the specified generic axis mutably. - pub fn get_mut(&mut self, axis: GenericAxis) -> &mut Direction { - match axis { - Primary => &mut self.primary, - Secondary => &mut self.secondary, - } - } - - /// Return the direction of the specified specific axis. - pub fn get_specific(self, axis: SpecificAxis) -> Direction { - self.get(axis.to_generic(self)) - } -} - /// The two generic layouting axes. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum GenericAxis { + /// The primary axis along which words are laid out. Primary, + /// The secondary axis along which lines and paragraphs are laid out. Secondary, } @@ -191,14 +138,6 @@ impl GenericAxis { pub fn to_specific(self, axes: LayoutAxes) -> SpecificAxis { axes.get(self).axis() } - - /// The other axis. - pub fn inv(self) -> GenericAxis { - match self { - Primary => Secondary, - Secondary => Primary, - } - } } impl Display for GenericAxis { @@ -213,7 +152,9 @@ impl Display for GenericAxis { /// The two specific layouting axes. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum SpecificAxis { + /// The horizontal layouting axis. Horizontal, + /// The vertical layouting axis. Vertical, } @@ -222,14 +163,6 @@ impl SpecificAxis { pub fn to_generic(self, axes: LayoutAxes) -> GenericAxis { if self == axes.primary.axis() { Primary } else { Secondary } } - - /// The other axis. - pub fn inv(self) -> SpecificAxis { - match self { - Horizontal => Vertical, - Vertical => Horizontal, - } - } } impl Display for SpecificAxis { @@ -241,8 +174,50 @@ impl Display for SpecificAxis { } } +/// Specifies along which directions content is laid out. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub struct LayoutAxes { + /// The primary layouting direction. + pub primary: Direction, + /// The secondary layouting direction. + pub secondary: Direction, +} + +impl LayoutAxes { + /// Create a new instance from the two values. + /// + /// # Panics + /// This function panics if the directions are aligned, that is, they are + /// on the same axis. + pub fn new(primary: Direction, secondary: Direction) -> LayoutAxes { + if primary.axis() == secondary.axis() { + panic!("LayoutAxes::new: invalid aligned axes \ + {} and {}", primary, secondary); + } + + LayoutAxes { primary, secondary } + } + + /// Return the direction of the specified generic axis. + pub fn get(self, axis: GenericAxis) -> Direction { + match axis { + Primary => self.primary, + Secondary => self.secondary, + } + } + + /// Borrow the direction of the specified generic axis mutably. + pub fn get_mut(&mut self, axis: GenericAxis) -> &mut Direction { + match axis { + Primary => &mut self.primary, + Secondary => &mut self.secondary, + } + } +} + /// Directions along which content is laid out. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[allow(missing_docs)] pub enum Direction { LeftToRight, RightToLeft, @@ -260,6 +235,8 @@ impl Direction { } /// Whether this axis points into the positive coordinate direction. + /// + /// The positive directions are left-to-right and top-to-bottom. pub fn is_positive(self) -> bool { match self { LeftToRight | TopToBottom => true, @@ -267,6 +244,14 @@ impl Direction { } } + /// The factor for this direction. + /// + /// - `1` if the direction is positive. + /// - `-1` if the direction is negative. + pub fn factor(self) -> i32 { + if self.is_positive() { 1 } else { -1 } + } + /// The inverse axis. pub fn inv(self) -> Direction { match self { @@ -276,14 +261,6 @@ impl Direction { BottomToTop => TopToBottom, } } - - /// The factor for this direction. - /// - /// - `1` if the direction is positive. - /// - `-1` if the direction is negative. - pub fn factor(self) -> i32 { - if self.is_positive() { 1 } else { -1 } - } } impl Display for Direction { @@ -297,18 +274,29 @@ impl Display for Direction { } } -/// Where to align a layout in a container. +/// Specifies where to align a layout in a parent container. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct LayoutAlignment { + /// The alignment along the primary axis. pub primary: Alignment, + /// The alignment along the secondary axis. pub secondary: Alignment, } impl LayoutAlignment { + /// Create a new instance from the two values. pub fn new(primary: Alignment, secondary: Alignment) -> LayoutAlignment { LayoutAlignment { primary, secondary } } + /// Return the alignment of the specified generic axis. + pub fn get(self, axis: GenericAxis) -> Alignment { + match axis { + Primary => self.primary, + Secondary => self.secondary, + } + } + /// Borrow the alignment of the specified generic axis mutably. pub fn get_mut(&mut self, axis: GenericAxis) -> &mut Alignment { match axis { @@ -321,8 +309,11 @@ impl LayoutAlignment { /// Where to align content. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub enum Alignment { + /// Align content at the start of the axis. Origin, + /// Align content centered on the axis. Center, + /// Align content at the end of the axis. End, } @@ -337,12 +328,53 @@ impl Alignment { } } -/// Whitespace between boxes with different interaction properties. +/// Specifies whether to expand a layout to the full size of the space it is +/// laid out in or to shrink it to fit the content. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub struct LayoutExpansion { + /// Whether to expand on the horizontal axis. + pub horizontal: bool, + /// Whether to expand on the vertical axis. + pub vertical: bool, +} + +impl LayoutExpansion { + /// Create a new instance from the two values. + pub fn new(horizontal: bool, vertical: bool) -> LayoutExpansion { + LayoutExpansion { horizontal, vertical } + } + + /// Return the expansion value for the given specific axis. + pub fn get(self, axis: SpecificAxis) -> bool { + match axis { + Horizontal => self.horizontal, + Vertical => self.vertical, + } + } + + /// Borrow the expansion value for the given specific axis mutably. + pub fn get_mut(&mut self, axis: SpecificAxis) -> &mut bool { + match axis { + Horizontal => &mut self.horizontal, + Vertical => &mut self.vertical, + } + } +} + +/// Defines how a given spacing interacts with (possibly existing) surrounding +/// spacing. +/// +/// There are two options for interaction: Hard and soft spacing. Typically, +/// hard spacing is used when a fixed amount of space needs to be inserted no +/// matter what. In contrast, soft spacing can be used to insert a default +/// spacing between e.g. two words or paragraphs that can still be overridden by +/// a hard space. #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum SpacingKind { - /// A hard space consumes surrounding soft spaces and is always layouted. + /// Hard spaces are always laid out and consume surrounding soft space. Hard, - /// A soft space consumes surrounding soft spaces with higher value. + /// Soft spaces are not laid out if they are touching a hard space and + /// consume neighbouring soft spaces with higher levels. Soft(u32), } @@ -357,11 +389,16 @@ impl SpacingKind { pub const WORD: SpacingKind = SpacingKind::Soft(1); } -/// The last appeared spacing. +/// The spacing kind of the most recently inserted item in a layouting process. +/// This is not about the last _spacing item_, but the last _item_, which is why +/// this can be `None`. #[derive(Debug, Copy, Clone, PartialEq)] enum LastSpacing { + /// The last item was hard spacing. Hard, + /// The last item was soft spacing with the given width and level. Soft(Size, u32), + /// The last item was not spacing. None, } |
