use thiserror::Error; use crate::{ContentSize, DefaultUiCamera, Node, Outline, Style, TargetCamera, UiScale}; use bevy_ecs::{ change_detection::{DetectChanges, DetectChangesMut}, entity::Entity, event::EventReader, query::{With, Without}, removal_detection::RemovedComponents, system::{Query, Res, ResMut, SystemParam}, world::Ref, }; use bevy_hierarchy::{Children, Parent}; use bevy_math::{UVec2, Vec2}; use bevy_render::camera::{Camera, NormalizedRenderTarget}; use bevy_transform::components::Transform; use bevy_utils::tracing::warn; use bevy_utils::{HashMap, HashSet}; use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged}; use ui_surface::UiSurface; mod convert; pub mod debug; pub(crate) mod ui_surface; pub struct LayoutContext { pub scale_factor: f32, pub physical_size: Vec2, pub min_size: f32, pub max_size: f32, } impl LayoutContext { pub const DEFAULT: Self = Self { scale_factor: 1.0, physical_size: Vec2::ZERO, min_size: 0.0, max_size: 0.0, }; /// create new a [`LayoutContext`] from the window's physical size and scale factor fn new(scale_factor: f32, physical_size: Vec2) -> Self { Self { scale_factor, physical_size, min_size: physical_size.x.min(physical_size.y), max_size: physical_size.x.max(physical_size.y), } } } impl Default for LayoutContext { fn default() -> Self { Self::DEFAULT } } #[derive(Debug, Error)] pub enum LayoutError { #[error("Invalid hierarchy")] InvalidHierarchy, #[error("Taffy error: {0}")] TaffyError(#[from] taffy::TaffyError), } #[derive(SystemParam)] pub struct UiLayoutSystemRemovedComponentParam<'w, 's> { removed_cameras: RemovedComponents<'w, 's, Camera>, removed_children: RemovedComponents<'w, 's, Children>, removed_content_sizes: RemovedComponents<'w, 's, ContentSize>, removed_nodes: RemovedComponents<'w, 's, Node>, } /// Updates the UI's layout tree, computes the new layout geometry and then updates the sizes and transforms of all the UI nodes. #[allow(clippy::too_many_arguments)] pub fn ui_layout_system( primary_window: Query<(Entity, &Window), With>, cameras: Query<(Entity, &Camera)>, default_ui_camera: DefaultUiCamera, ui_scale: Res, mut scale_factor_events: EventReader, mut resize_events: EventReader, mut ui_surface: ResMut, root_node_query: Query<(Entity, Option<&TargetCamera>), (With, Without)>, mut style_query: Query< ( Entity, Ref