1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
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);
}