mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
wip move out logic from ui
This commit is contained in:
parent
8a2f70ea01
commit
143bbfa8bc
14 changed files with 491 additions and 552 deletions
|
|
@ -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<IStoryProject> GetCurrentProject() = 0;
|
||||
|
||||
// Modules
|
||||
virtual void OpenModule(const std::string &uuid) = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -61,16 +61,9 @@ 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<StoryPage> CreatePage(const std::string &uuid);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<StoryProject> 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<FilterIterator, FilterIterator> AppController::Images()
|
||||
std::shared_ptr<IStoryProject> AppController::GetCurrentProject()
|
||||
{
|
||||
return m_resources.Images();
|
||||
}
|
||||
|
||||
std::pair<FilterIterator, FilterIterator> AppController::Sounds()
|
||||
{
|
||||
return m_resources.Sounds();
|
||||
return m_story; // Retourne le projet actuel
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ public:
|
|||
// Initialisation de l'AppController
|
||||
bool Initialize();
|
||||
|
||||
std::shared_ptr<StoryProject> 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<IStoryProject> 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<FilterIterator, FilterIterator> Images() override;
|
||||
virtual std::pair<FilterIterator, FilterIterator> 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
|
||||
|
|
|
|||
|
|
@ -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 <string> // Pour std::string
|
||||
#include "library_manager.h" // Pour LibraryManager::GetVersion()
|
||||
#include <SDL3/SDL.h> // Pour SDL_GetPlatform(), SDL_GetNumLogicalCPUCores(), SDL_GetSystemRAM()
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
// 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
|
||||
49
story-editor/src/dialogs/dialog_base.h
Normal file
49
story-editor/src/dialogs/dialog_base.h
Normal file
|
|
@ -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
|
||||
269
story-editor/src/dialogs/project_properties_dialog.h
Normal file
269
story-editor/src/dialogs/project_properties_dialog.h
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
// about_dialog.h
|
||||
#ifndef PROJECT_PROPERTIES_DIALOG_H
|
||||
#define PROJECT_PROPERTIES_DIALOG_H
|
||||
|
||||
#include "dialog_base.h" // Pour DialogBase
|
||||
#include <string> // Pour std::string
|
||||
#include "library_manager.h" // Pour LibraryManager::GetVersion()
|
||||
#include <SDL3/SDL.h> // 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<IStoryProject> 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<Resource::ImageFormat>(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<Resource::SoundFormat>(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
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "resources_window.h"
|
||||
#include "resources_dock.h"
|
||||
#include "imgui.h"
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
|
|
@ -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();
|
||||
|
|
@ -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};
|
||||
|
|
@ -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)
|
||||
{
|
||||
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<Resource::ImageFormat>(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<Resource::SoundFormat>(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,7 +458,7 @@ void MainWindow::Loop()
|
|||
}
|
||||
|
||||
m_aboutDialog.Draw();
|
||||
ProjectPropertiesPopup();
|
||||
m_projectPropertiesDialog.Draw();
|
||||
|
||||
if (aboutToClose)
|
||||
{
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<std::string> 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);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue