use crate::Editor;
use crate::app_context::{SceneBrowserContext, SceneInfo};
use crate::mosaic::Mosaic;
use crate::widgets::{EditorWidget, MaterialsWidget};
use nightshade::prelude::*;
#[derive(Clone)]
pub enum SceneAction {
SwitchTo(String),
#[cfg(not(target_arch = "wasm32"))]
Import(std::path::PathBuf),
#[cfg(not(target_arch = "wasm32"))]
Export(std::path::PathBuf),
Delete(String),
}
#[derive(Clone)]
pub enum EditorMessage {
SceneAction(SceneAction),
}
impl Editor {
pub fn render_mosaic_and_scene_browser(&mut self, world: &mut World, root_ui: &mut egui::Ui) {
#[cfg(not(target_arch = "wasm32"))]
self.context.ui.web_widget_rects.clear();
Mosaic::<EditorWidget, crate::app_context::AppContext, EditorMessage>::clear_required_cameras(world);
if self.scene_browser_dirty {
self.scene_browser_dirty = false;
self.context.scene_browser = self
.project
.as_ref()
.map(|project| {
let data = project.data.as_ref();
let active_name = data.and_then(|d| d.active_scene_name.as_deref());
let scenes_map = data.map(|d| &d.scenes);
let mut scenes: Vec<_> = scenes_map
.into_iter()
.flat_map(|s| s.iter())
.map(|(name, scene)| SceneInfo {
name: name.clone(),
entity_count: scene.entities.len(),
is_active: active_name == Some(name.as_str()),
})
.collect();
scenes.sort_by(|a, b| a.name.cmp(&b.name));
SceneBrowserContext {
scenes,
has_project: true,
}
})
.unwrap_or_default();
}
egui::CentralPanel::default()
.frame(egui::Frame::NONE)
.show_inside(root_ui, |ui| {
self.mosaic.show_inside(world, ui, &mut self.context);
});
}
pub fn process_mosaic_messages(&mut self, world: &mut World) {
for action in self.context.assets.inspector_actions.drain(..) {
match action {
crate::engine_editor::InspectorAction::LookupMaterial(material_name) => {
let found = self
.mosaic
.find_widget(|widget| matches!(widget, EditorWidget::Materials(_)));
if let Some(tile_id) = found {
if let Some(EditorWidget::Materials(materials_widget)) =
self.mosaic.get_widget_mut(tile_id)
{
materials_widget.selected_material = Some(material_name);
}
} else {
self.mosaic
.insert_pane(EditorWidget::Materials(MaterialsWidget {
selected_material: Some(material_name),
..Default::default()
}));
}
}
}
}
for message in self.mosaic.drain_messages() {
match message {
EditorMessage::SceneAction(action) => match action {
SceneAction::SwitchTo(name) => {
self.switch_to_map(world, &name);
}
#[cfg(not(target_arch = "wasm32"))]
SceneAction::Import(path) => {
self.load_scene_from_path(world, &path);
}
#[cfg(not(target_arch = "wasm32"))]
SceneAction::Export(path) => {
self.export_scene_to_path(world, &path);
}
SceneAction::Delete(name) => {
if let Some(ref mut project) = self.project
&& let Some(data) = project.data.as_mut()
&& data.scenes.len() > 1
&& data.active_scene_name.as_deref() != Some(&name)
{
data.remove_scene(&name);
self.project_state.mark_modified();
self.scene_browser_dirty = true;
#[cfg(not(target_arch = "wasm32"))]
self.toasts.push(
crate::mosaic::ToastKind::Success,
format!("Deleted scene: {}", name),
3.0,
);
}
}
},
}
}
if self.mosaic.take_layout_modified() {
self.project_state.mark_modified();
}
}
}