nightshade 0.14.1

A cross-platform data-oriented game engine.
Documentation
use nalgebra_glm::Vec2;

use crate::ecs::ui::components::ResponsiveOverride;
use crate::ecs::ui::resources::UiBreakpoint;
use crate::ecs::world::World;

pub fn ui_responsive_apply_system(world: &mut World) {
    if !world.resources.retained_ui.enabled {
        return;
    }

    let viewport_raw = world.resources.window.cached_viewport_size;
    let dpi_scale = world.resources.window.cached_scale_factor.max(0.0001);
    let viewport_size = viewport_raw
        .map(|(width, height)| Vec2::new(width as f32, height as f32))
        .unwrap_or(Vec2::new(800.0, 600.0))
        / dpi_scale;
    let breakpoint = UiBreakpoint::from_width(viewport_size.x);
    world.resources.retained_ui.viewport = crate::ecs::ui::resources::UiViewport {
        size: viewport_size,
        breakpoint,
    };

    let entities: Vec<freecs::Entity> = world
        .ui
        .query_entities(crate::ecs::world::UI_LAYOUT_NODE)
        .collect();

    for entity in entities {
        let Some(node) = world.ui.get_ui_layout_node(entity) else {
            continue;
        };
        let Some(responsive) = node.responsive.as_ref() else {
            continue;
        };
        if responsive.baseline_captured && responsive.current_applied == Some(breakpoint) {
            continue;
        }

        let mut responsive = responsive.clone();
        if !responsive.baseline_captured {
            responsive.baseline = ResponsiveOverride::capture_from(node);
            responsive.baseline_captured = true;
        }
        let baseline = responsive.baseline;
        let override_value = responsive.overrides[breakpoint.index()];
        responsive.current_applied = Some(breakpoint);

        let Some(node) = world.ui.get_ui_layout_node_mut(entity) else {
            continue;
        };
        baseline.apply_to(node);
        override_value.apply_to(node);
        node.responsive = Some(responsive);
    }

    world.resources.retained_ui.dirty.layout_dirty = true;
}