diff --git a/core/story-manager/interfaces/i_story_manager.h b/core/story-manager/interfaces/i_story_manager.h index 9b1a143..a7958e7 100644 --- a/core/story-manager/interfaces/i_story_manager.h +++ b/core/story-manager/interfaces/i_story_manager.h @@ -33,12 +33,15 @@ public: virtual ~IStoryManager() {} virtual void OpenProject(const std::string &uuid) = 0; + virtual void SaveProject() = 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; virtual std::string BuildFullAssetsPath(const std::string_view fileName) const = 0; virtual void OpenFunction(const std::string &uuid, const std::string &name) = 0; + virtual std::shared_ptr GetCurrentProject() = 0; + // Modules virtual void OpenModule(const std::string &uuid) = 0; diff --git a/core/story-manager/interfaces/i_story_project.h b/core/story-manager/interfaces/i_story_project.h index 422a547..f12727c 100644 --- a/core/story-manager/interfaces/i_story_project.h +++ b/core/story-manager/interfaces/i_story_project.h @@ -13,14 +13,30 @@ public: { PROJECT_TYPE_STORY = 0, PROJECT_TYPE_MODULE = 1, + PROJECT_TYPE_PRIMITIVE = 2 }; virtual ~IStoryProject() {}; virtual std::string GetName() const = 0; virtual std::string GetDescription() const = 0; + virtual Type GetProjectType() const = 0; virtual bool IsModule() const = 0; virtual std::string GetUuid() const = 0; + virtual std::string GetTitleImage() const = 0; + virtual std::string GetTitleSound() const = 0; + + virtual void SetTitleImage(const std::string &titleImage) = 0; + virtual void SetTitleSound(const std::string &titleSound) = 0; + virtual void SetDescription(const std::string &description) = 0; + virtual void SetProjectType(Type type) = 0; + virtual void SetImageFormat(Resource::ImageFormat format) = 0; + virtual void SetSoundFormat(Resource::SoundFormat format) = 0; + virtual void SetDisplayFormat(int w, int h) = 0; + virtual void SetName(const std::string &name) = 0; + virtual void SetUuid(const std::string &uuid) = 0; + + }; diff --git a/core/story-manager/src/story_primitive.h b/core/story-manager/src/story_primitive.h index 4c0ad97..90ce5e1 100644 --- a/core/story-manager/src/story_primitive.h +++ b/core/story-manager/src/story_primitive.h @@ -36,8 +36,50 @@ public: return m_uuid; } + + + virtual std::string GetTitleImage() const { + return ""; // No title image by default + } + virtual std::string GetTitleSound() const { + return ""; // No title sound by default + } + virtual Type GetProjectType() const { + return Type::PROJECT_TYPE_PRIMITIVE; + } + virtual void SetTitleImage(const std::string &titleImage) { + (void)titleImage; // No title image to set + } + virtual void SetTitleSound(const std::string &titleSound) { + (void)titleSound; // No title sound to set + } + virtual void SetDescription(const std::string &description) { + m_description = description; + } + virtual void SetProjectType(Type type) { + (void)type; // Project type is fixed for primitives + } + virtual void SetImageFormat(Resource::ImageFormat format) { + (void)format; // Image format is fixed for primitives + } + virtual void SetSoundFormat(Resource::SoundFormat format) { + (void)format; // Sound format is fixed for primitives + } + virtual void SetDisplayFormat(int w, int h) { + (void)w; // Display width is fixed for primitives + (void)h; // Display height is fixed for primitives + } + virtual void SetName(const std::string &name) { + m_name = name; + } + virtual void SetUuid(const std::string &uuid) { + m_uuid = uuid; + } + private: std::string m_name; std::string m_description; std::string m_uuid; + std::string m_titleImage; + std::string m_titleSound; }; \ No newline at end of file diff --git a/core/story-manager/src/story_project.h b/core/story-manager/src/story_project.h index 8c5433b..0008961 100644 --- a/core/story-manager/src/story_project.h +++ b/core/story-manager/src/story_project.h @@ -60,17 +60,10 @@ public: void Select(bool selected) { m_selected = selected; } bool IsSelected() const { return m_selected; } - - void SetImageFormat(Resource::ImageFormat format); - void SetSoundFormat(Resource::SoundFormat format); - - void SetDisplayFormat(int w, int h); - void SetName(const std::string &name) { m_name = name; } - void SetUuid(const std::string &uuid) { m_uuid = uuid; } std::string GetProjectFilePath() const; std::string GetWorkingDir() const; - virtual std::string GetName() const override { return m_name; } + std::string GetUuid() const { return m_uuid; } std::string GetDescription() const { return m_description; } uint32_t GetVersion() const { return m_version; } @@ -83,14 +76,11 @@ public: void SetTitleSound(const std::string &titleSound); void SetDescription(const std::string &description) { m_description = description; } - std::string GetTitleImage() const { return m_titleImage; } - std::string GetTitleSound() const { return m_titleSound; } - // Initialize with an existing project bool IsInitialized() const { return m_initialized; } bool IsModule() const override { return m_projectType == IStoryProject::PROJECT_TYPE_MODULE; } bool IsStory() const { return m_projectType == IStoryProject::PROJECT_TYPE_STORY; } - void SetProjectType(IStoryProject::Type type) { m_projectType = type; } + bool ParseStoryInformation(nlohmann::json &j); @@ -99,6 +89,16 @@ public: virtual int OutputsCount(const std::string &nodeId); StoryOptions GetOptions() { return m_storyOptions; } virtual bool UseResource(const std::string &label); + virtual std::string GetName() const override { return m_name; } + virtual std::string GetTitleImage() const override { return m_titleImage; } + virtual std::string GetTitleSound() const override { return m_titleSound; } + virtual void SetProjectType(IStoryProject::Type type) override { m_projectType = type; } + virtual void SetImageFormat(Resource::ImageFormat format) override; + virtual void SetSoundFormat(Resource::SoundFormat format) override; + virtual void SetDisplayFormat(int w, int h) override; + virtual void SetName(const std::string &name) override { m_name = name; } + virtual void SetUuid(const std::string &uuid) override { m_uuid = uuid; } + virtual Type GetProjectType() const override { return m_projectType; } // Node interaction std::shared_ptr CreatePage(const std::string &uuid); diff --git a/story-editor/CMakeLists.txt b/story-editor/CMakeLists.txt index 09bb7f1..06f3e6e 100644 --- a/story-editor/CMakeLists.txt +++ b/story-editor/CMakeLists.txt @@ -125,7 +125,6 @@ set(SRCS src/windows/window_base.cpp src/windows/console_window.cpp src/windows/library_window.cpp - src/windows/resources_window.cpp src/windows/properties_window.cpp src/windows/debugger_window.cpp src/windows/cpu_window.cpp @@ -133,6 +132,7 @@ set(SRCS ## Docks src/docks/emulator_dock.cpp + src/docks/resources_dock.cpp # src/node_editor/media_node_widget.cpp src/node_editor/base_node_widget.cpp diff --git a/story-editor/src/app/app_controller.cpp b/story-editor/src/app/app_controller.cpp index be1527c..ffba8d7 100644 --- a/story-editor/src/app/app_controller.cpp +++ b/story-editor/src/app/app_controller.cpp @@ -62,33 +62,6 @@ #endif -// Implémentation du callback pour le syscall de la VM -// C'est un peu délicat avec une fonction membre. -// Une solution courante est d'utiliser un 'trampoline' ou std::function. -// Pour ce projet, nous allons faire une adaptation simple en passant 'this' -// via un mécanisme global ou un wrapper. L'approche originale de MainWindow -// utilisait une classe Callback statique, que nous allons adapter ici. - -// Classe trampoline pour les syscalls de la VM -// Ceci est une version simplifiée. Dans un système plus robuste, vous pourriez -// vouloir un registre de callbacks ou une approche plus souple. -class SyscallTrampoline -{ -public: - static AppController* s_instance; // Pointer vers l'instance de AppController - - static uint8_t Callback(chip32_ctx_t *ctx, uint8_t code) - { - if (s_instance) - { - return s_instance->Syscall(ctx, code); - } - return SYSCALL_RET_OK; // Ou gérer l'erreur - } -}; -AppController* SyscallTrampoline::s_instance = nullptr; - - AppController::AppController(ILogger& logger, EventBus& eventBus) : m_logger(logger) , m_eventBus(eventBus) // m_eventBus pour les événements @@ -348,6 +321,26 @@ void AppController::BuildCode(std::shared_ptr story, bool compileo } } + +void AppController::BuildCode(bool compileonly) +{ + m_currentCode = SysLib::ReadFile(m_externalSourceFileName); + // m_debuggerWindow.SetScript(m_currentCode); // FIXME: GUI event + Build(compileonly); +} + + +void AppController::BuildNodes(bool compileonly) +{ + if (m_story->GenerateScript(m_currentCode)) + { + // m_debuggerWindow.SetScript(m_currentCode); // FIXME: GUI event + Build(compileonly); + } +} + + + void AppController::SetExternalSourceFile(const std::string &filename) { m_externalSourceFileName = filename; @@ -762,11 +755,11 @@ uint8_t AppController::Syscall(chip32_ctx_t *ctx, uint8_t code) std::string imageFile = m_story->BuildFullAssetsPath(GetStringFromMemory(ctx->registers[R0])); m_logger.Log("Image: " + imageFile); // Ici, vous notifieriez la fenêtre de l'émulateur - // m_emulatorWindow.SetImage(imageFile); // Ceci est une dépendance GUI + // m_emulatorDock.SetImage(imageFile); // Ceci est une dépendance GUI } else { - // m_emulatorWindow.ClearImage(); // Dépendance GUI + // m_emulatorDock.ClearImage(); // Dépendance GUI } if (ctx->registers[R1] != 0) @@ -865,6 +858,7 @@ void AppController::CloseProject() m_story->Clear(); // Clear story resources/data m_story.reset(); // Release shared_ptr } + m_resources.Clear(); // Clear VM state m_dbg.run_result = VM_FINISHED; @@ -875,24 +869,21 @@ void AppController::CloseProject() m_resources.Clear(); // Clear loaded resources m_eventQueue.clear(); // Clear any pending VM events - // Notify GUI (or specific windows) to clear/disable project-related data - // These would be events or direct calls from AppController to GUI objects - // m_nodeEditorWindow.Clear(); - // m_emulatorWindow.ClearImage(); - // m_consoleWindow.ClearLog(); - // m_debuggerWindow.ClearErrors(); - // m_debuggerWindow.SetScript(""); - // m_nodeEditorWindow.Disable(); - // m_emulatorWindow.Disable(); - // m_debuggerWindow.Disable(); - // m_resourcesWindow.Disable(); - // m_PropertiesWindow.Disable(); - // m_variablesWindow.Disable(); - // m_cpuWindow.Disable(); - m_logger.Log("Project closed."); } +void AppController::SaveProject() +{ + if (m_story) + { + m_story->Save(m_resources); + m_libraryManager.Scan(); // Add new project to library + m_logger.Log("Project saved: " + m_story->GetProjectFilePath()); + } else { + m_logger.Log("No project open to save.", true); + } +} + void AppController::NewModule() { m_module = m_nodesFactory.NewModule(); @@ -941,7 +932,7 @@ void AppController::CloseModule() void AppController::ImportProject(const std::string &filePathName, int format) { (void) format; // Not used in the original snippet but kept for signature. - PackArchive archive(*this, m_nodesFactory); // PackArchive constructor might need an ILogger, adjust if needed + PackArchive archive(m_logger, m_nodesFactory); // PackArchive constructor might need an ILogger, adjust if needed auto ext = SysLib::GetFileExtension(filePathName); auto filename = SysLib::GetFileName(filePathName); @@ -962,12 +953,7 @@ void AppController::ImportProject(const std::string &filePathName, int format) } } -std::pair AppController::Images() +std::shared_ptr AppController::GetCurrentProject() { - return m_resources.Images(); -} - -std::pair AppController::Sounds() -{ - return m_resources.Sounds(); + return m_story; // Retourne le projet actuel } diff --git a/story-editor/src/app/app_controller.h b/story-editor/src/app/app_controller.h index 673e004..f6ae258 100644 --- a/story-editor/src/app/app_controller.h +++ b/story-editor/src/app/app_controller.h @@ -48,6 +48,7 @@ public: // Initialisation de l'AppController bool Initialize(); + std::shared_ptr NewProject() { return m_libraryManager.NewProject(); } void OpenProject(const std::string &uuid); void ImportProject(const std::string &fileName, int format); void Log(const std::string &txt, bool critical = false) override; @@ -56,6 +57,7 @@ public: void OpenFunction(const std::string &uuid, const std::string &name); void NewStory(); void CloseProject(); + void SaveProject(); void NewModule(); void SaveModule(); void CloseModule(); @@ -87,6 +89,9 @@ public: virtual void Next() override; virtual void Previous() override; virtual std::string VmState() const override; + virtual void BuildNodes(bool compileonly); + virtual void BuildCode(bool compileonly); + virtual std::shared_ptr GetCurrentProject() override; // --- Fonctions de IAudioEvent --- virtual void EndOfAudio() override; @@ -117,9 +122,6 @@ public: // Méthode pour mettre à jour l'état de la vue VM (peut être un événement notifié à la GUI) void UpdateVmView(); - virtual std::pair Images() override; - virtual std::pair Sounds() override; - private: ILogger& m_logger; // Référence au logger pour les messages métier EventBus& m_eventBus; // Bus d'événements pour la communication entre composants diff --git a/story-editor/src/dialogs/about_dialog.h b/story-editor/src/dialogs/about_dialog.h index 5ee708a..59c9b88 100644 --- a/story-editor/src/dialogs/about_dialog.h +++ b/story-editor/src/dialogs/about_dialog.h @@ -2,16 +2,12 @@ #ifndef ABOUT_DIALOG_H #define ABOUT_DIALOG_H -#include "imgui.h" // Nécessaire pour ImGui::BeginPopupModal, ImGui::Text, etc. +#include "dialog_base.h" // Pour DialogBase #include // Pour std::string #include "library_manager.h" // Pour LibraryManager::GetVersion() -#include // Pour SDL_GetPlatform(), SDL_GetNumLogicalCPUCores(), SDL_GetSystemRAM() +#include -// Il est important de noter que cette classe AboutDialog -// dépendra de ImGui et de SDL pour afficher les informations -// système, comme c'est le cas dans le code original de MainWindow. - -class AboutDialog +class AboutDialog : public DialogBase { public: AboutDialog() = default; @@ -24,7 +20,7 @@ public: ImVec2 center = ImGui::GetMainViewport()->GetCenter(); ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); - if (ImGui::BeginPopupModal("AboutPopup", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) + if (ImGui::BeginPopupModal(GetTitle(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("Story Editor - v%s", LibraryManager::GetVersion().c_str()); ImGui::Text("http://www.openstoryteller.org"); @@ -41,33 +37,19 @@ public: if (ImGui::Button("Close", ImVec2(100, 35))) { ImGui::CloseCurrentPopup(); + Reset(); // Cache le popup après la fermeture } ImGui::EndPopup(); } } - // Ouvre le popup "About". - // Doit être appelée lorsque l'utilisateur clique sur "About" dans le menu. - void Open() - { - if (m_showAboutPopup) - { - ImGui::OpenPopup("AboutPopup"); - } - } - - void Show() - { - m_showAboutPopup = true; - } - - void Reset() - { - m_showAboutPopup = false; - } private: - bool m_showAboutPopup = false; // Indique si le popup "About" doit être affiché + // Implémentation de la méthode virtuelle pure GetTitle() + const char* GetTitle() const override + { + return "AboutPopup"; + } }; #endif // ABOUT_DIALOG_H \ No newline at end of file diff --git a/story-editor/src/dialogs/dialog_base.h b/story-editor/src/dialogs/dialog_base.h new file mode 100644 index 0000000..ed23b1c --- /dev/null +++ b/story-editor/src/dialogs/dialog_base.h @@ -0,0 +1,49 @@ +// dialog_base.h +#ifndef DIALOG_BASE_H +#define DIALOG_BASE_H + +#include "imgui.h" // Nécessaire pour ImGui::BeginPopupModal + +class DialogBase +{ +public: + virtual ~DialogBase() = default; + + // Affiche le contenu de la fenêtre de dialogue. + // Cette méthode est virtuelle pure et doit être implémentée par les classes dérivées. + virtual void Draw() = 0; + + // Ouvre le popup de la fenêtre de dialogue. + // Note: Ceci ne rend pas le dialogue visible tant que Draw() n'est pas appelé. + // Cette méthode est utilisée pour les popups modaux ImGui. + void Open() + { + if (m_show) + { + ImGui::OpenPopup(GetTitle()); + } + } + + // Rend le dialogue visible au prochain appel de Draw(). + void Show() + { + m_show = true; + m_firstOpen = true; + } + + // Cache le dialogue au prochain appel de Draw(). + void Reset() + { + m_show = false; + m_firstOpen = false; + } + +protected: + // Permet d'accéder au titre pour l'ouverture du popup. + virtual const char* GetTitle() const = 0; + + bool m_show = false; + bool m_firstOpen = false; +}; + +#endif // DIALOG_BASE_H \ No newline at end of file diff --git a/story-editor/src/dialogs/project_properties_dialog.h b/story-editor/src/dialogs/project_properties_dialog.h new file mode 100644 index 0000000..814804e --- /dev/null +++ b/story-editor/src/dialogs/project_properties_dialog.h @@ -0,0 +1,269 @@ +// about_dialog.h +#ifndef PROJECT_PROPERTIES_DIALOG_H +#define PROJECT_PROPERTIES_DIALOG_H + +#include "dialog_base.h" // Pour DialogBase +#include // Pour std::string +#include "library_manager.h" // Pour LibraryManager::GetVersion() +#include // Pour SDL_GetPlatform(), SDL_GetNumLogicalCPUCores(), SDL_GetSystemRAM() +#include "i_story_manager.h" +#include "IconsMaterialDesignIcons.h" + +class ProjectPropertiesDialog : public DialogBase +{ +public: + ProjectPropertiesDialog(IStoryManager &story, ResourceManager &resources) + : m_storyManager(story) + , m_resources(resources) + { + m_project_name[0] = '\0'; + } + + // Affiche le popup "Project Properties". + // Doit être appelée à chaque frame dans la boucle de rendu ImGui. + void Draw() + { + auto story = m_storyManager.GetCurrentProject(); + if (story) + { + if (m_firstOpen) + { + ImVec2 center = ImGui::GetMainViewport()->GetCenter(); + ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); + m_firstOpen = false; + std::size_t length = story->GetName().copy(m_project_name, sizeof(m_project_name)); + m_project_name[length] = '\0'; + } + DrawContent(story); + } + else + { + Reset(); + return; + } + + } +private: + IStoryManager &m_storyManager; + ResourceManager &m_resources; + char m_project_name[256] = ""; + + + // Implémentation de la méthode virtuelle pure GetTitle() + const char* GetTitle() const override + { + return "ProjectPropertiesPopup"; + } + + + void DrawContent(std::shared_ptr story) + { + if (ImGui::BeginPopupModal(GetTitle(), NULL, ImGuiWindowFlags_AlwaysAutoResize)) + { + + ImGui::Text("Project name: "); ImGui::SameLine(); + ImGui::InputTextWithHint("##project_name", "Project name", m_project_name, IM_ARRAYSIZE(m_project_name)); + + ImGui::Text("Size of display screen: "); + ImGui::SameLine(); + + static ImGuiComboFlags flags = 0; + + static int display_item_current_idx = 0; // Here we store our selection data as an index. + static int image_item_current_idx = 0; // Here we store our selection data as an index. + static int sound_item_current_idx = 0; // Here we store our selection data as an index. + + { + // Using the generic BeginCombo() API, you have full control over how to display the combo contents. + // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively + // stored in the object itself, etc.) + const char* display_items[] = { "320x240", "640x480" }; + + const char* combo_preview_value = display_items[display_item_current_idx]; // Pass in the preview value visible before opening the combo (it could be anything) + if (ImGui::BeginCombo("##ComboDisplay", combo_preview_value, flags)) + { + for (int n = 0; n < IM_ARRAYSIZE(display_items); n++) + { + const bool is_selected = (display_item_current_idx == n); + if (ImGui::Selectable(display_items[n], is_selected)) + display_item_current_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + } + + ImGui::Text("Image format: "); + ImGui::SameLine(); + { + // Using the generic BeginCombo() API, you have full control over how to display the combo contents. + // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively + // stored in the object itself, etc.) + const char* image_items[] = { "Native (no conversion)", "QOIF (Quite Ok Image Format" }; + const char* image_combo_preview_value = image_items[image_item_current_idx]; // Pass in the preview value visible before opening the combo (it could be anything) + if (ImGui::BeginCombo("##ComboImage", image_combo_preview_value, flags)) + { + for (int n = 0; n < IM_ARRAYSIZE(image_items); n++) + { + const bool is_selected = (image_item_current_idx == n); + if (ImGui::Selectable(image_items[n], is_selected)) + image_item_current_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + } + + + ImGui::Text("Sound format: "); + ImGui::SameLine(); + { + // Using the generic BeginCombo() API, you have full control over how to display the combo contents. + // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively + // stored in the object itself, etc.) + const char* sound_items[] = { "Native (no conversion)", "WAV (16-bit stereo)", "QOAF (Quite Ok Audio Format" }; + const char* sound_combo_preview_value = sound_items[sound_item_current_idx]; // Pass in the preview value visible before opening the combo (it could be anything) + if (ImGui::BeginCombo("##ComboSound", sound_combo_preview_value, flags)) + { + for (int n = 0; n < IM_ARRAYSIZE(sound_items); n++) + { + const bool is_selected = (sound_item_current_idx == n); + if (ImGui::Selectable(sound_items[n], is_selected)) + sound_item_current_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + } + + + ImGui::AlignTextToFramePadding(); + ImGui::Text("Image"); + ImGui::SameLine(); + + ImGui::Text("%s", story->GetTitleImage().c_str()); + + ImGui::SameLine(); + + static bool isImage = true; + if (ImGui::Button("Select...##image")) { + ImGui::OpenPopup("popup_button"); + isImage = true; + } + ImGui::SameLine(); + if (ImGui::Button(ICON_MDI_CLOSE_BOX_OUTLINE "##delimage")) { + story->SetTitleImage(""); + } + + ImGui::AlignTextToFramePadding(); + ImGui::Text("Sound"); + ImGui::SameLine(); + + ImGui::Text("%s", story->GetTitleSound().c_str()); + + ImGui::SameLine(); + + if (ImGui::Button("Play " ICON_MDI_PLAY)) + { + m_storyManager.PlaySoundFile(m_storyManager.BuildFullAssetsPath(story->GetTitleSound())); + } + + ImGui::SameLine(); + + if (ImGui::Button("Select...##sound")) { + ImGui::OpenPopup("popup_button"); + isImage = false; + } + + ImGui::SameLine(); + if (ImGui::Button(ICON_MDI_CLOSE_BOX_OUTLINE "##delsound")) { + story->SetTitleSound(""); + } + + + if (ImGui::BeginPopup("popup_button")) { + ImGui::SeparatorText(isImage ? "Images" : "Sounds"); + + auto [filtreDebut, filtreFin] = isImage ? m_resources.Images() : m_resources.Sounds(); + int n = 0; + for (auto it = filtreDebut; it != filtreFin; ++it, n++) + { + if (ImGui::Selectable((*it)->file.c_str())) + { + if (isImage) + { + story->SetTitleImage((*it)->file); + } + else + { + story->SetTitleSound((*it)->file); + } + } + } + + ImGui::EndPopup(); // Note this does not do anything to the popup open/close state. It just terminates the content declaration. + } + + + auto GetImageFormat = [](int idx) -> Resource::ImageFormat + { + Resource::ImageFormat img{Resource::IMG_SAME_FORMAT}; + if (idx < Resource::IMG_FORMAT_COUNT) { + img = static_cast(idx); + } + return img; + }; + + auto GetSoundFormat = [](int idx) -> Resource::SoundFormat { + + Resource::SoundFormat img{Resource::SND_FORMAT_WAV}; + if (idx < Resource::IMG_FORMAT_COUNT) { + img = static_cast(idx); + } + + return img; + }; + + + if (ImGui::Button("OK", ImVec2(120, 0))) + { + if (display_item_current_idx == 0) + { + story->SetDisplayFormat(320, 240); + } + else + { + story->SetDisplayFormat(640, 480); + } + + story->SetImageFormat(GetImageFormat(image_item_current_idx)); + story->SetSoundFormat(GetSoundFormat(sound_item_current_idx)); + story->SetName(m_project_name); + + m_storyManager.SaveProject(); + + ImGui::CloseCurrentPopup(); + + } + ImGui::SetItemDefaultFocus(); + ImGui::SameLine(); + if (ImGui::Button("Cancel", ImVec2(120, 0))) + { + ImGui::CloseCurrentPopup(); + Reset(); + } + ImGui::EndPopup(); + } + } +}; + +#endif // PROJECT_PROPERTIES_DIALOG_H diff --git a/story-editor/src/windows/resources_window.cpp b/story-editor/src/docks/resources_dock.cpp similarity index 91% rename from story-editor/src/windows/resources_window.cpp rename to story-editor/src/docks/resources_dock.cpp index a4b5d32..7328bb3 100644 --- a/story-editor/src/windows/resources_window.cpp +++ b/story-editor/src/docks/resources_dock.cpp @@ -1,4 +1,4 @@ -#include "resources_window.h" +#include "resources_dock.h" #include "imgui.h" #include #include @@ -7,19 +7,20 @@ //static thread_pool pool; -ResourcesWindow::ResourcesWindow(ResourceManager &resources) +ResourcesDock::ResourcesDock(ResourceManager &resources, IStoryManager &manager) : WindowBase("Resources") , m_resources(resources) + , m_storyManager(manager) { } -ResourcesWindow::~ResourcesWindow() +ResourcesDock::~ResourcesDock() { } -void ResourcesWindow::ChooseFile() +void ResourcesDock::ChooseFile() { static const char * soundFormats = ".wav,.mp3,.ogg,.flac"; static const char * imagesFormats = ".bmp,.png,.jpg"; @@ -29,7 +30,7 @@ void ResourcesWindow::ChooseFile() m_showImportDialog = false; // open Dialog Simple IGFD::FileDialogConfig config; - config.path = m_resources.BuildFullAssetsPath(""); + config.path = m_storyManager.BuildFullAssetsPath(""); config.countSelectionMax = 1; config.sidePaneWidth = 350.0f; config.flags = ImGuiFileDialogFlags_Modal; @@ -49,7 +50,7 @@ void ResourcesWindow::ChooseFile() std::filesystem::path p(filePathName); - std::filesystem::path p2 = m_resources.BuildFullAssetsPath( p.filename().generic_string()); + std::filesystem::path p2 = m_storyManager.BuildFullAssetsPath( p.filename().generic_string()); bool allowCopy = true; // On ne copie pas le fichier sur lui-même @@ -81,7 +82,7 @@ void ResourcesWindow::ChooseFile() } -void ResourcesWindow::Draw() +void ResourcesDock::Draw() { WindowBase::BeginDraw(); @@ -168,7 +169,7 @@ void ResourcesWindow::Draw() ImGui::TableNextColumn(); if (ImGui::SmallButton("Delete")) { - m_resources.DeleteResource(it); + m_resources.Delete(it); quitLoop = true; } ImGui::PopID(); diff --git a/story-editor/src/windows/resources_window.h b/story-editor/src/docks/resources_dock.h similarity index 62% rename from story-editor/src/windows/resources_window.h rename to story-editor/src/docks/resources_dock.h index c4c3101..a6782c8 100644 --- a/story-editor/src/windows/resources_window.h +++ b/story-editor/src/docks/resources_dock.h @@ -4,15 +4,16 @@ #include "window_base.h" #include "resource_manager.h" -class ResourcesWindow : public WindowBase +class ResourcesDock : public WindowBase { public: - ResourcesWindow(ResourceManager &resources); - ~ResourcesWindow(); + ResourcesDock(ResourceManager &resources, IStoryManager &manager); + ~ResourcesDock(); virtual void Draw() override; private: ResourceManager &m_resources; + IStoryManager &m_storyManager; bool m_showImportDialog{false}; bool m_soundFile{false}; diff --git a/story-editor/src/main_window.cpp b/story-editor/src/main_window.cpp index 40b120f..84e0b05 100644 --- a/story-editor/src/main_window.cpp +++ b/story-editor/src/main_window.cpp @@ -29,14 +29,15 @@ MainWindow::MainWindow(ILogger& logger, EventBus& eventBus, AppController& appCo : m_logger(logger) , m_eventBus(eventBus) , m_appController(appController) - , m_emulatorWindow(appController) + , m_emulatorDock(appController) , m_debuggerWindow(appController) , m_cpuWindow(appController) - , m_resourcesWindow(appController.GetResourceManager()) - , m_nodeEditorWindow(appController) - , m_moduleEditorWindow(appController) - , m_libraryWindow(appController) + , m_resourcesDock(appController.GetResourceManager(), appController) + , m_nodeEditorWindow(appController, appController.GetNodesFactory(), IStoryProject::PROJECT_TYPE_STORY) + , m_moduleEditorWindow(appController, appController.GetNodesFactory(), IStoryProject::PROJECT_TYPE_MODULE) + , m_libraryWindow(appController, appController.GetLibraryManager(), appController.GetNodesFactory()) , m_variablesWindow(appController) + , m_projectPropertiesDialog(appController, appController.GetResourceManager()) { logger.RegisterSubject(shared_from_this()); @@ -65,126 +66,8 @@ MainWindow::~MainWindow() } -std::string MainWindow::GetStringFromMemory(uint32_t addr) -{ - char strBuf[100]; - bool isRam = addr & 0x80000000; - addr &= 0xFFFF; // mask the RAM/ROM bit, ensure 16-bit addressing - if (isRam) { - strcpy(&strBuf[0], (const char *)&m_chip32_ctx.ram.mem[addr]); - } else { - strcpy(&strBuf[0], (const char *)&m_chip32_ctx.rom.mem[addr]); - } - return strBuf; -} - - -void MainWindow::StepInstruction() -{ - m_dbg.run_result = chip32_step(&m_chip32_ctx); - UpdateVmView(); -} - -uint8_t MainWindow::Syscall(chip32_ctx_t *ctx, uint8_t code) -{ - uint8_t retCode = SYSCALL_RET_OK; - m_logger.Log("SYSCALL: " + std::to_string(code)); - - // Media - if (code == 1) // Execute media - { - if (m_chip32_ctx.registers[R0] != 0) - { - // image file name address is in R0 - std::string imageFile = m_story->BuildFullAssetsPath(GetStringFromMemory(m_chip32_ctx.registers[R0])); - m_logger.Log("Image: " + imageFile); - m_emulatorWindow.SetImage(imageFile); - } - else - { - m_emulatorWindow.ClearImage(); - } - - if (m_chip32_ctx.registers[R1] != 0) - { - // sound file name address is in R1 - std::string soundFile = m_story->BuildFullAssetsPath(GetStringFromMemory(m_chip32_ctx.registers[R1])); - m_logger.Log("Sound: " + soundFile); - m_player.Play(soundFile); - } - retCode = SYSCALL_RET_OK; // We continue execution, script must wait for event if necessary (end of audio) - } - // WAIT EVENT bits: - // 0: block - // 1: OK button - // 2: home button - // 3: pause button - // 4: rotary left - // 5: rotary right - else if (code == 2) // Wait for event - { - // Empty event queue - m_eventQueue.clear(); - - // Event mask is located in R0 - m_dbg.event_mask = m_chip32_ctx.registers[R0]; - // optional timeout is located in R1 - // if timeout is set to zero, wait for infinite and beyond - retCode = SYSCALL_RET_WAIT_EV; // set the VM in pause - } - else if (code == 3) - { - // FIXME - } - else // Printf - if (code == 4) - { - // In R0: string with escaped characters - // R1: Number of arguments - // R2, R3 ... arguments - - // Integers: stored in registers by values - // Strings: first character address in register - - std::string text = GetStringFromMemory(ctx->registers[R0]); - - int arg_count = ctx->registers[R1]; - char working_buf[200] = {0}; - - switch(arg_count){ - case 0: - m_logger.Log(text); - break; - case 1: - snprintf(working_buf, sizeof(working_buf), text.c_str(), ctx->registers[R2]); - m_logger.Log(working_buf); - break; - case 2: - snprintf(working_buf, sizeof(working_buf), text.c_str(), ctx->registers[R2], ctx->registers[R3]); - m_logger.Log(working_buf); - break; - case 3: - snprintf(working_buf, sizeof(working_buf), text.c_str(), ctx->registers[R2], ctx->registers[R3], ctx->registers[R4]); - m_logger.Log(working_buf); - break; - default: - break; - } - - } - // WAIT (sleep) - else if (code == 5) - { - std::this_thread::sleep_for(std::chrono::milliseconds(ctx->registers[R0])); - } - - - return retCode; -} - float MainWindow::DrawMainMenuBar() { - bool showParameters = false; bool showNewProject = false; bool showOpenProject = false; @@ -199,12 +82,11 @@ float MainWindow::DrawMainMenuBar() { CloseProject(); - m_story = m_libraryManager.NewProject(); + m_story = m_appController.NewProject(); if (m_story) { - SaveProject(); - m_libraryManager.Scan(); // Add new project to library + m_appController.SaveProject(); OpenProject(m_story->GetUuid()); } } @@ -247,11 +129,9 @@ float MainWindow::DrawMainMenuBar() ImGui::Separator(); if (ImGui::MenuItem("Save project")) { - SaveProject(); + m_appController.SaveProject(); } - - if (ImGui::MenuItem("Close project")) { CloseProject(); @@ -259,7 +139,7 @@ float MainWindow::DrawMainMenuBar() if (ImGui::MenuItem("Project settings")) { - showParameters = true; + m_projectPropertiesDialog.Show(); } if (ImGui::MenuItem("Close module")) @@ -288,17 +168,9 @@ float MainWindow::DrawMainMenuBar() } m_aboutDialog.Open(); - - if (showParameters) + if (m_story) { - if (m_story) - { - ImGui::OpenPopup("ProjectPropertiesPopup"); - - // Init some variables - std::size_t length = m_story->GetName().copy(m_project_name, sizeof(m_project_name)); - m_project_name[length] = '\0'; - } + m_projectPropertiesDialog.Open(); } return height; @@ -307,18 +179,13 @@ float MainWindow::DrawMainMenuBar() bool MainWindow::Initialize() { bool success = false; - LoadParams(); - - m_nodesFactory.ScanModules(); // GUI Init if (m_gui.Initialize()) { - m_player.Initialize(); // Initialize audio after GUI (uses SDL) // gui.ApplyTheme(); - m_debuggerWindow.Initialize(); - m_emulatorWindow.Initialize(); + m_emulatorDock.Initialize(); m_nodeEditorWindow.Initialize(); m_moduleEditorWindow.Initialize(); m_PropertiesWindow.Initialize(); @@ -362,224 +229,6 @@ bool MainWindow::ShowQuitConfirm() } -void MainWindow::ProjectPropertiesPopup() -{ - // Always center this window when appearing - ImVec2 center = ImGui::GetMainViewport()->GetCenter(); - ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); - - if (ImGui::BeginPopupModal("ProjectPropertiesPopup", NULL, ImGuiWindowFlags_AlwaysAutoResize)) - { - - ImGui::Text("Project name: "); ImGui::SameLine(); - ImGui::InputTextWithHint("##project_name", "Project name", m_project_name, IM_ARRAYSIZE(m_project_name)); - - ImGui::Text("Size of display screen: "); - ImGui::SameLine(); - - static ImGuiComboFlags flags = 0; - - static int display_item_current_idx = 0; // Here we store our selection data as an index. - static int image_item_current_idx = 0; // Here we store our selection data as an index. - static int sound_item_current_idx = 0; // Here we store our selection data as an index. - - { - // Using the generic BeginCombo() API, you have full control over how to display the combo contents. - // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively - // stored in the object itself, etc.) - const char* display_items[] = { "320x240", "640x480" }; - - const char* combo_preview_value = display_items[display_item_current_idx]; // Pass in the preview value visible before opening the combo (it could be anything) - if (ImGui::BeginCombo("##ComboDisplay", combo_preview_value, flags)) - { - for (int n = 0; n < IM_ARRAYSIZE(display_items); n++) - { - const bool is_selected = (display_item_current_idx == n); - if (ImGui::Selectable(display_items[n], is_selected)) - display_item_current_idx = n; - - // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) - if (is_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - } - - ImGui::Text("Image format: "); - ImGui::SameLine(); - { - // Using the generic BeginCombo() API, you have full control over how to display the combo contents. - // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively - // stored in the object itself, etc.) - const char* image_items[] = { "Native (no conversion)", "QOIF (Quite Ok Image Format" }; - const char* image_combo_preview_value = image_items[image_item_current_idx]; // Pass in the preview value visible before opening the combo (it could be anything) - if (ImGui::BeginCombo("##ComboImage", image_combo_preview_value, flags)) - { - for (int n = 0; n < IM_ARRAYSIZE(image_items); n++) - { - const bool is_selected = (image_item_current_idx == n); - if (ImGui::Selectable(image_items[n], is_selected)) - image_item_current_idx = n; - - // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) - if (is_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - } - - - ImGui::Text("Sound format: "); - ImGui::SameLine(); - { - // Using the generic BeginCombo() API, you have full control over how to display the combo contents. - // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively - // stored in the object itself, etc.) - const char* sound_items[] = { "Native (no conversion)", "WAV (16-bit stereo)", "QOAF (Quite Ok Audio Format" }; - const char* sound_combo_preview_value = sound_items[sound_item_current_idx]; // Pass in the preview value visible before opening the combo (it could be anything) - if (ImGui::BeginCombo("##ComboSound", sound_combo_preview_value, flags)) - { - for (int n = 0; n < IM_ARRAYSIZE(sound_items); n++) - { - const bool is_selected = (sound_item_current_idx == n); - if (ImGui::Selectable(sound_items[n], is_selected)) - sound_item_current_idx = n; - - // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) - if (is_selected) - ImGui::SetItemDefaultFocus(); - } - ImGui::EndCombo(); - } - } - - - ImGui::AlignTextToFramePadding(); - ImGui::Text("Image"); - ImGui::SameLine(); - - ImGui::Text("%s", m_story->GetTitleImage().c_str()); - - ImGui::SameLine(); - - static bool isImage = true; - if (ImGui::Button("Select...##image")) { - ImGui::OpenPopup("popup_button"); - isImage = true; - } - ImGui::SameLine(); - if (ImGui::Button(ICON_MDI_CLOSE_BOX_OUTLINE "##delimage")) { - m_story->SetTitleImage(""); - } - - ImGui::AlignTextToFramePadding(); - ImGui::Text("Sound"); - ImGui::SameLine(); - - ImGui::Text("%s", m_story->GetTitleSound().c_str()); - - ImGui::SameLine(); - - if (ImGui::Button("Play " ICON_MDI_PLAY)) - { - PlaySoundFile(BuildFullAssetsPath(m_story->GetTitleSound())); - } - - ImGui::SameLine(); - - if (ImGui::Button("Select...##sound")) { - ImGui::OpenPopup("popup_button"); - isImage = false; - } - - ImGui::SameLine(); - if (ImGui::Button(ICON_MDI_CLOSE_BOX_OUTLINE "##delsound")) { - m_story->SetTitleSound(""); - } - - - if (ImGui::BeginPopup("popup_button")) { - ImGui::SeparatorText(isImage ? "Images" : "Sounds"); - - auto [filtreDebut, filtreFin] = isImage ? Images() : Sounds(); - int n = 0; - for (auto it = filtreDebut; it != filtreFin; ++it, n++) - { - if (ImGui::Selectable((*it)->file.c_str())) - { - if (isImage) - { - m_story->SetTitleImage((*it)->file); - } - else - { - m_story->SetTitleSound((*it)->file); - } - } - } - - ImGui::EndPopup(); // Note this does not do anything to the popup open/close state. It just terminates the content declaration. - } - - - auto GetImageFormat = [](int idx) -> Resource::ImageFormat - { - Resource::ImageFormat img{Resource::IMG_SAME_FORMAT}; - if (idx < Resource::IMG_FORMAT_COUNT) { - img = static_cast(idx); - } - return img; - }; - - auto GetSoundFormat = [](int idx) -> Resource::SoundFormat { - - Resource::SoundFormat img{Resource::SND_FORMAT_WAV}; - if (idx < Resource::IMG_FORMAT_COUNT) { - img = static_cast(idx); - } - - return img; - }; - - - if (ImGui::Button("OK", ImVec2(120, 0))) - { - if (display_item_current_idx == 0) - { - m_story->SetDisplayFormat(320, 240); - } - else - { - m_story->SetDisplayFormat(640, 480); - } - - m_story->SetImageFormat(GetImageFormat(image_item_current_idx)); - m_story->SetSoundFormat(GetSoundFormat(sound_item_current_idx)); - m_story->SetName(m_project_name); - - SaveProject(); - - ImGui::CloseCurrentPopup(); - - } - ImGui::SetItemDefaultFocus(); - ImGui::SameLine(); - if (ImGui::Button("Cancel", ImVec2(120, 0))) - { - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } -} - -void MainWindow::SaveProject() -{ - nlohmann::json model; - m_story->Save(m_resources); - m_logger.Log("Project saved"); -} void MainWindow::OpenProject(const std::string &uuid) { @@ -600,10 +249,10 @@ void MainWindow::OpenProject(const std::string &uuid) m_nodeEditorWindow.Enable(); - m_emulatorWindow.Enable(); + m_emulatorDock.Enable(); m_consoleWindow.Enable(); m_debuggerWindow.Enable(); - m_resourcesWindow.Enable(); + m_resourcesDock.Enable(); m_PropertiesWindow.Enable(); m_variablesWindow.Enable(); m_cpuWindow.Enable(); @@ -613,7 +262,7 @@ void MainWindow::OpenProject(const std::string &uuid) void MainWindow::NewModule() { - auto module = m_nodesFactory.NewModule(); + auto module = m_appController.NewModule(); m_moduleEditorWindow.Load(module); m_moduleEditorWindow.Enable(); @@ -622,7 +271,7 @@ void MainWindow::NewModule() void MainWindow::SaveModule() { - m_nodesFactory.SaveAllModules(m_resources);; + m_appController.SaveAllModules(m_resources);; m_logger.Log("Modules saved"); } @@ -656,18 +305,18 @@ void MainWindow::CloseProject() // m_story.reset(); // } - m_resources.Clear(); + m_appController.CloseProject(); m_nodeEditorWindow.Clear(); m_nodeEditorWindow.Disable(); - m_emulatorWindow.ClearImage(); + m_emulatorDock.ClearImage(); m_consoleWindow.ClearLog(); m_debuggerWindow.ClearErrors(); m_debuggerWindow.SetScript(""); - m_emulatorWindow.Disable(); + m_emulatorDock.Disable(); m_debuggerWindow.Disable(); - m_resourcesWindow.Disable(); + m_resourcesDock.Disable(); m_PropertiesWindow.Disable(); m_variablesWindow.Disable(); m_cpuWindow.Disable(); @@ -787,9 +436,9 @@ void MainWindow::Loop() if (m_libraryManager.IsInitialized()) { m_consoleWindow.Draw(); - m_emulatorWindow.Draw(); + m_emulatorDock.Draw(); m_debuggerWindow.Draw(); - m_resourcesWindow.Draw(); + m_resourcesDock.Draw(); m_nodeEditorWindow.Draw(); m_moduleEditorWindow.Draw(); m_variablesWindow.Draw(); @@ -809,11 +458,11 @@ void MainWindow::Loop() } m_aboutDialog.Draw(); - ProjectPropertiesPopup(); + m_projectPropertiesDialog.Draw(); if (aboutToClose) { - ImGui::OpenPopup("QuitConfirm"); + ImGui::OpenPopup("QuitConfirm"); } if (ShowQuitConfirm()) { @@ -843,59 +492,12 @@ void MainWindow::LogEvent(const std::string &txt, bool critical) } -std::string MainWindow::BuildFullAssetsPath(const std::string_view fileName) const -{ - return m_story->BuildFullAssetsPath(fileName); -} - - - void MainWindow::OpenFunction(const std::string &uuid, const std::string &name) { m_nodeEditorWindow.OpenFunction(uuid, name); } -void MainWindow::LoadBinaryStory(const std::string &filename) -{ - FILE *fp = fopen(filename.c_str(), "rb"); - if (fp != NULL) - { - fseek(fp, 0L, SEEK_END); - long int sz = ftell(fp); - fseek(fp, 0L, SEEK_SET); - - if (sz <= m_chip32_ctx.rom.size) - { - size_t sizeRead = fread(m_chip32_ctx.rom.mem, sz, 1, fp); - if (sizeRead == sz) - { - m_dbg.run_result = VM_READY; - chip32_initialize(&m_chip32_ctx); - m_logger.Log("Loaded binary file: " + filename); - } - else - { - m_logger.Log("Failed to load binary file", true); - } - - } - fclose(fp); - } -} - - - -void MainWindow::BuildNodes(bool compileonly) -{ - if (m_story->GenerateScript(m_currentCode)) - { - m_debuggerWindow.SetScript(m_currentCode); - Build(compileonly); - } -} - - void MainWindow::Build(bool compileonly) { m_dbg.run_result = VM_FINISHED; @@ -936,13 +538,6 @@ void MainWindow::Build(bool compileonly) } -void MainWindow::BuildCode(bool compileonly) -{ - m_currentCode = SysLib::ReadFile(m_externalSourceFileName); - m_debuggerWindow.SetScript(m_currentCode); - Build(compileonly); -} - void MainWindow::SetExternalSourceFile(const std::string &filename) { m_externalSourceFileName = filename; diff --git a/story-editor/src/main_window.h b/story-editor/src/main_window.h index 1ff9b95..db1721c 100644 --- a/story-editor/src/main_window.h +++ b/story-editor/src/main_window.h @@ -10,7 +10,7 @@ #include "console_window.h" #include "debugger_window.h" #include "emulator_dock.h" -#include "resources_window.h" +#include "resources_dock.h" #include "node_editor_window.h" #include "properties_window.h" #include "variables_window.h" @@ -18,6 +18,7 @@ #include "cpu_window.h" // Dialogs #include "about_dialog.h" +#include "project_properties_dialog.h" #include "event_bus.h" #include "app_controller.h" @@ -46,14 +47,11 @@ private: std::vector m_recentProjects; Gui m_gui; - EmulatorDock m_emulatorWindow; + EmulatorDock m_emulatorDock; ConsoleWindow m_consoleWindow; DebuggerWindow m_debuggerWindow; CpuWindow m_cpuWindow; - - char m_project_name[256] = ""; - - ResourcesWindow m_resourcesWindow; + ResourcesDock m_resourcesDock; NodeEditorWindow m_nodeEditorWindow; NodeEditorWindow m_moduleEditorWindow; PropertiesWindow m_PropertiesWindow; @@ -62,12 +60,12 @@ private: // Dialogs AboutDialog m_aboutDialog; + ProjectPropertiesDialog m_projectPropertiesDialog; // From IStoryManager (proxy to StoryProject class) void OpenProject(const std::string &uuid); - void SaveProject(); void CloseProject(); - + void OpenFunction(const std::string &uuid, const std::string &name); void OpenModule(const std::string &uuid); void NewModule(); void SaveModule(); @@ -77,18 +75,13 @@ private: virtual void LogEvent(const std::string &txt, bool critical) override; void LoadParams(); - + void RefreshProjectInformation(); float DrawMainMenuBar(); bool ShowQuitConfirm(); void DrawToolBar(float topPadding); void UpdateVmView(); - uint8_t Syscall(chip32_ctx_t *ctx, uint8_t code); - std::string GetStringFromMemory(uint32_t addr); - void ProcessStory(); - void StepInstruction(); - void RefreshProjectInformation(); - void ProjectPropertiesPopup(); + void RefreshProjectIœnformation(); void Build(bool compileonly); };