294 lines
8.1 KiB
C++
Executable File

#include "SceneExplorer.h"
#include <regex>
#include <string>
#include "Deer/DataStore.h"
#include "Deer/Log.h"
#include "Deer/Path.h"
#include "Deer/Scene.h"
#include "DeerRender/Render/Texture.h"
#include "DeerStudio/Editor/ActiveEntity.h"
#include "DeerStudio/Project.h"
#include "EditorUtils.h"
#include "Icons.h"
#include "imgui.h"
namespace Deer {
Path m_currentScenePath("null");
Path m_currentSceneName;
Path m_loadSceneName;
Path m_deleteSceneName;
Path m_dialogSceneName;
void drawSceneExplorerFolder(const Path& path);
void drawSceneExplorerScene(const Path& path);
void saveSceneBeforeLoadingPopup();
void sceneDialogPopup();
void saveSceneName(const std::string&);
void createFolderName(const std::string& name);
void saveBeforeCreatingNew(bool save);
void saveSceneNameBeforeCreatingNew(const std::string& name);
void deleteScene();
void openFileExplorer(const std::string& relativePath);
void sceneExplorer_onImGUI() {
if (m_currentScenePath == "null")
m_currentScenePath = DataStore::rootPath / DEER_SCENE_PATH;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 10));
ImGui::Begin("Scene Explorer", (bool*)0, ImGuiWindowFlags_MenuBar);
ImGui::PopStyleVar();
if (ImGui::BeginMenuBar()) {
if (ImGui::MenuItem("Save")) {
if (m_currentSceneName == "")
ImGui::OpenPopup("SAVE_SCENE_NAME");
else
DataStore::exportScene(Project::m_scene,
m_currentSceneName);
}
if (ImGui::MenuItem("Save as")) {
ImGui::OpenPopup("SAVE_SCENE_NAME");
}
if (ImGui::MenuItem("New Scene")) {
ImGui::OpenPopup("SAVE_SCENE_BEFORE_CREATING_NEW");
}
if (ImGui::MenuItem("New folder")) {
ImGui::OpenPopup("CREATE_SCENE_FOLDER");
}
if (ImGui::MenuItem("Explorer")) {
openFileExplorer(m_currentScenePath.generic_string());
}
stringInputPopup<saveSceneName>("SAVE_SCENE_NAME", "Scene name");
stringInputPopup<createFolderName>("CREATE_SCENE_FOLDER",
"Folder name");
saveInputPopup<saveBeforeCreatingNew>(
"SAVE_SCENE_BEFORE_CREATING_NEW",
"Do you want to save the scene before creating new?");
stringInputPopup<saveSceneNameBeforeCreatingNew>(
"SAVE_SCENE_NAME_CREATE_NEW", "Scene name");
ImGui::EndMenuBar();
}
ImGui::Text("%s", m_currentScenePath.generic_string().c_str());
ImGui::TextDisabled("Active Scene : ");
ImGui::SameLine();
ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.7f, 1), "%s",
m_currentSceneName.generic_string().c_str());
setupColumns(ICON_MIN_SIZE + 80);
if (m_currentScenePath != DEER_SCENE_PATH) {
drawSceneExplorerFolder("..");
float cursorOffset =
(ICON_MIN_SIZE - ImGui::CalcTextSize("..").x) / 2;
ImGui::SetCursorPos(ImVec2(cursorOffset + ImGui::GetCursorPos().x,
ImGui::GetCursorPos().y));
ImGui::Text("..");
ImGui::NextColumn();
}
for (const auto& entry :
std::filesystem::directory_iterator(m_currentScenePath)) {
if (entry.is_directory())
drawSceneExplorerFolder(entry.path());
else {
std::string extension =
entry.path().filename().extension().string();
if (extension != ".dscn") continue;
Path sceneName = entry.path().parent_path().lexically_relative(
DEER_SCENE_PATH) /
entry.path().stem();
drawSceneExplorerScene(sceneName);
}
float cursorOffset =
(ICON_MIN_SIZE -
ImGui::CalcTextSize(entry.path().stem().string().c_str()).x) /
2;
ImGui::SetCursorPos(ImVec2(cursorOffset + ImGui::GetCursorPos().x,
ImGui::GetCursorPos().y));
ImGui::Text("%s", entry.path().stem().string().c_str());
ImGui::NextColumn();
}
ImGui::Columns();
saveSceneBeforeLoadingPopup();
sceneDialogPopup();
deleteInputPopup<deleteScene>(
"DELETE_SCENE", "Are you sure you want to delete the scene?");
ImGui::End();
}
void drawSceneExplorerFolder(const Path& path) {
ImGui::Image((void*)(uint64_t)Icons::folder_icon->getTextureID(),
ImVec2(ICON_MIN_SIZE, ICON_MIN_SIZE), ImVec2(0, 1),
ImVec2(1, 0));
if (ImGui::IsItemClicked(0) && ImGui::IsMouseDoubleClicked(0)) {
if (path == "..")
m_currentScenePath = m_currentScenePath.parent_path();
else
m_currentScenePath = path;
}
}
void drawSceneExplorerScene(const Path& path) {
ImGui::Image((void*)(uint64_t)Icons::scene_icon->getTextureID(),
ImVec2(ICON_MIN_SIZE, ICON_MIN_SIZE), ImVec2(0, 1),
ImVec2(1, 0));
if (ImGui::IsItemClicked(0) && ImGui::IsMouseDoubleClicked(0)) {
ImGui::OpenPopup("SAVE_SCENE_BEFORE_LOADING");
m_loadSceneName = path;
}
if (ImGui::IsItemClicked(1)) {
ImGui::OpenPopup("SCENE_DIALOG");
m_dialogSceneName = path;
}
}
std::string sanitizeInput(const std::string& input) {
std::string sanitized;
for (char c : input) {
if (isalnum(c) || c == '_') {
sanitized += c;
}
}
return sanitized;
}
void saveSceneBeforeLoadingPopup() {
if (ImGui::BeginPopup("SAVE_SCENE_BEFORE_LOADING")) {
if (m_currentSceneName == "") {
DataStore::loadScene(Project::m_scene, m_loadSceneName);
m_currentSceneName = m_loadSceneName;
ImGui::CloseCurrentPopup();
}
ImGui::Text("Do you want to save the current scene?");
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(100, 255, 120, 255));
bool save = ImGui::Button("Save");
ImGui::PopStyleColor();
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 100, 120, 255));
ImGui::SameLine();
bool dont_save = ImGui::Button("Don't save");
ImGui::PopStyleColor();
ImGui::SameLine();
bool cancel = ImGui::Button("Cancel");
if (save) {
ActiveEntity::clear();
DataStore::exportScene(Project::m_scene, m_currentSceneName);
DataStore::loadScene(Project::m_scene, m_loadSceneName);
m_currentSceneName = m_loadSceneName;
ImGui::CloseCurrentPopup();
} else if (dont_save) {
ActiveEntity::clear();
DataStore::loadScene(Project::m_scene, m_loadSceneName);
m_currentSceneName = m_loadSceneName;
ImGui::CloseCurrentPopup();
}
if (cancel) {
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
void sceneDialogPopup() {
if (ImGui::BeginPopup("SCENE_DIALOG")) {
if (ImGui::MenuItem("Rename Scene")) {
ImGui::CloseCurrentPopup();
}
if (ImGui::MenuItem("Delete Scene")) {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
ImGui::OpenPopup("DELETE_SCENE");
m_deleteSceneName = m_dialogSceneName;
return;
}
ImGui::EndPopup();
}
}
// Implement delete scene
void deleteScene() {}
void createFolderName(const std::string& name) {
std::string correctInput = sanitizeInput(name);
if (name.size() != 0) {
DataStore::createFolder(m_currentScenePath / correctInput);
}
}
void saveSceneName(const std::string& name) {
std::string correctInput = sanitizeInput(name);
if (name.size() != 0) {
Path fullName;
if (m_currentScenePath == DEER_SCENE_PATH)
fullName = correctInput;
else
fullName =
m_currentScenePath.lexically_relative(DEER_SCENE_PATH) /
correctInput;
m_currentSceneName = fullName;
DataStore::exportScene(Project::m_scene, fullName);
}
}
void saveBeforeCreatingNew(bool save) {
if (save) {
if (m_currentSceneName == "") {
ImGui::OpenPopup("SAVE_SCENE_NAME_CREATE_NEW");
return;
} else {
ActiveEntity::clear();
DataStore::exportScene(Project::m_scene, m_currentSceneName);
Project::m_scene.clear();
m_currentSceneName = Path();
}
} else {
ActiveEntity::clear();
Project::m_scene.clear();
m_currentSceneName = Path();
}
}
void saveSceneNameBeforeCreatingNew(const std::string& name) {
std::string correctInput = sanitizeInput(name);
if (name.size() != 0) {
Path fullName;
if (m_currentScenePath == DEER_SCENE_PATH)
fullName = correctInput;
else
fullName =
m_currentScenePath.lexically_relative(DEER_SCENE_PATH) /
correctInput;
DataStore::exportScene(Project::m_scene, fullName);
ActiveEntity::clear();
Project::m_scene.clear();
m_currentSceneName = Path();
}
}
} // namespace Deer