zaplib 0.0.3

⚡ Zaplib is a fast, cross-platform (web+native), GPU-based application framework, written in Rust.
Documentation
use crate::*;

/// Indicates when to wrap the current line to a new line. See also [`Direction`].
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum LineWrap {
    /// Never wrap to a new line.
    None,

    /// Wrap to a new line when the available width is exhausted.
    Overflow,
}
impl LineWrap {
    /// TODO(JP): Replace these with LineWrap::default() when
    /// <https://github.com/rust-lang/rust/issues/67792> gets done
    pub const DEFAULT: LineWrap = LineWrap::None;
}
impl Default for LineWrap {
    fn default() -> Self {
        LineWrap::DEFAULT
    }
}

/// Configure how a [`CxLayoutBox`] is going to walk, typically bounded by the
/// dimensions of a parent [`CxLayoutBox`].
#[derive(Copy, Clone, Debug)]
pub(crate) struct Layout {
    /// See [`LayoutSize`].
    pub layout_size: LayoutSize,
    /// See [`Padding`].
    pub padding: Padding,
    /// See [`Direction`].
    pub direction: Direction,
    /// See [`LineWrap`].
    pub line_wrap: LineWrap,
    /// Absolutely position by overriding the [`CxLayoutBox::origin`] with (0,0) instead of using the parent's
    /// current position.
    pub absolute: bool,
    /// Override the maximum size of the [`Window`]/[`Pass`]. Should typically
    /// not be used; instead set [`CxLayoutBox::width`] and [`CxLayoutBox::height`]
    /// through [`Layout::layout_size`].
    pub abs_size: Option<Vec2>,
}

impl Layout {
    /// TODO(JP): Replace these with Layout::default() when
    /// <https://github.com/rust-lang/rust/issues/67792> gets done
    pub const DEFAULT: Layout = Layout {
        layout_size: LayoutSize::DEFAULT,
        padding: Padding::DEFAULT,
        direction: Direction::DEFAULT,
        line_wrap: LineWrap::DEFAULT,
        absolute: false,
        abs_size: None,
    };
}

impl Default for Layout {
    fn default() -> Self {
        Layout::DEFAULT
    }
}

/// Determines how a [`CxLayoutBox`] should walk. Can be applied to a new [`CxLayoutBox`]
/// through [`Layout::layout_size`], or directly to move an existing [`CxLayoutBox`] by
/// using [`Cx::add_box`].
#[derive(Copy, Clone, Debug)]
pub struct LayoutSize {
    pub width: Width,
    pub height: Height,
}

impl LayoutSize {
    /// TODO(JP): Replace these with Align::default() when
    /// <https://github.com/rust-lang/rust/issues/67792> gets done
    pub const DEFAULT: LayoutSize = LayoutSize { width: Width::DEFAULT, height: Height::DEFAULT };
    pub const FILL: LayoutSize = LayoutSize { width: Width::Fill, height: Height::Fill };

    pub const fn new(w: Width, h: Height) -> Self {
        Self { width: w, height: h }
    }
}
impl Default for LayoutSize {
    fn default() -> Self {
        LayoutSize::DEFAULT
    }
}

/// The direction in which the [`CxLayoutBox`] should walk. It will typically walk
/// in a straight line in this direction. E.g. when walking to [`Direction::Right`],
/// it will only walk horizontally, not vertically, until it hits the [`CxLayoutBox::width`],
/// at which point it will wrap around using [`LineWrap`], based on the maximum
/// height of widgets that have been drawn so far, which is registered in
/// [`CxLayoutBox::biggest`].
///
/// TODO(JP): This line wrapping behavior makes sense for [`Direction::Right`],
/// but not so much for [`Direction::Down`].. Maybe we should split [`CxLayoutBox`]
/// into different kinds of behavior?
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Direction {
    Right,
    Down,
}
impl Direction {
    /// TODO(JP): Replace these with Direction::default() when
    /// <https://github.com/rust-lang/rust/issues/67792> gets done
    pub const DEFAULT: Direction = Direction::Right;
}
impl Default for Direction {
    fn default() -> Self {
        Direction::DEFAULT
    }
}

/// Different ways in which a [`LayoutSize`] can get a width.
///
/// TODO(JP): See [`Height::DEFAULT`] for a related TODO.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Width {
    /// Fill up as much of the available space as possible.
    Fill,
    /// Use a fixed width.
    Fix(f32),
    /// Will defer computation of [`CxLayoutBox::width`] by setting it to [`f32::NAN`],
    /// and only properly computing it later on.
    ///
    /// TODO(JP): This can also be passed into [`Cx::add_box`] but there it
    /// makes no sense!
    Compute,
    /// Fill up as much of the available space as possible up to provided width
    FillUntil(f32),
}
impl Width {
    /// TODO(JP): Replace these with Width::default() when
    /// <https://github.com/rust-lang/rust/issues/67792> gets done
    pub const DEFAULT: Width = Width::Fill;
}
impl Default for Width {
    fn default() -> Self {
        Width::Fill
    }
}

/// Different ways in which a [`LayoutSize`] can get a height.
///
/// See [`Width`] for more documentation, since it's analogous.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Height {
    /// See [`Width::Fill`].
    Fill,
    /// See [`Width::Fix`].
    Fix(f32),
    /// See [`Width::Compute`].
    Compute,
    /// See [`Width::FillUntil`],
    FillUntil(f32),
}
impl Height {
    /// TODO(JP): [`Height::Fill`] might be a bad default, because if you use
    /// [`Direction::Down`] it will push out everything out it below.
    /// HTML/CSS uses something more like [`Height::Compute`] by default for height,
    /// and only [`Height::Fill`] for width (for block-layout elements).
    ///
    /// TODO(JP): Replace these with Height::default() when
    /// <https://github.com/rust-lang/rust/issues/67792> gets done
    pub const DEFAULT: Height = Height::Fill;
}
impl Default for Height {
    fn default() -> Self {
        Height::Fill
    }
}

/// Defines how elements on [`Cx::layout_box_align_list`] should be moved horizontally
pub(crate) struct AlignX(pub f32);

impl AlignX {
    // Note: LEFT is the default so not needed as explicit option
    pub(crate) const CENTER: AlignX = AlignX(0.5);
    #[allow(dead_code)]
    pub(crate) const RIGHT: AlignX = AlignX(1.0);
}

/// Defines how elements on [`Cx::layout_box_align_list`] should be moved vertically
pub(crate) struct AlignY(pub f32);

impl AlignY {
    // Note: TOP is the default so not needed as explicit option
    pub(crate) const CENTER: AlignY = AlignY(0.5);
    #[allow(dead_code)]
    pub(crate) const BOTTOM: AlignY = AlignY(1.0);
}