mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
Add module properties popup.
This commit is contained in:
parent
dc11cb33dd
commit
8aa18fa5af
7 changed files with 165 additions and 22 deletions
|
|
@ -34,6 +34,7 @@ public:
|
|||
|
||||
virtual void OpenProject(const std::string &uuid) = 0;
|
||||
virtual void SaveProject() = 0;
|
||||
virtual void SaveModule() = 0;
|
||||
virtual void ImportProject(const std::string &fileName, int format) = 0;
|
||||
virtual void Log(const std::string &txt, bool critical = false) = 0;
|
||||
virtual void PlaySoundFile(const std::string &fileName) = 0;
|
||||
|
|
@ -41,6 +42,7 @@ public:
|
|||
virtual void OpenFunction(const std::string &uuid, const std::string &name) = 0;
|
||||
|
||||
virtual std::shared_ptr<IStoryProject> GetCurrentProject() = 0;
|
||||
virtual std::shared_ptr<IStoryProject> GetCurrentModule() = 0;
|
||||
|
||||
// Node interaction
|
||||
virtual void BuildCode(bool compileonly) = 0;
|
||||
|
|
|
|||
|
|
@ -854,5 +854,10 @@ void AppController::ImportProject(const std::string &filePathName, int format)
|
|||
|
||||
std::shared_ptr<IStoryProject> AppController::GetCurrentProject()
|
||||
{
|
||||
return m_story; // Retourne le projet actuel
|
||||
return m_story;
|
||||
}
|
||||
|
||||
std::shared_ptr<IStoryProject> AppController::GetCurrentModule()
|
||||
{
|
||||
return m_module;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,20 +60,19 @@ public:
|
|||
void CloseProject();
|
||||
void SaveProject();
|
||||
std::shared_ptr<StoryProject> NewModule();
|
||||
void SaveModule();
|
||||
|
||||
void CloseModule();
|
||||
std::shared_ptr<StoryProject> OpenModule(const std::string &uuid);
|
||||
void OpenStory(const std::string &path = "");
|
||||
void SaveStory(const std::string &path = "");
|
||||
void ExportStory(const std::string &filename);
|
||||
std::shared_ptr<StoryProject> GetCurrentStory() const { return m_story; }
|
||||
std::shared_ptr<StoryProject> GetCurrentModule() const { return m_module; }
|
||||
void CompileNodes(IStoryProject::Type type);
|
||||
void Build(bool compileonly);
|
||||
void BuildModule(bool compileonly);
|
||||
void BuildCode(std::shared_ptr<StoryProject> story, bool compileonly, bool force = false);
|
||||
|
||||
// --- Fonctions de IStoryManager ---
|
||||
void SaveModule() override;
|
||||
virtual void SetExternalSourceFile(const std::string &filename) override;
|
||||
virtual void LoadBinaryStory(const std::string &filename) override;
|
||||
virtual void ToggleBreakpoint(int line) override;
|
||||
|
|
@ -90,6 +89,7 @@ public:
|
|||
virtual std::string VmState() const override;
|
||||
virtual void BuildCode(bool compileonly);
|
||||
virtual std::shared_ptr<IStoryProject> GetCurrentProject() override;
|
||||
virtual std::shared_ptr<IStoryProject> GetCurrentModule() override;
|
||||
|
||||
// --- Fonctions de IAudioEvent ---
|
||||
virtual void EndOfAudio() override;
|
||||
|
|
|
|||
116
story-editor/src/dialogs/module_properties_dialog.h
Normal file
116
story-editor/src/dialogs/module_properties_dialog.h
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
// module_properties_dialog.h
|
||||
#ifndef MODULE_PROPERTIES_DIALOG_H
|
||||
#define MODULE_PROPERTIES_DIALOG_H
|
||||
|
||||
#include "dialog_base.h"
|
||||
#include <string>
|
||||
#include "i_story_manager.h"
|
||||
#include "IconsMaterialDesignIcons.h"
|
||||
|
||||
class ModulePropertiesDialog : public DialogBase
|
||||
{
|
||||
public:
|
||||
ModulePropertiesDialog(IStoryManager &storyManager)
|
||||
: m_storyManager(storyManager)
|
||||
{
|
||||
m_module_name[0] = '\0';
|
||||
}
|
||||
|
||||
// Affiche le popup "Module Properties".
|
||||
// Doit être appelée à chaque frame dans la boucle de rendu ImGui.
|
||||
void Draw() override
|
||||
{
|
||||
auto module = m_storyManager.GetCurrentModule();
|
||||
if (module)
|
||||
{
|
||||
if (m_firstOpen)
|
||||
{
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
m_firstOpen = false;
|
||||
// Copy current module name to the edit buffer
|
||||
std::size_t length = module->GetName().copy(m_module_name, sizeof(m_module_name) - 1);
|
||||
m_module_name[length] = '\0';
|
||||
}
|
||||
DrawContent(module);
|
||||
}
|
||||
else
|
||||
{
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
IStoryManager &m_storyManager;
|
||||
char m_module_name[256] = "";
|
||||
|
||||
// Implémentation de la méthode virtuelle pure GetTitle()
|
||||
const char* GetTitle() const override
|
||||
{
|
||||
return "ModulePropertiesPopup";
|
||||
}
|
||||
|
||||
void DrawContent(std::shared_ptr<IStoryProject> module)
|
||||
{
|
||||
if (ImGui::BeginPopupModal(GetTitle(), nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
ImGui::Text(ICON_MDI_PUZZLE_OUTLINE " Module Properties");
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
// Module Name
|
||||
ImGui::Text("Module name:");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(300.0f);
|
||||
ImGui::InputTextWithHint("##module_name", "Enter module name", m_module_name, IM_ARRAYSIZE(m_module_name));
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
// Buttons
|
||||
if (ImGui::Button("OK", ImVec2(120, 0)))
|
||||
{
|
||||
// Validate and save
|
||||
if (strlen(m_module_name) > 0)
|
||||
{
|
||||
module->SetName(m_module_name);
|
||||
m_storyManager.SaveModule();
|
||||
ImGui::CloseCurrentPopup();
|
||||
Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show error: name cannot be empty
|
||||
ImGui::OpenPopup("EmptyNameError");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SetItemDefaultFocus();
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Cancel", ImVec2(120, 0)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
Reset();
|
||||
}
|
||||
|
||||
// Error popup for empty name
|
||||
if (ImGui::BeginPopupModal("EmptyNameError", NULL, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
ImGui::Text(ICON_MDI_ALERT " Module name cannot be empty!");
|
||||
ImGui::Spacing();
|
||||
if (ImGui::Button("OK", ImVec2(120, 0)))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // MODULE_PROPERTIES_DIALOG_H
|
||||
|
|
@ -58,7 +58,7 @@ private:
|
|||
|
||||
void DrawContent(std::shared_ptr<IStoryProject> story)
|
||||
{
|
||||
if (ImGui::BeginPopupModal(GetTitle(), NULL, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
if (ImGui::BeginPopupModal(GetTitle(), nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
|
||||
ImGui::Text("Project name: "); ImGui::SameLine();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "main_window.h"
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
|
||||
#include "main_window.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include "platform_folders.h"
|
||||
|
||||
|
|
@ -24,6 +26,7 @@
|
|||
|
||||
#include "app_controller.h"
|
||||
#include "all_events.h"
|
||||
#include "story_project.h"
|
||||
|
||||
#include "nodes_factory.h"
|
||||
#include "media_node_widget.h"
|
||||
|
|
@ -55,6 +58,7 @@ MainWindow::MainWindow(ILogger& logger, EventBus& eventBus, AppController& appCo
|
|||
, m_moduleEditorWindow(appController, appController.GetNodesFactory(), m_widgetFactory, IStoryProject::PROJECT_TYPE_MODULE)
|
||||
, m_libraryWindow(appController, appController.GetLibraryManager(), appController.GetNodesFactory(), eventBus)
|
||||
, m_projectPropertiesDialog(appController, appController.GetResourceManager())
|
||||
, m_modulePropertiesDialog(appController)
|
||||
{
|
||||
CloseProject();
|
||||
CloseModule();
|
||||
|
|
@ -174,12 +178,12 @@ float MainWindow::DrawMainMenuBar()
|
|||
{
|
||||
CloseProject();
|
||||
|
||||
m_story = m_appController.NewProject();
|
||||
auto newProject = m_appController.NewProject();
|
||||
|
||||
if (m_story)
|
||||
if (newProject)
|
||||
{
|
||||
m_appController.SaveProject();
|
||||
OpenProject(m_story->GetUuid());
|
||||
OpenProject(newProject->GetUuid());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,7 +205,7 @@ float MainWindow::DrawMainMenuBar()
|
|||
}
|
||||
*/
|
||||
|
||||
bool init = m_story ? true : false; // local copy because CloseProject() changes the status between BeginDisabled/EndDisabled
|
||||
bool init = m_nodeEditorWindow.GetCurrentStory() ? true : false; // local copy because CloseProject() changes the status between BeginDisabled/EndDisabled
|
||||
if (!init)
|
||||
ImGui::BeginDisabled();
|
||||
|
||||
|
|
@ -244,6 +248,11 @@ float MainWindow::DrawMainMenuBar()
|
|||
CloseModule();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Module settings"))
|
||||
{
|
||||
m_modulePropertiesDialog.Show();
|
||||
}
|
||||
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
|
@ -273,10 +282,14 @@ float MainWindow::DrawMainMenuBar()
|
|||
}
|
||||
|
||||
m_aboutDialog.Open();
|
||||
if (m_story)
|
||||
if (m_nodeEditorWindow.GetCurrentStory())
|
||||
{
|
||||
m_projectPropertiesDialog.Open();
|
||||
}
|
||||
if (m_moduleEditorWindow.GetCurrentStory())
|
||||
{
|
||||
m_modulePropertiesDialog.Open();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
|
@ -339,8 +352,9 @@ bool MainWindow::ShowQuitConfirm()
|
|||
|
||||
void MainWindow::OpenProject(const std::string &uuid)
|
||||
{
|
||||
m_nodeEditorWindow.Load(m_story);
|
||||
auto proj = m_story->GetProjectFilePath();
|
||||
auto p = dynamic_pointer_cast<StoryProject>(m_appController.GetCurrentProject());
|
||||
m_nodeEditorWindow.Load(p);
|
||||
auto proj = p->GetProjectFilePath();
|
||||
// Add to recent if not exists
|
||||
if (std::find(m_recentProjects.begin(), m_recentProjects.end(), proj) == m_recentProjects.end())
|
||||
{
|
||||
|
|
@ -452,9 +466,14 @@ void MainWindow::RefreshProjectInformation()
|
|||
{
|
||||
std::string fullText = "Story Editor " + LibraryManager::GetVersion();
|
||||
|
||||
if (m_story)
|
||||
auto p = m_nodeEditorWindow.GetCurrentStory();
|
||||
if (p)
|
||||
{
|
||||
fullText += " - " + m_story->GetProjectFilePath();
|
||||
auto proj = dynamic_pointer_cast<StoryProject>(p);
|
||||
if (proj)
|
||||
{
|
||||
fullText += " - " + proj->GetProjectFilePath();
|
||||
}
|
||||
}
|
||||
m_gui.SetWindowTitle(fullText);
|
||||
}
|
||||
|
|
@ -607,14 +626,14 @@ bool MainWindow::Loop()
|
|||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_S, false))
|
||||
{
|
||||
if (moduleEditorFocused && m_module)
|
||||
if (moduleEditorFocused && m_moduleEditorWindow.GetCurrentStory())
|
||||
{
|
||||
// Si l'éditeur de module a le focus, sauvegarder le module
|
||||
m_appController.SaveModule();
|
||||
m_toastNotifier.success("Module sauvegardé");
|
||||
m_logger.Log("Module sauvegardé via Ctrl+S");
|
||||
}
|
||||
else if (m_story)
|
||||
else if (m_nodeEditorWindow.GetCurrentStory())
|
||||
{
|
||||
// Sinon, sauvegarder l'histoire principale
|
||||
m_appController.SaveProject();
|
||||
|
|
@ -633,12 +652,12 @@ bool MainWindow::Loop()
|
|||
{
|
||||
bool moduleEditorFocused = m_moduleEditorWindow.IsFocused();
|
||||
|
||||
if (moduleEditorFocused && m_module)
|
||||
if (moduleEditorFocused && m_moduleEditorWindow.GetCurrentStory())
|
||||
{
|
||||
m_logger.Log("Building module...");
|
||||
m_appController.CompileNodes(IStoryProject::PROJECT_TYPE_MODULE);
|
||||
}
|
||||
else if (m_story)
|
||||
else if (m_nodeEditorWindow.GetCurrentStory())
|
||||
{
|
||||
m_logger.Log("Building story...");
|
||||
m_appController.CompileNodes(IStoryProject::PROJECT_TYPE_STORY);
|
||||
|
|
@ -648,6 +667,7 @@ bool MainWindow::Loop()
|
|||
|
||||
m_aboutDialog.Draw();
|
||||
m_projectPropertiesDialog.Draw();
|
||||
m_modulePropertiesDialog.Draw();
|
||||
|
||||
m_toastNotifier.render();
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
// Dialogs
|
||||
#include "about_dialog.h"
|
||||
#include "project_properties_dialog.h"
|
||||
#include "module_properties_dialog.h"
|
||||
|
||||
#include "event_bus.h"
|
||||
#include "app_controller.h"
|
||||
|
|
@ -31,6 +32,7 @@
|
|||
#include "LanguageSelector.h"
|
||||
#include "chip32_machine.h"
|
||||
|
||||
|
||||
class MainWindow : public std::enable_shared_from_this<MainWindow>, public ILogSubject
|
||||
{
|
||||
public:
|
||||
|
|
@ -48,9 +50,6 @@ private:
|
|||
AppController &m_appController; // Controller for application logic
|
||||
NodeWidgetFactory m_widgetFactory;
|
||||
|
||||
std::shared_ptr<StoryProject> m_story; // Current story
|
||||
std::shared_ptr<StoryProject> m_module; // Current module
|
||||
|
||||
std::vector<std::string> m_recentProjects;
|
||||
|
||||
Gui m_gui;
|
||||
|
|
@ -69,6 +68,7 @@ private:
|
|||
// Dialogs
|
||||
AboutDialog m_aboutDialog;
|
||||
ProjectPropertiesDialog m_projectPropertiesDialog;
|
||||
ModulePropertiesDialog m_modulePropertiesDialog;
|
||||
|
||||
ImGuiToastNotifier m_toastNotifier;
|
||||
LanguageSelector m_languageSelector;
|
||||
|
|
|
|||
Loading…
Reference in a new issue