use nalgebra_glm::{Vec2, Vec4};
use crate::ecs::text::components::{TextAlignment, VerticalAlignment};
use crate::ecs::ui::layout_types::{FlowLayout, GridLayout, UiLayoutType};
use crate::ecs::ui::state::{STATE_COUNT, UiBase, UiStateTrait};
use crate::ecs::ui::types::Rect;
use crate::ecs::ui::units::UiValue;
use crate::render::wgpu::passes::geometry::UiLayer;
use super::{AutoSizeMode, TextOverflow, UiDepthMode};
#[derive(Clone, Debug)]
pub struct UiLayoutNode {
pub layouts: Vec<Option<UiLayoutType>>,
pub flow_layout: Option<FlowLayout>,
pub responsive_flow: Option<crate::ecs::ui::layout_types::ResponsiveFlowOverride>,
pub grid_layout: Option<GridLayout>,
pub depth: UiDepthMode,
pub font_size: Option<f32>,
pub clip_content: bool,
pub pointer_events: bool,
pub visible: bool,
pub flow_child_size: Option<UiValue<Vec2>>,
pub flex_grow: Option<f32>,
pub flex_shrink: Option<f32>,
pub min_size: Option<Vec2>,
pub max_size: Option<Vec2>,
pub z_index: Option<i32>,
pub auto_size: AutoSizeMode,
pub auto_size_padding: Vec2,
pub computed_rect: Rect,
pub computed_depth: f32,
pub computed_clip_rect: Option<Rect>,
pub layer: Option<UiLayer>,
pub computed_layer: Option<UiLayer>,
pub animation: Option<UiNodeAnimation>,
}
impl Default for UiLayoutNode {
fn default() -> Self {
Self {
layouts: vec![None; STATE_COUNT],
flow_layout: None,
responsive_flow: None,
grid_layout: None,
depth: UiDepthMode::default(),
font_size: None,
clip_content: false,
pointer_events: true,
visible: true,
flow_child_size: None,
flex_grow: None,
flex_shrink: None,
min_size: None,
max_size: None,
z_index: None,
auto_size: AutoSizeMode::None,
auto_size_padding: Vec2::new(0.0, 0.0),
computed_rect: Rect::default(),
computed_depth: 0.0,
computed_clip_rect: None,
layer: None,
computed_layer: None,
animation: None,
}
}
}
impl UiLayoutNode {
pub fn base_layout(&self) -> Option<&UiLayoutType> {
self.layouts[UiBase::INDEX].as_ref()
}
pub fn ensure_state_capacity(&mut self, count: usize) {
if self.layouts.len() < count {
self.layouts.resize(count, None);
}
}
}
#[derive(Clone, Debug)]
pub struct UiNodeColor {
pub colors: Vec<Option<Vec4>>,
pub computed_color: Vec4,
}
impl Default for UiNodeColor {
fn default() -> Self {
Self {
colors: vec![None; STATE_COUNT],
computed_color: Vec4::new(1.0, 1.0, 1.0, 1.0),
}
}
}
impl UiNodeColor {
pub fn ensure_state_capacity(&mut self, count: usize) {
if self.colors.len() < count {
self.colors.resize(count, None);
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum UiNodeContent {
None,
Rect {
corner_radius: f32,
border_width: f32,
border_color: Vec4,
},
Text {
text_slot: usize,
font_index: usize,
font_size_override: Option<f32>,
outline_color: Vec4,
outline_width: f32,
alignment: TextAlignment,
vertical_alignment: VerticalAlignment,
overflow: TextOverflow,
},
Image {
texture_index: u32,
uv_min: Vec2,
uv_max: Vec2,
},
}
impl Default for UiNodeContent {
fn default() -> Self {
Self::None
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum UiAnimationType {
Fade,
SlideLeft,
SlideRight,
SlideUp,
SlideDown,
Scale,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum UiAnimationPhase {
Idle,
IntroPlaying,
OutroPlaying,
OutroComplete,
}
#[derive(Clone, Copy, Debug)]
pub struct UiNodeAnimation {
pub intro: Option<UiAnimationType>,
pub outro: Option<UiAnimationType>,
pub duration: f32,
pub progress: f32,
pub phase: UiAnimationPhase,
}