bevy_editor_pls/
lib.rs

1#![allow(clippy::needless_doctest_main)]
2
3/// input settings for the editor UI
4#[cfg(feature = "default_windows")]
5pub mod controls;
6
7use bevy::{
8    prelude::{Entity, Plugin, Update},
9    window::{MonitorSelection, Window, WindowPosition, WindowRef, WindowResolution},
10};
11
12pub use bevy_editor_pls_core::egui_dock;
13#[doc(inline)]
14pub use bevy_editor_pls_core::{editor, editor_window, AddEditorWindow};
15pub use egui;
16
17#[cfg(feature = "default_windows")]
18#[doc(inline)]
19pub use bevy_editor_pls_default_windows as default_windows;
20
21/// Commonly used types and extension traits
22pub mod prelude {
23    pub use crate::{AddEditorWindow, EditorPlugin};
24    #[cfg(feature = "default_windows")]
25    pub use bevy_editor_pls_default_windows::scenes::NotInScene;
26}
27
28/// Where to show the editor
29#[derive(Default)]
30pub enum EditorWindowPlacement {
31    /// On the primary window
32    #[default]
33    Primary,
34    /// Spawn a new window for the editor
35    New(Window),
36    /// On an existing window
37    Window(Entity),
38}
39
40/// Plugin adding various editor UI to the game executable.
41///
42/// ```rust,no_run
43/// use bevy::prelude::*;
44/// use bevy_editor_pls::EditorPlugin;
45///
46/// fn main() {
47///     App::new()
48///         .add_plugins(DefaultPlugins)
49///         .add_plugins(EditorPlugin::new())
50///         .run();
51/// }
52/// ```
53#[derive(Default)]
54pub struct EditorPlugin {
55    pub window: EditorWindowPlacement,
56}
57
58impl EditorPlugin {
59    pub fn new() -> Self {
60        EditorPlugin::default()
61    }
62
63    /// Start the editor in a new window. Use [`Window::default`] for creating a new window with default settings.
64    pub fn in_new_window(mut self, window: Window) -> Self {
65        self.window = EditorWindowPlacement::New(window);
66        self
67    }
68    /// Start the editor on the second window ([`MonitorSelection::Index(1)`].
69    pub fn on_second_monitor_fullscreen(self) -> Self {
70        self.in_new_window(Window {
71            // TODO: just use `mode: BorderlessFullscreen` https://github.com/bevyengine/bevy/pull/8178
72            resolution: WindowResolution::new(1920.0, 1080.0),
73            position: WindowPosition::Centered(MonitorSelection::Index(1)),
74            decorations: false,
75            ..Default::default()
76        })
77    }
78}
79
80impl Plugin for EditorPlugin {
81    fn build(&self, app: &mut bevy::prelude::App) {
82        let window = match self.window {
83            EditorWindowPlacement::New(ref window) => {
84                let mut window = window.clone();
85                if window.title == "Bevy App" {
86                    window.title = "bevy_editor_pls".into();
87                }
88                let entity = app.world_mut().spawn(window);
89                WindowRef::Entity(entity.id())
90            }
91            EditorWindowPlacement::Window(entity) => WindowRef::Entity(entity),
92            EditorWindowPlacement::Primary => WindowRef::Primary,
93        };
94
95        app.add_plugins(bevy_editor_pls_core::EditorPlugin { window });
96
97        // if !app.is_plugin_added::<bevy_framepace::FramepacePlugin>() {
98        //     app.add_plugins(bevy_framepace::FramepacePlugin);
99        //     app.add_plugins(bevy_framepace::debug::DiagnosticsPlugin);
100        // }
101
102        #[cfg(feature = "default_windows")]
103        {
104            use bevy_editor_pls_default_windows::add::AddWindow;
105            use bevy_editor_pls_default_windows::assets::AssetsWindow;
106            use bevy_editor_pls_default_windows::cameras::CameraWindow;
107            use bevy_editor_pls_default_windows::debug_settings::DebugSettingsWindow;
108            use bevy_editor_pls_default_windows::diagnostics::DiagnosticsWindow;
109            use bevy_editor_pls_default_windows::gizmos::GizmoWindow;
110            use bevy_editor_pls_default_windows::hierarchy::HierarchyWindow;
111            use bevy_editor_pls_default_windows::inspector::InspectorWindow;
112            use bevy_editor_pls_default_windows::renderer::RendererWindow;
113            use bevy_editor_pls_default_windows::resources::ResourcesWindow;
114            use bevy_editor_pls_default_windows::scenes::SceneWindow;
115
116            app.add_editor_window::<HierarchyWindow>();
117            app.add_editor_window::<AssetsWindow>();
118            app.add_editor_window::<InspectorWindow>();
119            app.add_editor_window::<DebugSettingsWindow>();
120            app.add_editor_window::<AddWindow>();
121            app.add_editor_window::<DiagnosticsWindow>();
122            app.add_editor_window::<RendererWindow>();
123            app.add_editor_window::<CameraWindow>();
124            app.add_editor_window::<ResourcesWindow>();
125            app.add_editor_window::<SceneWindow>();
126            app.add_editor_window::<GizmoWindow>();
127            app.add_editor_window::<controls::ControlsWindow>();
128
129            app.add_plugins(bevy::pbr::wireframe::WireframePlugin);
130
131            // required for the GizmoWindow
132            if !app.is_plugin_added::<transform_gizmo_bevy::TransformGizmoPlugin>() {
133                app.add_plugins(transform_gizmo_bevy::TransformGizmoPlugin);
134            }
135
136            app.insert_resource(controls::EditorControls::default_bindings())
137                .add_systems(Update, controls::editor_controls_system);
138
139            let mut internal_state = app.world_mut().resource_mut::<editor::EditorInternalState>();
140
141            let [game, _inspector] =
142                internal_state.split_right::<InspectorWindow>(egui_dock::NodeIndex::root(), 0.75);
143            let [game, _hierarchy] = internal_state.split_left::<HierarchyWindow>(game, 0.2);
144            let [_game, _bottom] = internal_state.split_many(
145                game,
146                0.8,
147                egui_dock::Split::Below,
148                &[
149                    std::any::TypeId::of::<ResourcesWindow>(),
150                    std::any::TypeId::of::<AssetsWindow>(),
151                    std::any::TypeId::of::<DebugSettingsWindow>(),
152                    std::any::TypeId::of::<DiagnosticsWindow>(),
153                ],
154            );
155        }
156    }
157}