Skip to main content

cu_bevymon/
viewport.rs

1use bevy::camera::Viewport;
2use bevy::prelude::*;
3use bevy::ui::UiGlobalTransform;
4use bevy::window::PrimaryWindow;
5
6use crate::focus::{CuBevyMonSurface, CuBevyMonSurfaceNode, surface_local_rect};
7
8#[derive(Component, Clone, Copy, Debug, PartialEq, Eq)]
9pub struct CuBevyMonViewportSurface(pub CuBevyMonSurface);
10
11pub(crate) fn sync_camera_viewports_to_surfaces(
12    window: Single<&Window, With<PrimaryWindow>>,
13    surfaces: Query<(&ComputedNode, &UiGlobalTransform, &CuBevyMonSurfaceNode)>,
14    mut cameras: Query<(&CuBevyMonViewportSurface, &mut Camera)>,
15) {
16    let window_size = Vec2::new(
17        window.physical_width() as f32,
18        window.physical_height() as f32,
19    );
20
21    for (target_surface, mut camera) in &mut cameras {
22        let Some((node, transform, _)) = surfaces
23            .iter()
24            .find(|(_, _, surface)| surface.0 == target_surface.0)
25        else {
26            camera.viewport = None;
27            continue;
28        };
29
30        let rect = surface_local_rect(node.content_box(), transform);
31        let min = rect.min.max(Vec2::ZERO);
32        let max = rect.max.min(window_size);
33        let size = max - min;
34
35        if size.x <= 1.0 || size.y <= 1.0 {
36            camera.viewport = None;
37            continue;
38        }
39
40        camera.viewport = Some(Viewport {
41            physical_position: UVec2::new(min.x.floor() as u32, min.y.floor() as u32),
42            physical_size: UVec2::new(size.x.floor() as u32, size.y.floor() as u32),
43            ..default()
44        });
45    }
46}