use super::{Anchors, Margins}; use bevy_sprite::Quad; use glam::Vec2; #[derive(Debug, Clone)] enum MarginGrowDirection { Negative, Positive, } #[derive(Debug, Clone)] pub struct Node { pub position: Vec2, pub anchors: Anchors, pub margins: Margins, } impl Default for Node { fn default() -> Self { Node { position: Vec2::default(), anchors: Anchors::default(), margins: Margins::default(), } } } impl Node { pub fn new(position: Vec2, anchors: Anchors, margins: Margins) -> Self { Node { position, anchors, margins, } } pub fn update( &mut self, quad: &mut Quad, parent_size: Vec2, parent_position: Vec2, z_index: f32, ) { let (quad_x, quad_width) = Self::compute_dimension_properties( self.position.x(), self.margins.left, self.margins.right, self.anchors.left, self.anchors.right, parent_size.x(), ); let (quad_y, quad_height) = Self::compute_dimension_properties( self.position.y(), self.margins.bottom, self.margins.top, self.anchors.bottom, self.anchors.top, parent_size.y(), ); quad.size = Vec2::new(quad_width, quad_height); quad.position = Vec2::new(quad_x, quad_y) + parent_position; quad.z_index = z_index; } fn compute_dimension_properties( offset: f32, margin0: f32, margin1: f32, anchor0: f32, anchor1: f32, length: f32, ) -> (f32, f32) { let anchor_p0 = anchor0 * length; let anchor_p1 = anchor1 * length; let p0_grow_direction = if anchor_p0 <= 0.5 { MarginGrowDirection::Positive } else { MarginGrowDirection::Negative }; let p1_grow_direction = if anchor_p1 <= 0.5 { MarginGrowDirection::Positive } else { MarginGrowDirection::Negative }; let p0 = Self::compute_quad_position(offset, margin0, anchor_p0, p0_grow_direction); let p1 = Self::compute_quad_position(offset, margin1, anchor_p1, p1_grow_direction); let final_width = p1 - p0; let p = (p0 + p1) / 2.0; (p, final_width.abs()) } fn compute_quad_position( position: f32, margin: f32, anchor_position: f32, grow_direction: MarginGrowDirection, ) -> f32 { match grow_direction { MarginGrowDirection::Negative => position + anchor_position - margin, MarginGrowDirection::Positive => position + anchor_position + margin, } } }