nightshade-editor 0.13.4

An interactive editor for the Nightshade game engine
use crate::Editor;
use crate::app_context::PrefabMetadata;
#[cfg(not(target_arch = "wasm32"))]
use crate::engine_editor::load_fbx;
use crate::engine_editor::{GltfImportResult, load_gltf, load_gltf_from_bytes};
use crate::widgets::{self, AssetCategory};
use nightshade::prelude::*;

fn register_gltf_import(
    import_result: GltfImportResult,
    prefabs: &mut Vec<PrefabMetadata>,
    tree_dirty: &mut bool,
) {
    *tree_dirty |= import_result.tree_dirty;
    let source_path = import_result.source_path;
    let animations = import_result.animations;
    for prefab in import_result.prefabs {
        prefabs.push(PrefabMetadata {
            prefab,
            animations: animations.clone(),
            source_path: Some(source_path.clone()),
        });
    }
}

impl Editor {
    pub fn handle_dropped_file(&mut self, world: &mut World, path: &std::path::Path) {
        let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
        let category = widgets::categorize_asset(file_name);

        match category {
            AssetCategory::Texture => {
                if file_name.to_lowercase().ends_with(".hdr") {
                    load_hdr_skybox_from_path(world, path.to_path_buf());
                    world.resources.graphics.atmosphere = Atmosphere::Hdr;
                    self.context.project_edit.hdr_skybox_path = Some(path.to_path_buf());
                    self.project_state.mark_modified();
                }
            }
            AssetCategory::Mesh => {
                let lower = file_name.to_lowercase();
                if lower.ends_with(".gltf") || lower.ends_with(".glb") {
                    let import_result = load_gltf(&mut self.context.editor, world, path);
                    register_gltf_import(
                        import_result,
                        &mut self.context.assets.prefabs,
                        &mut self.context.ui.tree_dirty,
                    );
                    self.project_state.mark_modified();
                } else if lower.ends_with(".fbx") {
                    #[cfg(not(target_arch = "wasm32"))]
                    {
                        let notifications = load_fbx(world, path);
                        self.context.notifications.extend(notifications);
                        self.project_state.mark_modified();
                    }
                }
            }
            AssetCategory::Project => {
                #[cfg(not(target_arch = "wasm32"))]
                self.load_project_from_path(world, path);
            }
            AssetCategory::Prefab => {
                let lower = file_name.to_lowercase();
                if lower.ends_with(".json") || lower.ends_with(".bin") {
                    #[cfg(not(target_arch = "wasm32"))]
                    self.load_scene_from_path(world, path);
                }
            }
            _ => {
                tracing::warn!("Unsupported file type: {}", file_name);
                #[cfg(not(target_arch = "wasm32"))]
                self.toasts.push(
                    crate::mosaic::ToastKind::Warning,
                    format!("Unsupported file type: {}", file_name),
                    3.0,
                );
            }
        }

        self.context.drag_drop.hovered_file_path = None;
        self.context.drag_drop.file_category = None;
    }

    pub fn handle_hovered_file(&mut self, path: &std::path::Path) {
        self.context.drag_drop.hovered_file_path = Some(path.to_path_buf());
        let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
        self.context.drag_drop.file_category = Some(widgets::categorize_asset(file_name));
    }

    pub fn handle_hovered_file_cancelled(&mut self) {
        self.context.drag_drop.hovered_file_path = None;
        self.context.drag_drop.file_category = None;
    }

    pub fn handle_dropped_file_data(&mut self, world: &mut World, name: &str, data: &[u8]) {
        let category = widgets::categorize_asset(name);
        match category {
            AssetCategory::Mesh => {
                let import_result =
                    load_gltf_from_bytes(&mut self.context.editor, world, name, data);
                register_gltf_import(
                    import_result,
                    &mut self.context.assets.prefabs,
                    &mut self.context.ui.tree_dirty,
                );
                self.project_state.mark_modified();
            }
            AssetCategory::Project => {
                self.load_project_from_bytes(world, data);
            }
            _ => {
                tracing::warn!("Unsupported file type: {}", name);
            }
        }
    }
}