#include "EditorResources.hpp" #include "EditorCore.hpp" #include "EditorNotification.hpp" #include "EditorUtils.hpp" #include "Macros.hpp" #include "ScopeGuard.hpp" #include "Shader.hpp" #include #include #include #include #include #include using namespace std::literals; EditorContentBrowser::EditorContentBrowser(EditorInstance* editor) : mEditor{ editor } { } EditorContentBrowser::~EditorContentBrowser() { } void EditorContentBrowser::Show(bool* open) { ImGuiWindowFlags windowFlags; if (mDocked) { // Center window horizontally, align bottom vertically auto& viewportSize = ImGui::GetMainViewport()->Size; ImGui::SetNextWindowPos(ImVec2(viewportSize.x / 2, viewportSize.y), ImGuiCond_Always, ImVec2(0.5f, 1.0f)); ImGui::SetNextWindowSizeRelScreen(0.8f, mBrowserHeight); windowFlags = ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse; } else { windowFlags = 0; } ImGui::Begin("Content Browser", open, windowFlags); ImGui::Splitter(true, kSplitterThickness, &mSplitterLeft, &mSplitterRight, kLeftPaneMinWidth, kRightPaneMinWidth); ImGui::BeginChild("LeftPane", ImVec2(mSplitterLeft - kPadding, 0.0f)); { if (ImGui::Selectable("Settings", mPane == P_Settings)) { mPane = P_Settings; } if (ImGui::Selectable("Shaders", mPane == P_Shader)) { mPane = P_Shader; } if (ImGui::Selectable("Materials", mPane == P_Material)) { mPane = P_Material; } if (ImGui::Selectable("Ires", mPane == P_Ires)) { mPane = P_Ires; } } ImGui::EndChild(); ImGui::SameLine(0.0f, kPadding + kSplitterThickness + kPadding); ImGui::BeginChild("RightPane"); // Fill remaining space { switch (mPane) { case P_Settings: { ImGui::Checkbox("Docked", &mDocked); ImGui::SliderFloat("Height", &mBrowserHeight, 0.1f, 1.0f); } break; case P_Shader: { if (ImGui::Button("Refresh")) { // TODO reload shaders while keeping existing references working } ImGui::SameLine(); if (ImGui::Button("Save all")) { auto& shaders = ShaderManager::instance->GetShaders(); for (auto&& [DISCARD, shader] : shaders) { shader->SaveMetadataToFile(shader->GetDesignatedMetadataPath()); } } auto& shaders = ShaderManager::instance->GetShaders(); for (auto it = shaders.begin(); it != shaders.end(); ++it) { auto shader = it->second.Get(); auto& name = shader->GetName(); bool selected = mEditor->GetSelectedItPtr() == shader; if (ImGui::Selectable(name.c_str(), selected)) { mEditor->SelectIt(shader, EditorInstance::ITT_Shader); } if (ImGui::BeginDragDropSource()) { // Reason: intentionally using pointer as Fpayload ImGui::SetDragDropPayload(BRUSSEL_DRAG_DROP_SHADER, &shader, sizeof(shader)); // NOLINT(bugprone-sizeof-expression) ImGui::Text("Shader '%s'", name.c_str()); ImGui::EndDragDropSource(); } } } break; case P_Material: { if (ImGui::Button("New")) { int n = std::rand(); auto mat = new Material("Unnamed Material " + std::to_string(n)); auto guard = GuardDeletion(mat); auto [DISCARD, inserted] = MaterialManager::instance->SaveMaterial(mat); if (inserted) { guard.Dismiss(); } else { ImGui::AddNotification(ImGuiToast(ImGuiToastType_Error, "Failed to create material.")); } } ImGui::SameLine(); if (ImGui::Button("Refresh")) { // TODO } ImGui::SameLine(); if (ImGui::Button("Save all")) { auto& mats = MaterialManager::instance->GetMaterials(); for (auto&& [DISCARD, mat] : mats) { mat->SaveToFile(mat->GetDesignatedPath()); } } auto& mats = MaterialManager::instance->GetMaterials(); for (auto it = mats.begin(); it != mats.end(); ++it) { auto mat = it->second.Get(); auto& name = mat->GetName(); bool selected = mEditor->GetSelectedItPtr() == mat; if (ImGui::Selectable(name.c_str(), selected)) { mEditor->SelectIt(mat, EditorInstance::ITT_Material); } if (ImGui::BeginDragDropSource()) { // Reason: intentionally using pointer as payload ImGui::SetDragDropPayload(BRUSSEL_DRAG_DROP_MATERIAL, &mat, sizeof(mat)); // NOLINT(bugprone-sizeof-expression) ImGui::Text("Material '%s'", name.c_str()); ImGui::EndDragDropSource(); } } } break; case P_Ires: { if (ImGui::Button("New")) { ImGui::OpenPopup("NewIresMenu"); } if (ImGui::BeginPopup("NewIresMenu")) { for (int i = 0; i < IresObject::KD_COUNT; ++i) { auto kind = static_cast(i); if (ImGui::MenuItem(IresObject::ToString(kind).data())) { auto ires = IresObject::Create(kind); auto [DISCARD, success] = IresManager::instance->Add(ires.get()); if (success) { (void)ires.release(); } } } ImGui::EndPopup(); } auto& objects = IresManager::instance->GetObjects(); for (auto it = objects.begin(); it != objects.end(); ++it) { auto ires = it->second.Get(); auto& name = ires->GetName(); bool selected = mEditor->GetSelectedItPtr() == ires; if (ImGui::Selectable(name.c_str(), selected)) { mEditor->SelectIt(ires, EditorInstance::ITT_Ires); } } } break; } } ImGui::EndChild(); ImGui::End(); }