mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
(WIP) Library Manager
This commit is contained in:
parent
ce26db3aaa
commit
4bcb8e4490
13 changed files with 505 additions and 103 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -67,3 +67,5 @@ build-story-editor-Desktop-Debug/
|
|||
docs/.vitepress/cache/
|
||||
|
||||
docs/.vitepress/dist/
|
||||
|
||||
software/.cache/
|
||||
|
|
|
|||
26
.vscode/launch.json
vendored
26
.vscode/launch.json
vendored
|
|
@ -23,6 +23,32 @@
|
|||
}
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
"name": "Black Magic Probe",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"executable": "${workspaceRoot}/software/build/RaspberryPico/open-story-teller.elf",
|
||||
"request": "launch",
|
||||
"type": "cortex-debug",
|
||||
"showDevDebugOutput": "raw",
|
||||
"BMPGDBSerialPort": "/dev/ttyACM0",
|
||||
"servertype": "bmp",
|
||||
"interface": "swd",
|
||||
"gdbPath": "gdb-multiarch",
|
||||
"svdFile": "${workspaceRoot}/software/platform/raspberry-pico-w/rp2040.svd",
|
||||
// "device": "STM32L431VC",
|
||||
"runToMain": true,
|
||||
"preRestartCommands": [
|
||||
"cd ${workspaceRoot}/software/build/RaspberryPico",
|
||||
"file open-story-teller.elf",
|
||||
// "target extended-remote /dev/ttyACM0",
|
||||
"set mem inaccessible-by-default off",
|
||||
"enable breakpoint",
|
||||
"monitor reset",
|
||||
"monitor swdp_scan",
|
||||
"attach 1",
|
||||
"load"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
70
software/common/tlv.h
Normal file
70
software/common/tlv.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#ifndef TLV_H
|
||||
#define TLV_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define TLV_ARRAY_TYPE 0xAB
|
||||
#define TLV_OBJECT_TYPE 0xE7
|
||||
#define TLV_STRING_TYPE 0x3D
|
||||
#define TLV_INTEGER 0x77
|
||||
#define TLV_REAL 0xB8
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
class Tlv
|
||||
{
|
||||
public:
|
||||
explicit Tlv(const std::string &filename)
|
||||
{
|
||||
m_file = std::ofstream(filename, std::ios::out | std::ios::binary);
|
||||
}
|
||||
|
||||
~Tlv() {
|
||||
m_file.close();
|
||||
}
|
||||
|
||||
void add_array(uint16_t size)
|
||||
{
|
||||
m_file.write(reinterpret_cast<const char*>(&m_objectType), sizeof(m_objectType));
|
||||
m_file.write(reinterpret_cast<const char*>(&size), sizeof(size));
|
||||
}
|
||||
|
||||
void add_string(const char *s, uint16_t size)
|
||||
{
|
||||
m_file.write(reinterpret_cast<const char*>(&m_stringType), sizeof(m_stringType));
|
||||
|
||||
m_file.write(s, size);
|
||||
}
|
||||
|
||||
void add_integer(uint32_t value)
|
||||
{
|
||||
static const uint16_t size = 4;
|
||||
m_file.write(reinterpret_cast<const char*>(&m_integerType), sizeof(m_integerType));
|
||||
m_file.write(reinterpret_cast<const char*>(&size), sizeof(size));
|
||||
m_file.write(reinterpret_cast<const char*>(&value), sizeof(value));
|
||||
}
|
||||
|
||||
void add_string(const std::string &s)
|
||||
{
|
||||
add_string(s.c_str(), s.size());
|
||||
}
|
||||
|
||||
void add_object(uint16_t entries)
|
||||
{
|
||||
m_file.write(reinterpret_cast<const char*>(&m_arrayType), sizeof(m_arrayType));
|
||||
m_file.write(reinterpret_cast<const char*>(&entries), sizeof(entries));
|
||||
}
|
||||
|
||||
private:
|
||||
std::ofstream m_file;
|
||||
|
||||
uint8_t m_arrayType = TLV_ARRAY_TYPE;
|
||||
uint8_t m_objectType = TLV_OBJECT_TYPE;
|
||||
uint8_t m_stringType = TLV_STRING_TYPE;
|
||||
uint8_t m_integerType = TLV_INTEGER;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // TLV_H
|
||||
106
software/library/library_manager.cpp
Normal file
106
software/library/library_manager.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#include "library_manager.h"
|
||||
#include "tlv.h"
|
||||
#include <filesystem>
|
||||
#include <regex>
|
||||
#include "json.hpp"
|
||||
#include "story_project.h"
|
||||
|
||||
LibraryManager::LibraryManager() {}
|
||||
|
||||
void LibraryManager::Initialize(const std::string &library_path)
|
||||
{
|
||||
m_library_path = library_path;
|
||||
Scan();
|
||||
}
|
||||
|
||||
bool IsUUIDV4(const std::string& input) {
|
||||
// Le motif regex pour un UUID V4
|
||||
std::regex uuidRegex("^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$",std::regex_constants::icase);
|
||||
|
||||
// Vérifier si la chaîne correspond au motif UUID V4
|
||||
return std::regex_match(input, uuidRegex);
|
||||
}
|
||||
|
||||
void LibraryManager::Scan()
|
||||
{
|
||||
std::filesystem::path directoryPath(m_library_path);
|
||||
if (std::filesystem::exists(directoryPath) && std::filesystem::is_directory(directoryPath))
|
||||
{
|
||||
m_projectsList.clear();
|
||||
for (const auto& entry : std::filesystem::directory_iterator(directoryPath))
|
||||
{
|
||||
if (std::filesystem::is_directory(entry.path()))
|
||||
{
|
||||
// Si c'est un sous-répertoire, récursivement scanner le contenu
|
||||
std::string uuid = entry.path().filename();
|
||||
if (IsUUIDV4(uuid))
|
||||
{
|
||||
std::cout << "Found story directory" << std::endl;
|
||||
// Look for a story.json file in this directory
|
||||
auto p = entry.path() / "project.json";
|
||||
if (std::filesystem::exists(p))
|
||||
{
|
||||
// okay, open it
|
||||
auto proj = std::make_shared<StoryProject>();
|
||||
try {
|
||||
std::ifstream f(p);
|
||||
nlohmann::json j = nlohmann::json::parse(f);
|
||||
|
||||
if (proj->ParseStoryInformation(j))
|
||||
{
|
||||
// Valid project file, add it to the list
|
||||
m_projectsList.push_back(proj);
|
||||
}
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LibraryManager::Save()
|
||||
{
|
||||
auto p = std::filesystem::path(m_library_path) / "index.ost";
|
||||
Tlv tlv(p.string());
|
||||
|
||||
tlv.add_object(1);
|
||||
tlv.add_string(GetVersion());
|
||||
|
||||
tlv.add_array(m_projectsList.size());
|
||||
for (auto &p : m_projectsList)
|
||||
{
|
||||
tlv.add_object(6);
|
||||
tlv.add_string(p->GetUuid());
|
||||
tlv.add_string(p->GetTitleImage());
|
||||
tlv.add_string(p->GetTitleSound());
|
||||
tlv.add_string(p->GetName());
|
||||
tlv.add_string(p->GetDescription());
|
||||
tlv.add_integer(p->GetVersion());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
// Title image
|
||||
std::string image = RemoveFileExtension(m_titleImage) + ".qoi";
|
||||
tlv.add_string(image.c_str(), image.size());
|
||||
|
||||
std::string sound = RemoveFileExtension(m_titleSound) + ".wav";
|
||||
tlv.add_string(sound.c_str(), sound.size()); // title sound
|
||||
*/
|
||||
}
|
||||
|
||||
bool LibraryManager::IsInitialized() const
|
||||
{
|
||||
return m_library_path.size() > 0;
|
||||
}
|
||||
|
||||
std::string LibraryManager::GetVersion()
|
||||
{
|
||||
return std::to_string(VERSION_MAJOR) + '.' + std::to_string(VERSION_MINOR) + '.' + std::to_string(VERSION_PATCH);
|
||||
}
|
||||
30
software/library/library_manager.h
Normal file
30
software/library/library_manager.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef LIBRARYMANAGER_H
|
||||
#define LIBRARYMANAGER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "story_project.h"
|
||||
|
||||
class LibraryManager
|
||||
{
|
||||
public:
|
||||
LibraryManager();
|
||||
|
||||
void Initialize(const std::string &library_path);
|
||||
bool IsInitialized() const;
|
||||
|
||||
std::string LibraryPath() const { return m_library_path; }
|
||||
static std::string GetVersion();
|
||||
|
||||
std::vector<std::shared_ptr<StoryProject>>::const_iterator begin() const { return m_projectsList.begin(); }
|
||||
std::vector<std::shared_ptr<StoryProject>>::const_iterator end() const { return m_projectsList.end(); }
|
||||
|
||||
void Save();
|
||||
void Scan();
|
||||
private:
|
||||
std::string m_library_path;
|
||||
std::vector<std::shared_ptr<StoryProject>> m_projectsList;
|
||||
};
|
||||
|
||||
#endif // LIBRARYMANAGER_H
|
||||
|
|
@ -24,74 +24,12 @@ void StoryProject::New(const std::string &uuid, const std::string &file_path)
|
|||
Initialize(file_path);
|
||||
}
|
||||
|
||||
#define TLV_ARRAY_TYPE 0xAB
|
||||
#define TLV_OBJECT_TYPE 0xE7
|
||||
#define TLV_STRING_TYPE 0x3D
|
||||
#define TLV_INTEGER 0x77
|
||||
#define TLV_REAL 0xB8
|
||||
|
||||
class Tlv
|
||||
{
|
||||
public:
|
||||
explicit Tlv(const std::string &filename)
|
||||
{
|
||||
m_file = std::ofstream(filename, std::ios::out | std::ios::binary);
|
||||
}
|
||||
|
||||
~Tlv() {
|
||||
m_file.close();
|
||||
}
|
||||
|
||||
void add_array(uint16_t size)
|
||||
{
|
||||
m_file.write(reinterpret_cast<const char*>(&m_objectType), sizeof(m_objectType));
|
||||
m_file.write(reinterpret_cast<const char*>(&size), sizeof(size));
|
||||
}
|
||||
|
||||
void add_string(const char *s, uint16_t size)
|
||||
{
|
||||
m_file.write(reinterpret_cast<const char*>(&m_stringType), sizeof(m_stringType));
|
||||
m_file.write(reinterpret_cast<const char*>(&size), sizeof(size));
|
||||
m_file.write(s, size);
|
||||
}
|
||||
|
||||
void add_object(uint16_t entries)
|
||||
{
|
||||
m_file.write(reinterpret_cast<const char*>(&m_arrayType), sizeof(m_arrayType));
|
||||
m_file.write(reinterpret_cast<const char*>(&entries), sizeof(entries));
|
||||
}
|
||||
|
||||
private:
|
||||
std::ofstream m_file;
|
||||
|
||||
uint8_t m_arrayType = TLV_ARRAY_TYPE;
|
||||
uint8_t m_objectType = TLV_OBJECT_TYPE;
|
||||
uint8_t m_stringType = TLV_STRING_TYPE;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
void StoryProject::SaveStory(const std::vector<uint8_t> &m_program)
|
||||
{
|
||||
std::ofstream o(m_working_dir / "story.c32", std::ios::out | std::ios::binary);
|
||||
o.write(reinterpret_cast<const char*>(m_program.data()), m_program.size());
|
||||
o.close();
|
||||
|
||||
auto p = m_working_dir / "index.ost";
|
||||
Tlv tlv(p.string());
|
||||
|
||||
tlv.add_array(1);
|
||||
|
||||
tlv.add_object(3);
|
||||
tlv.add_string(m_uuid.c_str(), m_uuid.size()); // uuid
|
||||
|
||||
// Title image
|
||||
std::string image = RemoveFileExtension(m_titleImage) + ".qoi";
|
||||
tlv.add_string(image.c_str(), image.size());
|
||||
|
||||
std::string sound = RemoveFileExtension(m_titleSound) + ".wav";
|
||||
tlv.add_string(sound.c_str(), sound.size()); // title sound
|
||||
}
|
||||
|
||||
void StoryProject::Initialize(const std::string &file_path)
|
||||
|
|
@ -100,7 +38,7 @@ void StoryProject::Initialize(const std::string &file_path)
|
|||
std::filesystem::path p(file_path);
|
||||
m_working_dir= p.parent_path().generic_string();
|
||||
|
||||
// Frist try to create the working directory
|
||||
// First try to create the working directory
|
||||
if (!std::filesystem::is_directory(m_working_dir))
|
||||
{
|
||||
std::filesystem::create_directories(m_working_dir);
|
||||
|
|
@ -112,6 +50,27 @@ void StoryProject::Initialize(const std::string &file_path)
|
|||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
bool StoryProject::ParseStoryInformation(nlohmann::json &j)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (j.contains("project"))
|
||||
{
|
||||
nlohmann::json projectData = j["project"];
|
||||
|
||||
m_name = projectData["name"].get<std::string>();
|
||||
m_uuid = projectData["uuid"].get<std::string>();
|
||||
m_titleImage = projectData.value("title_image", "");
|
||||
m_titleSound = projectData.value("title_sound", "");
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool StoryProject::Load(const std::string &file_path, nlohmann::json &model, ResourceManager &manager)
|
||||
{
|
||||
|
||||
|
|
@ -130,15 +89,8 @@ bool StoryProject::Load(const std::string &file_path, nlohmann::json &model, Res
|
|||
// m_nodes.clear();
|
||||
manager.Clear();
|
||||
|
||||
if (j.contains("project"))
|
||||
if (ParseStoryInformation(j))
|
||||
{
|
||||
nlohmann::json projectData = j["project"];
|
||||
|
||||
m_name = projectData["name"].get<std::string>();
|
||||
m_uuid = projectData["uuid"].get<std::string>();
|
||||
m_titleImage = projectData.value("title_image", "");
|
||||
m_titleSound = projectData.value("title_sound", "");
|
||||
|
||||
if (j.contains("resources"))
|
||||
{
|
||||
nlohmann::json resourcesData = j["resources"];
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ struct StoryNode
|
|||
// "sound": 0
|
||||
};
|
||||
|
||||
|
||||
struct StoryProject
|
||||
{
|
||||
|
||||
|
|
@ -74,6 +75,8 @@ public:
|
|||
std::string GetWorkingDir() const;
|
||||
std::string GetName() const { return m_name; }
|
||||
std::string GetUuid() const { return m_uuid; }
|
||||
std::string GetDescription() const { return m_description; }
|
||||
int GetVersion() const { return m_version; }
|
||||
|
||||
std::string BuildFullAssetsPath(const std::string &fileName) const;
|
||||
|
||||
|
|
@ -101,17 +104,20 @@ public:
|
|||
|
||||
void SaveStory(const std::vector<uint8_t> &m_program);
|
||||
|
||||
bool ParseStoryInformation(nlohmann::json &j);
|
||||
private:
|
||||
// Project properties and location
|
||||
std::string m_name; /// human readable name
|
||||
std::string m_uuid;
|
||||
std::string m_titleImage;
|
||||
std::string m_titleSound;
|
||||
std::string m_description;
|
||||
int m_version;
|
||||
|
||||
std::filesystem::path m_assetsPath;
|
||||
|
||||
bool m_initialized{false};
|
||||
|
||||
std::string m_titleImage;
|
||||
std::string m_titleSound;
|
||||
|
||||
std::filesystem::path m_working_dir; /// Temporary folder based on the uuid, where the archive is unzipped
|
||||
std::string m_story_file_path; /// JSON project file
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,9 @@ set(SRCS
|
|||
src/node_editor_window.cpp
|
||||
src/node_editor_window.h
|
||||
|
||||
src/library_window.cpp
|
||||
src/library_window.h
|
||||
|
||||
src/media_node.h
|
||||
src/media_node.cpp
|
||||
|
||||
|
|
@ -148,8 +151,11 @@ set(SRCS
|
|||
|
||||
../software/chip32/chip32_assembler.cpp
|
||||
../software/chip32/chip32_vm.c
|
||||
../software/library/audio_player.cpp
|
||||
../software/library/audio_player.h
|
||||
|
||||
../software/common/audio_player.cpp
|
||||
../software/common/audio_player.h
|
||||
../software/common/tlv.h
|
||||
|
||||
../software/library/miniaudio.h
|
||||
../software/library/uuid.h
|
||||
../software/library/resource.h
|
||||
|
|
@ -157,6 +163,8 @@ set(SRCS
|
|||
../software/library/story_project.cpp
|
||||
../software/library/story_project.h
|
||||
../software/library/thread_safe_queue.h
|
||||
../software/library/library_manager.h
|
||||
../software/library/library_manager.cpp
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
|
@ -174,6 +182,8 @@ if(WIN32)
|
|||
else()
|
||||
add_executable(${STORY_EDITOR_PROJECT}
|
||||
${SRCS}
|
||||
|
||||
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
@ -187,6 +197,7 @@ target_include_directories(${STORY_EDITOR_PROJECT} PUBLIC
|
|||
|
||||
../software/library/
|
||||
../software/chip32/
|
||||
../software/common
|
||||
)
|
||||
|
||||
add_definitions(-DIMGUI_USE_WCHAR32 -DVERSION_MAJOR=${PROJECT_VERSION_MAJOR} -DVERSION_MINOR=${PROJECT_VERSION_MINOR} -DVERSION_PATCH=${PROJECT_VERSION_PATCH})
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
|
||||
|
|
@ -15,6 +14,7 @@ class IStoryManager
|
|||
public:
|
||||
virtual ~IStoryManager() {}
|
||||
|
||||
virtual void OpenProject(const std::string &filename) = 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 &fileName) const = 0;
|
||||
|
|
|
|||
159
story-editor/src/library_window.cpp
Normal file
159
story-editor/src/library_window.cpp
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
#include "library_window.h"
|
||||
#include "gui.h"
|
||||
#include "ImGuiFileDialog.h"
|
||||
#include <filesystem>
|
||||
|
||||
LibraryWindow::LibraryWindow(IStoryManager &project, LibraryManager &library)
|
||||
: WindowBase("Library Manager")
|
||||
, m_storyManager(project)
|
||||
, m_libraryManager(library)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LibraryWindow::Initialize()
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
static bool canValidateDialog = false;
|
||||
inline void InfosPane(const char *vFilter, IGFDUserDatas vUserDatas, bool *vCantContinue) // if vCantContinue is false, the user cant validate the dialog
|
||||
{
|
||||
ImGui::TextColored(ImVec4(0, 1, 1, 1), "Infos Pane");
|
||||
ImGui::Text("Selected Filter : %s", vFilter);
|
||||
ImGui::Checkbox("if not checked you cant validate the dialog", &canValidateDialog);
|
||||
if (vCantContinue)
|
||||
*vCantContinue = canValidateDialog;
|
||||
}
|
||||
|
||||
|
||||
void LibraryWindow::Draw()
|
||||
{
|
||||
// if (!IsVisible())
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
WindowBase::BeginDraw();
|
||||
ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
|
||||
|
||||
if (ImGui::Button("Select directory"))
|
||||
{
|
||||
ImGuiFileDialog::Instance()->OpenDialog("ChooseLibraryDirDialog", "Choose a library directory", nullptr, ".", 1, nullptr, ImGuiFileDialogFlags_Modal);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (!m_libraryManager.IsInitialized())
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255,0,0,255));
|
||||
ImGui::Text("No any library directory set. Please select one where stories will be located.");
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text("Library path: %s", m_libraryManager.LibraryPath().c_str());
|
||||
}
|
||||
|
||||
if (ImGui::Button("Scan library"))
|
||||
{
|
||||
m_libraryManager.Scan();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Import story"))
|
||||
{
|
||||
ImGuiFileDialog::Instance()->OpenDialogWithPane("ImportStoryDlgKey", "Import story", "", "", InfosPane);
|
||||
}
|
||||
|
||||
if (m_libraryManager.IsInitialized())
|
||||
{
|
||||
static ImGuiTableFlags tableFlags =
|
||||
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable
|
||||
| ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti
|
||||
| ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_NoBordersInBody
|
||||
| ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
|
||||
| ImGuiTableFlags_SizingFixedFit;
|
||||
|
||||
if (ImGui::BeginTable("library_table", 2, tableFlags))
|
||||
{
|
||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed);
|
||||
|
||||
ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed);
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (auto &p : m_libraryManager)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", p->GetName().c_str());
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (ImGui::SmallButton("Load"))
|
||||
{
|
||||
auto filename = std::filesystem::path(m_libraryManager.LibraryPath()) / p->GetUuid() / std::filesystem::path("project.json");
|
||||
m_storyManager.OpenProject(filename);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::SmallButton("Remove"))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------- ADD EXISTING STORY TELLER STORY
|
||||
if (ImGuiFileDialog::Instance()->Display("ImportStoryDlgKey"))
|
||||
{
|
||||
if (ImGuiFileDialog::Instance()->IsOk())
|
||||
{
|
||||
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
|
||||
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
|
||||
std::string filter = ImGuiFileDialog::Instance()->GetCurrentFilter();
|
||||
// here convert from string because a string was passed as a userDatas, but it can be what you want
|
||||
// std::string userDatas;
|
||||
// if (ImGuiFileDialog::Instance()->GetUserDatas())
|
||||
// userDatas = std::string((const char*)ImGuiFileDialog::Instance()->GetUserDatas());
|
||||
// auto selection = ImGuiFileDialog::Instance()->GetSelection(); // multiselection
|
||||
|
||||
// action
|
||||
}
|
||||
// close
|
||||
ImGuiFileDialog::Instance()->Close();
|
||||
}
|
||||
|
||||
|
||||
// ---------------- CHOOSE LIBRARY DIR
|
||||
if (ImGuiFileDialog::Instance()->Display("ChooseLibraryDirDialog"))
|
||||
{
|
||||
// action if OK
|
||||
if (ImGuiFileDialog::Instance()->IsOk())
|
||||
{
|
||||
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
|
||||
std::string projdir = ImGuiFileDialog::Instance()->GetCurrentPath();
|
||||
|
||||
if (std::filesystem::is_directory(projdir))
|
||||
{
|
||||
m_libraryManager.Initialize(projdir);
|
||||
}
|
||||
}
|
||||
|
||||
// close
|
||||
ImGuiFileDialog::Instance()->Close();
|
||||
}
|
||||
|
||||
|
||||
WindowBase::EndDraw();
|
||||
}
|
||||
|
||||
20
story-editor/src/library_window.h
Normal file
20
story-editor/src/library_window.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "window_base.h"
|
||||
#include "library_manager.h"
|
||||
#include "i_story_manager.h"
|
||||
|
||||
class LibraryWindow : public WindowBase
|
||||
{
|
||||
public:
|
||||
LibraryWindow(IStoryManager &project, LibraryManager &library);
|
||||
|
||||
void Initialize();
|
||||
virtual void Draw() override;
|
||||
|
||||
private:
|
||||
IStoryManager &m_storyManager;
|
||||
LibraryManager &m_libraryManager;
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
#include "main_window.h"
|
||||
#include <filesystem>
|
||||
#include <random>
|
||||
#include <SDL.h>
|
||||
#include "platform_folders.h"
|
||||
#include "uuid.h"
|
||||
|
|
@ -19,17 +18,14 @@
|
|||
#include "IconsMaterialDesignIcons.h"
|
||||
#include "ImGuiFileDialog.h"
|
||||
|
||||
static std::string gVersion;
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: m_emulatorWindow(*this)
|
||||
, m_resourcesWindow(*this)
|
||||
, m_nodeEditorWindow(*this)
|
||||
, m_libraryWindow(*this, m_libraryManager)
|
||||
, m_player(*this)
|
||||
|
||||
{
|
||||
|
||||
gVersion = std::to_string(VERSION_MAJOR) + '.' + std::to_string(VERSION_MINOR) + '.' + std::to_string(VERSION_PATCH);
|
||||
|
||||
// VM Initialize
|
||||
m_chip32_ctx.stack_size = 512;
|
||||
|
||||
|
|
@ -51,7 +47,7 @@ MainWindow::MainWindow()
|
|||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
|
||||
SaveParams();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -270,7 +266,7 @@ void MainWindow::DrawMainMenuBar()
|
|||
{
|
||||
showNewProject = true;
|
||||
}
|
||||
|
||||
/*
|
||||
if (ImGui::MenuItem("Open project"))
|
||||
{
|
||||
showOpenProject = true;
|
||||
|
|
@ -279,17 +275,22 @@ void MainWindow::DrawMainMenuBar()
|
|||
if (ImGui::BeginMenu("Open Recent"))
|
||||
{
|
||||
for (auto &e : m_recentProjects)
|
||||
{
|
||||
if (e.size() > 0)
|
||||
{
|
||||
if (ImGui::MenuItem(e.c_str()))
|
||||
{
|
||||
OpenProject(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
*/
|
||||
|
||||
if (!m_story.IsInitialized())
|
||||
bool init = m_story.IsInitialized(); // local copy because CloseProject() changes the status between BeginDisabled/EndDisabled
|
||||
if (!init)
|
||||
ImGui::BeginDisabled();
|
||||
|
||||
ImGui::Separator();
|
||||
|
|
@ -308,7 +309,7 @@ void MainWindow::DrawMainMenuBar()
|
|||
showParameters = true;
|
||||
}
|
||||
|
||||
if (!m_story.IsInitialized())
|
||||
if (!init)
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::EndMenu();
|
||||
|
|
@ -359,7 +360,7 @@ void MainWindow::DrawMainMenuBar()
|
|||
|
||||
if (ImGui::BeginPopupModal("AboutPopup", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
{
|
||||
ImGui::Text("Story Editor - v%s", gVersion.c_str());
|
||||
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");
|
||||
|
|
@ -505,7 +506,6 @@ void MainWindow::ProjectPropertiesPopup()
|
|||
ImGuiFileDialog::Instance()->OpenDialog("ChooseDirDialog", "Choose File", nullptr, ".", 1, nullptr, ImGuiFileDialogFlags_Modal);
|
||||
}
|
||||
|
||||
|
||||
// display
|
||||
if (ImGuiFileDialog::Instance()->Display("ChooseDirDialog"))
|
||||
{
|
||||
|
|
@ -681,8 +681,7 @@ void MainWindow::SaveProject()
|
|||
|
||||
void MainWindow::OpenProject(const std::string &filename)
|
||||
{
|
||||
m_story.Initialize(filename);
|
||||
|
||||
CloseProject();
|
||||
nlohmann::json model;
|
||||
|
||||
if (m_story.Load(filename, model, m_resources))
|
||||
|
|
@ -720,7 +719,7 @@ void MainWindow::OpenProject(const std::string &filename)
|
|||
|
||||
void MainWindow::RefreshProjectInformation()
|
||||
{
|
||||
std::string fullText = "Story Editor " + gVersion + " - " + m_story.GetProjectFilePath();
|
||||
std::string fullText = "Story Editor " + LibraryManager::GetVersion() + " - " + m_story.GetProjectFilePath();
|
||||
m_gui.SetWindowTitle(fullText);
|
||||
}
|
||||
|
||||
|
|
@ -738,7 +737,6 @@ void MainWindow::CloseProject()
|
|||
|
||||
m_nodeEditorWindow.Disable();
|
||||
m_emulatorWindow.Disable();
|
||||
m_consoleWindow.Disable();
|
||||
m_editorWindow.Disable();
|
||||
m_resourcesWindow.Disable();
|
||||
m_PropertiesWindow.Disable();
|
||||
|
|
@ -768,14 +766,20 @@ void MainWindow::Loop()
|
|||
|
||||
|
||||
// ------------ Draw all windows
|
||||
m_libraryWindow.Draw();
|
||||
|
||||
if (m_libraryManager.IsInitialized())
|
||||
{
|
||||
m_consoleWindow.Draw();
|
||||
m_emulatorWindow.Draw();
|
||||
m_editorWindow.Draw();
|
||||
m_resourcesWindow.Draw();
|
||||
m_nodeEditorWindow.Draw();
|
||||
|
||||
|
||||
m_PropertiesWindow.SetSelectedNode(m_nodeEditorWindow.GetSelectedNode());
|
||||
m_PropertiesWindow.Draw();
|
||||
}
|
||||
|
||||
NewProjectPopup();
|
||||
OpenProjectDialog();
|
||||
|
|
@ -798,6 +802,7 @@ void MainWindow::Loop()
|
|||
m_gui.Destroy();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::Log(const std::string &txt, bool critical)
|
||||
{
|
||||
m_consoleWindow.AddLog(txt, critical ? 1 : 0);
|
||||
|
|
@ -1007,6 +1012,7 @@ void MainWindow::SaveParams()
|
|||
nlohmann::json recents(m_recentProjects);
|
||||
|
||||
j["recents"] = recents;
|
||||
j["library_path"] = m_libraryManager.LibraryPath();
|
||||
|
||||
std::string loc = pf::getConfigHome() + "/ost_settings.json";
|
||||
std::ofstream o(loc);
|
||||
|
|
@ -1032,6 +1038,14 @@ void MainWindow::LoadParams()
|
|||
m_recentProjects.push_back(element);
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json library_path = j["library_path"];
|
||||
|
||||
if (std::filesystem::exists(library_path))
|
||||
{
|
||||
m_libraryManager.Initialize(library_path);
|
||||
}
|
||||
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include "i_story_manager.h"
|
||||
#include "thread_safe_queue.h"
|
||||
#include "audio_player.h"
|
||||
#include "library_manager.h"
|
||||
#include "library_window.h"
|
||||
|
||||
struct DebugContext
|
||||
{
|
||||
|
|
@ -110,6 +112,8 @@ private:
|
|||
|
||||
ResourceManager m_resources;
|
||||
|
||||
LibraryManager m_libraryManager;
|
||||
|
||||
Gui m_gui;
|
||||
EmulatorWindow m_emulatorWindow;
|
||||
ConsoleWindow m_consoleWindow;
|
||||
|
|
@ -121,6 +125,8 @@ private:
|
|||
|
||||
PropertiesWindow m_PropertiesWindow;
|
||||
|
||||
LibraryWindow m_libraryWindow;
|
||||
|
||||
AudioPlayer m_player;
|
||||
|
||||
struct VmEvent
|
||||
|
|
@ -132,6 +138,7 @@ private:
|
|||
|
||||
|
||||
// From IStoryManager (proxy to StoryProject class)
|
||||
virtual void OpenProject(const std::string &filename) override;
|
||||
virtual void Log(const std::string &txt, bool critical = false) override;
|
||||
virtual void PlaySoundFile(const std::string &fileName) override;;
|
||||
virtual std::string BuildFullAssetsPath(const std::string &fileName) const override;
|
||||
|
|
@ -162,7 +169,6 @@ private:
|
|||
|
||||
void NewProjectPopup();
|
||||
void SaveProject();
|
||||
void OpenProject(const std::string &filename);
|
||||
void CloseProject();
|
||||
void OpenProjectDialog();
|
||||
void DrawStatusBar();
|
||||
|
|
|
|||
Loading…
Reference in a new issue