Load/Save dialogues implemented
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
#include "../ui/RenderableEditor.hpp"
|
||||
#include <imgui.h>
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <cstring>
|
||||
|
||||
EditorUISystem::EditorUISystem(flecs::world &world,
|
||||
Ogre::SceneManager *sceneMgr)
|
||||
@@ -115,6 +117,11 @@ void EditorUISystem::update()
|
||||
if (m_gizmo && m_gizmo->isAttached()) {
|
||||
m_gizmo->update();
|
||||
}
|
||||
|
||||
// Render file dialog if open
|
||||
if (m_showFileDialog) {
|
||||
renderFileDialog();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorUISystem::setSelectedEntity(flecs::entity entity)
|
||||
@@ -149,11 +156,11 @@ void EditorUISystem::renderHierarchyWindow()
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
// File menu
|
||||
if (ImGui::BeginMenu("File")) {
|
||||
if (ImGui::MenuItem("Save Scene", "Ctrl+S")) {
|
||||
saveScene("scene.json");
|
||||
if (ImGui::MenuItem("Save Scene...", "Ctrl+S")) {
|
||||
showFileDialog(true);
|
||||
}
|
||||
if (ImGui::MenuItem("Load Scene", "Ctrl+O")) {
|
||||
loadScene("scene.json");
|
||||
if (ImGui::MenuItem("Load Scene...", "Ctrl+O")) {
|
||||
showFileDialog(false);
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@@ -703,3 +710,145 @@ void EditorUISystem::loadScene(const std::string& filepath)
|
||||
"Failed to load scene: " + m_serializer->getLastError());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// File Dialog Implementation
|
||||
|
||||
void EditorUISystem::showFileDialog(bool isSave)
|
||||
{
|
||||
m_showFileDialog = true;
|
||||
m_fileDialogIsSave = isSave;
|
||||
m_refreshDirectory = true;
|
||||
|
||||
// Initialize current path if empty
|
||||
if (m_currentPath.empty()) {
|
||||
m_currentPath = std::filesystem::current_path().string();
|
||||
}
|
||||
|
||||
// Set default filename for save dialog
|
||||
if (isSave && strlen(m_filenameBuffer) == 0) {
|
||||
std::strncpy(m_filenameBuffer, "scene.json", sizeof(m_filenameBuffer) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorUISystem::closeFileDialog()
|
||||
{
|
||||
m_showFileDialog = false;
|
||||
}
|
||||
|
||||
void EditorUISystem::renderFileDialog()
|
||||
{
|
||||
const char* title = m_fileDialogIsSave ? "Save Scene" : "Load Scene";
|
||||
|
||||
// Center the dialog
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowSize(ImVec2(500, 400), ImGuiCond_FirstUseEver);
|
||||
|
||||
if (!ImGui::Begin(title, &m_showFileDialog)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
// Current path display
|
||||
ImGui::Text("Location: %s", m_currentPath.c_str());
|
||||
ImGui::Separator();
|
||||
|
||||
// Refresh directory contents if needed
|
||||
if (m_refreshDirectory) {
|
||||
m_directoryContents.clear();
|
||||
try {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(m_currentPath)) {
|
||||
m_directoryContents.push_back(entry.path().filename().string());
|
||||
}
|
||||
std::sort(m_directoryContents.begin(), m_directoryContents.end());
|
||||
} catch (...) {
|
||||
// Ignore errors (e.g., permission denied)
|
||||
}
|
||||
m_refreshDirectory = false;
|
||||
}
|
||||
|
||||
// Parent directory button
|
||||
if (ImGui::Button("..")) {
|
||||
std::filesystem::path p(m_currentPath);
|
||||
if (p.has_parent_path()) {
|
||||
m_currentPath = p.parent_path().string();
|
||||
m_refreshDirectory = true;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("(Parent Directory)");
|
||||
|
||||
// File list
|
||||
ImGui::BeginChild("FileList", ImVec2(0, -60), true);
|
||||
|
||||
for (const auto& name : m_directoryContents) {
|
||||
std::filesystem::path fullPath = std::filesystem::path(m_currentPath) / name;
|
||||
bool isDirectory = std::filesystem::is_directory(fullPath);
|
||||
|
||||
// Skip non-json files in load mode (but show directories)
|
||||
if (!m_fileDialogIsSave && !isDirectory) {
|
||||
if (fullPath.extension() != ".json") {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::string label = isDirectory ? "[D] " + name : name;
|
||||
|
||||
if (ImGui::Selectable(label.c_str(), m_selectedFile == name)) {
|
||||
if (isDirectory) {
|
||||
m_currentPath = fullPath.string();
|
||||
m_refreshDirectory = true;
|
||||
m_selectedFile.clear();
|
||||
} else {
|
||||
m_selectedFile = name;
|
||||
std::strncpy(m_filenameBuffer, name.c_str(), sizeof(m_filenameBuffer) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Double-click to enter directory or select file
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
|
||||
if (isDirectory) {
|
||||
m_currentPath = fullPath.string();
|
||||
m_refreshDirectory = true;
|
||||
m_selectedFile.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
// Filename input
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Filename:");
|
||||
ImGui::SameLine();
|
||||
ImGui::InputText("##filename", m_filenameBuffer, sizeof(m_filenameBuffer));
|
||||
|
||||
// Buttons
|
||||
if (ImGui::Button(m_fileDialogIsSave ? "Save" : "Load", ImVec2(120, 0))) {
|
||||
std::string filename(m_filenameBuffer);
|
||||
if (!filename.empty()) {
|
||||
// Add .json extension if missing in save mode
|
||||
if (m_fileDialogIsSave && filename.find('.') == std::string::npos) {
|
||||
filename += ".json";
|
||||
}
|
||||
|
||||
std::string fullPath = (std::filesystem::path(m_currentPath) / filename).string();
|
||||
|
||||
if (m_fileDialogIsSave) {
|
||||
saveScene(fullPath);
|
||||
} else {
|
||||
loadScene(fullPath);
|
||||
}
|
||||
closeFileDialog();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Cancel", ImVec2(120, 0))) {
|
||||
closeFileDialog();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <Ogre.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../ui/ComponentRegistry.hpp"
|
||||
#include "../components/EntityName.hpp"
|
||||
#include "../gizmo/Gizmo.hpp"
|
||||
@@ -75,6 +76,13 @@ public:
|
||||
*/
|
||||
void loadScene(const std::string& filepath);
|
||||
|
||||
/**
|
||||
* Show file dialog for save/load
|
||||
*/
|
||||
void showFileDialog(bool isSave);
|
||||
void renderFileDialog();
|
||||
void closeFileDialog();
|
||||
|
||||
private:
|
||||
// File menu
|
||||
void renderFileMenu();
|
||||
@@ -116,6 +124,15 @@ private:
|
||||
// Settings
|
||||
bool m_parentSceneNodes = true; // Whether child entities inherit parent's SceneNode
|
||||
|
||||
// File dialog state
|
||||
bool m_showFileDialog = false;
|
||||
bool m_fileDialogIsSave = false; // true = save, false = load
|
||||
std::string m_currentPath;
|
||||
std::string m_selectedFile;
|
||||
std::vector<std::string> m_directoryContents;
|
||||
bool m_refreshDirectory = true;
|
||||
char m_filenameBuffer[256] = "scene.json";
|
||||
|
||||
// Queries
|
||||
flecs::query<EntityNameComponent> m_nameQuery;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user