diff --git a/Sources/Overload/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp b/Sources/Overload/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp index ede67a179..f134a7476 100644 --- a/Sources/Overload/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp +++ b/Sources/Overload/OvEditor/src/OvEditor/Panels/AssetBrowser.cpp @@ -44,946 +44,962 @@ using namespace OvUI::Widgets; const std::string FILENAMES_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_=+ 0123456789()[]"; -std::string GetAssociatedMetaFile(const std::string& p_assetPath) +namespace { - return p_assetPath + ".meta"; -} - -void RenameAsset(const std::string& p_prev, const std::string& p_new) -{ - std::filesystem::rename(p_prev, p_new); + template + auto& GetResource(const std::string& p_path, bool p_isEngineResource) + { + auto resource = OvCore::Global::ServiceLocator::Get()[EDITOR_EXEC(GetResourcePath(p_path, p_isEngineResource))]; + OVASSERT(resource, "Resource not found"); + return *resource; + } - if (const std::string previousMetaPath = GetAssociatedMetaFile(p_prev); std::filesystem::exists(previousMetaPath)) + void OpenInAssetView(auto& p_resource) { - if (const std::string newMetaPath = GetAssociatedMetaFile(p_new); !std::filesystem::exists(newMetaPath)) - { - std::filesystem::rename(previousMetaPath, newMetaPath); - } - else - { - OVLOG_ERROR(newMetaPath + " is already existing, .meta creation failed"); - } + auto& assetView = EDITOR_PANEL(OvEditor::Panels::AssetView, "Asset View"); + assetView.SetResource(OvEditor::Panels::AssetView::ViewableResource{ &p_resource }); + assetView.Open(); + assetView.Focus(); } -} -void RemoveAsset(const std::string& p_toDelete) -{ - std::filesystem::remove(p_toDelete); + void OpenInMaterialEditor(auto& p_resource) + { + auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); + materialEditor.SetTarget(p_resource); + materialEditor.Open(); + materialEditor.Focus(); + } - if (const std::string metaPath = GetAssociatedMetaFile(p_toDelete); std::filesystem::exists(metaPath)) + std::string GetAssociatedMetaFile(const std::string& p_assetPath) { - std::filesystem::remove(metaPath); + return p_assetPath + ".meta"; } -} -class TexturePreview : public OvUI::Plugins::IPlugin -{ -public: - TexturePreview() : image(0, { 80, 80 }) + void RenameAsset(const std::string& p_prev, const std::string& p_new) { + std::filesystem::rename(p_prev, p_new); + if (const std::string previousMetaPath = GetAssociatedMetaFile(p_prev); std::filesystem::exists(previousMetaPath)) + { + if (const std::string newMetaPath = GetAssociatedMetaFile(p_new); !std::filesystem::exists(newMetaPath)) + { + std::filesystem::rename(previousMetaPath, newMetaPath); + } + else + { + OVLOG_ERROR(newMetaPath + " is already existing, .meta creation failed"); + } + } } - void SetPath(const std::string& p_path) + void RemoveAsset(const std::string& p_toDelete) { - texture = OvCore::Global::ServiceLocator::Get()[p_path]; + std::filesystem::remove(p_toDelete); + + if (const std::string metaPath = GetAssociatedMetaFile(p_toDelete); std::filesystem::exists(metaPath)) + { + std::filesystem::remove(metaPath); + } } - virtual void Execute(OvUI::Plugins::EPluginExecutionContext p_context) override + class TexturePreview : public OvUI::Plugins::IPlugin { - if (ImGui::IsItemHovered()) + public: + TexturePreview() : image(0, { 80, 80 }) { - if (texture) - image.textureID.id = texture->id; - ImGui::BeginTooltip(); - image.Draw(); - ImGui::EndTooltip(); } - } - OvRendering::Resources::Texture* texture = nullptr; - OvUI::Widgets::Visual::Image image; -}; + void SetPath(const std::string& p_path) + { + texture = OvCore::Global::ServiceLocator::Get()[p_path]; + } -class BrowserItemContextualMenu : public OvUI::Plugins::ContextualMenu -{ -public: - BrowserItemContextualMenu(const std::string p_filePath, bool p_protected = false) : m_protected(p_protected), filePath(p_filePath) {} + virtual void Execute(OvUI::Plugins::EPluginExecutionContext p_context) override + { + if (ImGui::IsItemHovered()) + { + if (texture) + image.textureID.id = texture->id; - virtual void CreateList() + ImGui::BeginTooltip(); + image.Draw(); + ImGui::EndTooltip(); + } + } + + OvRendering::Resources::Texture* texture = nullptr; + OvUI::Widgets::Visual::Image image; + }; + + class BrowserItemContextualMenu : public OvUI::Plugins::ContextualMenu { - if (!m_protected) + public: + BrowserItemContextualMenu(const std::string p_filePath, bool p_protected = false) : m_protected(p_protected), filePath(p_filePath) {} + + virtual void CreateList() { - auto& deleteAction = CreateWidget("Delete"); - deleteAction.ClickedEvent += [this] { DeleteItem(); }; + if (!m_protected) + { + auto& deleteAction = CreateWidget("Delete"); + deleteAction.ClickedEvent += [this] { DeleteItem(); }; - auto& renameMenu = CreateWidget("Rename to..."); + auto& renameMenu = CreateWidget("Rename to..."); - auto& nameEditor = renameMenu.CreateWidget(""); - nameEditor.selectAllOnClick = true; + auto& nameEditor = renameMenu.CreateWidget(""); + nameEditor.selectAllOnClick = true; - renameMenu.ClickedEvent += [this, &nameEditor] - { - nameEditor.content = OvTools::Utils::PathParser::GetElementName(filePath); + renameMenu.ClickedEvent += [this, &nameEditor] + { + nameEditor.content = OvTools::Utils::PathParser::GetElementName(filePath); - if (!std::filesystem::is_directory(filePath)) - if (size_t pos = nameEditor.content.rfind('.'); pos != std::string::npos) - nameEditor.content = nameEditor.content.substr(0, pos); - }; + if (!std::filesystem::is_directory(filePath)) + if (size_t pos = nameEditor.content.rfind('.'); pos != std::string::npos) + nameEditor.content = nameEditor.content.substr(0, pos); + }; - nameEditor.EnterPressedEvent += [this](std::string p_newName) - { - if (!std::filesystem::is_directory(filePath)) - p_newName += '.' + OvTools::Utils::PathParser::GetExtension(filePath); + nameEditor.EnterPressedEvent += [this](std::string p_newName) + { + if (!std::filesystem::is_directory(filePath)) + p_newName += '.' + OvTools::Utils::PathParser::GetExtension(filePath); - /* Clean the name (Remove special chars) */ - p_newName.erase(std::remove_if(p_newName.begin(), p_newName.end(), [](auto& c) - { - return std::find(FILENAMES_CHARS.begin(), FILENAMES_CHARS.end(), c) == FILENAMES_CHARS.end(); - }), p_newName.end()); + /* Clean the name (Remove special chars) */ + p_newName.erase(std::remove_if(p_newName.begin(), p_newName.end(), [](auto& c) + { + return std::find(FILENAMES_CHARS.begin(), FILENAMES_CHARS.end(), c) == FILENAMES_CHARS.end(); + }), p_newName.end()); - std::string containingFolderPath = OvTools::Utils::PathParser::GetContainingFolder(filePath); - std::string newPath = containingFolderPath + p_newName; - std::string oldPath = filePath; + std::string containingFolderPath = OvTools::Utils::PathParser::GetContainingFolder(filePath); + std::string newPath = containingFolderPath + p_newName; + std::string oldPath = filePath; - if (filePath != newPath && !std::filesystem::exists(newPath)) - filePath = newPath; + if (filePath != newPath && !std::filesystem::exists(newPath)) + filePath = newPath; - if (std::filesystem::is_directory(oldPath)) - filePath += '\\'; + if (std::filesystem::is_directory(oldPath)) + filePath += '\\'; - RenamedEvent.Invoke(oldPath, newPath); - }; + RenamedEvent.Invoke(oldPath, newPath); + }; + } } - } - - virtual void Execute(OvUI::Plugins::EPluginExecutionContext p_context) override - { - if (m_widgets.size() > 0) - OvUI::Plugins::ContextualMenu::Execute(p_context); - } - virtual void DeleteItem() = 0; + virtual void Execute(OvUI::Plugins::EPluginExecutionContext p_context) override + { + if (m_widgets.size() > 0) + OvUI::Plugins::ContextualMenu::Execute(p_context); + } -public: - bool m_protected; - std::string filePath; - OvTools::Eventing::Event DestroyedEvent; - OvTools::Eventing::Event RenamedEvent; -}; + virtual void DeleteItem() = 0; -class FolderContextualMenu : public BrowserItemContextualMenu -{ -public: - FolderContextualMenu(const std::string& p_filePath, bool p_protected = false) : BrowserItemContextualMenu(p_filePath, p_protected) {} + public: + bool m_protected; + std::string filePath; + OvTools::Eventing::Event DestroyedEvent; + OvTools::Eventing::Event RenamedEvent; + }; - virtual void CreateList() override + class FolderContextualMenu : public BrowserItemContextualMenu { - auto& showInExplorer = CreateWidget("Show in explorer"); - showInExplorer.ClickedEvent += [this] - { - OvTools::Utils::SystemCalls::ShowInExplorer(filePath); - }; + public: + FolderContextualMenu(const std::string& p_filePath, bool p_protected = false) : BrowserItemContextualMenu(p_filePath, p_protected) {} - if (!m_protected) + virtual void CreateList() override { - auto& importAssetHere = CreateWidget("Import Here..."); - importAssetHere.ClickedEvent += [this] - { - if (EDITOR_EXEC(ImportAssetAtLocation(filePath))) + auto& showInExplorer = CreateWidget("Show in explorer"); + showInExplorer.ClickedEvent += [this] { - OvUI::Widgets::Layout::TreeNode* pluginOwner = reinterpret_cast(userData); - pluginOwner->Close(); - EDITOR_EXEC(DelayAction(std::bind(&OvUI::Widgets::Layout::TreeNode::Open, pluginOwner))); - } - }; + OvTools::Utils::SystemCalls::ShowInExplorer(filePath); + }; - auto& createMenu = CreateWidget("Create.."); - - auto& createFolderMenu = createMenu.CreateWidget("Folder"); - auto& createSceneMenu = createMenu.CreateWidget("Scene"); - auto& createShaderMenu = createMenu.CreateWidget("Shader"); - auto& createMaterialMenu = createMenu.CreateWidget("Material"); - - auto& createEmptyShaderMenu = createShaderMenu.CreateWidget("Empty"); - auto& createPartialShaderMenu = createShaderMenu.CreateWidget("Partial"); - auto& createStandardShaderMenu = createShaderMenu.CreateWidget("Standard template"); - auto& createStandardPBRShaderMenu = createShaderMenu.CreateWidget("Standard PBR template"); - auto& createUnlitShaderMenu = createShaderMenu.CreateWidget("Unlit template"); - auto& createLambertShaderMenu = createShaderMenu.CreateWidget("Lambert template"); - - auto& createEmptyMaterialMenu = createMaterialMenu.CreateWidget("Empty"); - auto& createStandardMaterialMenu = createMaterialMenu.CreateWidget("Standard"); - auto& createStandardPBRMaterialMenu = createMaterialMenu.CreateWidget("Standard PBR"); - auto& createUnlitMaterialMenu = createMaterialMenu.CreateWidget("Unlit"); - auto& createLambertMaterialMenu = createMaterialMenu.CreateWidget("Lambert"); - - auto& createFolder = createFolderMenu.CreateWidget(""); - auto& createScene = createSceneMenu.CreateWidget(""); - - auto& createEmptyMaterial = createEmptyMaterialMenu.CreateWidget(""); - auto& createStandardMaterial = createStandardMaterialMenu.CreateWidget(""); - auto& createStandardPBRMaterial = createStandardPBRMaterialMenu.CreateWidget(""); - auto& createUnlitMaterial = createUnlitMaterialMenu.CreateWidget(""); - auto& createLambertMaterial = createLambertMaterialMenu.CreateWidget(""); - - auto& createEmptyShader = createEmptyShaderMenu.CreateWidget(""); - auto& createPartialShader = createPartialShaderMenu.CreateWidget(""); - auto& createStandardShader = createStandardShaderMenu.CreateWidget(""); - auto& createStandardPBRShader = createStandardPBRShaderMenu.CreateWidget(""); - auto& createUnlitShader = createUnlitShaderMenu.CreateWidget(""); - auto& createLambertShader = createLambertShaderMenu.CreateWidget(""); - - createFolderMenu.ClickedEvent += [&createFolder] { createFolder.content = ""; }; - createSceneMenu.ClickedEvent += [&createScene] { createScene.content = ""; }; - createStandardShaderMenu.ClickedEvent += [&createStandardShader] { createStandardShader.content = ""; }; - createStandardPBRShaderMenu.ClickedEvent += [&createStandardPBRShader] { createStandardPBRShader.content = ""; }; - createUnlitShaderMenu.ClickedEvent += [&createUnlitShader] { createUnlitShader.content = ""; }; - createLambertShaderMenu.ClickedEvent += [&createLambertShader] { createLambertShader.content = ""; }; - createEmptyMaterialMenu.ClickedEvent += [&createEmptyMaterial] { createEmptyMaterial.content = ""; }; - createEmptyShaderMenu.ClickedEvent += [&createEmptyShader] { createEmptyShader.content = ""; }; - createPartialShaderMenu.ClickedEvent += [&createPartialShader] { createPartialShader.content = ""; }; - createStandardMaterialMenu.ClickedEvent += [&createStandardMaterial] { createStandardMaterial.content = ""; }; - createStandardPBRMaterialMenu.ClickedEvent += [&createStandardPBRMaterial] { createStandardPBRMaterial.content = ""; }; - createUnlitMaterialMenu.ClickedEvent += [&createUnlitMaterial] { createUnlitMaterial.content = ""; }; - createLambertMaterialMenu.ClickedEvent += [&createLambertMaterial] { createLambertMaterial.content = ""; }; - - createFolder.EnterPressedEvent += [this](std::string newFolderName) + if (!m_protected) { - size_t fails = 0; - std::string finalPath; + auto& importAssetHere = CreateWidget("Import Here..."); + importAssetHere.ClickedEvent += [this] + { + if (EDITOR_EXEC(ImportAssetAtLocation(filePath))) + { + OvUI::Widgets::Layout::TreeNode* pluginOwner = reinterpret_cast(userData); + pluginOwner->Close(); + EDITOR_EXEC(DelayAction(std::bind(&OvUI::Widgets::Layout::TreeNode::Open, pluginOwner))); + } + }; + + auto& createMenu = CreateWidget("Create.."); + + auto& createFolderMenu = createMenu.CreateWidget("Folder"); + auto& createSceneMenu = createMenu.CreateWidget("Scene"); + auto& createShaderMenu = createMenu.CreateWidget("Shader"); + auto& createMaterialMenu = createMenu.CreateWidget("Material"); + + auto& createEmptyShaderMenu = createShaderMenu.CreateWidget("Empty"); + auto& createPartialShaderMenu = createShaderMenu.CreateWidget("Partial"); + auto& createStandardShaderMenu = createShaderMenu.CreateWidget("Standard template"); + auto& createStandardPBRShaderMenu = createShaderMenu.CreateWidget("Standard PBR template"); + auto& createUnlitShaderMenu = createShaderMenu.CreateWidget("Unlit template"); + auto& createLambertShaderMenu = createShaderMenu.CreateWidget("Lambert template"); + + auto& createEmptyMaterialMenu = createMaterialMenu.CreateWidget("Empty"); + auto& createStandardMaterialMenu = createMaterialMenu.CreateWidget("Standard"); + auto& createStandardPBRMaterialMenu = createMaterialMenu.CreateWidget("Standard PBR"); + auto& createUnlitMaterialMenu = createMaterialMenu.CreateWidget("Unlit"); + auto& createLambertMaterialMenu = createMaterialMenu.CreateWidget("Lambert"); + + auto& createFolder = createFolderMenu.CreateWidget(""); + auto& createScene = createSceneMenu.CreateWidget(""); + + auto& createEmptyMaterial = createEmptyMaterialMenu.CreateWidget(""); + auto& createStandardMaterial = createStandardMaterialMenu.CreateWidget(""); + auto& createStandardPBRMaterial = createStandardPBRMaterialMenu.CreateWidget(""); + auto& createUnlitMaterial = createUnlitMaterialMenu.CreateWidget(""); + auto& createLambertMaterial = createLambertMaterialMenu.CreateWidget(""); + + auto& createEmptyShader = createEmptyShaderMenu.CreateWidget(""); + auto& createPartialShader = createPartialShaderMenu.CreateWidget(""); + auto& createStandardShader = createStandardShaderMenu.CreateWidget(""); + auto& createStandardPBRShader = createStandardPBRShaderMenu.CreateWidget(""); + auto& createUnlitShader = createUnlitShaderMenu.CreateWidget(""); + auto& createLambertShader = createLambertShaderMenu.CreateWidget(""); + + createFolderMenu.ClickedEvent += [&createFolder] { createFolder.content = ""; }; + createSceneMenu.ClickedEvent += [&createScene] { createScene.content = ""; }; + createStandardShaderMenu.ClickedEvent += [&createStandardShader] { createStandardShader.content = ""; }; + createStandardPBRShaderMenu.ClickedEvent += [&createStandardPBRShader] { createStandardPBRShader.content = ""; }; + createUnlitShaderMenu.ClickedEvent += [&createUnlitShader] { createUnlitShader.content = ""; }; + createLambertShaderMenu.ClickedEvent += [&createLambertShader] { createLambertShader.content = ""; }; + createEmptyMaterialMenu.ClickedEvent += [&createEmptyMaterial] { createEmptyMaterial.content = ""; }; + createEmptyShaderMenu.ClickedEvent += [&createEmptyShader] { createEmptyShader.content = ""; }; + createPartialShaderMenu.ClickedEvent += [&createPartialShader] { createPartialShader.content = ""; }; + createStandardMaterialMenu.ClickedEvent += [&createStandardMaterial] { createStandardMaterial.content = ""; }; + createStandardPBRMaterialMenu.ClickedEvent += [&createStandardPBRMaterial] { createStandardPBRMaterial.content = ""; }; + createUnlitMaterialMenu.ClickedEvent += [&createUnlitMaterial] { createUnlitMaterial.content = ""; }; + createLambertMaterialMenu.ClickedEvent += [&createLambertMaterial] { createLambertMaterial.content = ""; }; + + createFolder.EnterPressedEvent += [this](std::string newFolderName) + { + size_t fails = 0; + std::string finalPath; - do - { - finalPath = filePath + (!fails ? newFolderName : newFolderName + " (" + std::to_string(fails) + ')'); + do + { + finalPath = filePath + (!fails ? newFolderName : newFolderName + " (" + std::to_string(fails) + ')'); - ++fails; - } while (std::filesystem::exists(finalPath)); + ++fails; + } while (std::filesystem::exists(finalPath)); - std::filesystem::create_directory(finalPath); + std::filesystem::create_directory(finalPath); - ItemAddedEvent.Invoke(finalPath); - Close(); - }; + ItemAddedEvent.Invoke(finalPath); + Close(); + }; - createScene.EnterPressedEvent += [this](std::string newSceneName) - { - size_t fails = 0; - std::string finalPath; + createScene.EnterPressedEvent += [this](std::string newSceneName) + { + size_t fails = 0; + std::string finalPath; - do - { - finalPath = filePath + (!fails ? newSceneName : newSceneName + " (" + std::to_string(fails) + ')') + ".ovscene"; + do + { + finalPath = filePath + (!fails ? newSceneName : newSceneName + " (" + std::to_string(fails) + ')') + ".ovscene"; - ++fails; - } while (std::filesystem::exists(finalPath)); + ++fails; + } while (std::filesystem::exists(finalPath)); - auto emptyScene = OvCore::SceneSystem::Scene{}; - emptyScene.AddDefaultCamera(); - emptyScene.AddDefaultLights(); + auto emptyScene = OvCore::SceneSystem::Scene{}; + emptyScene.AddDefaultCamera(); + emptyScene.AddDefaultLights(); - EDITOR_EXEC(SaveSceneToDisk(emptyScene, finalPath)); + EDITOR_EXEC(SaveSceneToDisk(emptyScene, finalPath)); - ItemAddedEvent.Invoke(finalPath); - Close(); - }; + ItemAddedEvent.Invoke(finalPath); + Close(); + }; - createEmptyShader.EnterPressedEvent += [this](std::string newShaderName) - { - size_t fails = 0; - std::string finalPath; + createEmptyShader.EnterPressedEvent += [this](std::string newShaderName) + { + size_t fails = 0; + std::string finalPath; - do - { - finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfx"; + do + { + finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfx"; - ++fails; - } while (std::filesystem::exists(finalPath)); + ++fails; + } while (std::filesystem::exists(finalPath)); - { - std::ofstream outfile(finalPath); - } + { + std::ofstream outfile(finalPath); + } - ItemAddedEvent.Invoke(finalPath); - Close(); - }; + ItemAddedEvent.Invoke(finalPath); + Close(); + }; - createPartialShader.EnterPressedEvent += [this](std::string newShaderName) - { - size_t fails = 0; - std::string finalPath; + createPartialShader.EnterPressedEvent += [this](std::string newShaderName) + { + size_t fails = 0; + std::string finalPath; - do - { - finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfxh"; + do + { + finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfxh"; - ++fails; - } while (std::filesystem::exists(finalPath)); + ++fails; + } while (std::filesystem::exists(finalPath)); - { - std::ofstream outfile(finalPath); - } + { + std::ofstream outfile(finalPath); + } - ItemAddedEvent.Invoke(finalPath); - Close(); - }; + ItemAddedEvent.Invoke(finalPath); + Close(); + }; - createStandardShader.EnterPressedEvent += [this](std::string newShaderName) - { - size_t fails = 0; - std::string finalPath; + createStandardShader.EnterPressedEvent += [this](std::string newShaderName) + { + size_t fails = 0; + std::string finalPath; - do - { - finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfx"; + do + { + finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfx"; - ++fails; - } while (std::filesystem::exists(finalPath)); + ++fails; + } while (std::filesystem::exists(finalPath)); - std::filesystem::copy_file(EDITOR_CONTEXT(engineAssetsPath) + "Shaders\\Standard.ovfx", finalPath); - ItemAddedEvent.Invoke(finalPath); - Close(); - }; + std::filesystem::copy_file(EDITOR_CONTEXT(engineAssetsPath) + "Shaders\\Standard.ovfx", finalPath); + ItemAddedEvent.Invoke(finalPath); + Close(); + }; - createStandardPBRShader.EnterPressedEvent += [this](std::string newShaderName) - { - size_t fails = 0; - std::string finalPath; + createStandardPBRShader.EnterPressedEvent += [this](std::string newShaderName) + { + size_t fails = 0; + std::string finalPath; - do - { - finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfx"; + do + { + finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfx"; - ++fails; - } while (std::filesystem::exists(finalPath)); + ++fails; + } while (std::filesystem::exists(finalPath)); - std::filesystem::copy_file(EDITOR_CONTEXT(engineAssetsPath) + "Shaders\\StandardPBR.ovfx", finalPath); - ItemAddedEvent.Invoke(finalPath); - Close(); - }; + std::filesystem::copy_file(EDITOR_CONTEXT(engineAssetsPath) + "Shaders\\StandardPBR.ovfx", finalPath); + ItemAddedEvent.Invoke(finalPath); + Close(); + }; - createUnlitShader.EnterPressedEvent += [this](std::string newShaderName) - { - size_t fails = 0; - std::string finalPath; + createUnlitShader.EnterPressedEvent += [this](std::string newShaderName) + { + size_t fails = 0; + std::string finalPath; - do - { - finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfx"; + do + { + finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfx"; - ++fails; - } while (std::filesystem::exists(finalPath)); + ++fails; + } while (std::filesystem::exists(finalPath)); - std::filesystem::copy_file(EDITOR_CONTEXT(engineAssetsPath) + "Shaders\\Unlit.ovfx", finalPath); - ItemAddedEvent.Invoke(finalPath); - Close(); - }; + std::filesystem::copy_file(EDITOR_CONTEXT(engineAssetsPath) + "Shaders\\Unlit.ovfx", finalPath); + ItemAddedEvent.Invoke(finalPath); + Close(); + }; - createLambertShader.EnterPressedEvent += [this](std::string newShaderName) - { - size_t fails = 0; - std::string finalPath; + createLambertShader.EnterPressedEvent += [this](std::string newShaderName) + { + size_t fails = 0; + std::string finalPath; - do - { - finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfx"; + do + { + finalPath = filePath + '\\' + (!fails ? newShaderName : newShaderName + " (" + std::to_string(fails) + ')') + ".ovfx"; - ++fails; - } while (std::filesystem::exists(finalPath)); + ++fails; + } while (std::filesystem::exists(finalPath)); - std::filesystem::copy_file(EDITOR_CONTEXT(engineAssetsPath) + "Shaders\\Lambert.ovfx", finalPath); - ItemAddedEvent.Invoke(finalPath); - Close(); - }; - - createEmptyMaterial.EnterPressedEvent += [this](std::string materialName) - { - size_t fails = 0; - std::string finalPath; + std::filesystem::copy_file(EDITOR_CONTEXT(engineAssetsPath) + "Shaders\\Lambert.ovfx", finalPath); + ItemAddedEvent.Invoke(finalPath); + Close(); + }; - do - { - finalPath = filePath + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; + createEmptyMaterial.EnterPressedEvent += [this](std::string materialName) + { + size_t fails = 0; + std::string finalPath; - ++fails; - } while (std::filesystem::exists(finalPath)); + do + { + finalPath = filePath + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; - { - std::ofstream outfile(finalPath); - outfile << "?" << std::endl; // Empty material content - } + ++fails; + } while (std::filesystem::exists(finalPath)); - ItemAddedEvent.Invoke(finalPath); + { + std::ofstream outfile(finalPath); + outfile << "?" << std::endl; // Empty material content + } - if (auto instance = EDITOR_CONTEXT(materialManager)[EDITOR_EXEC(GetResourcePath(finalPath))]) - { - auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); - materialEditor.SetTarget(*instance); - materialEditor.Open(); - materialEditor.Focus(); - materialEditor.Preview(); - } - Close(); - }; + ItemAddedEvent.Invoke(finalPath); - createStandardMaterial.EnterPressedEvent += [this](std::string materialName) - { - size_t fails = 0; - std::string finalPath; + if (auto instance = EDITOR_CONTEXT(materialManager)[EDITOR_EXEC(GetResourcePath(finalPath))]) + { + auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); + materialEditor.SetTarget(*instance); + materialEditor.Open(); + materialEditor.Focus(); + materialEditor.Preview(); + } + Close(); + }; - do - { - finalPath = filePath + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; + createStandardMaterial.EnterPressedEvent += [this](std::string materialName) + { + size_t fails = 0; + std::string finalPath; - ++fails; - } while (std::filesystem::exists(finalPath)); + do + { + finalPath = filePath + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; - { - std::ofstream outfile(finalPath); - outfile << ":Shaders\\Standard.ovfx" << std::endl; // Empty standard material content - } + ++fails; + } while (std::filesystem::exists(finalPath)); - ItemAddedEvent.Invoke(finalPath); + { + std::ofstream outfile(finalPath); + outfile << ":Shaders\\Standard.ovfx" << std::endl; // Empty standard material content + } - if (auto instance = EDITOR_CONTEXT(materialManager)[EDITOR_EXEC(GetResourcePath(finalPath))]) - { - auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); - materialEditor.SetTarget(*instance); - materialEditor.Open(); - materialEditor.Focus(); - materialEditor.Preview(); - } - Close(); - }; + ItemAddedEvent.Invoke(finalPath); - createStandardPBRMaterial.EnterPressedEvent += [this](std::string materialName) - { - size_t fails = 0; - std::string finalPath; + if (auto instance = EDITOR_CONTEXT(materialManager)[EDITOR_EXEC(GetResourcePath(finalPath))]) + { + auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); + materialEditor.SetTarget(*instance); + materialEditor.Open(); + materialEditor.Focus(); + materialEditor.Preview(); + } + Close(); + }; - do - { - finalPath = filePath + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; + createStandardPBRMaterial.EnterPressedEvent += [this](std::string materialName) + { + size_t fails = 0; + std::string finalPath; - ++fails; - } while (std::filesystem::exists(finalPath)); + do + { + finalPath = filePath + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; - { - std::ofstream outfile(finalPath); - outfile << ":Shaders\\StandardPBR.ovfx" << std::endl; // Empty standard material content - } + ++fails; + } while (std::filesystem::exists(finalPath)); - ItemAddedEvent.Invoke(finalPath); + { + std::ofstream outfile(finalPath); + outfile << ":Shaders\\StandardPBR.ovfx" << std::endl; // Empty standard material content + } - if (auto instance = EDITOR_CONTEXT(materialManager)[EDITOR_EXEC(GetResourcePath(finalPath))]) - { - auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); - materialEditor.SetTarget(*instance); - materialEditor.Open(); - materialEditor.Focus(); - materialEditor.Preview(); - } - Close(); - }; + ItemAddedEvent.Invoke(finalPath); - createUnlitMaterial.EnterPressedEvent += [this](std::string materialName) - { - std::string newSceneName = "Material"; - size_t fails = 0; - std::string finalPath; + if (auto instance = EDITOR_CONTEXT(materialManager)[EDITOR_EXEC(GetResourcePath(finalPath))]) + { + auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); + materialEditor.SetTarget(*instance); + materialEditor.Open(); + materialEditor.Focus(); + materialEditor.Preview(); + } + Close(); + }; - do - { - finalPath = filePath + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; + createUnlitMaterial.EnterPressedEvent += [this](std::string materialName) + { + std::string newSceneName = "Material"; + size_t fails = 0; + std::string finalPath; - ++fails; - } while (std::filesystem::exists(finalPath)); + do + { + finalPath = filePath + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; - { - std::ofstream outfile(finalPath); - outfile << ":Shaders\\Unlit.ovfx" << std::endl; // Empty unlit material content - } + ++fails; + } while (std::filesystem::exists(finalPath)); - ItemAddedEvent.Invoke(finalPath); + { + std::ofstream outfile(finalPath); + outfile << ":Shaders\\Unlit.ovfx" << std::endl; // Empty unlit material content + } - if (auto instance = EDITOR_CONTEXT(materialManager)[EDITOR_EXEC(GetResourcePath(finalPath))]) - { - auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); - materialEditor.SetTarget(*instance); - materialEditor.Open(); - materialEditor.Focus(); - materialEditor.Preview(); - } - Close(); - }; + ItemAddedEvent.Invoke(finalPath); - createLambertMaterial.EnterPressedEvent += [this](std::string materialName) - { - size_t fails = 0; - std::string finalPath; + if (auto instance = EDITOR_CONTEXT(materialManager)[EDITOR_EXEC(GetResourcePath(finalPath))]) + { + auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); + materialEditor.SetTarget(*instance); + materialEditor.Open(); + materialEditor.Focus(); + materialEditor.Preview(); + } + Close(); + }; - do - { - finalPath = filePath + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; + createLambertMaterial.EnterPressedEvent += [this](std::string materialName) + { + size_t fails = 0; + std::string finalPath; - ++fails; - } while (std::filesystem::exists(finalPath)); + do + { + finalPath = filePath + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; - { - std::ofstream outfile(finalPath); - outfile << ":Shaders\\Lambert.ovfx" << std::endl; // Empty unlit material content - } + ++fails; + } while (std::filesystem::exists(finalPath)); - ItemAddedEvent.Invoke(finalPath); + { + std::ofstream outfile(finalPath); + outfile << ":Shaders\\Lambert.ovfx" << std::endl; // Empty unlit material content + } - if (auto instance = EDITOR_CONTEXT(materialManager)[EDITOR_EXEC(GetResourcePath(finalPath))]) - { - auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); - materialEditor.SetTarget(*instance); - materialEditor.Open(); - materialEditor.Focus(); - materialEditor.Preview(); - } - Close(); - }; + ItemAddedEvent.Invoke(finalPath); - BrowserItemContextualMenu::CreateList(); - } - } + if (auto instance = EDITOR_CONTEXT(materialManager)[EDITOR_EXEC(GetResourcePath(finalPath))]) + { + auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); + materialEditor.SetTarget(*instance); + materialEditor.Open(); + materialEditor.Focus(); + materialEditor.Preview(); + } + Close(); + }; - virtual void DeleteItem() override - { - using namespace OvWindowing::Dialogs; - MessageBox message("Delete folder", "Deleting a folder (and all its content) is irreversible, are you sure that you want to delete \"" + filePath + "\"?", MessageBox::EMessageType::WARNING, MessageBox::EButtonLayout::YES_NO); + BrowserItemContextualMenu::CreateList(); + } + } - if (message.GetUserAction() == MessageBox::EUserAction::YES) + virtual void DeleteItem() override { - if (std::filesystem::exists(filePath) == true) + using namespace OvWindowing::Dialogs; + MessageBox message("Delete folder", "Deleting a folder (and all its content) is irreversible, are you sure that you want to delete \"" + filePath + "\"?", MessageBox::EMessageType::WARNING, MessageBox::EButtonLayout::YES_NO); + + if (message.GetUserAction() == MessageBox::EUserAction::YES) { - EDITOR_EXEC(PropagateFolderDestruction(filePath)); - std::filesystem::remove_all(filePath); - DestroyedEvent.Invoke(filePath); + if (std::filesystem::exists(filePath) == true) + { + EDITOR_EXEC(PropagateFolderDestruction(filePath)); + std::filesystem::remove_all(filePath); + DestroyedEvent.Invoke(filePath); + } } } - } -public: - OvTools::Eventing::Event ItemAddedEvent; -}; - -class ScriptFolderContextualMenu : public FolderContextualMenu -{ -public: - ScriptFolderContextualMenu(const std::string& p_filePath, bool p_protected = false) : FolderContextualMenu(p_filePath, p_protected) {} + public: + OvTools::Eventing::Event ItemAddedEvent; + }; - void CreateScript(const std::string& p_name, const std::string& p_path) + class ScriptFolderContextualMenu : public FolderContextualMenu { - const std::string fileContent = OVSERVICE(OvCore::Scripting::ScriptEngine).GetDefaultScriptContent(p_name); - - std::ofstream outfile(p_path); - outfile << fileContent << std::endl; + public: + ScriptFolderContextualMenu(const std::string& p_filePath, bool p_protected = false) : FolderContextualMenu(p_filePath, p_protected) {} - ItemAddedEvent.Invoke(p_path); - Close(); - } + void CreateScript(const std::string& p_name, const std::string& p_path) + { + const std::string fileContent = OVSERVICE(OvCore::Scripting::ScriptEngine).GetDefaultScriptContent(p_name); - virtual void CreateList() override - { - FolderContextualMenu::CreateList(); + std::ofstream outfile(p_path); + outfile << fileContent << std::endl; - auto& newScriptMenu = CreateWidget("New script..."); - auto& nameEditor = newScriptMenu.CreateWidget(""); + ItemAddedEvent.Invoke(p_path); + Close(); + } - newScriptMenu.ClickedEvent += [this, &nameEditor] + virtual void CreateList() override { - nameEditor.content = OvTools::Utils::PathParser::GetElementName(""); - }; + FolderContextualMenu::CreateList(); - nameEditor.EnterPressedEvent += [this](std::string p_newName) - { - /* Clean the name (Remove special chars) */ - p_newName.erase(std::remove_if(p_newName.begin(), p_newName.end(), [](auto& c) - { - return std::find(FILENAMES_CHARS.begin(), FILENAMES_CHARS.end(), c) == FILENAMES_CHARS.end(); - }), p_newName.end()); + auto& newScriptMenu = CreateWidget("New script..."); + auto& nameEditor = newScriptMenu.CreateWidget(""); - const std::string extension = OVSERVICE(OvCore::Scripting::ScriptEngine).GetDefaultExtension(); - const std::string newPath = filePath + p_newName + extension; + newScriptMenu.ClickedEvent += [this, &nameEditor] + { + nameEditor.content = OvTools::Utils::PathParser::GetElementName(""); + }; - if (!std::filesystem::exists(newPath)) - { - CreateScript(p_newName, newPath); - } - }; - } -}; + nameEditor.EnterPressedEvent += [this](std::string p_newName) + { + /* Clean the name (Remove special chars) */ + p_newName.erase(std::remove_if(p_newName.begin(), p_newName.end(), [](auto& c) + { + return std::find(FILENAMES_CHARS.begin(), FILENAMES_CHARS.end(), c) == FILENAMES_CHARS.end(); + }), p_newName.end()); -class FileContextualMenu : public BrowserItemContextualMenu -{ -public: - FileContextualMenu(const std::string& p_filePath, bool p_protected = false) : BrowserItemContextualMenu(p_filePath, p_protected) {} + const std::string extension = OVSERVICE(OvCore::Scripting::ScriptEngine).GetDefaultExtension(); + const std::string newPath = filePath + p_newName + extension; + + if (!std::filesystem::exists(newPath)) + { + CreateScript(p_newName, newPath); + } + }; + } + }; - virtual void CreateList() override + class FileContextualMenu : public BrowserItemContextualMenu { - auto& editAction = CreateWidget("Open"); + public: + FileContextualMenu(const std::string& p_filePath, bool p_protected = false) : BrowserItemContextualMenu(p_filePath, p_protected) {} - editAction.ClickedEvent += [this] + virtual void CreateList() override { - OvTools::Utils::SystemCalls::OpenFile(filePath); - }; + auto& editAction = CreateWidget("Open"); - if (!m_protected) - { - auto& duplicateAction = CreateWidget("Duplicate"); + editAction.ClickedEvent += [this] + { + OvTools::Utils::SystemCalls::OpenFile(filePath); + }; - duplicateAction.ClickedEvent += [this] + if (!m_protected) { - std::string filePathWithoutExtension = filePath; + auto& duplicateAction = CreateWidget("Duplicate"); - if (size_t pos = filePathWithoutExtension.rfind('.'); pos != std::string::npos) - filePathWithoutExtension = filePathWithoutExtension.substr(0, pos); + duplicateAction.ClickedEvent += [this] + { + std::string filePathWithoutExtension = filePath; - std::string extension = "." + OvTools::Utils::PathParser::GetExtension(filePath); + if (size_t pos = filePathWithoutExtension.rfind('.'); pos != std::string::npos) + filePathWithoutExtension = filePathWithoutExtension.substr(0, pos); - auto filenameAvailable = [&extension](const std::string& target) - { - return !std::filesystem::exists(target + extension); - }; + std::string extension = "." + OvTools::Utils::PathParser::GetExtension(filePath); - const auto newNameWithoutExtension = OvTools::Utils::String::GenerateUnique(filePathWithoutExtension, filenameAvailable); + auto filenameAvailable = [&extension](const std::string& target) + { + return !std::filesystem::exists(target + extension); + }; - std::string finalPath = newNameWithoutExtension + extension; - std::filesystem::copy(filePath, finalPath); + const auto newNameWithoutExtension = OvTools::Utils::String::GenerateUnique(filePathWithoutExtension, filenameAvailable); - DuplicateEvent.Invoke(finalPath); - }; - } + std::string finalPath = newNameWithoutExtension + extension; + std::filesystem::copy(filePath, finalPath); - BrowserItemContextualMenu::CreateList(); + DuplicateEvent.Invoke(finalPath); + }; + } + BrowserItemContextualMenu::CreateList(); - auto& editMetadata = CreateWidget("Properties"); - editMetadata.ClickedEvent += [this] - { - auto& panel = EDITOR_PANEL(OvEditor::Panels::AssetProperties, "Asset Properties"); - std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); - panel.SetTarget(resourcePath); - panel.Open(); - panel.Focus(); - }; - } + auto& editMetadata = CreateWidget("Properties"); - virtual void DeleteItem() override - { - using namespace OvWindowing::Dialogs; - MessageBox message("Delete file", "Deleting a file is irreversible, are you sure that you want to delete \"" + filePath + "\"?", MessageBox::EMessageType::WARNING, MessageBox::EButtonLayout::YES_NO); + editMetadata.ClickedEvent += [this] + { + auto& panel = EDITOR_PANEL(OvEditor::Panels::AssetProperties, "Asset Properties"); + std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); + panel.SetTarget(resourcePath); + panel.Open(); + panel.Focus(); + }; + } - if (message.GetUserAction() == MessageBox::EUserAction::YES) + virtual void DeleteItem() override { - RemoveAsset(filePath); - DestroyedEvent.Invoke(filePath); - EDITOR_EXEC(PropagateFileRename(filePath, "?")); - } - } + using namespace OvWindowing::Dialogs; + MessageBox message("Delete file", "Deleting a file is irreversible, are you sure that you want to delete \"" + filePath + "\"?", MessageBox::EMessageType::WARNING, MessageBox::EButtonLayout::YES_NO); -public: - OvTools::Eventing::Event DuplicateEvent; -}; + if (message.GetUserAction() == MessageBox::EUserAction::YES) + { + RemoveAsset(filePath); + DestroyedEvent.Invoke(filePath); + EDITOR_EXEC(PropagateFileRename(filePath, "?")); + } + } -template -class PreviewableContextualMenu : public FileContextualMenu -{ -public: - PreviewableContextualMenu(const std::string& p_filePath, bool p_protected = false) : FileContextualMenu(p_filePath, p_protected) {} + public: + OvTools::Eventing::Event DuplicateEvent; + }; - virtual void CreateList() override + template + class PreviewableContextualMenu : public FileContextualMenu { - auto& previewAction = CreateWidget("Preview"); + public: + PreviewableContextualMenu(const std::string& p_filePath, bool p_protected = false) : FileContextualMenu(p_filePath, p_protected) {} - previewAction.ClickedEvent += [this] + virtual void CreateList() override { - Resource* resource = OvCore::Global::ServiceLocator::Get()[EDITOR_EXEC(GetResourcePath(filePath, m_protected))]; - auto& assetView = EDITOR_PANEL(OvEditor::Panels::AssetView, "Asset View"); - assetView.SetResource(resource); - assetView.Open(); - assetView.Focus(); - }; + auto& previewAction = CreateWidget("Preview"); - FileContextualMenu::CreateList(); - } -}; + previewAction.ClickedEvent += [this] + { + OpenInAssetView(GetResource(filePath, m_protected)); + }; -class ShaderContextualMenu : public FileContextualMenu -{ -public: - ShaderContextualMenu(const std::string& p_filePath, bool p_protected = false) : FileContextualMenu(p_filePath, p_protected) {} + FileContextualMenu::CreateList(); + } + }; - virtual void CreateList() override + class ShaderContextualMenu : public FileContextualMenu { - FileContextualMenu::CreateList(); + public: + ShaderContextualMenu(const std::string& p_filePath, bool p_protected = false) : FileContextualMenu(p_filePath, p_protected) {} - auto& compileAction = CreateWidget("Compile"); - - compileAction.ClickedEvent += [this] + virtual void CreateList() override { - auto& shaderManager = OVSERVICE(OvCore::ResourceManagement::ShaderManager); - std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); - if (shaderManager.IsResourceRegistered(resourcePath)) - { - /* Trying to recompile */ - shaderManager.ReloadResource(shaderManager[resourcePath], filePath); - } - else - { - /* Trying to compile */ - OvRendering::Resources::Shader* shader = OVSERVICE(OvCore::ResourceManagement::ShaderManager)[resourcePath]; - if (shader) - OVLOG_INFO("[COMPILE] \"" + filePath + "\": Success!"); - } - - }; - } -}; + FileContextualMenu::CreateList(); -class ShaderPartContextualMenu : public FileContextualMenu -{ -public: - ShaderPartContextualMenu(const std::string& p_filePath, bool p_protected = false) : FileContextualMenu(p_filePath, p_protected) {} + auto& compileAction = CreateWidget("Compile"); - virtual void CreateList() override - { - FileContextualMenu::CreateList(); - } -}; + compileAction.ClickedEvent += [this] + { + auto& shaderManager = OVSERVICE(OvCore::ResourceManagement::ShaderManager); + std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); + if (shaderManager.IsResourceRegistered(resourcePath)) + { + /* Trying to recompile */ + shaderManager.ReloadResource(shaderManager[resourcePath], filePath); + } + else + { + /* Trying to compile */ + OvRendering::Resources::Shader* shader = OVSERVICE(OvCore::ResourceManagement::ShaderManager)[resourcePath]; + if (shader) + OVLOG_INFO("[COMPILE] \"" + filePath + "\": Success!"); + } -class ModelContextualMenu : public PreviewableContextualMenu -{ -public: - ModelContextualMenu(const std::string& p_filePath, bool p_protected = false) : PreviewableContextualMenu(p_filePath, p_protected) {} + }; + } + }; - virtual void CreateList() override + class ShaderPartContextualMenu : public FileContextualMenu { - auto& reloadAction = CreateWidget("Reload"); + public: + ShaderPartContextualMenu(const std::string& p_filePath, bool p_protected = false) : FileContextualMenu(p_filePath, p_protected) {} - reloadAction.ClickedEvent += [this] + virtual void CreateList() override { - auto& modelManager = OVSERVICE(OvCore::ResourceManagement::ModelManager); - std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); - if (modelManager.IsResourceRegistered(resourcePath)) - { - modelManager.AResourceManager::ReloadResource(resourcePath); - } - }; + FileContextualMenu::CreateList(); + } + }; - if (!m_protected) + class ModelContextualMenu : public PreviewableContextualMenu + { + public: + ModelContextualMenu(const std::string& p_filePath, bool p_protected = false) : PreviewableContextualMenu(p_filePath, p_protected) {} + + virtual void CreateList() override { - auto& generateMaterialsMenu = CreateWidget("Generate materials..."); + auto& reloadAction = CreateWidget("Reload"); - generateMaterialsMenu.CreateWidget("Standard").ClickedEvent += [this] - { - auto& modelManager = OVSERVICE(OvCore::ResourceManagement::ModelManager); - std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); - if (auto model = modelManager.GetResource(resourcePath)) + reloadAction.ClickedEvent += [this] { - for (const std::string& materialName : model->GetMaterialNames()) + auto& modelManager = OVSERVICE(OvCore::ResourceManagement::ModelManager); + std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); + if (modelManager.IsResourceRegistered(resourcePath)) { - size_t fails = 0; - std::string finalPath; + modelManager.AResourceManager::ReloadResource(resourcePath); + } + }; - do + if (!m_protected) + { + auto& generateMaterialsMenu = CreateWidget("Generate materials..."); + + generateMaterialsMenu.CreateWidget("Standard").ClickedEvent += [this] + { + auto& modelManager = OVSERVICE(OvCore::ResourceManagement::ModelManager); + std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); + if (auto model = modelManager.GetResource(resourcePath)) { - finalPath = OvTools::Utils::PathParser::GetContainingFolder(filePath) + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; + for (const std::string& materialName : model->GetMaterialNames()) + { + size_t fails = 0; + std::string finalPath; - ++fails; - } while (std::filesystem::exists(finalPath)); + do + { + finalPath = OvTools::Utils::PathParser::GetContainingFolder(filePath) + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; - { - std::ofstream outfile(finalPath); - outfile << ":Shaders\\Standard.ovfx" << std::endl; // Empty standard material content - } + ++fails; + } while (std::filesystem::exists(finalPath)); - DuplicateEvent.Invoke(finalPath); - } - } - }; + { + std::ofstream outfile(finalPath); + outfile << ":Shaders\\Standard.ovfx" << std::endl; // Empty standard material content + } - generateMaterialsMenu.CreateWidget("StandardPBR").ClickedEvent += [this] - { - auto& modelManager = OVSERVICE(OvCore::ResourceManagement::ModelManager); - std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); - if (auto model = modelManager.GetResource(resourcePath)) - { - for (const std::string& materialName : model->GetMaterialNames()) - { - size_t fails = 0; - std::string finalPath; + DuplicateEvent.Invoke(finalPath); + } + } + }; - do + generateMaterialsMenu.CreateWidget("StandardPBR").ClickedEvent += [this] + { + auto& modelManager = OVSERVICE(OvCore::ResourceManagement::ModelManager); + std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); + if (auto model = modelManager.GetResource(resourcePath)) { - finalPath = OvTools::Utils::PathParser::GetContainingFolder(filePath) + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; + for (const std::string& materialName : model->GetMaterialNames()) + { + size_t fails = 0; + std::string finalPath; - ++fails; - } while (std::filesystem::exists(finalPath)); + do + { + finalPath = OvTools::Utils::PathParser::GetContainingFolder(filePath) + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; - { - std::ofstream outfile(finalPath); - outfile << ":Shaders\\StandardPBR.ovfx" << std::endl; // Empty standard material content - } + ++fails; + } while (std::filesystem::exists(finalPath)); - DuplicateEvent.Invoke(finalPath); - } - } - }; + { + std::ofstream outfile(finalPath); + outfile << ":Shaders\\StandardPBR.ovfx" << std::endl; // Empty standard material content + } - generateMaterialsMenu.CreateWidget("Unlit").ClickedEvent += [this] - { - auto& modelManager = OVSERVICE(OvCore::ResourceManagement::ModelManager); - std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); - if (auto model = modelManager.GetResource(resourcePath)) - { - for (const std::string& materialName : model->GetMaterialNames()) - { - size_t fails = 0; - std::string finalPath; + DuplicateEvent.Invoke(finalPath); + } + } + }; - do + generateMaterialsMenu.CreateWidget("Unlit").ClickedEvent += [this] + { + auto& modelManager = OVSERVICE(OvCore::ResourceManagement::ModelManager); + std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); + if (auto model = modelManager.GetResource(resourcePath)) { - finalPath = OvTools::Utils::PathParser::GetContainingFolder(filePath) + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; + for (const std::string& materialName : model->GetMaterialNames()) + { + size_t fails = 0; + std::string finalPath; - ++fails; - } while (std::filesystem::exists(finalPath)); + do + { + finalPath = OvTools::Utils::PathParser::GetContainingFolder(filePath) + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; - { - std::ofstream outfile(finalPath); - outfile << ":Shaders\\Unlit.ovfx" << std::endl; // Empty standard material content - } + ++fails; + } while (std::filesystem::exists(finalPath)); - DuplicateEvent.Invoke(finalPath); - } - } - }; + { + std::ofstream outfile(finalPath); + outfile << ":Shaders\\Unlit.ovfx" << std::endl; // Empty standard material content + } - generateMaterialsMenu.CreateWidget("Lambert").ClickedEvent += [this] - { - auto& modelManager = OVSERVICE(OvCore::ResourceManagement::ModelManager); - std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); - if (auto model = modelManager.GetResource(resourcePath)) - { - for (const std::string& materialName : model->GetMaterialNames()) - { - size_t fails = 0; - std::string finalPath; + DuplicateEvent.Invoke(finalPath); + } + } + }; - do + generateMaterialsMenu.CreateWidget("Lambert").ClickedEvent += [this] + { + auto& modelManager = OVSERVICE(OvCore::ResourceManagement::ModelManager); + std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); + if (auto model = modelManager.GetResource(resourcePath)) { - finalPath = OvTools::Utils::PathParser::GetContainingFolder(filePath) + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; + for (const std::string& materialName : model->GetMaterialNames()) + { + size_t fails = 0; + std::string finalPath; - ++fails; - } while (std::filesystem::exists(finalPath)); + do + { + finalPath = OvTools::Utils::PathParser::GetContainingFolder(filePath) + (!fails ? materialName : materialName + " (" + std::to_string(fails) + ')') + ".ovmat"; - { - std::ofstream outfile(finalPath); - outfile << ":Shaders\\Lambert.ovfx" << std::endl; // Empty standard material content - } + ++fails; + } while (std::filesystem::exists(finalPath)); - DuplicateEvent.Invoke(finalPath); - } - } - }; - } + { + std::ofstream outfile(finalPath); + outfile << ":Shaders\\Lambert.ovfx" << std::endl; // Empty standard material content + } - PreviewableContextualMenu::CreateList(); - } -}; + DuplicateEvent.Invoke(finalPath); + } + } + }; + } -class TextureContextualMenu : public PreviewableContextualMenu -{ -public: - TextureContextualMenu(const std::string& p_filePath, bool p_protected = false) : PreviewableContextualMenu(p_filePath, p_protected) {} + PreviewableContextualMenu::CreateList(); + } + }; - virtual void CreateList() override + class TextureContextualMenu : public PreviewableContextualMenu { - auto& reloadAction = CreateWidget("Reload"); + public: + TextureContextualMenu(const std::string& p_filePath, bool p_protected = false) : PreviewableContextualMenu(p_filePath, p_protected) {} - reloadAction.ClickedEvent += [this] + virtual void CreateList() override { - auto& textureManager = OVSERVICE(OvCore::ResourceManagement::TextureManager); - std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); - if (textureManager.IsResourceRegistered(resourcePath)) - { - /* Trying to recompile */ - textureManager.AResourceManager::ReloadResource(resourcePath); - EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor").Refresh(); - } - }; + auto& reloadAction = CreateWidget("Reload"); - PreviewableContextualMenu::CreateList(); - } -}; + reloadAction.ClickedEvent += [this] + { + auto& textureManager = OVSERVICE(OvCore::ResourceManagement::TextureManager); + std::string resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); + if (textureManager.IsResourceRegistered(resourcePath)) + { + /* Trying to recompile */ + textureManager.AResourceManager::ReloadResource(resourcePath); + EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor").Refresh(); + } + }; -class SceneContextualMenu : public FileContextualMenu -{ -public: - SceneContextualMenu(const std::string& p_filePath, bool p_protected = false) : FileContextualMenu(p_filePath, p_protected) {} + PreviewableContextualMenu::CreateList(); + } + }; - virtual void CreateList() override + class SceneContextualMenu : public FileContextualMenu { - auto& editAction = CreateWidget("Edit"); + public: + SceneContextualMenu(const std::string& p_filePath, bool p_protected = false) : FileContextualMenu(p_filePath, p_protected) {} - editAction.ClickedEvent += [this] + virtual void CreateList() override { - EDITOR_EXEC(LoadSceneFromDisk(EDITOR_EXEC(GetResourcePath(filePath)))); - }; + auto& editAction = CreateWidget("Edit"); - FileContextualMenu::CreateList(); - } -}; + editAction.ClickedEvent += [this] + { + EDITOR_EXEC(LoadSceneFromDisk(EDITOR_EXEC(GetResourcePath(filePath)))); + }; -class MaterialContextualMenu : public PreviewableContextualMenu -{ -public: - MaterialContextualMenu(const std::string& p_filePath, bool p_protected = false) : PreviewableContextualMenu(p_filePath, p_protected) {} + FileContextualMenu::CreateList(); + } + }; - virtual void CreateList() override + class MaterialContextualMenu : public PreviewableContextualMenu { - auto& editAction = CreateWidget("Edit"); + public: + MaterialContextualMenu(const std::string& p_filePath, bool p_protected = false) : PreviewableContextualMenu(p_filePath, p_protected) {} - editAction.ClickedEvent += [this] + virtual void CreateList() override { - OvCore::Resources::Material* material = OVSERVICE(OvCore::ResourceManagement::MaterialManager)[EDITOR_EXEC(GetResourcePath(filePath, m_protected))]; - if (material) - { - auto& materialEditor = EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor"); - materialEditor.SetTarget(*material); - materialEditor.Open(); - materialEditor.Focus(); - - OvCore::Resources::Material* resource = OvCore::Global::ServiceLocator::Get()[EDITOR_EXEC(GetResourcePath(filePath, m_protected))]; - auto& assetView = EDITOR_PANEL(OvEditor::Panels::AssetView, "Asset View"); - assetView.SetResource(resource); - assetView.Open(); - assetView.Focus(); - } - }; + auto& editAction = CreateWidget("Edit"); - auto& reload = CreateWidget("Reload"); - reload.ClickedEvent += [this] - { - auto materialManager = OVSERVICE(OvCore::ResourceManagement::MaterialManager); - auto resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); - OvCore::Resources::Material* material = materialManager[resourcePath]; - if (material) - { - materialManager.AResourceManager::ReloadResource(resourcePath); - EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor").Refresh(); - } - }; + editAction.ClickedEvent += [this] + { + OvCore::Resources::Material* material = OVSERVICE(OvCore::ResourceManagement::MaterialManager)[EDITOR_EXEC(GetResourcePath(filePath, m_protected))]; + if (material) + { + auto& res = GetResource(filePath, m_protected); + OpenInAssetView(res); + OpenInMaterialEditor(res); + } + }; - PreviewableContextualMenu::CreateList(); - } -}; + auto& reload = CreateWidget("Reload"); + reload.ClickedEvent += [this] + { + auto materialManager = OVSERVICE(OvCore::ResourceManagement::MaterialManager); + auto resourcePath = EDITOR_EXEC(GetResourcePath(filePath, m_protected)); + OvCore::Resources::Material* material = materialManager[resourcePath]; + if (material) + { + materialManager.AResourceManager::ReloadResource(resourcePath); + EDITOR_PANEL(OvEditor::Panels::MaterialEditor, "Material Editor").Refresh(); + } + }; + + PreviewableContextualMenu::CreateList(); + } + }; +} OvEditor::Panels::AssetBrowser::AssetBrowser ( @@ -1343,10 +1359,46 @@ void OvEditor::Panels::AssetBrowser::ConsiderItem(OvUI::Widgets::Layout::TreeNod EDITOR_EXEC(DelayAction(std::bind(&AssetBrowser::ConsiderItem, this, p_root, std::filesystem::directory_entry{ newItem }, p_isEngineItem, false, false), 0)); }; + if (fileType == OvTools::Utils::PathParser::EFileType::SOUND || + fileType == OvTools::Utils::PathParser::EFileType::SCRIPT || + fileType == OvTools::Utils::PathParser::EFileType::SHADER || + fileType == OvTools::Utils::PathParser::EFileType::SHADER_PART) + { + clickableText.DoubleClickedEvent += [path] + { + OvTools::Utils::SystemCalls::OpenFile(path); + }; + } + + if (fileType == OvTools::Utils::PathParser::EFileType::MODEL) + { + clickableText.DoubleClickedEvent += [path, p_isEngineItem] + { + auto& res = GetResource(path, p_isEngineItem); + OpenInAssetView(res); + }; + } + + if (fileType == OvTools::Utils::PathParser::EFileType::MATERIAL) + { + clickableText.DoubleClickedEvent += [path, p_isEngineItem] + { + auto& res = GetResource(path, p_isEngineItem); + OpenInAssetView(res); + OpenInMaterialEditor(res); + }; + } + if (fileType == OvTools::Utils::PathParser::EFileType::TEXTURE) { auto& texturePreview = clickableText.AddPlugin(); texturePreview.SetPath(resourceFormatPath); + + clickableText.DoubleClickedEvent += [path, p_isEngineItem] + { + auto& res = GetResource(path, p_isEngineItem); + OpenInAssetView(res); + }; } if (fileType == OvTools::Utils::PathParser::EFileType::SCENE)