mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
SDL 3 + curl thread download manager
This commit is contained in:
parent
001034db61
commit
42c3d9d215
11 changed files with 313 additions and 145 deletions
|
|
@ -12,9 +12,16 @@ LibraryManager::LibraryManager() {}
|
||||||
void LibraryManager::Initialize(const std::string &library_path)
|
void LibraryManager::Initialize(const std::string &library_path)
|
||||||
{
|
{
|
||||||
m_library_path = library_path;
|
m_library_path = library_path;
|
||||||
|
CheckDirectories();
|
||||||
Scan();
|
Scan();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LibraryManager::CheckDirectories()
|
||||||
|
{
|
||||||
|
std::filesystem::path dlDir = std::filesystem::path(m_library_path) / "store";
|
||||||
|
std::filesystem::create_directories(dlDir);
|
||||||
|
}
|
||||||
|
|
||||||
void LibraryManager::Scan()
|
void LibraryManager::Scan()
|
||||||
{
|
{
|
||||||
std::filesystem::path directoryPath(m_library_path);
|
std::filesystem::path directoryPath(m_library_path);
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,17 @@ public:
|
||||||
void Scan();
|
void Scan();
|
||||||
|
|
||||||
std::shared_ptr<StoryProject> NewProject();
|
std::shared_ptr<StoryProject> NewProject();
|
||||||
|
void CheckDirectories();
|
||||||
|
|
||||||
std::shared_ptr<StoryProject> GetStory(const std::string &uuid);
|
std::shared_ptr<StoryProject> GetStory(const std::string &uuid);
|
||||||
|
|
||||||
|
void SetStoreUrl(const std::string &store_url) { m_storeUrl = store_url; }
|
||||||
|
std::string GetStoreUrl() const { return m_storeUrl; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_library_path;
|
std::string m_library_path;
|
||||||
std::vector<std::shared_ptr<StoryProject>> m_projectsList;
|
std::vector<std::shared_ptr<StoryProject>> m_projectsList;
|
||||||
|
std::string m_storeUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LIBRARYMANAGER_H
|
#endif // LIBRARYMANAGER_H
|
||||||
|
|
|
||||||
|
|
@ -60,24 +60,36 @@ add_compile_definitions(IMGUI_INCLUDE="imgui.h")
|
||||||
add_subdirectory(libs/ImGuiFileDialog)
|
add_subdirectory(libs/ImGuiFileDialog)
|
||||||
|
|
||||||
# =========================================================================================================================
|
# =========================================================================================================================
|
||||||
# SDL
|
# SDL2
|
||||||
# =========================================================================================================================
|
# =========================================================================================================================
|
||||||
Set(FETCHCONTENT_QUIET FALSE)
|
|
||||||
|
|
||||||
|
# FetchContent_Declare(
|
||||||
|
# sdl2
|
||||||
|
# GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
||||||
|
# GIT_TAG origin/SDL2
|
||||||
|
# GIT_SHALLOW TRUE
|
||||||
|
# GIT_PROGRESS TRUE
|
||||||
|
# )
|
||||||
|
|
||||||
|
# set(BUILD_SHARED_LIBS TRUE)
|
||||||
|
# set(SDL_STATIC TRUE)
|
||||||
|
# FetchContent_MakeAvailable(sdl2)
|
||||||
|
|
||||||
|
# =========================================================================================================================
|
||||||
|
# SDL3
|
||||||
|
# =========================================================================================================================
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
sdl2
|
sdl3
|
||||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
||||||
GIT_TAG origin/SDL2
|
GIT_TAG prerelease-3.1.0
|
||||||
GIT_SHALLOW TRUE
|
GIT_SHALLOW TRUE
|
||||||
GIT_PROGRESS TRUE
|
GIT_PROGRESS TRUE
|
||||||
)
|
)
|
||||||
|
|
||||||
set(BUILD_SHARED_LIBS TRUE)
|
set(BUILD_SHARED_LIBS TRUE)
|
||||||
set(SDL_STATIC TRUE)
|
set(SDL_STATIC TRUE)
|
||||||
FetchContent_MakeAvailable(sdl2)
|
FetchContent_MakeAvailable(sdl3)
|
||||||
|
include_directories(${sdl3_SOURCE_DIR}/include)
|
||||||
# add_subdirectory(libs/SDL)
|
|
||||||
# include_directories(libs/SDL/include)
|
|
||||||
|
|
||||||
# =========================================================================================================================
|
# =========================================================================================================================
|
||||||
# SDL3-Image
|
# SDL3-Image
|
||||||
|
|
@ -155,8 +167,8 @@ set(SRCS
|
||||||
libs/imgui-node-editor/crude_json.cpp
|
libs/imgui-node-editor/crude_json.cpp
|
||||||
libs/ImGuiFileDialog/ImGuiFileDialog.cpp
|
libs/ImGuiFileDialog/ImGuiFileDialog.cpp
|
||||||
|
|
||||||
${imgui_SOURCE_DIR}/backends/imgui_impl_sdl2.cpp
|
${imgui_SOURCE_DIR}/backends/imgui_impl_sdl3.cpp
|
||||||
${imgui_SOURCE_DIR}/backends/imgui_impl_sdlrenderer2.cpp
|
${imgui_SOURCE_DIR}/backends/imgui_impl_sdlrenderer3.cpp
|
||||||
${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
|
${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
|
||||||
${imgui_SOURCE_DIR}/imgui.cpp
|
${imgui_SOURCE_DIR}/imgui.cpp
|
||||||
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
||||||
|
|
@ -243,16 +255,17 @@ target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC cimg_display=0)
|
||||||
|
|
||||||
target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC "$<$<CONFIG:DEBUG>:DEBUG>")
|
target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC "$<$<CONFIG:DEBUG>:DEBUG>")
|
||||||
|
|
||||||
target_link_directories(${STORY_EDITOR_PROJECT} PUBLIC ${sdl2_BINARY_DIR} ${curl_BINARY_DIR})
|
target_link_directories(${STORY_EDITOR_PROJECT} PUBLIC ${sdl3_BINARY_DIR} ${curl_BINARY_DIR})
|
||||||
message(${sdl2_BINARY_DIR})
|
|
||||||
set(SDL2_BIN_DIR ${sdl2_BINARY_DIR})
|
|
||||||
|
set(SDL2_BIN_DIR ${sdl3_BINARY_DIR})
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
target_link_libraries(${STORY_EDITOR_PROJECT}
|
target_link_libraries(${STORY_EDITOR_PROJECT}
|
||||||
pthread
|
pthread
|
||||||
OpenGL::GL
|
OpenGL::GL
|
||||||
dl
|
dl
|
||||||
SDL2
|
SDL3
|
||||||
libcurl_static
|
libcurl_static
|
||||||
OpenSSL::SSL OpenSSL::Crypto
|
OpenSSL::SSL OpenSSL::Crypto
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -11,23 +11,34 @@ your use of the corresponding standard functions.
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
#include "imgui_impl_sdl2.h"
|
|
||||||
#include "imgui_impl_sdlrenderer2.h"
|
#include "imgui_internal.h"
|
||||||
#include <stdio.h>
|
// SDL2 ---------------------------------
|
||||||
#include <SDL2/SDL.h>
|
// #include "imgui_impl_sdl2.h"
|
||||||
|
// #include "imgui_impl_sdlrenderer2.h"
|
||||||
|
// #include <SDL2/SDL.h>
|
||||||
|
// #if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||||
|
// #include <SDL2/SDL_opengles2.h>
|
||||||
|
// #else
|
||||||
|
// #include <SDL2/SDL_opengl.h>
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
// SDL3 ---------------------------------
|
||||||
|
#include "imgui_impl_sdl3.h"
|
||||||
|
#include "imgui_impl_sdlrenderer3.h"
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||||
#include <SDL2/SDL_opengles2.h>
|
#include <SDL3/SDL_opengles2.h>
|
||||||
#else
|
#else
|
||||||
#include <SDL2/SDL_opengl.h>
|
#include <SDL3/SDL_opengl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "IconsMaterialDesignIcons.h"
|
#include "IconsMaterialDesignIcons.h"
|
||||||
#include "IconsFontAwesome5_c.h"
|
#include "IconsFontAwesome5_c.h"
|
||||||
#include "qoi.h"
|
#include "qoi.h"
|
||||||
|
|
||||||
|
|
||||||
#include "platform_folders.h"
|
|
||||||
|
|
||||||
static void glfw_error_callback(int error, const char* description)
|
static void glfw_error_callback(int error, const char* description)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
|
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
|
||||||
|
|
@ -50,8 +61,6 @@ static std::string GetFileExtension(const std::string &fileName)
|
||||||
// Simple helper function to load an image into a OpenGL texture with common settings
|
// Simple helper function to load an image into a OpenGL texture with common settings
|
||||||
bool LoadTextureFromFile(const char* filename, Gui::Image &img)
|
bool LoadTextureFromFile(const char* filename, Gui::Image &img)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
std::string ext = GetFileExtension(filename);
|
std::string ext = GetFileExtension(filename);
|
||||||
|
|
||||||
SDL_Surface* surface = nullptr;
|
SDL_Surface* surface = nullptr;
|
||||||
|
|
@ -64,8 +73,12 @@ bool LoadTextureFromFile(const char* filename, Gui::Image &img)
|
||||||
img.w = desc.width;
|
img.w = desc.width;
|
||||||
img.h = desc.height;
|
img.h = desc.height;
|
||||||
|
|
||||||
surface = SDL_CreateRGBSurfaceFrom((void*)pixels, img.w, img.h, channels * 8, channels * img.w,
|
// SDL3
|
||||||
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
surface = SDL_CreateSurfaceFrom((void*)pixels, img.w, img.h, 4 * img.w, SDL_PIXELFORMAT_RGBA8888);
|
||||||
|
|
||||||
|
// SDL2
|
||||||
|
// surface = SDL_CreateRGBSurfaceFrom((void*)pixels, img.w, img.h, channels * 8, channels * img.w,
|
||||||
|
// 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||||
|
|
||||||
if (pixels != NULL)
|
if (pixels != NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -85,11 +98,11 @@ bool LoadTextureFromFile(const char* filename, Gui::Image &img)
|
||||||
|
|
||||||
|
|
||||||
//SDL3
|
//SDL3
|
||||||
// SDL_Surface* surface = SDL_CreateSurfaceFrom((void*)data, img.w, img.h, 4 * img.w, SDL_PIXELFORMAT_RGBA8888);
|
surface = SDL_CreateSurfaceFrom((void*)data, img.w, img.h, 4 * img.w, SDL_PIXELFORMAT_RGBA32);
|
||||||
|
|
||||||
// SDL2
|
// SDL2
|
||||||
surface = SDL_CreateRGBSurfaceFrom((void*)data, img.w, img.h, channels * 8, channels * img.w,
|
// surface = SDL_CreateRGBSurfaceFrom((void*)data, img.w, img.h, channels * 8, channels * img.w,
|
||||||
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
// 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,8 +118,8 @@ bool LoadTextureFromFile(const char* filename, Gui::Image &img)
|
||||||
fprintf(stderr, "Failed to create SDL texture: %s\n", SDL_GetError());
|
fprintf(stderr, "Failed to create SDL texture: %s\n", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
// SDL_DestroySurface(surface); // SDL3
|
SDL_DestroySurface(surface); // SDL3
|
||||||
SDL_FreeSurface(surface); // SDL2
|
// SDL_FreeSurface(surface); // SDL2
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -129,8 +142,11 @@ Gui::Gui()
|
||||||
|
|
||||||
bool Gui::Initialize()
|
bool Gui::Initialize()
|
||||||
{
|
{
|
||||||
// Setup SDL
|
// Setup SDL2
|
||||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
|
// if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
|
||||||
|
|
||||||
|
// Setup SDL3
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMEPAD) != 0)
|
||||||
{
|
{
|
||||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -143,17 +159,17 @@ bool Gui::Initialize()
|
||||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN);
|
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN);
|
||||||
|
|
||||||
// SDL3
|
// SDL3
|
||||||
//window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", 1280, 720, window_flags);
|
window = SDL_CreateWindow("Story Editor", 1280, 720, window_flags);
|
||||||
|
|
||||||
// SDL2
|
// SDL2
|
||||||
window = SDL_CreateWindow("Story Editor", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
// window = SDL_CreateWindow("Story Editor", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
||||||
|
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
renderer = SDL_CreateRenderer(window, nullptr, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||||
if (renderer == nullptr)
|
if (renderer == nullptr)
|
||||||
{
|
{
|
||||||
SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError());
|
SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError());
|
||||||
|
|
@ -170,6 +186,7 @@ bool Gui::Initialize()
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||||
|
|
||||||
|
|
||||||
io.Fonts->AddFontFromFileTTF( std::string(m_executablePath + "/fonts/roboto.ttf").c_str(), 20);
|
io.Fonts->AddFontFromFileTTF( std::string(m_executablePath + "/fonts/roboto.ttf").c_str(), 20);
|
||||||
|
|
@ -201,13 +218,12 @@ bool Gui::Initialize()
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
|
|
||||||
// SDL3
|
// SDL3
|
||||||
// ImGui_ImplSDL3_InitForSDLRenderer(window, renderer);
|
ImGui_ImplSDL3_InitForSDLRenderer(window, renderer);
|
||||||
// ImGui_ImplSDLRenderer3_Init(renderer);
|
ImGui_ImplSDLRenderer3_Init(renderer);
|
||||||
|
|
||||||
|
|
||||||
// SDL2
|
// SDL2
|
||||||
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
// ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
||||||
ImGui_ImplSDLRenderer2_Init(renderer);
|
// ImGui_ImplSDLRenderer2_Init(renderer);
|
||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
|
|
@ -237,20 +253,19 @@ bool Gui::PollEvent()
|
||||||
while (SDL_PollEvent(&event))
|
while (SDL_PollEvent(&event))
|
||||||
{
|
{
|
||||||
// SDL3
|
// SDL3
|
||||||
/*
|
|
||||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||||
if (event.type == SDL_EVENT_QUIT)
|
if (event.type == SDL_EVENT_QUIT)
|
||||||
done = true;
|
done = true;
|
||||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||||
done = true;
|
done = true;
|
||||||
*/
|
|
||||||
|
|
||||||
// SLD2
|
// SLD2
|
||||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
// ImGui_ImplSDL2_ProcessEvent(&event);
|
||||||
if (event.type == SDL_QUIT)
|
// if (event.type == SDL_QUIT)
|
||||||
done = true;
|
// done = true;
|
||||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
|
// if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
|
||||||
done = true;
|
// done = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
return done;
|
return done;
|
||||||
|
|
@ -262,12 +277,12 @@ void Gui::StartFrame()
|
||||||
// Start the Dear ImGui frame
|
// Start the Dear ImGui frame
|
||||||
|
|
||||||
// SDL3
|
// SDL3
|
||||||
// ImGui_ImplSDLRenderer3_NewFrame();
|
ImGui_ImplSDLRenderer3_NewFrame();
|
||||||
// ImGui_ImplSDL3_NewFrame();
|
ImGui_ImplSDL3_NewFrame();
|
||||||
|
|
||||||
// SDL2
|
// SDL2
|
||||||
ImGui_ImplSDLRenderer2_NewFrame();
|
// ImGui_ImplSDLRenderer2_NewFrame();
|
||||||
ImGui_ImplSDL2_NewFrame();
|
// ImGui_ImplSDL2_NewFrame();
|
||||||
|
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
}
|
}
|
||||||
|
|
@ -284,8 +299,8 @@ void Gui::EndFrame()
|
||||||
|
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
|
||||||
//ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData()); // SDL3
|
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData()); // SDL3
|
||||||
ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData()); // SDL2
|
// ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData()); // SDL2
|
||||||
|
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
}
|
}
|
||||||
|
|
@ -295,12 +310,12 @@ void Gui::Destroy()
|
||||||
// Cleanup
|
// Cleanup
|
||||||
|
|
||||||
// SDL3
|
// SDL3
|
||||||
// ImGui_ImplSDLRenderer3_Shutdown();
|
ImGui_ImplSDLRenderer3_Shutdown();
|
||||||
// ImGui_ImplSDL3_Shutdown();
|
ImGui_ImplSDL3_Shutdown();
|
||||||
|
|
||||||
// SDL2
|
// SDL2
|
||||||
ImGui_ImplSDLRenderer2_Shutdown();
|
// ImGui_ImplSDLRenderer2_Shutdown();
|
||||||
ImGui_ImplSDL2_Shutdown();
|
// ImGui_ImplSDL2_Shutdown();
|
||||||
|
|
||||||
|
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
@ -495,7 +510,7 @@ void Gui::ApplyTheme()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "imgui_internal.h"
|
|
||||||
namespace ImGui {
|
namespace ImGui {
|
||||||
void LoadingIndicatorCircle(const char* label, const float indicator_radius,
|
void LoadingIndicatorCircle(const char* label, const float indicator_radius,
|
||||||
const ImVec4& main_color, const ImVec4& backdrop_color,
|
const ImVec4& main_color, const ImVec4& backdrop_color,
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,10 @@ private:
|
||||||
std::string m_executablePath;
|
std::string m_executablePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace ImGui {
|
// namespace ImGui {
|
||||||
void LoadingIndicatorCircle(const char* label, const float indicator_radius,
|
// void LoadingIndicatorCircle(const char* label, const float indicator_radius,
|
||||||
const ImVec4& main_color, const ImVec4& backdrop_color,
|
// const ImVec4& main_color, const ImVec4& backdrop_color,
|
||||||
const int circle_count, const float speed);
|
// const int circle_count, const float speed);
|
||||||
}
|
// }
|
||||||
|
|
||||||
#endif // GUI_H
|
#endif // GUI_H
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,26 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Callback;
|
||||||
|
|
||||||
|
template <typename Ret, typename... Params>
|
||||||
|
struct Callback<Ret(Params...)> {
|
||||||
|
template <typename... Args>
|
||||||
|
static Ret callback(Args... args) {
|
||||||
|
return func(args...);
|
||||||
|
}
|
||||||
|
static std::function<Ret(Params...)> func;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Ret, typename... Params>
|
||||||
|
std::function<Ret(Params...)> Callback<Ret(Params...)>::func;
|
||||||
|
|
||||||
class IStoryManager
|
class IStoryManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -36,8 +52,6 @@ public:
|
||||||
virtual void Pause() = 0;
|
virtual void Pause() = 0;
|
||||||
virtual void Next() = 0;
|
virtual void Next() = 0;
|
||||||
virtual void Previous() = 0;
|
virtual void Previous() = 0;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // I_STORY_MANAGER_H
|
#endif // I_STORY_MANAGER_H
|
||||||
|
|
|
||||||
|
|
@ -3,61 +3,44 @@
|
||||||
#include "ImGuiFileDialog.h"
|
#include "ImGuiFileDialog.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "IconsMaterialDesignIcons.h"
|
#include "IconsMaterialDesignIcons.h"
|
||||||
|
#include "i_story_manager.h"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#define CPPHTTPLIB_OPENSSL_SUPPORT
|
typedef int (*xfer_callback_t)(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
|
||||||
#include "httplib.h"
|
curl_off_t ultotal, curl_off_t ulnow);
|
||||||
#define CA_CERT_FILE "./ca-bundle.crt"
|
|
||||||
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
int xfer_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
|
void download_file(CURL *curl,
|
||||||
curl_off_t ultotal, curl_off_t ulnow)
|
const std::string &url,
|
||||||
|
const std::string &output_file,
|
||||||
|
std::function<void(bool)> finished_callback)
|
||||||
{
|
{
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void download_file(const std::string &output_file = "pi.txt")
|
|
||||||
{
|
|
||||||
|
|
||||||
CURL *curl_download;
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
std::string url = "http://www.gecif.net/articles/mathematiques/pi/pi_1_million.txt";
|
|
||||||
|
|
||||||
curl_download = curl_easy_init();
|
if (curl)
|
||||||
|
|
||||||
if (curl_download)
|
|
||||||
{
|
{
|
||||||
//SetConsoleTextAttribute(hConsole, 11);
|
//SetConsoleTextAttribute(hConsole, 11);
|
||||||
fp = fopen(output_file.c_str(),"wb");
|
fp = fopen(output_file.c_str(),"wb");
|
||||||
|
|
||||||
curl_easy_setopt(curl_download, CURLOPT_URL, url.c_str());
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||||
curl_easy_setopt(curl_download, CURLOPT_WRITEFUNCTION, NULL);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||||
curl_easy_setopt(curl_download, CURLOPT_WRITEDATA, fp);
|
|
||||||
curl_easy_setopt(curl_download, CURLOPT_NOPROGRESS, 0);
|
|
||||||
//progress_bar : the fonction for the progress bar
|
|
||||||
curl_easy_setopt(curl_download, CURLOPT_XFERINFOFUNCTION, xfer_callback);
|
|
||||||
|
|
||||||
|
|
||||||
std::cout<<" Start download"<<std::endl<<std::endl;
|
std::cout<<" Start download"<<std::endl<<std::endl;
|
||||||
|
|
||||||
res = curl_easy_perform(curl_download);
|
res = curl_easy_perform(curl);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
if(res == CURLE_OK)
|
if(res == CURLE_OK)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::cout<< std::endl<< std::endl<<" The file was download with succes"<< std::endl;
|
std::cout<< std::endl<< std::endl<<" The file was download with succes"<< std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
std::cout<< std::endl << std::endl<<" Error"<< std::endl;
|
std::cout<< std::endl << std::endl<<" Error"<< std::endl;
|
||||||
}
|
}
|
||||||
curl_easy_cleanup(curl_download);
|
|
||||||
|
finished_callback(res == CURLE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -66,36 +49,78 @@ LibraryWindow::LibraryWindow(IStoryManager &project, LibraryManager &library)
|
||||||
, m_storyManager(project)
|
, m_storyManager(project)
|
||||||
, m_libraryManager(library)
|
, m_libraryManager(library)
|
||||||
{
|
{
|
||||||
|
m_downloadThread = std::thread( std::bind(&LibraryWindow::DownloadThread, this) );
|
||||||
|
|
||||||
download_file();
|
m_store_url[0] = 0;
|
||||||
|
|
||||||
httplib::SSLClient cli("gist.githubusercontent.com", 443);
|
|
||||||
cli.set_ca_cert_path(CA_CERT_FILE);
|
|
||||||
cli.enable_server_certificate_verification(false);
|
|
||||||
|
|
||||||
if (auto res = cli.Get("/UnofficialStories/32702fb104aebfe650d4ef8d440092c1/raw/luniicreations.json")) {
|
|
||||||
std::cout << res->status << std::endl;
|
|
||||||
std::cout << res->get_header_value("Content-Type") << std::endl;
|
|
||||||
m_storeRawJson = res->body;
|
|
||||||
ParseStoreData();
|
|
||||||
//std::cout << res->body << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << "error code: " << res.error() << std::endl;
|
|
||||||
|
|
||||||
auto result = cli.get_openssl_verify_result();
|
|
||||||
if (result) {
|
|
||||||
std::cout << "verify error: " << X509_verify_cert_error_string(result) <<std:: endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LibraryWindow::~LibraryWindow()
|
||||||
|
{
|
||||||
|
// Cancel any pending download
|
||||||
|
|
||||||
|
if (m_curl)
|
||||||
|
{
|
||||||
|
m_downloadMutex.lock();
|
||||||
|
m_cancel = true;
|
||||||
|
m_downloadMutex.unlock();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quit download thread
|
||||||
|
m_downloadQueue.push({"quit", ""});
|
||||||
|
if (m_downloadThread.joinable())
|
||||||
|
{
|
||||||
|
m_downloadThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_global_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LibraryWindow::ParseStoreData()
|
void LibraryWindow::DownloadThread()
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
auto cmd = m_downloadQueue.front();
|
||||||
|
m_downloadQueue.pop();
|
||||||
|
|
||||||
|
if (cmd.order == "quit")
|
||||||
|
{
|
||||||
|
curl_easy_cleanup(m_curl);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (cmd.order == "dl")
|
||||||
|
{
|
||||||
|
download_file(m_curl, cmd.url, cmd.filename, cmd.finished_callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int LibraryWindow::TransferCallback(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
|
||||||
|
curl_off_t ultotal, curl_off_t ulnow)
|
||||||
|
{
|
||||||
|
std::cout << "DL total: " << dltotal << ", now: " << dlnow << std::endl;
|
||||||
|
m_downloadMutex.lock();
|
||||||
|
bool cancel = m_cancel;
|
||||||
|
m_downloadMutex.unlock();
|
||||||
|
|
||||||
|
if (cancel)
|
||||||
|
{
|
||||||
|
return 1; // Annuler la requête curl
|
||||||
|
}
|
||||||
|
|
||||||
|
m_transferProgress.push(TransferProgress(dltotal, dlnow));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LibraryWindow::ParseStoreData(bool success)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
std::ifstream f(m_storeIndexFilename);
|
||||||
nlohmann::json j = nlohmann::json::parse(m_storeRawJson);
|
nlohmann::json j = nlohmann::json::parse(f);
|
||||||
|
|
||||||
m_store.clear();
|
m_store.clear();
|
||||||
for (const auto &obj : j)
|
for (const auto &obj : j)
|
||||||
|
|
@ -116,10 +141,27 @@ void LibraryWindow::ParseStoreData()
|
||||||
|
|
||||||
void LibraryWindow::Initialize()
|
void LibraryWindow::Initialize()
|
||||||
{
|
{
|
||||||
|
// Try to download the store index file
|
||||||
|
m_curl = curl_easy_init();
|
||||||
|
|
||||||
|
if (m_curl)
|
||||||
|
{
|
||||||
|
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, NULL);
|
||||||
|
curl_easy_setopt(m_curl, CURLOPT_NOPROGRESS, 0);
|
||||||
|
|
||||||
|
//progress_bar : the fonction for the progress bar
|
||||||
|
Callback<int(void *, curl_off_t, curl_off_t, curl_off_t, curl_off_t)>::func = std::bind(
|
||||||
|
&LibraryWindow::TransferCallback,
|
||||||
|
this,
|
||||||
|
std::placeholders::_1,
|
||||||
|
std::placeholders::_2,
|
||||||
|
std::placeholders::_3,
|
||||||
|
std::placeholders::_4,
|
||||||
|
std::placeholders::_5);
|
||||||
|
curl_easy_setopt(m_curl, CURLOPT_XFERINFOFUNCTION, static_cast<xfer_callback_t>(Callback<int(void *, curl_off_t, curl_off_t, curl_off_t, curl_off_t)>::callback));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool canValidateDialog = false;
|
static bool canValidateDialog = false;
|
||||||
inline void InfosPane(const char *vFilter, IGFDUserDatas vUserDatas, bool *vCantContinue) // if vCantContinue is false, the user cant validate the dialog
|
inline void InfosPane(const char *vFilter, IGFDUserDatas vUserDatas, bool *vCantContinue) // if vCantContinue is false, the user cant validate the dialog
|
||||||
|
|
@ -131,6 +173,14 @@ inline void InfosPane(const char *vFilter, IGFDUserDatas vUserDatas, bool *vCant
|
||||||
*vCantContinue = canValidateDialog;
|
*vCantContinue = canValidateDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string LibraryWindow::ToLocalStoreFile(const std::string &url)
|
||||||
|
{
|
||||||
|
auto filename = StoryProject::GetFileName(m_store_url);
|
||||||
|
|
||||||
|
filename = m_libraryManager.LibraryPath() + "/store/" + filename;
|
||||||
|
std::cout << "Store file: " << filename << std::endl;
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
void LibraryWindow::Draw()
|
void LibraryWindow::Draw()
|
||||||
{
|
{
|
||||||
|
|
@ -178,8 +228,6 @@ void LibraryWindow::Draw()
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
if (ImGui::BeginTabItem("Local library ##LocalTabBar", nullptr, ImGuiTabItemFlags_None))
|
if (ImGui::BeginTabItem("Local library ##LocalTabBar", nullptr, ImGuiTabItemFlags_None))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
if (ImGui::Button("Scan library"))
|
if (ImGui::Button("Scan library"))
|
||||||
{
|
{
|
||||||
m_libraryManager.Scan();
|
m_libraryManager.Scan();
|
||||||
|
|
@ -228,10 +276,45 @@ void LibraryWindow::Draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// LOCAL TABLE
|
// STORE STORY LIST
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
if (ImGui::BeginTabItem("Remote Store##StoreTabBar", nullptr, ImGuiTabItemFlags_None))
|
if (ImGui::BeginTabItem("Remote Store##StoreTabBar", nullptr, ImGuiTabItemFlags_None))
|
||||||
{
|
{
|
||||||
|
ImGui::InputTextWithHint("##store_url", "Store URL", m_store_url, IM_ARRAYSIZE(m_store_url));
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Load"))
|
||||||
|
{
|
||||||
|
m_storeIndexFilename = ToLocalStoreFile(m_store_url);
|
||||||
|
m_downloadQueue.push({
|
||||||
|
"dl",
|
||||||
|
m_store_url,
|
||||||
|
m_storeIndexFilename,
|
||||||
|
std::bind(&LibraryWindow::ParseStoreData, this, std::placeholders::_1)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static TransferProgress progressItem;
|
||||||
|
static std::string currentDownload;
|
||||||
|
static float progress = 0.0f;
|
||||||
|
if (m_transferProgress.try_pop(progressItem))
|
||||||
|
{
|
||||||
|
if (progressItem.total > 0)
|
||||||
|
{
|
||||||
|
// currentDownload = ""
|
||||||
|
progress += (progressItem.current / progressItem.total);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
progress = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width,
|
||||||
|
// or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth.
|
||||||
|
ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f));
|
||||||
|
// ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
|
||||||
|
// ImGui::Text("Current download: ");
|
||||||
|
|
||||||
if (ImGui::BeginTable("store_table", 3, tableFlags))
|
if (ImGui::BeginTable("store_table", 3, tableFlags))
|
||||||
{
|
{
|
||||||
ImGui::TableSetupColumn("Title", ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("Title", ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,41 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
#include "window_base.h"
|
#include "window_base.h"
|
||||||
#include "library_manager.h"
|
#include "library_manager.h"
|
||||||
#include "i_story_manager.h"
|
#include "i_story_manager.h"
|
||||||
|
#include "thread_safe_queue.h"
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
struct StoryInf {
|
struct StoryInf {
|
||||||
int age;
|
int age;
|
||||||
std::string title;
|
std::string title;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DownloadCommand {
|
||||||
|
std::string order;
|
||||||
|
std::string url;
|
||||||
|
std::string filename;
|
||||||
|
std::function<void(bool)> finished_callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct TransferProgress {
|
||||||
|
long total;
|
||||||
|
long current;
|
||||||
|
|
||||||
|
TransferProgress() {
|
||||||
|
total = 0;
|
||||||
|
current = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TransferProgress(int t, int c) {
|
||||||
|
total = t;
|
||||||
|
current = c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class LibraryWindow : public WindowBase
|
class LibraryWindow : public WindowBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -17,13 +44,27 @@ public:
|
||||||
void Initialize();
|
void Initialize();
|
||||||
virtual void Draw() override;
|
virtual void Draw() override;
|
||||||
|
|
||||||
|
~LibraryWindow();
|
||||||
private:
|
private:
|
||||||
IStoryManager &m_storyManager;
|
IStoryManager &m_storyManager;
|
||||||
LibraryManager &m_libraryManager;
|
LibraryManager &m_libraryManager;
|
||||||
|
|
||||||
|
CURL *m_curl;
|
||||||
|
char m_store_url[1024];
|
||||||
|
std::thread m_downloadThread;
|
||||||
|
ThreadSafeQueue<DownloadCommand> m_downloadQueue;
|
||||||
|
ThreadSafeQueue<TransferProgress> m_transferProgress;
|
||||||
|
std::mutex m_downloadMutex;
|
||||||
|
bool m_cancel{false};
|
||||||
|
|
||||||
std::vector<StoryInf> m_store;
|
std::vector<StoryInf> m_store;
|
||||||
|
std::string m_storeIndexFilename;
|
||||||
|
|
||||||
std::string m_storeRawJson;
|
std::string m_storeRawJson;
|
||||||
void ParseStoreData();
|
void ParseStoreData(bool success);
|
||||||
|
void DownloadThread();
|
||||||
|
int TransferCallback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
|
||||||
|
|
||||||
|
std::string ToLocalStoreFile(const std::string &url);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include "main_window.h"
|
#include "main_window.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include "platform_folders.h"
|
#include "platform_folders.h"
|
||||||
|
|
||||||
#include "media_converter.h"
|
#include "media_converter.h"
|
||||||
|
|
@ -372,6 +372,8 @@ void MainWindow::DrawMainMenuBar()
|
||||||
|
|
||||||
void MainWindow::Initialize()
|
void MainWindow::Initialize()
|
||||||
{
|
{
|
||||||
|
LoadParams();
|
||||||
|
|
||||||
// GUI Init
|
// GUI Init
|
||||||
m_gui.Initialize();
|
m_gui.Initialize();
|
||||||
// gui.ApplyTheme();
|
// gui.ApplyTheme();
|
||||||
|
|
@ -380,8 +382,9 @@ void MainWindow::Initialize()
|
||||||
m_emulatorWindow.Initialize();
|
m_emulatorWindow.Initialize();
|
||||||
m_nodeEditorWindow.Initialize();
|
m_nodeEditorWindow.Initialize();
|
||||||
m_PropertiesWindow.Initialize();
|
m_PropertiesWindow.Initialize();
|
||||||
|
m_libraryWindow.Initialize();
|
||||||
|
|
||||||
|
|
||||||
LoadParams();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -979,6 +982,9 @@ void MainWindow::LoadParams()
|
||||||
m_libraryManager.Initialize(library_path);
|
m_libraryManager.Initialize(library_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nlohmann::json store_url = j["store_url"];
|
||||||
|
m_libraryManager.SetStoreUrl(store_url);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -63,24 +63,6 @@ struct DebugContext
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct Callback;
|
|
||||||
|
|
||||||
template <typename Ret, typename... Params>
|
|
||||||
struct Callback<Ret(Params...)> {
|
|
||||||
template <typename... Args>
|
|
||||||
static Ret callback(Args... args) {
|
|
||||||
return func(args...);
|
|
||||||
}
|
|
||||||
static std::function<Ret(Params...)> func;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Ret, typename... Params>
|
|
||||||
std::function<Ret(Params...)> Callback<Ret(Params...)>::func;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MainWindow : public IStoryManager, public IAudioEvent
|
class MainWindow : public IStoryManager, public IAudioEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
#include "node_editor_window.h"
|
#include "node_editor_window.h"
|
||||||
|
|
||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue