(WIP) Refactoring MainWindow, open existing module for edit (still buggy)
Some checks are pending
Build-StoryEditor / build_linux (push) Waiting to run
Build-StoryEditor / build_win32 (push) Waiting to run
Deploy-Documentation / deploy (push) Waiting to run

This commit is contained in:
anthony@rabine.fr 2025-07-27 23:25:57 +02:00
parent 65094d88a3
commit 03fc21dd17
15 changed files with 235 additions and 98 deletions

View file

@ -39,6 +39,9 @@ public:
virtual std::string BuildFullAssetsPath(const std::string_view fileName) const = 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 void OpenFunction(const std::string &uuid, const std::string &name) = 0;
// Modules
virtual void OpenModule(const std::string &uuid) = 0;
// Resources management // Resources management
virtual std::pair<FilterIterator, FilterIterator> Images() = 0; virtual std::pair<FilterIterator, FilterIterator> Images() = 0;
virtual std::pair<FilterIterator, FilterIterator> Sounds() = 0; virtual std::pair<FilterIterator, FilterIterator> Sounds() = 0;

View file

@ -18,7 +18,9 @@ public:
virtual ~IStoryProject() {}; virtual ~IStoryProject() {};
virtual std::string GetName() const = 0; virtual std::string GetName() const = 0;
virtual std::string GetDescription() const = 0;
virtual bool IsModule() const = 0;
virtual std::string GetUuid() const = 0;
}; };

View file

@ -21,7 +21,7 @@ static const std::string CallFunctionNodeUuid = "02745f38-9b11-49fe-94b1-b2a6b78
static const std::string VariableNodeUuid = "020cca4e-9cdc-47e7-a6a5-53e4c9152ed0"; static const std::string VariableNodeUuid = "020cca4e-9cdc-47e7-a6a5-53e4c9152ed0";
static const std::string PrintNodeUuid = "02ee27bc-ff1d-4f94-b700-eab55052ad1c"; static const std::string PrintNodeUuid = "02ee27bc-ff1d-4f94-b700-eab55052ad1c";
static const std::string SyscallNodeUuid = "02225cff-4975-400e-8130-41524d8af773"; static const std::string SyscallNodeUuid = "02225cff-4975-400e-8130-41524d8af773";
static const std::string ModuleNodeUuid = "02e4c728-ef72-4003-b7c8-2bee8834a47e";
typedef std::shared_ptr<BaseNode> (*GenericCreator)(const std::string &type); typedef std::shared_ptr<BaseNode> (*GenericCreator)(const std::string &type);
@ -48,12 +48,25 @@ public:
struct NodeInfo { struct NodeInfo {
std::string uuid; std::string uuid;
std::string name; std::string name;
std::string description;
}; };
// key: uuid, value: node name // key: uuid, value: node name
std::vector<NodeInfo> LitOfNodes() const { std::vector<NodeInfo> LitOfNodes() const {
std::vector<NodeInfo> l; std::vector<NodeInfo> l;
for(auto const& imap: m_registry) l.push_back(NodeInfo{imap.first, imap.second.first->GetName() }); for (auto const& imap : m_registry) {
l.push_back(NodeInfo{imap.first, imap.second.first->GetName(), imap.second.first->GetDescription() });
}
return l;
}
std::vector<NodeInfo> LitOfModules() const {
std::vector<NodeInfo> l;
for (auto const& imap : m_registry) {
if (imap.second.first->IsModule()) {
l.push_back(NodeInfo{imap.first, imap.second.first->GetName(), imap.second.first->GetDescription() });
}
}
return l; return l;
} }
@ -71,19 +84,16 @@ public:
} }
} }
std::shared_ptr<StoryProject> GetModule(const std::string &name) std::shared_ptr<StoryProject> GetModule(const std::string &uuid)
{ {
std::shared_ptr<StoryProject> module; std::shared_ptr<StoryProject> module;
// Scan all function nodes and find the one with that name // Scan all function nodes and find the one with that name
for (auto n : m_registry) for (auto n : m_registry)
{ {
if (n.first == ModuleNodeUuid) if (n.first == uuid)
{ {
if (n.second.first) if (n.second.first)
{
// We have a module here, get the name
if (n.second.first->GetName() == name)
{ {
auto p = dynamic_cast<StoryProject*>(n.second.first.get()); auto p = dynamic_cast<StoryProject*>(n.second.first.get());
if (p == nullptr) if (p == nullptr)
@ -94,7 +104,6 @@ public:
} }
} }
} }
}
return module; return module;
} }
@ -103,10 +112,7 @@ public:
{ {
for (const auto &entry : m_registry) for (const auto &entry : m_registry)
{ {
// Uniquement les modules custom (ici ModuleNodeUuid) // Only modules
if (entry.first == ModuleNodeUuid)
{
// Get the module from the registry
auto module = std::dynamic_pointer_cast<StoryProject>(entry.second.first); auto module = std::dynamic_pointer_cast<StoryProject>(entry.second.first);
if (module) if (module)
{ {
@ -114,7 +120,6 @@ public:
} }
} }
} }
}
// Creates a new empty module (StoryProject) and registers it as a module node. // Creates a new empty module (StoryProject) and registers it as a module node.
std::shared_ptr<StoryProject> NewModule(const std::string& moduleName = "Untitled Module") { std::shared_ptr<StoryProject> NewModule(const std::string& moduleName = "Untitled Module") {
@ -131,7 +136,7 @@ public:
module->SetProjectType(IStoryProject::PROJECT_TYPE_MODULE); module->SetProjectType(IStoryProject::PROJECT_TYPE_MODULE);
// Register as module node if not already in registry // Register as module node if not already in registry
registerNode<ModuleNode>(ModuleNodeUuid, module); registerNode<ModuleNode>(module->GetUuid(), module);
return module; return module;
} }
@ -166,7 +171,7 @@ public:
p->ParseStoryInformation(j); p->ParseStoryInformation(j);
if (p->IsModule()) if (p->IsModule())
{ {
registerNode<ModuleNode>(ModuleNodeUuid, p); registerNode<ModuleNode>(p->GetUuid(), p);
// For now, function node use only primitives nodes // For now, function node use only primitives nodes
// FIXME: in the future, allow function node to use other function nodes // FIXME: in the future, allow function node to use other function nodes
// Need a list of required nodes to be registered // Need a list of required nodes to be registered

View file

@ -7,8 +7,10 @@ class StoryPrimitive : public IStoryProject
{ {
public: public:
StoryPrimitive(const std::string &name) StoryPrimitive(const std::string &name, const std::string &description = "", const std::string &uuid = "00000000-0000-0000-0000-000000000000")
: m_name(name) : m_name(name)
, m_description(description)
, m_uuid(uuid)
{ {
} }
@ -19,7 +21,23 @@ public:
return m_name; return m_name;
} }
virtual std::string GetDescription() const
{
return m_description;
}
virtual bool IsModule() const
{
return false; // This is not a module, it's a primitive
}
virtual std::string GetUuid() const
{
return m_uuid;
}
private: private:
std::string m_name; std::string m_name;
std::string m_description;
std::string m_uuid;
}; };

View file

@ -104,7 +104,7 @@ bool StoryProject::ParseStoryInformation(nlohmann::json &j)
m_name = projectData["name"].get<std::string>(); m_name = projectData["name"].get<std::string>();
m_uuid = projectData["uuid"].get<std::string>(); m_uuid = projectData["uuid"].get<std::string>();
m_uuid = projectData["description"].get<std::string>(); m_description = projectData["description"].get<std::string>();
std::string typeString = projectData["type"].get<std::string>(); std::string typeString = projectData["type"].get<std::string>();
if (typeString == "story") if (typeString == "story")

View file

@ -87,9 +87,9 @@ public:
std::string GetTitleSound() const { return m_titleSound; } std::string GetTitleSound() const { return m_titleSound; }
// Initialize with an existing project // Initialize with an existing project
const bool IsInitialized() const { return m_initialized; } bool IsInitialized() const { return m_initialized; }
const bool IsModule() const { return m_projectType == IStoryProject::PROJECT_TYPE_MODULE; } bool IsModule() const override { return m_projectType == IStoryProject::PROJECT_TYPE_MODULE; }
const bool IsStory() const { return m_projectType == IStoryProject::PROJECT_TYPE_STORY; } bool IsStory() const { return m_projectType == IStoryProject::PROJECT_TYPE_STORY; }
void SetProjectType(IStoryProject::Type type) { m_projectType = type; } void SetProjectType(IStoryProject::Type type) { m_projectType = type; }
bool ParseStoryInformation(nlohmann::json &j); bool ParseStoryInformation(nlohmann::json &j);

View file

@ -118,11 +118,10 @@ add_subdirectory(externals/SDL_image EXCLUDE_FROM_ALL)
set(SRCS set(SRCS
src/main.cpp src/main.cpp
src/main_window.cpp
src/windows/window_base.cpp src/windows/window_base.cpp
src/windows/console_window.cpp src/windows/console_window.cpp
src/windows/emulator_window.cpp
src/windows/main_window.cpp
src/windows/library_window.cpp src/windows/library_window.cpp
src/windows/resources_window.cpp src/windows/resources_window.cpp
src/windows/properties_window.cpp src/windows/properties_window.cpp
@ -130,6 +129,9 @@ set(SRCS
src/windows/cpu_window.cpp src/windows/cpu_window.cpp
src/windows/variables_window.cpp src/windows/variables_window.cpp
## Docks
src/docks/emulator_dock.cpp
# src/node_editor/media_node_widget.cpp # src/node_editor/media_node_widget.cpp
src/node_editor/base_node_widget.cpp src/node_editor/base_node_widget.cpp
src/node_editor/node_editor_window.cpp src/node_editor/node_editor_window.cpp
@ -263,6 +265,8 @@ target_include_directories(${STORY_EDITOR_PROJECT} PUBLIC
src/importers src/importers
src/node_editor src/node_editor
src/windows src/windows
src/docks
src/dialogs
../firmware/library ../firmware/library
../core/chip32 ../core/chip32

View file

@ -9,8 +9,8 @@ Size=400,400
Collapsed=0 Collapsed=0
[Window][Library Manager] [Window][Library Manager]
Pos=643,26 Pos=568,26
Size=637,268 Size=712,288
Collapsed=0 Collapsed=0
DockId=0x00000003,0 DockId=0x00000003,0
@ -21,20 +21,20 @@ Collapsed=0
DockId=0x00000004,0 DockId=0x00000004,0
[Window][Emulator] [Window][Emulator]
Pos=643,26 Pos=568,26
Size=637,268 Size=712,288
Collapsed=0 Collapsed=0
DockId=0x00000003,5 DockId=0x00000003,5
[Window][Code viewer] [Window][Code viewer]
Pos=643,26 Pos=568,26
Size=637,268 Size=712,288
Collapsed=0 Collapsed=0
DockId=0x00000003,4 DockId=0x00000003,4
[Window][Resources] [Window][Resources]
Pos=643,26 Pos=568,26
Size=637,268 Size=712,288
Collapsed=0 Collapsed=0
DockId=0x00000003,1 DockId=0x00000003,1
@ -56,20 +56,20 @@ Collapsed=0
DockId=0x00000005,0 DockId=0x00000005,0
[Window][CPU] [Window][CPU]
Pos=643,26 Pos=568,26
Size=637,268 Size=712,288
Collapsed=0 Collapsed=0
DockId=0x00000003,2 DockId=0x00000003,2
[Window][RAM view] [Window][RAM view]
Pos=643,26 Pos=568,26
Size=637,268 Size=712,288
Collapsed=0 Collapsed=0
DockId=0x00000003,3 DockId=0x00000003,3
[Window][Properties] [Window][Properties]
Pos=643,296 Pos=568,316
Size=637,169 Size=712,149
Collapsed=0 Collapsed=0
DockId=0x00000006,0 DockId=0x00000006,0
@ -90,13 +90,13 @@ Collapsed=0
[Window][Module editor] [Window][Module editor]
Pos=60,26 Pos=60,26
Size=581,439 Size=506,439
Collapsed=0 Collapsed=0
DockId=0x00000001,1 DockId=0x00000001,1
[Window][Story editor] [Window][Story editor]
Pos=60,26 Pos=60,26
Size=581,439 Size=506,439
Collapsed=0 Collapsed=0
DockId=0x00000001,0 DockId=0x00000001,0
@ -119,13 +119,26 @@ Column 0 Width=259 Sort=0v
Column 1 Width=88 Column 1 Width=88
Column 2 Width=124 Column 2 Width=124
[Table][0x37CE7681,4]
RefScale=20
Column 0 Width=567 Sort=0v
Column 1 Width=3930
Column 2 Width=47
Column 3 Width=93
[Table][0xC3F86B91,3]
RefScale=20
Column 0 Width=120 Sort=0v
Column 1 Width=104
Column 2 Width=120
[Docking][Data] [Docking][Data]
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=60,26 Size=1220,694 Split=Y DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=60,26 Size=1220,694 Split=Y
DockNode ID=0x00000007 Parent=0x08BD597D SizeRef=1220,439 Split=X DockNode ID=0x00000007 Parent=0x08BD597D SizeRef=1220,439 Split=X
DockNode ID=0x00000001 Parent=0x00000007 SizeRef=581,694 CentralNode=1 Selected=0x54E37131 DockNode ID=0x00000001 Parent=0x00000007 SizeRef=506,694 CentralNode=1 Selected=0x93ADCAAB
DockNode ID=0x00000002 Parent=0x00000007 SizeRef=637,694 Split=Y Selected=0x52EB28B5 DockNode ID=0x00000002 Parent=0x00000007 SizeRef=712,694 Split=Y Selected=0x52EB28B5
DockNode ID=0x00000003 Parent=0x00000002 SizeRef=718,268 Selected=0x63869CAF DockNode ID=0x00000003 Parent=0x00000002 SizeRef=718,369 Selected=0x63869CAF
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=718,169 Selected=0x8C72BEA8 DockNode ID=0x00000006 Parent=0x00000002 SizeRef=718,191 Selected=0x8C72BEA8
DockNode ID=0x00000008 Parent=0x08BD597D SizeRef=1220,253 Split=X Selected=0xEA83D666 DockNode ID=0x00000008 Parent=0x08BD597D SizeRef=1220,253 Split=X Selected=0xEA83D666
DockNode ID=0x00000004 Parent=0x00000008 SizeRef=610,192 Selected=0xEA83D666 DockNode ID=0x00000004 Parent=0x00000008 SizeRef=610,192 Selected=0xEA83D666
DockNode ID=0x00000005 Parent=0x00000008 SizeRef=608,192 Selected=0x6DE9B20C DockNode ID=0x00000005 Parent=0x00000008 SizeRef=608,192 Selected=0x6DE9B20C

View file

@ -0,0 +1,73 @@
// about_dialog.h
#ifndef ABOUT_DIALOG_H
#define ABOUT_DIALOG_H
#include "imgui.h" // Nécessaire pour ImGui::BeginPopupModal, ImGui::Text, etc.
#include <string> // Pour std::string
#include "library_manager.h" // Pour LibraryManager::GetVersion()
#include <SDL3/SDL.h> // Pour SDL_GetPlatform(), SDL_GetNumLogicalCPUCores(), SDL_GetSystemRAM()
// 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
{
public:
AboutDialog() = default;
// Affiche le popup "About".
// Doit être appelée à chaque frame dans la boucle de rendu ImGui.
void Draw()
{
// Toujours centrer cette fenêtre lorsqu'elle apparaît
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal("AboutPopup", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
{
ImGui::Text("Story Editor - v%s", LibraryManager::GetVersion().c_str());
ImGui::Text("http://www.openstoryteller.org");
ImGui::Separator();
ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Platform");
ImGui::Text("%s", SDL_GetPlatform());
ImGui::Text("CPU cores: %d", SDL_GetNumLogicalCPUCores());
ImGui::Text("RAM: %.2f GB", SDL_GetSystemRAM() / 1024.0f);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::Separator();
ImGui::SameLine(300);
if (ImGui::Button("Close", ImVec2(100, 35)))
{
ImGui::CloseCurrentPopup();
}
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é
};
#endif // ABOUT_DIALOG_H

View file

@ -1,23 +1,23 @@
#include "emulator_window.h" #include "emulator_dock.h"
#include "gui.h" #include "gui.h"
#include "ImGuiFileDialog.h" #include "ImGuiFileDialog.h"
#include "IconsMaterialDesignIcons.h" #include "IconsMaterialDesignIcons.h"
EmulatorWindow::EmulatorWindow(IStoryManager &proj) EmulatorDock::EmulatorDock(IStoryManager &proj)
: WindowBase("Emulator") : WindowBase("Emulator")
, m_story(proj) , m_story(proj)
{ {
} }
void EmulatorWindow::Initialize() void EmulatorDock::Initialize()
{ {
} }
void EmulatorWindow::Draw() void EmulatorDock::Draw()
{ {
// if (!IsVisible()) // if (!IsVisible())
// { // {
@ -170,12 +170,12 @@ void EmulatorWindow::Draw()
WindowBase::EndDraw(); WindowBase::EndDraw();
} }
void EmulatorWindow::ClearImage() void EmulatorDock::ClearImage()
{ {
m_image.Clear(); m_image.Clear();
} }
void EmulatorWindow::SetImage(const std::string &image) void EmulatorDock::SetImage(const std::string &image)
{ {
m_imageFileName = image; m_imageFileName = image;
m_image.Load(m_story.BuildFullAssetsPath(image)); m_image.Load(m_story.BuildFullAssetsPath(image));

View file

@ -4,10 +4,10 @@
#include "i_story_manager.h" #include "i_story_manager.h"
#include "gui.h" #include "gui.h"
class EmulatorWindow : public WindowBase class EmulatorDock : public WindowBase
{ {
public: public:
EmulatorWindow(IStoryManager &proj); EmulatorDock(IStoryManager &proj);
void Initialize(); void Initialize();
virtual void Draw() override; virtual void Draw() override;

View file

@ -32,7 +32,7 @@ MainWindow::MainWindow()
, m_resourcesWindow(*this) , m_resourcesWindow(*this)
, m_nodeEditorWindow(*this, m_nodesFactory) , m_nodeEditorWindow(*this, m_nodesFactory)
, m_moduleEditorWindow(*this, m_nodesFactory, IStoryProject::Type::PROJECT_TYPE_MODULE) , m_moduleEditorWindow(*this, m_nodesFactory, IStoryProject::Type::PROJECT_TYPE_MODULE)
, m_libraryWindow(*this, m_libraryManager) , m_libraryWindow(*this, m_libraryManager, m_nodesFactory)
, m_variablesWindow(*this) , m_variablesWindow(*this)
, m_player(*this) , m_player(*this)
, m_webServer(m_libraryManager) , m_webServer(m_libraryManager)
@ -435,7 +435,6 @@ void MainWindow::DrawStatusBar()
float MainWindow::DrawMainMenuBar() float MainWindow::DrawMainMenuBar()
{ {
bool showAboutPopup = false;
bool showParameters = false; bool showParameters = false;
bool showNewProject = false; bool showNewProject = false;
bool showOpenProject = false; bool showOpenProject = false;
@ -529,7 +528,7 @@ float MainWindow::DrawMainMenuBar()
{ {
if (ImGui::MenuItem("About")) if (ImGui::MenuItem("About"))
{ {
showAboutPopup = true; m_aboutDialog.Show();
} }
ImGui::EndMenu(); ImGui::EndMenu();
} }
@ -539,10 +538,7 @@ float MainWindow::DrawMainMenuBar()
ImGui::EndMainMenuBar(); ImGui::EndMainMenuBar();
} }
if (showAboutPopup) m_aboutDialog.Open();
{
ImGui::OpenPopup("AboutPopup");
}
if (showParameters) if (showParameters)
{ {
@ -556,34 +552,6 @@ float MainWindow::DrawMainMenuBar()
} }
} }
// Always center this window when appearing
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
//ImVec2 parent_pos = ImGui::GetWindowPos();
//ImVec2 parent_size = ImGui::GetWindowSize();
//ImVec2 center(parent_pos.x + parent_size.x * 0.5f, parent_pos.y + parent_size.y * 0.5f);
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
if (ImGui::BeginPopupModal("AboutPopup", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
{
ImGui::Text("Story Editor - v%s", LibraryManager::GetVersion().c_str());
ImGui::Text("http://www.openstoryteller.org");
ImGui::Separator();
ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Platform");
ImGui::Text("%s", SDL_GetPlatform());
ImGui::Text("CPU cores: %d", SDL_GetNumLogicalCPUCores());
ImGui::Text("RAM: %.2f GB", SDL_GetSystemRAM() / 1024.0f);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::Separator();
ImGui::SameLine(300);
if (ImGui::Button("Close", ImVec2(100, 35)))
{
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
return height; return height;
} }
@ -1117,6 +1085,7 @@ void MainWindow::Loop()
DrawToolBar(height); DrawToolBar(height);
} }
m_aboutDialog.Draw();
ProjectPropertiesPopup(); ProjectPropertiesPopup();
if (aboutToClose) if (aboutToClose)

View file

@ -8,7 +8,7 @@
#include "console_window.h" #include "console_window.h"
#include "debugger_window.h" #include "debugger_window.h"
#include "emulator_window.h" #include "emulator_dock.h"
#include "resources_window.h" #include "resources_window.h"
#include "node_editor_window.h" #include "node_editor_window.h"
#include "properties_window.h" #include "properties_window.h"
@ -27,6 +27,9 @@
#include "web_server.h" #include "web_server.h"
#include "nodes_factory.h" #include "nodes_factory.h"
// Dialogs
#include "about_dialog.h"
struct DebugContext struct DebugContext
{ {
uint32_t event_mask{0}; uint32_t event_mask{0};
@ -106,7 +109,7 @@ private:
LibraryManager m_libraryManager; LibraryManager m_libraryManager;
Gui m_gui; Gui m_gui;
EmulatorWindow m_emulatorWindow; EmulatorDock m_emulatorWindow;
ConsoleWindow m_consoleWindow; ConsoleWindow m_consoleWindow;
DebuggerWindow m_debuggerWindow; DebuggerWindow m_debuggerWindow;
CpuWindow m_cpuWindow; CpuWindow m_cpuWindow;
@ -136,6 +139,9 @@ private:
WebServer m_webServer; WebServer m_webServer;
// Dialogs
AboutDialog m_aboutDialog;
// From IStoryManager (proxy to StoryProject class) // From IStoryManager (proxy to StoryProject class)
virtual void OpenProject(const std::string &uuid) override; virtual void OpenProject(const std::string &uuid) override;
void SaveProject(); void SaveProject();

View file

@ -50,10 +50,11 @@ void download_file(CURL *curl,
} }
LibraryWindow::LibraryWindow(IStoryManager &project, LibraryManager &library) LibraryWindow::LibraryWindow(IStoryManager &project, LibraryManager &library, NodesFactory &nodesFactory)
: WindowBase("Library Manager") : WindowBase("Library Manager")
, m_storyManager(project) , m_storyManager(project)
, m_libraryManager(library) , m_libraryManager(library)
, m_nodesFactory(nodesFactory)
{ {
m_downloadThread = std::thread( std::bind(&LibraryWindow::DownloadThread, this) ); m_downloadThread = std::thread( std::bind(&LibraryWindow::DownloadThread, this) );
@ -648,8 +649,50 @@ void LibraryWindow::Draw()
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
// ============================================================================
// LOCAL MODULES LIST
// ============================================================================
if (ImGui::BeginTabItem("Local modules ##ModuleTabBar", nullptr, ImGuiTabItemFlags_None))
{
const auto &modules = m_nodesFactory.LitOfModules();
if (ImGui::BeginTable("modules_table", 3, tableFlags))
{
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableHeadersRow();
for (const auto &module : modules)
{
ImGui::TableNextColumn();
ImGui::Text("%s", module.name.c_str());
ImGui::TableNextColumn();
ImGui::Text("%s", module.description.c_str());
// Add a button to open the module
ImGui::TableNextColumn();
ImGui::PushID(module.uuid.c_str());
if (ImGui::SmallButton("Open"))
{
// Open the module in the editor
m_storyManager.OpenModule(module.uuid);
}
ImGui::PopID();
}
ImGui::EndTable();
}
ImGui::EndTabItem();
}
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
} }

View file

@ -65,7 +65,7 @@ struct TransferProgress {
class LibraryWindow : public WindowBase class LibraryWindow : public WindowBase
{ {
public: public:
LibraryWindow(IStoryManager &project, LibraryManager &library); LibraryWindow(IStoryManager &project, LibraryManager &library, NodesFactory &nodesFactory);
void Initialize(); void Initialize();
virtual void Draw() override; virtual void Draw() override;
@ -74,6 +74,7 @@ public:
private: private:
IStoryManager &m_storyManager; IStoryManager &m_storyManager;
LibraryManager &m_libraryManager; LibraryManager &m_libraryManager;
NodesFactory &m_nodesFactory;
Downloader m_downloader; Downloader m_downloader;
CURL *m_curl; CURL *m_curl;