bevy_yoleck/
editor_window.rs1use bevy::prelude::*;
2use bevy::window::PrimaryWindow;
3use bevy_egui::{EguiContext, PrimaryEguiContext, egui};
4
5use crate::YoleckEditorBottomPanelSections;
6use crate::YoleckEditorLeftPanelSections;
7use crate::YoleckEditorRightPanelSections;
8use crate::YoleckEditorTopPanelSections;
9use crate::editor_panels::EditorPanel;
10
11#[derive(Resource, Default)]
12pub struct YoleckEditorViewportRect {
13 pub rect: Option<egui::Rect>,
14}
15
16pub(crate) fn yoleck_editor_window(
17 world: &mut World,
18 mut egui_query: Local<Option<QueryState<&mut EguiContext, With<PrimaryEguiContext>>>>,
19) {
20 let egui_query = egui_query.get_or_insert_with(|| world.query_filtered());
21 let mut borrowed_egui = if let Ok(mut egui_context) = egui_query.single_mut(world) {
22 core::mem::take(egui_context.as_mut())
23 } else {
24 return;
25 };
26
27 let ctx = borrowed_egui.get_mut();
28
29 let mut viewport_ui = egui::Ui::new(
36 ctx.clone(),
37 "viewport".into(),
38 egui::UiBuilder::new()
39 .layer_id(egui::LayerId::background())
40 .max_rect(ctx.viewport_rect()),
41 );
42
43 let top = YoleckEditorTopPanelSections::show_panel(world, ctx, &mut viewport_ui)
44 .rect
45 .height();
46
47 let left = YoleckEditorLeftPanelSections::show_panel(world, ctx, &mut viewport_ui)
48 .rect
49 .width();
50
51 let right = YoleckEditorRightPanelSections::show_panel(world, ctx, &mut viewport_ui)
52 .rect
53 .width();
54
55 let bottom = YoleckEditorBottomPanelSections::show_panel(world, ctx, &mut viewport_ui)
56 .rect
57 .height();
58
59 let viewport_rect = egui::Rect::from_min_max(
60 egui::Pos2::new(left, top),
61 egui::Pos2::new(
62 ctx.input(|i| i.viewport_rect().width()) - right,
63 ctx.input(|i| i.viewport_rect().height()) - bottom,
64 ),
65 );
66
67 if let Some(mut editor_viewport) = world.get_resource_mut::<YoleckEditorViewportRect>() {
68 editor_viewport.rect = Some(viewport_rect);
69 }
70
71 if let Ok(window) = world
72 .query_filtered::<&bevy::window::Window, With<PrimaryWindow>>()
73 .single(world)
74 {
75 let scale = window.scale_factor();
76
77 let left_px = (left * scale) as u32;
78 let right_px = (right * scale) as u32;
79 let top_px = (top * scale) as u32;
80 let bottom_px = (bottom * scale) as u32;
81
82 let pos = UVec2::new(left_px, top_px);
83 let size = UVec2::new(window.physical_width(), window.physical_height())
84 .saturating_sub(pos)
85 .saturating_sub(UVec2::new(right_px, bottom_px));
86
87 if size.x > 0 && size.y > 0 {
88 let mut camera_query =
89 world.query_filtered::<&mut Camera, Without<PrimaryEguiContext>>();
90 for mut camera in camera_query.iter_mut(world) {
91 camera.viewport = Some(bevy::camera::Viewport {
92 physical_position: pos,
93 physical_size: size,
94 ..default()
95 });
96 }
97 }
98 }
99
100 if let Ok(mut egui_context) = egui_query.single_mut(world) {
101 *egui_context = borrowed_egui;
102 }
103}