use crate::types::rect::WidgetRect;
use crate::types::state::WidgetId;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum Display {
#[default]
Flex,
Stack,
Grid,
None,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum FlexDirection {
#[default]
Row,
Column,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum AlignItems {
#[default]
Stretch,
Start,
End,
Center,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum JustifyContent {
#[default]
Start,
End,
Center,
SpaceBetween,
SpaceAround,
SpaceEvenly,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum Position {
#[default]
Relative,
Absolute,
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[derive(Default)]
pub enum SizeSpec {
Fix(f64),
Pct(f64),
Fill,
#[default]
Content,
}
#[derive(Clone, Copy, Debug, PartialEq, Default)]
pub struct Insets {
pub top: f64,
pub right: f64,
pub bottom: f64,
pub left: f64,
}
impl Insets {
pub fn all(val: f64) -> Self {
Self { top: val, right: val, bottom: val, left: val }
}
pub fn symmetric(v: f64, h: f64) -> Self {
Self { top: v, right: h, bottom: v, left: h }
}
pub fn width(&self) -> f64 { self.left + self.right }
pub fn height(&self) -> f64 { self.top + self.bottom }
}
#[derive(Clone, Debug, Default)]
pub struct LayoutStyle {
pub display: Display,
pub direction: FlexDirection,
pub align_items: AlignItems,
pub justify_content: JustifyContent,
pub position: Position,
pub gap: f64,
pub padding: Insets,
pub margin: Insets,
pub width: SizeSpec,
pub height: SizeSpec,
pub min_width: Option<f64>,
pub max_width: Option<f64>,
pub min_height: Option<f64>,
pub max_height: Option<f64>,
pub offset_x: f64,
pub offset_y: f64,
pub z_index: i32,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum LayoutKind {
#[default]
Container,
Widget,
Overlay,
}
#[derive(Clone, Debug)]
pub struct LayoutNode {
pub id: WidgetId,
pub kind: LayoutKind,
pub style: LayoutStyle,
pub children: Vec<LayoutNode>,
pub flags: LayoutFlags,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct LayoutFlags(u32);
impl LayoutFlags {
pub const NONE: Self = Self(0);
pub const CLIP_CONTENT: Self = Self(1 << 0);
pub const SCROLL_Y: Self = Self(1 << 1);
pub const SCROLL_X: Self = Self(1 << 2);
pub const IS_ROOT: Self = Self(1 << 3);
pub fn contains(&self, other: Self) -> bool {
(self.0 & other.0) == other.0
}
pub fn insert(&mut self, other: Self) {
self.0 |= other.0;
}
}
impl std::ops::BitOr for LayoutFlags {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0 | rhs.0)
}
}
impl LayoutNode {
pub fn new(id: impl Into<WidgetId>) -> Self {
Self {
id: id.into(),
kind: LayoutKind::Container,
style: LayoutStyle::default(),
children: Vec::new(),
flags: LayoutFlags::NONE,
}
}
pub fn with_style(mut self, style: LayoutStyle) -> Self {
self.style = style;
self
}
pub fn with_child(mut self, child: LayoutNode) -> Self {
self.children.push(child);
self
}
pub fn with_children(mut self, children: Vec<LayoutNode>) -> Self {
self.children = children;
self
}
pub fn with_kind(mut self, kind: LayoutKind) -> Self {
self.kind = kind;
self
}
pub fn with_flags(mut self, flags: LayoutFlags) -> Self {
self.flags = flags;
self
}
}
#[derive(Clone, Debug)]
pub struct LayoutComputed {
pub rect: WidgetRect,
pub content_rect: WidgetRect,
pub clip_rect: Option<WidgetRect>,
pub z_order: i32,
}