mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
Open and draw a story teller project format
This commit is contained in:
parent
3c01a29c66
commit
8b13a63e6b
35 changed files with 14091 additions and 2209 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -59,3 +59,7 @@ story-editor-v2/src/CMakeSettings.json
|
|||
story-editor-v2/imgui.ini
|
||||
|
||||
story-editor-v2/src/.vscode/
|
||||
|
||||
build-story-editor-v2-Desktop-Debug/
|
||||
|
||||
build-story-editor-Desktop-Debug/
|
||||
|
|
|
|||
|
|
@ -22,64 +22,79 @@ if(POLICY CMP0072)
|
|||
endif()
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
set(IMGUI_VERSION 1.89.9)
|
||||
set(IMGUI_VERSION 1.90)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
|
||||
#=========================================================================================================================
|
||||
# IMGUI and plugins
|
||||
#=========================================================================================================================
|
||||
FetchContent_Declare(imgui
|
||||
URL https://github.com/ocornut/imgui/archive/refs/tags/v${IMGUI_VERSION}-docking.zip
|
||||
)
|
||||
|
||||
|
||||
FetchContent_GetProperties(imgui)
|
||||
if (NOT imgui_POPULATED) # Have we downloaded raylib yet?
|
||||
if (NOT imgui_POPULATED)
|
||||
set(FETCHCONTENT_QUIET NO)
|
||||
FetchContent_Populate(imgui)
|
||||
endif()
|
||||
|
||||
# ImGuiFileDialog
|
||||
include_directories(${imgui_SOURCE_DIR})
|
||||
add_compile_definitions(CUSTOM_IMGUIFILEDIALOG_CONFIG="${CMAKE_SOURCE_DIR}/src/CustomImGuiFileDialogConfig.h")
|
||||
add_compile_definitions(IMGUI_INCLUDE="imgui.h")
|
||||
add_subdirectory(libs/ImGuiFileDialog)
|
||||
|
||||
|
||||
#=========================================================================================================================
|
||||
# SDL3
|
||||
# SDL
|
||||
#=========================================================================================================================
|
||||
include(FetchContent)
|
||||
|
||||
Set(FETCHCONTENT_QUIET FALSE)
|
||||
|
||||
FetchContent_Declare(
|
||||
SDL3
|
||||
sdl2
|
||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
||||
GIT_TAG origin/main
|
||||
GIT_TAG origin/SDL2
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
)
|
||||
|
||||
set(BUILD_SHARED_LIBS TRUE)
|
||||
set(SDL_STATIC TRUE)
|
||||
FetchContent_MakeAvailable(SDL3)
|
||||
FetchContent_MakeAvailable(sdl2)
|
||||
#add_subdirectory(libs/SDL)
|
||||
#include_directories(libs/SDL/include)
|
||||
|
||||
|
||||
#=========================================================================================================================
|
||||
# SDL3-Image
|
||||
#=========================================================================================================================
|
||||
FetchContent_Declare(
|
||||
SDL2_image
|
||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git
|
||||
GIT_TAG origin/main
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
)
|
||||
#FetchContent_Declare(
|
||||
# SDL2_image
|
||||
# GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git
|
||||
# GIT_TAG origin/main
|
||||
# GIT_SHALLOW TRUE
|
||||
# GIT_PROGRESS TRUE
|
||||
#)
|
||||
|
||||
# START ADDITION
|
||||
set(SDL2IMAGE_INSTALL OFF)
|
||||
set(BUILD_SHARED_LIBS FALSE)
|
||||
# END ADDITION
|
||||
## START ADDITION
|
||||
#set(SDL2IMAGE_INSTALL OFF)
|
||||
#set(BUILD_SHARED_LIBS FALSE)
|
||||
## END ADDITION
|
||||
|
||||
FetchContent_MakeAvailable(SDL2_image)
|
||||
#FetchContent_MakeAvailable(SDL2_image)
|
||||
|
||||
|
||||
set(SRCS
|
||||
|
||||
src/main.cpp
|
||||
|
||||
src/window_base.h
|
||||
src/window_base.cpp
|
||||
|
||||
src/console_window.cpp
|
||||
src/console_window.h
|
||||
|
||||
|
|
@ -95,6 +110,9 @@ set(SRCS
|
|||
src/media_node.h
|
||||
src/media_node.cpp
|
||||
|
||||
src/platform_folders.cpp
|
||||
src/platform_folders.h
|
||||
|
||||
src/base_node.h
|
||||
src/base_node.cpp
|
||||
|
||||
|
|
@ -115,8 +133,8 @@ set(SRCS
|
|||
libs/imgui-node-editor/crude_json.cpp
|
||||
libs/ImGuiFileDialog/ImGuiFileDialog.cpp
|
||||
|
||||
${imgui_SOURCE_DIR}/backends/imgui_impl_sdl3.cpp
|
||||
${imgui_SOURCE_DIR}/backends/imgui_impl_sdlrenderer3.cpp
|
||||
${imgui_SOURCE_DIR}/backends/imgui_impl_sdl2.cpp
|
||||
${imgui_SOURCE_DIR}/backends/imgui_impl_sdlrenderer2.cpp
|
||||
${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
|
||||
${imgui_SOURCE_DIR}/imgui.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
||||
|
|
@ -144,11 +162,13 @@ endif()
|
|||
|
||||
add_executable(${STORY_EDITOR_PROJECT}
|
||||
${SRCS}
|
||||
src/uuid.h
|
||||
src/window_base.h src/window_base.cpp
|
||||
)
|
||||
|
||||
target_include_directories(${STORY_EDITOR_PROJECT} PUBLIC
|
||||
${imgui_SOURCE_DIR}
|
||||
${sdl3_SOURCE_DIR}/include
|
||||
${sdl2_SOURCE_DIR}/include
|
||||
libs/ImGuiColorTextEdit/
|
||||
${imgui_SOURCE_DIR}/backends
|
||||
libs/ImGuiFileDialog
|
||||
|
|
@ -159,21 +179,23 @@ target_include_directories(${STORY_EDITOR_PROJECT} PUBLIC
|
|||
)
|
||||
|
||||
|
||||
|
||||
add_definitions(-DIMGUI_USE_WCHAR32)
|
||||
add_link_options(-static-libgcc -static-libstdc++)
|
||||
|
||||
target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC cimg_display=0)
|
||||
|
||||
target_link_directories(${STORY_EDITOR_PROJECT} PUBLIC ${sdl3_BINARY_DIR})
|
||||
message(${sdl3_BINARY_DIR})
|
||||
target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC "$<$<CONFIG:DEBUG>:DEBUG>")
|
||||
|
||||
target_link_directories(${STORY_EDITOR_PROJECT} PUBLIC ${sdl2_BINARY_DIR})
|
||||
message(${sdl2_BINARY_DIR})
|
||||
if (UNIX)
|
||||
target_link_libraries(${STORY_EDITOR_PROJECT}
|
||||
pthread
|
||||
udev
|
||||
glfw
|
||||
OpenGL::GL
|
||||
dl
|
||||
SDL3
|
||||
SDL2
|
||||
)
|
||||
elseif(WIN32)
|
||||
target_link_libraries(${STORY_EDITOR_PROJECT}
|
||||
|
|
|
|||
15
story-editor-v2/libs/ImGuiFileDialog/CMakeLists.txt
Normal file
15
story-editor-v2/libs/ImGuiFileDialog/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(ImGuiFileDialog)
|
||||
|
||||
add_library(ImGuiFileDialog STATIC
|
||||
ImGuiFileDialog.cpp
|
||||
ImGuiFileDialog.h
|
||||
ImGuiFileDialogConfig.h
|
||||
)
|
||||
|
||||
target_include_directories(ImGuiFileDialog PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if(UNIX)
|
||||
target_compile_options(ImGuiFileDialog PUBLIC "-Wno-unknown-pragmas")
|
||||
endif()
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -43,21 +43,21 @@ SOFTWARE.
|
|||
/*
|
||||
// generated with "Text to ASCII Art Generator (TAAG)"
|
||||
// https://patorjk.com/software/taag/#p=display&h=1&v=0&f=Big&t=ImGuiFileDialog%0Av0.6.5
|
||||
_____ _____ _ ______ _ _ _____ _ _
|
||||
|_ _| / ____| (_) ____(_) | | __ \(_) | |
|
||||
| | _ __ ___ | | __ _ _ _| |__ _| | ___| | | |_ __ _| | ___ __ _
|
||||
| | | '_ ` _ \| | |_ | | | | | __| | | |/ _ \ | | | |/ _` | |/ _ \ / _` |
|
||||
_| |_| | | | | | |__| | |_| | | | | | | __/ |__| | | (_| | | (_) | (_| |
|
||||
|_____|_| |_| |_|\_____|\__,_|_|_| |_|_|\___|_____/|_|\__,_|_|\___/ \__, |
|
||||
_________________________________________________________________________/ |
|
||||
|__________________________________________________________________________/
|
||||
___ __ __
|
||||
/ _ \ / / / /
|
||||
__ __| | | | / /_ / /_
|
||||
\ \ / /| | | | | '_ \ | '_ \
|
||||
\ V / | |_| |_| (_) |_| (_) |
|
||||
\_/ \___/(_)\___/(_)\___/
|
||||
|
||||
_____ _____ _ ______ _ _ _____ _ _
|
||||
|_ _| / ____| (_)| ____|(_)| | | __ \ (_) | |
|
||||
| | _ __ ___ | | __ _ _ _ | |__ _ | | ___ | | | | _ __ _ | | ___ __ _
|
||||
| | | '_ ` _ \ | | |_ || | | || || __| | || | / _ \| | | || | / _` || | / _ \ / _` |
|
||||
_| |_ | | | | | || |__| || |_| || || | | || || __/| |__| || || (_| || || (_) || (_| |
|
||||
|_____||_| |_| |_| \_____| \__,_||_||_| |_||_| \___||_____/ |_| \__,_||_| \___/ \__, |
|
||||
__/ |
|
||||
|___/
|
||||
___ __ ______
|
||||
/ _ \ / / |____ |
|
||||
__ __| | | | / /_ / /
|
||||
\ \ / /| | | | | '_ \ / /
|
||||
\ V / | |_| |_| (_) |_ / /
|
||||
\_/ \___/(_)\___/(_)/_/
|
||||
|
||||
github repo : https://github.com/aiekick/ImGuiFileDialog
|
||||
this section is the content of the ReadMe.md file
|
||||
|
|
@ -73,7 +73,7 @@ solutions.
|
|||
|
||||
## ImGui Supported Version
|
||||
|
||||
ImGuiFileDialog follow the master and docking branch of ImGui . currently ImGui 1.89.7 WIP
|
||||
ImGuiFileDialog follow the master and docking branch of ImGui . currently ImGui 1.90.1 WIP
|
||||
|
||||
## Structure
|
||||
|
||||
|
|
@ -760,7 +760,7 @@ ImGuiFileDialog::Instance()->ManageGPUThumbnails();
|
|||
|
||||
The dialog can be embedded in another user frame than the standard or modal dialog
|
||||
|
||||
You have to create a variable of type ImGuiFileDialog. (if you are suing the singleton, you will not have the
|
||||
You have to create a variable of type ImGuiFileDialog. (if you are using the singleton, you will not have the
|
||||
possibility to open other dialog)
|
||||
|
||||
ex :
|
||||
|
|
@ -769,7 +769,7 @@ ex :
|
|||
ImGuiFileDialog fileDialog;
|
||||
|
||||
// open dialog; in this case, Bookmark, directory creation are disabled with, and also the file input field is readonly.
|
||||
// btw you can od what you want
|
||||
// btw you can do what you want
|
||||
fileDialog.OpenDialog("embedded", "Select File", ".*", "", -1, nullptr,
|
||||
ImGuiFileDialogFlags_NoDialog |
|
||||
ImGuiFileDialogFlags_DisableBookmarkMode |
|
||||
|
|
@ -790,8 +790,8 @@ the result :
|
|||
you have a separator between two directories in the path composer
|
||||
when you click on it you can explore a list of parrallels directories of this point
|
||||
|
||||
this feature is disabled by default
|
||||
you can enable it with the compiler flag : flags
|
||||
this feature is enabled by default
|
||||
you can disable it with the flag : ImGuiFileDialogFlags_DisableQuickPathSelection
|
||||
|
||||
you can also customize the spacing between path button's with and without this mode
|
||||
you can do that by define the compiler flag : #define CUSTOM_PATH_SPACING 2
|
||||
|
|
@ -915,7 +915,7 @@ but you can modify them.
|
|||
|
||||
There is 3 Modes :
|
||||
```cpp
|
||||
IGFD_ResultMode_AddIfNoFileExt [DEFAULT for
|
||||
IGFD_ResultMode_AddIfNoFileExt [DEFAULT]
|
||||
This mode add the filter ext only if there is no file ext. (compatible multi layer)
|
||||
ex :
|
||||
filter {.cpp,.h} with file :
|
||||
|
|
@ -981,6 +981,27 @@ to note :
|
|||
a collection {.a, .b.z} is a two dots filter, so a file toto.g.z will be replaced by toto.a
|
||||
a collection {.z; .b} is a one dot filter, so a file toto.g.z will be replaced by toto.g.a
|
||||
|
||||
################################################################
|
||||
## Custom FileSystem
|
||||
################################################################
|
||||
|
||||
you can use your custom file system interface.
|
||||
|
||||
by default IGFD come with the File System Interfaces for Dirent or std::filesystem
|
||||
but you have now a FileSystem interface called IFileSystem who can be overrided with your needs
|
||||
by ex for android, emscripten, or boost
|
||||
|
||||
2 steps :
|
||||
|
||||
1) create a include file who must contain :
|
||||
- your override of IGFD::IFileSystem
|
||||
- a define of your class name in FILE_SYSTEM_OVERRIDE (ex : #define FILE_SYSTEM_OVERRIDE FileSystemBoost)
|
||||
|
||||
2) define your file system include file path in the preprocessor var "CUSTOM_FILESYSTEM_INCLUDE"
|
||||
ex : #define CUSTOM_FILESYSTEM_INCLUDE "src/FileSystemBoost.hpp"
|
||||
|
||||
you can check the DemoApp who is using an override for the Boost::filesystem
|
||||
|
||||
################################################################
|
||||
## How to Integrate ImGuiFileDialog in your project
|
||||
################################################################
|
||||
|
|
@ -1100,8 +1121,8 @@ The Custom Icon Font (in CustomFont.cpp and CustomFont.h) was made with ImGuiFon
|
|||
|
||||
#pragma region IGFD VERSION
|
||||
|
||||
// compatible with 1.89.7 WIP
|
||||
#define IMGUIFILEDIALOG_VERSION "v0.6.6"
|
||||
// compatible with 1.90.1 WIP
|
||||
#define IMGUIFILEDIALOG_VERSION "v0.6.7"
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
|
@ -1127,8 +1148,7 @@ enum IGFD_FileStyleFlags_ // by evaluation / priority order
|
|||
IGFD_FileStyleByTypeLink = (1 << 2), // define style for all link
|
||||
IGFD_FileStyleByExtention = (1 << 3), // define style by extention, for files or links
|
||||
IGFD_FileStyleByFullName = (1 << 4), // define style for particular file/dir/link full name (filename + extention)
|
||||
IGFD_FileStyleByContainedInFullName =
|
||||
(1 << 5), // define style for file/dir/link when criteria is contained in full name
|
||||
IGFD_FileStyleByContainedInFullName = (1 << 5), // define style for file/dir/link when criteria is contained in full name
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
|
@ -1145,10 +1165,8 @@ enum ImGuiFileDialogFlags_ {
|
|||
ImGuiFileDialogFlags_HideColumnSize = (1 << 4), // hide column file size
|
||||
ImGuiFileDialogFlags_HideColumnDate = (1 << 5), // hide column file date
|
||||
ImGuiFileDialogFlags_NoDialog = (1 << 6), // let the dialog embedded in your own imgui begin / end scope
|
||||
ImGuiFileDialogFlags_ReadOnlyFileNameField =
|
||||
(1 << 7), // don't let user type in filename field for file open style dialogs
|
||||
ImGuiFileDialogFlags_CaseInsensitiveExtention =
|
||||
(1 << 8), // the file extentions treatments will not take into account the case
|
||||
ImGuiFileDialogFlags_ReadOnlyFileNameField = (1 << 7), // don't let user type in filename field for file open style dialogs
|
||||
ImGuiFileDialogFlags_CaseInsensitiveExtention = (1 << 8), // the file extentions treatments will not take into account the case
|
||||
ImGuiFileDialogFlags_Modal = (1 << 9), // modal
|
||||
ImGuiFileDialogFlags_DisableThumbnailMode = (1 << 10), // disable the thumbnail mode
|
||||
ImGuiFileDialogFlags_DisableBookmarkMode = (1 << 11), // disable the bookmark mode
|
||||
|
|
@ -1341,14 +1359,30 @@ public:
|
|||
m_Array.clear();
|
||||
}
|
||||
|
||||
bool empty() const { return m_Array.empty(); }
|
||||
size_t size() const { return m_Array.size(); }
|
||||
T& operator[](const size_t& vIdx) { return m_Array[vIdx]; }
|
||||
T& at(const size_t& vIdx) { return m_Array.at(vIdx); }
|
||||
typename std::vector<T>::iterator begin() { return m_Array.begin(); }
|
||||
typename std::vector<T>::const_iterator begin() const { return m_Array.begin(); }
|
||||
typename std::vector<T>::iterator end() { return m_Array.end(); }
|
||||
typename std::vector<T>::const_iterator end() const { return m_Array.end(); }
|
||||
bool empty() const {
|
||||
return m_Array.empty();
|
||||
}
|
||||
size_t size() const {
|
||||
return m_Array.size();
|
||||
}
|
||||
T& operator[](const size_t& vIdx) {
|
||||
return m_Array[vIdx];
|
||||
}
|
||||
T& at(const size_t& vIdx) {
|
||||
return m_Array.at(vIdx);
|
||||
}
|
||||
typename std::vector<T>::iterator begin() {
|
||||
return m_Array.begin();
|
||||
}
|
||||
typename std::vector<T>::const_iterator begin() const {
|
||||
return m_Array.begin();
|
||||
}
|
||||
typename std::vector<T>::iterator end() {
|
||||
return m_Array.end();
|
||||
}
|
||||
typename std::vector<T>::const_iterator end() const {
|
||||
return m_Array.end();
|
||||
}
|
||||
|
||||
bool try_add(T vKey) {
|
||||
if (!exist(vKey)) {
|
||||
|
|
@ -1368,7 +1402,9 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool exist(const std::string& vKey) const { return (m_Dico.find(vKey) != m_Dico.end()); }
|
||||
bool exist(const std::string& vKey) const {
|
||||
return (m_Dico.find(vKey) != m_Dico.end());
|
||||
}
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
|
@ -1377,7 +1413,7 @@ public:
|
|||
|
||||
class IGFD_API Utils {
|
||||
public:
|
||||
struct IGFD_API PathStruct {
|
||||
struct PathStruct {
|
||||
std::string path;
|
||||
std::string name;
|
||||
std::string ext;
|
||||
|
|
@ -1385,31 +1421,18 @@ public:
|
|||
};
|
||||
|
||||
public:
|
||||
static bool ImSplitter(bool split_vertically,
|
||||
float thickness,
|
||||
float* size1,
|
||||
float* size2,
|
||||
float min_size1,
|
||||
float min_size2,
|
||||
float splitter_long_axis_size = -1.0f);
|
||||
static bool ReplaceString(
|
||||
std::string& str, const std::string& oldStr, const std::string& newStr, const size_t& vMaxRecursion = 10U);
|
||||
static bool IsDirectoryCanBeOpened(const std::string& name); // by ex protected dirs (not user rights)
|
||||
static bool IsDirectoryExist(const std::string& name);
|
||||
static bool CreateDirectoryIfNotExist(const std::string& name);
|
||||
static PathStruct ParsePathFileName(const std::string& vPathFileName);
|
||||
static bool ImSplitter(
|
||||
bool split_vertically, float thickness, float* size1, float* size2, float min_size1, float min_size2, float splitter_long_axis_size = -1.0f);
|
||||
static bool ReplaceString(std::string& str, const std::string& oldStr, const std::string& newStr, const size_t& vMaxRecursion = 10U);
|
||||
static void AppendToBuffer(char* vBuffer, size_t vBufferLen, const std::string& vStr);
|
||||
static void ResetBuffer(char* vBuffer);
|
||||
static void SetBuffer(char* vBuffer, size_t vBufferLen, const std::string& vStr);
|
||||
static std::string UTF8Encode(const std::wstring& wstr);
|
||||
static std::wstring UTF8Decode(const std::string& str);
|
||||
static std::vector<std::string> SplitStringToVector(
|
||||
const std::string& vText, const char& vDelimiter, const bool& vPushEmpty);
|
||||
static std::vector<std::string> GetDrivesList();
|
||||
static std::vector<std::string> SplitStringToVector(const std::string& vText, const char& vDelimiter, const bool& vPushEmpty);
|
||||
static std::string LowerCaseString(const std::string& vString); // turn all text in lower case for search facilitie
|
||||
static size_t GetCharCountInString(const std::string& vString, const char& vChar);
|
||||
static size_t GetLastCharPosWithMinCharCount(
|
||||
const std::string& vString, const char& vChar, const size_t& vMinCharCount);
|
||||
static size_t GetLastCharPosWithMinCharCount(const std::string& vString, const char& vChar, const size_t& vMinCharCount);
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
|
@ -1440,9 +1463,9 @@ public:
|
|||
class IGFD_API FileDialogInternal;
|
||||
class IGFD_API SearchManager {
|
||||
public:
|
||||
std::string puSearchTag;
|
||||
char puSearchBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = "";
|
||||
bool puSearchInputIsActive = false;
|
||||
std::string searchTag;
|
||||
char searchBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = "";
|
||||
bool searchInputIsActive = false;
|
||||
|
||||
public:
|
||||
void Clear(); // clear datas
|
||||
|
|
@ -1476,8 +1499,7 @@ public:
|
|||
void setCollectionTitle(const std::string& vTitle); // set the collection title
|
||||
void addFilter(const std::string& vFilter, const bool& vIsRegex); // add a filter
|
||||
void addCollectionFilter(const std::string& vFilter, const bool& vIsRegex); // add a filter in collection
|
||||
std::string transformAsteriskBasedFilterToRegex(
|
||||
const std::string& vFilter); // will transform a filter who contain * to a regex
|
||||
std::string transformAsteriskBasedFilterToRegex(const std::string& vFilter); // will transform a filter who contain * to a regex
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
|
@ -1491,23 +1513,22 @@ public:
|
|||
#else
|
||||
private:
|
||||
#endif
|
||||
std::vector<FilterInfos> prParsedFilters;
|
||||
std::unordered_map<IGFD_FileStyleFlags, std::unordered_map<std::string, std::shared_ptr<FileStyle>>>
|
||||
prFilesStyle; // file infos for file extention only
|
||||
std::vector<FileStyle::FileStyleFunctor> prFilesStyleFunctors; // file style via lambda function
|
||||
FilterInfos prSelectedFilter;
|
||||
std::vector<FilterInfos> m_ParsedFilters;
|
||||
std::unordered_map<IGFD_FileStyleFlags, std::unordered_map<std::string, std::shared_ptr<FileStyle>>> m_FilesStyle; // file infos for file
|
||||
// extention only
|
||||
std::vector<FileStyle::FileStyleFunctor> m_FilesStyleFunctors; // file style via lambda function
|
||||
FilterInfos m_SelectedFilter;
|
||||
|
||||
public:
|
||||
std::string puDLGFilters;
|
||||
std::string puDLGdefaultExt;
|
||||
std::string dLGFilters;
|
||||
std::string dLGdefaultExt;
|
||||
|
||||
public:
|
||||
const FilterInfos& GetSelectedFilter() const;
|
||||
void ParseFilters(const char* vFilters); // Parse filter syntax, detect and parse filter collection
|
||||
void SetSelectedFilterWithExt(const std::string& vFilter); // Select filter
|
||||
bool prFillFileStyle(std::shared_ptr<FileInfos> vFileInfos) const; // fill with the good style
|
||||
void SetFileStyle(
|
||||
const IGFD_FileStyleFlags& vFlags, const char* vCriteria, const FileStyle& vInfos); // Set FileStyle
|
||||
bool m_FillFileStyle(std::shared_ptr<FileInfos> vFileInfos) const; // fill with the good style
|
||||
void SetFileStyle(const IGFD_FileStyleFlags& vFlags, const char* vCriteria, const FileStyle& vInfos); // Set FileStyle
|
||||
void SetFileStyle(const IGFD_FileStyleFlags& vFlags,
|
||||
const char* vCriteria,
|
||||
const ImVec4& vColor,
|
||||
|
|
@ -1519,12 +1540,11 @@ public:
|
|||
ImVec4* vOutColor,
|
||||
std::string* vOutIcon,
|
||||
ImFont** vOutFont); // Get Color and Icon for Filter
|
||||
void ClearFilesStyle(); // clear prFileStyle
|
||||
bool IsCoveredByFilters(const FileInfos& vFileInfos, bool vIsCaseInsensitive)
|
||||
const; // check if current file extention (vExt) is covered by current filter, or by regex (vNameExt)
|
||||
void ClearFilesStyle(); // clear m_FileStyle
|
||||
bool IsCoveredByFilters(const FileInfos& vFileInfos,
|
||||
bool vIsCaseInsensitive) const; // check if current file extention (vExt) is covered by current filter, or by regex (vNameExt)
|
||||
float GetFilterComboBoxWidth() const; // will return the current combo box widget width
|
||||
bool DrawFilterComboBox(
|
||||
FileDialogInternal& vFileDialogInternal); // draw the filter combobox // get the current selected filter
|
||||
bool DrawFilterComboBox(FileDialogInternal& vFileDialogInternal); // draw the filter combobox // get the current selected filter
|
||||
std::string ReplaceExtentionWithCurrentFilterIfNeeded(const std::string& vFileName,
|
||||
IGFD_ResultMode vFlag) const; // replace the extention of the current file by the selected filter
|
||||
void SetDefaultFilterIfNotDefined(); // define the first filter if no filter is selected
|
||||
|
|
@ -1593,13 +1613,37 @@ public:
|
|||
|
||||
public:
|
||||
bool SearchForTag(const std::string& vTag) const; // will search a tag in fileNameExt and fileNameExt_optimized
|
||||
bool SearchForExt(const std::string& vExt, const bool& vIsCaseInsensitive, const size_t& vMaxLevel = EXT_MAX_LEVEL)
|
||||
const; // will check the fileExtLevels levels for vExt, until vMaxLevel
|
||||
bool SearchForExts(
|
||||
const std::string& vComaSepExts, const bool& vIsCaseInsensitive, const size_t& vMaxLevel = EXT_MAX_LEVEL)
|
||||
const; // will check the fileExtLevels levels for vExts (ext are coma separated), until vMaxLevel
|
||||
bool FinalizeFileTypeParsing(
|
||||
const size_t& vMaxDotToExtract); // finalize the parsing the file (only a file or link to file. no dir)
|
||||
bool SearchForExt(const std::string& vExt,
|
||||
const bool& vIsCaseInsensitive,
|
||||
const size_t& vMaxLevel = EXT_MAX_LEVEL) const; // will check the fileExtLevels levels for vExt, until vMaxLevel
|
||||
bool SearchForExts(const std::string& vComaSepExts,
|
||||
const bool& vIsCaseInsensitive,
|
||||
const size_t& vMaxLevel = EXT_MAX_LEVEL) const; // will check the fileExtLevels levels for vExts (ext are coma separated), until vMaxLevel
|
||||
bool FinalizeFileTypeParsing(const size_t& vMaxDotToExtract); // finalize the parsing the file (only a file or link to file. no dir)
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region FILE SYSTEM INTERFACE
|
||||
|
||||
class IFileSystem {
|
||||
public:
|
||||
// say if a directory can be openened or for any reason locked
|
||||
virtual bool IsDirectoryCanBeOpened(const std::string& vName) = 0;
|
||||
// say if a directory exist
|
||||
virtual bool IsDirectoryExist(const std::string& vName) = 0;
|
||||
// say if a file exist
|
||||
virtual bool IsFileExist(const std::string& vName) = 0;
|
||||
// say if a directory was created, return false if vName is invalid or alreayd exist
|
||||
virtual bool CreateDirectoryIfNotExist(const std::string& vName) = 0;
|
||||
// extract the component of a file apth name, like path, name, ext
|
||||
virtual IGFD::Utils::PathStruct ParsePathFileName(const std::string& vPathFileName) = 0;
|
||||
// will return a list of files inside a path
|
||||
virtual std::vector<IGFD::FileInfos> ScanDirectory(const std::string& vPath) = 0;
|
||||
// say if the path is well a directory
|
||||
virtual bool IsDirectory(const std::string& vFilePathName) = 0;
|
||||
// return a drive list on windows, bu can be used on android or linux for give to the suer a list of root dir
|
||||
virtual std::vector<std::string> GetDrivesList() = 0;
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
|
@ -1609,7 +1653,7 @@ public:
|
|||
class IGFD_API FileManager {
|
||||
public: // types
|
||||
enum class SortingFieldEnum { // sorting for filetering of the file lsit
|
||||
FIELD_NONE = 0, // no sorting preference, result indetermined haha..
|
||||
FIELD_NONE = 0, // no sorting reference, result indetermined haha..
|
||||
FIELD_FILENAME, // sorted by filename
|
||||
FIELD_TYPE, // sorted by filetype
|
||||
FIELD_SIZE, // sorted by filesize (formated file size)
|
||||
|
|
@ -1622,85 +1666,75 @@ public:
|
|||
#else
|
||||
private:
|
||||
#endif
|
||||
std::string prCurrentPath; // current path (to be decomposed in prCurrentPathDecomposition
|
||||
std::vector<std::string> prCurrentPathDecomposition; // part words
|
||||
std::vector<std::shared_ptr<FileInfos>> prFileList; // base container
|
||||
std::vector<std::shared_ptr<FileInfos>> prFilteredFileList; // filtered container (search, sorting, etc..)
|
||||
std::vector<std::shared_ptr<FileInfos>> prPathList; // base container for path selection
|
||||
std::vector<std::shared_ptr<FileInfos>> prFilteredPathList; // filtered container for path selection (search,
|
||||
// sorting, etc..)
|
||||
std::vector<std::string>::iterator prPopupComposedPath; // iterator on prCurrentPathDecomposition for Current Path
|
||||
// popup
|
||||
std::string prLastSelectedFileName; // for shift multi selection
|
||||
std::set<std::string> prSelectedFileNames; // the user selection of FilePathNames
|
||||
bool prCreateDirectoryMode = false; // for create directory widget
|
||||
std::string m_CurrentPath; // current path (to be decomposed in m_CurrentPathDecomposition
|
||||
std::vector<std::string> m_CurrentPathDecomposition; // part words
|
||||
std::vector<std::shared_ptr<FileInfos>> m_FileList; // base container
|
||||
std::vector<std::shared_ptr<FileInfos>> m_FilteredFileList; // filtered container (search, sorting, etc..)
|
||||
std::vector<std::shared_ptr<FileInfos>> m_PathList; // base container for path selection
|
||||
std::vector<std::shared_ptr<FileInfos>> m_FilteredPathList; // filtered container for path selection (search, sorting, etc..)
|
||||
std::vector<std::string>::iterator m_PopupComposedPath; // iterator on m_CurrentPathDecomposition for Current Path popup
|
||||
std::string m_LastSelectedFileName; // for shift multi selection
|
||||
std::set<std::string> m_SelectedFileNames; // the user selection of FilePathNames
|
||||
bool m_CreateDirectoryMode = false; // for create directory widget
|
||||
std::unique_ptr<IFileSystem> m_FileSystemPtr = nullptr;
|
||||
|
||||
public:
|
||||
bool puInputPathActivated = false; // show input for path edition
|
||||
bool puDrivesClicked = false; // event when a drive button is clicked
|
||||
bool inputPathActivated = false; // show input for path edition
|
||||
bool drivesClicked = false; // event when a drive button is clicked
|
||||
bool puPathClicked = false; // event when a path button was clicked
|
||||
char puInputPathBuffer[MAX_PATH_BUFFER_SIZE] =
|
||||
""; // input path buffer for imgui widget input text (displayed in palce of composer)
|
||||
char puVariadicBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = ""; // called by prSelectableItem
|
||||
char puFileNameBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = ""; // file name buffer in footer for imgui widget input text
|
||||
char puDirectoryNameBuffer[MAX_FILE_DIALOG_NAME_BUFFER] =
|
||||
""; // directory name buffer in footer for imgui widget input text (when is directory mode)
|
||||
std::string puHeaderFileName; // detail view name of column file
|
||||
std::string puHeaderFileType; // detail view name of column type
|
||||
std::string puHeaderFileSize; // detail view name of column size
|
||||
std::string puHeaderFileDate; // detail view name of column date + time
|
||||
char inputPathBuffer[MAX_PATH_BUFFER_SIZE] = ""; // input path buffer for imgui widget input text (displayed in palce of composer)
|
||||
char variadicBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = ""; // called by m_SelectableItem
|
||||
char fileNameBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = ""; // file name buffer in footer for imgui widget input text
|
||||
char directoryNameBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = ""; // directory name buffer (when in directory mode)
|
||||
std::string headerFileName; // detail view name of column file
|
||||
std::string headerFileType; // detail view name of column type
|
||||
std::string headerFileSize; // detail view name of column size
|
||||
std::string headerFileDate; // detail view name of column date + time
|
||||
#ifdef USE_THUMBNAILS
|
||||
std::string puHeaderFileThumbnails; // detail view name of column thumbnails
|
||||
bool puSortingDirection[5] = { // true => Ascending, false => Descending
|
||||
defaultSortOrderFilename, defaultSortOrderType, defaultSortOrderSize, defaultSortOrderDate,
|
||||
defaultSortOrderThumbnails};
|
||||
std::string headerFileThumbnails; // detail view name of column thumbnails
|
||||
bool sortingDirection[5] = { // true => Ascending, false => Descending
|
||||
defaultSortOrderFilename, defaultSortOrderType, defaultSortOrderSize, defaultSortOrderDate, defaultSortOrderThumbnails};
|
||||
#else
|
||||
bool puSortingDirection[4] = { // true => Ascending, false => Descending
|
||||
bool sortingDirection[4] = { // true => Ascending, false => Descending
|
||||
defaultSortOrderFilename, defaultSortOrderType, defaultSortOrderSize, defaultSortOrderDate};
|
||||
#endif
|
||||
SortingFieldEnum puSortingField = SortingFieldEnum::FIELD_FILENAME; // detail view sorting column
|
||||
bool puShowDrives = false; // drives are shown (only on os windows)
|
||||
SortingFieldEnum sortingField = SortingFieldEnum::FIELD_FILENAME; // detail view sorting column
|
||||
bool showDrives = false; // drives are shown (only on os windows)
|
||||
|
||||
std::string puDLGpath; // base path set by user when OpenDialog was called
|
||||
std::string puDLGDefaultFileName; // base default file path name set by user when OpenDialog was called
|
||||
size_t puDLGcountSelectionMax =
|
||||
1U; // 0 for infinite // base max selection count set by user when OpenDialog was called
|
||||
bool puDLGDirectoryMode = false; // is directory mode (defiend like : puDLGDirectoryMode = (filters.empty()))
|
||||
std::string dLGpath; // base path set by user when OpenDialog was called
|
||||
std::string dLGDefaultFileName; // base default file path name set by user when OpenDialog was called
|
||||
size_t dLGcountSelectionMax = 1U; // 0 for infinite // base max selection count set by user when OpenDialog was called
|
||||
bool dLGDirectoryMode = false; // is directory mode (defiend like : dLGDirectoryMode = (filters.empty()))
|
||||
|
||||
std::string puFsRoot;
|
||||
std::string fsRoot;
|
||||
|
||||
#ifdef NEED_TO_BE_PUBLIC_FOR_TESTS
|
||||
public:
|
||||
#else
|
||||
private:
|
||||
#endif
|
||||
static std::string prRoundNumber(double vvalue, int n); // custom rounding number
|
||||
static std::string prFormatFileSize(size_t vByteSize); // format file size field
|
||||
static void prCompleteFileInfos(
|
||||
const std::shared_ptr<FileInfos>& FileInfos); // set time and date infos of a file (detail view mode)
|
||||
void prRemoveFileNameInSelection(const std::string& vFileName); // selection : remove a file name
|
||||
void prAddFileNameInSelection(
|
||||
const std::string& vFileName, bool vSetLastSelectionFileName); // selection : add a file name
|
||||
void AddFile(const FileDialogInternal& vFileDialogInternal,
|
||||
static std::string m_RoundNumber(double vvalue, int n); // custom rounding number
|
||||
static std::string m_FormatFileSize(size_t vByteSize); // format file size field
|
||||
static void m_CompleteFileInfos(const std::shared_ptr<FileInfos>& FileInfos); // set time and date infos of a file (detail view mode)
|
||||
void m_RemoveFileNameInSelection(const std::string& vFileName); // selection : remove a file name
|
||||
void m_m_AddFileNameInSelection(const std::string& vFileName, bool vSetLastSelectionFileName); // selection : add a file name
|
||||
void m_AddFile(const FileDialogInternal& vFileDialogInternal,
|
||||
const std::string& vPath,
|
||||
const std::string& vFileName,
|
||||
const FileType& vFileType); // add file called by scandir
|
||||
void AddPath(const FileDialogInternal& vFileDialogInternal,
|
||||
void m_AddPath(const FileDialogInternal& vFileDialogInternal,
|
||||
const std::string& vPath,
|
||||
const std::string& vFileName,
|
||||
const FileType& vFileType); // add file called by scandir
|
||||
|
||||
void ScanDirForPathSelection(const FileDialogInternal& vFileDialogInternal,
|
||||
void m_ScanDirForPathSelection(const FileDialogInternal& vFileDialogInternal,
|
||||
const std::string& vPath); // scan the directory for retrieve the path list
|
||||
void OpenPathPopup(const FileDialogInternal& vFileDialogInternal,
|
||||
void m_OpenPathPopup(const FileDialogInternal& vFileDialogInternal,
|
||||
std::vector<std::string>::iterator vPathIter); // open the popup list of paths
|
||||
|
||||
void SetCurrentPath(std::vector<std::string>::iterator vPathIter); // set the current path, update the path bar
|
||||
|
||||
void ApplyFilteringOnFileList(const FileDialogInternal& vFileDialogInternal,
|
||||
void m_SetCurrentPath(std::vector<std::string>::iterator vPathIter); // set the current path, update the path bar
|
||||
void m_ApplyFilteringOnFileList(const FileDialogInternal& vFileDialogInternal,
|
||||
std::vector<std::shared_ptr<FileInfos>>& vFileInfosList,
|
||||
std::vector<std::shared_ptr<FileInfos>>& vFileInfosFilteredList);
|
||||
void SortFields(const FileDialogInternal& vFileDialogInternal,
|
||||
void m_SortFields(const FileDialogInternal& vFileDialogInternal,
|
||||
std::vector<std::shared_ptr<FileInfos>>& vFileInfosList,
|
||||
std::vector<std::shared_ptr<FileInfos>>& vFileInfosFilteredList); // will sort a column
|
||||
|
||||
|
|
@ -1731,12 +1765,10 @@ public:
|
|||
// scandir for populate the file listview
|
||||
bool GetDrives(); // list drives on windows platform
|
||||
bool CreateDir(const std::string& vPath); // create a directory on the file system
|
||||
std::string ComposeNewPath(
|
||||
std::vector<std::string>::iterator vIter); // compose a path from the compose path widget
|
||||
std::string ComposeNewPath(std::vector<std::string>::iterator vIter); // compose a path from the compose path widget
|
||||
bool SetPathOnParentDirectoryIfAny(); // compose paht on parent directory
|
||||
std::string GetCurrentPath(); // get the current path
|
||||
void SetCurrentPath(const std::string& vCurrentPath); // set the current path
|
||||
static bool IsFileExist(const std::string& vFile);
|
||||
void SetDefaultFileName(const std::string& vFileName);
|
||||
bool SelectDirectory(const std::shared_ptr<FileInfos>& vInfos); // enter directory
|
||||
void SelectFileName(const FileDialogInternal& vFileDialogInternal,
|
||||
|
|
@ -1745,16 +1777,17 @@ public:
|
|||
void ScanDir(const FileDialogInternal& vFileDialogInternal,
|
||||
const std::string& vPath); // scan the directory for retrieve the file list
|
||||
|
||||
public:
|
||||
std::string GetResultingPath();
|
||||
std::string GetResultingFileName(FileDialogInternal& vFileDialogInternal, IGFD_ResultMode vFlag);
|
||||
std::string GetResultingFilePathName(FileDialogInternal& vFileDialogInternal, IGFD_ResultMode vFlag);
|
||||
std::map<std::string, std::string> GetResultingSelection(
|
||||
FileDialogInternal& vFileDialogInternal, IGFD_ResultMode vFlag);
|
||||
std::map<std::string, std::string> GetResultingSelection(FileDialogInternal& vFileDialogInternal, IGFD_ResultMode vFlag);
|
||||
|
||||
public:
|
||||
void DrawDirectoryCreation(const FileDialogInternal& vFileDialogInternal); // draw directory creation widget
|
||||
void DrawPathComposer(const FileDialogInternal& vFileDialogInternal); // draw path composer widget
|
||||
void DrawPathComposer(const FileDialogInternal& vFileDialogInternal);
|
||||
|
||||
IFileSystem* GetFileSystemInstance() {
|
||||
return m_FileSystemPtr.get();
|
||||
}
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
|
@ -1765,32 +1798,32 @@ typedef void* UserDatas;
|
|||
typedef std::function<void(const char*, UserDatas, bool*)> PaneFun; // side pane function binding
|
||||
class IGFD_API FileDialogInternal {
|
||||
public:
|
||||
FileManager puFileManager; // the file manager
|
||||
FilterManager puFilterManager; // the filter manager
|
||||
SearchManager puSearchManager; // the search manager
|
||||
FileManager fileManager; // the file manager
|
||||
FilterManager filterManager; // the filter manager
|
||||
SearchManager searchManager; // the search manager
|
||||
|
||||
public:
|
||||
std::string puName; // the internal dialog name (title + ##word)
|
||||
bool puShowDialog = false; // the dialog is shown
|
||||
ImVec2 puDialogCenterPos = ImVec2(0, 0); // center pos for display the confirm overwrite dialog
|
||||
int puLastImGuiFrameCount = 0; // to be sure than only one dialog displayed per frame
|
||||
float puFooterHeight = 0.0f; // footer height
|
||||
bool puCanWeContinue = true; // events
|
||||
bool puOkResultToConfirm = false; // to confim if ok for OverWrite
|
||||
bool puIsOk = false; // is dialog ok button click
|
||||
bool puFileInputIsActive = false; // when input text for file or directory is active
|
||||
bool puFileListViewIsActive = false; // when list view is active
|
||||
std::string puDLGkey; // the dialog key
|
||||
std::string puDLGtitle; // the dialog title
|
||||
ImGuiFileDialogFlags puDLGflags = ImGuiFileDialogFlags_None; // default dialog flag
|
||||
UserDatas puDLGuserDatas = nullptr; // the user datas passed to a dialog
|
||||
PaneFun puDLGoptionsPane = nullptr; // the user side pane
|
||||
float puDLGoptionsPaneWidth = 0.0f; // the user side pane width
|
||||
bool puNeedToExitDialog = false; // we need to exit the dialog
|
||||
std::string name; // the internal dialog name (title + ##word)
|
||||
bool showDialog = false; // the dialog is shown
|
||||
ImVec2 dialogCenterPos = ImVec2(0, 0); // center pos for display the confirm overwrite dialog
|
||||
int lastImGuiFrameCount = 0; // to be sure than only one dialog displayed per frame
|
||||
float footerHeight = 0.0f; // footer height
|
||||
bool canWeContinue = true; // events
|
||||
bool okResultToConfirm = false; // to confim if ok for OverWrite
|
||||
bool isOk = false; // is dialog ok button click
|
||||
bool fileInputIsActive = false; // when input text for file or directory is active
|
||||
bool fileListViewIsActive = false; // when list view is active
|
||||
std::string dLGkey; // the dialog key
|
||||
std::string dLGtitle; // the dialog title
|
||||
ImGuiFileDialogFlags dLGflags = ImGuiFileDialogFlags_None; // default dialog flag
|
||||
UserDatas dLGuserDatas = nullptr; // the user datas passed to a dialog
|
||||
PaneFun dLGoptionsPane = nullptr; // the user side pane
|
||||
float dLGoptionsPaneWidth = 0.0f; // the user side pane width
|
||||
bool needToExitDialog = false; // we need to exit the dialog
|
||||
bool puUseCustomLocale = false; // custom user locale
|
||||
int puLocaleCategory = LC_ALL; // locale category to use
|
||||
std::string puLocaleBegin; // the locale who will be applied at start of the display dialog
|
||||
std::string puLocaleEnd; // the locale who will be applaied at end of the display dialog
|
||||
int localeCategory = LC_ALL; // locale category to use
|
||||
std::string localeBegin; // the locale who will be applied at start of the display dialog
|
||||
std::string localeEnd; // the locale who will be applaied at end of the display dialog
|
||||
|
||||
public:
|
||||
void NewFrame(); // new frame, so maybe neded to do somethings, like reset events
|
||||
|
|
@ -1815,46 +1848,45 @@ protected:
|
|||
ThumbnailFeature();
|
||||
~ThumbnailFeature();
|
||||
|
||||
void NewThumbnailFrame(FileDialogInternal& vFileDialogInternal);
|
||||
void EndThumbnailFrame(FileDialogInternal& vFileDialogInternal);
|
||||
void QuitThumbnailFrame(FileDialogInternal& vFileDialogInternal);
|
||||
void m_NewThumbnailFrame(FileDialogInternal& vFileDialogInternal);
|
||||
void m_EndThumbnailFrame(FileDialogInternal& vFileDialogInternal);
|
||||
void m_QuitThumbnailFrame(FileDialogInternal& vFileDialogInternal);
|
||||
|
||||
#ifdef USE_THUMBNAILS
|
||||
protected:
|
||||
enum class DisplayModeEnum { FILE_LIST = 0, THUMBNAILS_LIST, THUMBNAILS_GRID };
|
||||
|
||||
private:
|
||||
uint32_t prCountFiles = 0U;
|
||||
bool prIsWorking = false;
|
||||
std::shared_ptr<std::thread> prThumbnailGenerationThread = nullptr;
|
||||
std::list<std::shared_ptr<FileInfos>> prThumbnailFileDatasToGet; // base container
|
||||
std::mutex prThumbnailFileDatasToGetMutex;
|
||||
std::list<std::shared_ptr<FileInfos>> prThumbnailToCreate; // base container
|
||||
std::mutex prThumbnailToCreateMutex;
|
||||
std::list<IGFD_Thumbnail_Info> prThumbnailToDestroy; // base container
|
||||
std::mutex prThumbnailToDestroyMutex;
|
||||
uint32_t m_CountFiles = 0U;
|
||||
bool m_IsWorking = false;
|
||||
std::shared_ptr<std::thread> m_ThumbnailGenerationThread = nullptr;
|
||||
std::list<std::shared_ptr<FileInfos>> m_ThumbnailFileDatasToGet; // base container
|
||||
std::mutex m_ThumbnailFileDatasToGetMutex;
|
||||
std::list<std::shared_ptr<FileInfos>> m_ThumbnailToCreate; // base container
|
||||
std::mutex m_ThumbnailToCreateMutex;
|
||||
std::list<IGFD_Thumbnail_Info> m_ThumbnailToDestroy; // base container
|
||||
std::mutex m_ThumbnailToDestroyMutex;
|
||||
|
||||
CreateThumbnailFun prCreateThumbnailFun = nullptr;
|
||||
DestroyThumbnailFun prDestroyThumbnailFun = nullptr;
|
||||
CreateThumbnailFun m_CreateThumbnailFun = nullptr;
|
||||
DestroyThumbnailFun m_DestroyThumbnailFun = nullptr;
|
||||
|
||||
protected:
|
||||
DisplayModeEnum prDisplayMode = DisplayModeEnum::FILE_LIST;
|
||||
DisplayModeEnum m_DisplayMode = DisplayModeEnum::FILE_LIST;
|
||||
|
||||
private:
|
||||
void prVariadicProgressBar(float fraction, const ImVec2& size_arg, const char* fmt, ...);
|
||||
void m_VariadicProgressBar(float fraction, const ImVec2& size_arg, const char* fmt, ...);
|
||||
|
||||
protected:
|
||||
// will be call in cpu zone (imgui computations, will call a texture file retrieval thread)
|
||||
void prStartThumbnailFileDatasExtraction(); // start the thread who will get byte buffer from image files
|
||||
bool prStopThumbnailFileDatasExtraction(); // stop the thread who will get byte buffer from image files
|
||||
void prThreadThumbnailFileDatasExtractionFunc(); // the thread who will get byte buffer from image files
|
||||
void prDrawThumbnailGenerationProgress(); // a little progressbar who will display the texture gen status
|
||||
void prAddThumbnailToLoad(const std::shared_ptr<FileInfos>& vFileInfos); // add texture to load in the thread
|
||||
void prAddThumbnailToCreate(const std::shared_ptr<FileInfos>& vFileInfos);
|
||||
void prAddThumbnailToDestroy(const IGFD_Thumbnail_Info& vIGFD_Thumbnail_Info);
|
||||
void prDrawDisplayModeToolBar(); // draw display mode toolbar (file list, thumbnails list, small thumbnails grid,
|
||||
// big thumbnails grid)
|
||||
void prClearThumbnails(FileDialogInternal& vFileDialogInternal);
|
||||
void m_StartThumbnailFileDatasExtraction(); // start the thread who will get byte buffer from image files
|
||||
bool m_StopThumbnailFileDatasExtraction(); // stop the thread who will get byte buffer from image files
|
||||
void m_ThreadThumbnailFileDatasExtractionFunc(); // the thread who will get byte buffer from image files
|
||||
void m_DrawThumbnailGenerationProgress(); // a little progressbar who will display the texture gen status
|
||||
void m_AddThumbnailToLoad(const std::shared_ptr<FileInfos>& vFileInfos); // add texture to load in the thread
|
||||
void m_AddThumbnailToCreate(const std::shared_ptr<FileInfos>& vFileInfos);
|
||||
void m_AddThumbnailToDestroy(const IGFD_Thumbnail_Info& vIGFD_Thumbnail_Info);
|
||||
void m_DrawDisplayModeToolBar(); // draw display mode toolbar (file list, thumbnails list, small thumbnails grid, big thumbnails grid)
|
||||
void m_ClearThumbnails(FileDialogInternal& vFileDialogInternal);
|
||||
|
||||
public:
|
||||
void SetCreateThumbnailCallback(const CreateThumbnailFun& vCreateThumbnailFun);
|
||||
|
|
@ -1885,24 +1917,23 @@ private:
|
|||
};
|
||||
|
||||
private:
|
||||
ImGuiListClipper prBookmarkClipper;
|
||||
std::vector<BookmarkStruct> prBookmarks;
|
||||
char prBookmarkEditBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = "";
|
||||
ImGuiListClipper m_BookmarkClipper;
|
||||
std::vector<BookmarkStruct> m_Bookmarks;
|
||||
char m_BookmarkEditBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = "";
|
||||
|
||||
protected:
|
||||
float prBookmarkWidth = 200.0f;
|
||||
bool prBookmarkPaneShown = false;
|
||||
float m_BookmarkWidth = 200.0f;
|
||||
bool m_BookmarkPaneShown = false;
|
||||
|
||||
protected:
|
||||
void prDrawBookmarkButton(); // draw bookmark button
|
||||
bool prDrawBookmarkPane(FileDialogInternal& vFileDialogInternal, const ImVec2& vSize); // draw bookmark Pane
|
||||
void m_DrawBookmarkButton(); // draw bookmark button
|
||||
bool m_DrawBookmarkPane(FileDialogInternal& vFileDialogInternal, const ImVec2& vSize); // draw bookmark Pane
|
||||
|
||||
public:
|
||||
std::string SerializeBookmarks( // serialize bookmarks : return bookmark buffer to save in a file
|
||||
const bool& vDontSerializeCodeBasedBookmarks = true); // for avoid serialization of bookmarks added by code
|
||||
void DeserializeBookmarks( // deserialize bookmarks : load bookmark buffer to load in the dialog (saved from
|
||||
// previous use with SerializeBookmarks())
|
||||
const std::string& vBookmarks); // bookmark buffer to load
|
||||
const std::string& vBookmarks); // previous use with SerializeBookmarks()) bookmark buffer to load
|
||||
void AddBookmark( // add a bookmark by code
|
||||
const std::string& vBookMarkName, // bookmark name
|
||||
const std::string& vBookMarkPath); // bookmark path
|
||||
|
|
@ -1923,30 +1954,28 @@ protected:
|
|||
|
||||
#ifdef USE_EXPLORATION_BY_KEYS
|
||||
private:
|
||||
bool prLocateFileByInputChar_lastFound = false;
|
||||
ImWchar prLocateFileByInputChar_lastChar = 0;
|
||||
float prFlashAlpha = 0.0f; // flash when select by char
|
||||
float prFlashAlphaAttenInSecs = 1.0f; // fps display dependant
|
||||
int prLocateFileByInputChar_InputQueueCharactersSize = 0;
|
||||
size_t prFlashedItem = 0; // flash when select by char
|
||||
size_t prLocateFileByInputChar_lastFileIdx = 0;
|
||||
bool m_LocateFileByInputChar_lastFound = false;
|
||||
ImWchar m_LocateFileByInputChar_lastChar = 0;
|
||||
float m_FlashAlpha = 0.0f; // flash when select by char
|
||||
float m_FlashAlphaAttenInSecs = 1.0f; // fps display dependant
|
||||
int m_LocateFileByInputChar_InputQueueCharactersSize = 0;
|
||||
size_t m_FlashedItem = 0; // flash when select by char
|
||||
size_t m_LocateFileByInputChar_lastFileIdx = 0;
|
||||
|
||||
protected:
|
||||
void prLocateByInputKey(
|
||||
FileDialogInternal& vFileDialogInternal); // select a file line in listview according to char key
|
||||
bool prLocateItem_Loop(FileDialogInternal& vFileDialogInternal,
|
||||
void m_LocateByInputKey(FileDialogInternal& vFileDialogInternal); // select a file line in listview according to char key
|
||||
bool m_LocateItem_Loop(FileDialogInternal& vFileDialogInternal,
|
||||
ImWchar vC); // restrat for start of list view if not found a corresponding file
|
||||
void prExploreWithkeys(FileDialogInternal& vFileDialogInternal,
|
||||
void m_ExploreWithkeys(FileDialogInternal& vFileDialogInternal,
|
||||
ImGuiID vListViewID); // select file/directory line in listview accroding to up/down enter/backspace keys
|
||||
void prStartFlashItem(size_t vIdx); // define than an item must be flashed
|
||||
bool prBeginFlashItem(size_t vIdx); // start the flashing of a line in lsit view
|
||||
static void prEndFlashItem(); // end the fleshing accrdoin to var prFlashAlphaAttenInSecs
|
||||
static bool prFlashableSelectable(const char* label,
|
||||
void m_StartFlashItem(size_t vIdx); // define than an item must be flashed
|
||||
bool m_BeginFlashItem(size_t vIdx); // start the flashing of a line in lsit view
|
||||
static void m_EndFlashItem(); // end the fleshing accrdoin to var m_FlashAlphaAttenInSecs
|
||||
static bool m_FlashableSelectable(const char* label,
|
||||
bool selected = false,
|
||||
ImGuiSelectableFlags flags = 0,
|
||||
bool vFlashing = false,
|
||||
const ImVec2& size = ImVec2(
|
||||
0, 0)); // custom flashing selectable widgets, for flash the selected line in a short time
|
||||
const ImVec2& size = ImVec2(0, 0)); // custom flashing selectable widgets, for flash the selected line in a short time
|
||||
|
||||
public:
|
||||
void SetFlashingAttenuationInSeconds( // set the flashing time of the line in file list when use exploration keys
|
||||
|
|
@ -1962,9 +1991,9 @@ public:
|
|||
|
||||
class IGFD_API FileDialog : public BookMarkFeature, public KeyExplorerFeature, public ThumbnailFeature {
|
||||
protected:
|
||||
FileDialogInternal prFileDialogInternal;
|
||||
ImGuiListClipper prFileListClipper;
|
||||
ImGuiListClipper prPathListClipper;
|
||||
FileDialogInternal m_FileDialogInternal;
|
||||
ImGuiListClipper m_FileListClipper;
|
||||
ImGuiListClipper m_PathListClipper;
|
||||
float prOkCancelButtonWidth = 0.0f;
|
||||
|
||||
public:
|
||||
|
|
@ -1989,7 +2018,8 @@ public:
|
|||
|
||||
virtual // todo : need to refactor all theses function to maybe just one
|
||||
// standard dialog
|
||||
void OpenDialog( // open simple dialog (path and fileName can be specified)
|
||||
void
|
||||
OpenDialog( // open simple dialog (path and fileName can be specified)
|
||||
const std::string& vKey, // key dialog
|
||||
const std::string& vTitle, // title
|
||||
const char* vFilters, // filters
|
||||
|
|
@ -2053,11 +2083,8 @@ public:
|
|||
IGFD_ResultMode vFlag = IGFD_ResultMode_KeepInputFile); // Open File behavior : will return selection via a
|
||||
// map<FileName, FilePathName>
|
||||
std::string GetFilePathName(
|
||||
IGFD_ResultMode vFlag =
|
||||
IGFD_ResultMode_AddIfNoFileExt); // Save File behavior : will return the current file path name
|
||||
std::string GetCurrentFileName(
|
||||
IGFD_ResultMode vFlag =
|
||||
IGFD_ResultMode_AddIfNoFileExt); // Save File behavior : will return the content file name
|
||||
IGFD_ResultMode vFlag = IGFD_ResultMode_AddIfNoFileExt); // Save File behavior : will return the current file path name
|
||||
std::string GetCurrentFileName(IGFD_ResultMode vFlag = IGFD_ResultMode_AddIfNoFileExt); // Save File behavior : will return the content file name
|
||||
std::string GetCurrentPath(); // will return current file path
|
||||
std::string GetCurrentFilter(); // will return current filter
|
||||
UserDatas GetUserDatas() const; // will return user datas send with Open Dialog
|
||||
|
|
@ -2089,48 +2116,48 @@ public:
|
|||
const std::string& vLocaleEnd); // locale to use at the end of the dialog display
|
||||
|
||||
protected:
|
||||
void NewFrame(); // new frame just at begining of display
|
||||
void EndFrame(); // end frame just at end of display
|
||||
void QuitFrame(); // quit frame when qui quit the dialog
|
||||
void m_NewFrame(); // new frame just at begining of display
|
||||
void m_EndFrame(); // end frame just at end of display
|
||||
void m_QuitFrame(); // quit frame when qui quit the dialog
|
||||
|
||||
// others
|
||||
bool prConfirm_Or_OpenOverWriteFileDialog_IfNeeded(
|
||||
bool m_Confirm_Or_OpenOverWriteFileDialog_IfNeeded(
|
||||
bool vLastAction, ImGuiWindowFlags vFlags); // treatment of the result, start the confirm to overwrite dialog
|
||||
// if needed (if defined with flag)
|
||||
|
||||
// dialog parts
|
||||
virtual void prDrawHeader(); // draw header part of the dialog (bookmark btn, dir creation, path composer, search
|
||||
virtual void m_DrawHeader(); // draw header part of the dialog (bookmark btn, dir creation, path composer, search
|
||||
// bar)
|
||||
virtual void prDrawContent(); // draw content part of the dialog (bookmark pane, file list, side pane)
|
||||
virtual bool prDrawFooter(); // draw footer part of the dialog (file field, fitler combobox, ok/cancel btn's)
|
||||
virtual void m_DrawContent(); // draw content part of the dialog (bookmark pane, file list, side pane)
|
||||
virtual bool m_DrawFooter(); // draw footer part of the dialog (file field, fitler combobox, ok/cancel btn's)
|
||||
|
||||
// widgets components
|
||||
virtual void DisplayPathPopup(ImVec2 vSize); // draw path popup when click on a \ or /
|
||||
virtual bool prDrawValidationButtons(); // draw validations btns, ok, cancel buttons
|
||||
virtual bool prDrawOkButton(); // draw ok button
|
||||
virtual bool prDrawCancelButton(); // draw cancel button
|
||||
virtual void prDrawSidePane(float vHeight); // draw side pane
|
||||
virtual void prSelectableItem(int vidx,
|
||||
virtual void m_DisplayPathPopup(ImVec2 vSize); // draw path popup when click on a \ or /
|
||||
virtual bool m_DrawValidationButtons(); // draw validations btns, ok, cancel buttons
|
||||
virtual bool m_DrawOkButton(); // draw ok button
|
||||
virtual bool m_DrawCancelButton(); // draw cancel button
|
||||
virtual void m_DrawSidePane(float vHeight); // draw side pane
|
||||
virtual void m_SelectableItem(int vidx,
|
||||
std::shared_ptr<FileInfos> vInfos,
|
||||
bool vSelected,
|
||||
const char* vFmt,
|
||||
...); // draw a custom selectable behavior item
|
||||
virtual void prDrawFileListView(ImVec2 vSize); // draw file list view (default mode)
|
||||
virtual void m_DrawFileListView(ImVec2 vSize); // draw file list view (default mode)
|
||||
|
||||
#ifdef USE_THUMBNAILS
|
||||
virtual void prDrawThumbnailsListView(ImVec2 vSize); // draw file list view with small thumbnails on the same line
|
||||
virtual void prDrawThumbnailsGridView(ImVec2 vSize); // draw a grid of small thumbnails
|
||||
virtual void m_DrawThumbnailsListView(ImVec2 vSize); // draw file list view with small thumbnails on the same line
|
||||
virtual void m_DrawThumbnailsGridView(ImVec2 vSize); // draw a grid of small thumbnails
|
||||
#endif
|
||||
|
||||
// to be called only by these function and theirs overrides
|
||||
// - prDrawFileListView
|
||||
// - prDrawThumbnailsListView
|
||||
// - prDrawThumbnailsGridView
|
||||
void prBeginFileColorIconStyle(std::shared_ptr<FileInfos> vFileInfos,
|
||||
// - m_DrawFileListView
|
||||
// - m_DrawThumbnailsListView
|
||||
// - m_DrawThumbnailsGridView
|
||||
void m_BeginFileColorIconStyle(std::shared_ptr<FileInfos> vFileInfos,
|
||||
bool& vOutShowColor,
|
||||
std::string& vOutStr,
|
||||
ImFont** vOutFont); // begin style apply of filter with color an icon if any
|
||||
void prEndFileColorIconStyle(const bool& vShowColor, ImFont* vFont); // end style apply of filter
|
||||
void m_EndFileColorIconStyle(const bool& vShowColor, ImFont* vFont); // end style apply of filter
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
|
@ -2177,8 +2204,7 @@ struct IGFD_Selection_Pair {
|
|||
};
|
||||
|
||||
IGFD_C_API IGFD_Selection_Pair IGFD_Selection_Pair_Get(); // return an initialized IGFD_Selection_Pair
|
||||
IGFD_C_API void IGFD_Selection_Pair_DestroyContent(
|
||||
IGFD_Selection_Pair* vSelection_Pair); // destroy the content of a IGFD_Selection_Pair
|
||||
IGFD_C_API void IGFD_Selection_Pair_DestroyContent(IGFD_Selection_Pair* vSelection_Pair); // destroy the content of a IGFD_Selection_Pair
|
||||
|
||||
struct IGFD_Selection {
|
||||
IGFD_Selection_Pair* table; // 0
|
||||
|
|
@ -2272,8 +2298,7 @@ IGFD_C_API bool IGFD_IsKeyOpened( // say if the dialog key is opened
|
|||
IGFD_C_API bool IGFD_IsOpened( // say if the dialog is opened somewhere
|
||||
ImGuiFileDialog* vContextPtr); // ImGuiFileDialog context
|
||||
|
||||
IGFD_C_API IGFD_Selection
|
||||
IGFD_GetSelection( // Open File behavior : will return selection via a map<FileName, FilePathName>
|
||||
IGFD_C_API IGFD_Selection IGFD_GetSelection( // Open File behavior : will return selection via a map<FileName, FilePathName>
|
||||
ImGuiFileDialog* vContextPtr, // user datas (can be retrieved in pane)
|
||||
IGFD_ResultMode vMode); // Result Mode
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
// uncomment and modify defines under for customize ImGuiFileDialog
|
||||
|
||||
// uncomment if you need to use your FileSystem Interface
|
||||
// if commented, you have two defualt interface, std::filesystem or dirent
|
||||
// #define USE_CUSTOM_FILESYSTEM
|
||||
|
||||
// this options need c++17
|
||||
// #define USE_STD_FILESYSTEM
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
[](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Win.yml)
|
||||
[](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Linux.yml)
|
||||
[](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Osx.yml)
|
||||
[](https://github.com/ocornut/imgui)
|
||||
[](https://github.com/ocornut/imgui)
|
||||
|
||||
# ImGuiFileDialog
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ solutions.
|
|||
|
||||
## ImGui Supported Version
|
||||
|
||||
ImGuiFileDialog follow the master and docking branch of ImGui . currently ImGui 1.89.9
|
||||
ImGuiFileDialog follow the master and docking branch of ImGui. Currently ImGui 1.90.1
|
||||
|
||||
## Structure
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ Android Requirements : Api 21 mini
|
|||
- 0 => Infinite
|
||||
- 1 => One file (default)
|
||||
- n => n files
|
||||
- Compatible with MacOs, Linux, Windows
|
||||
- Compatible with MacOs, Linux, Windows, Emscripten
|
||||
- Windows version can list drives
|
||||
- Supports modal or standard dialog types
|
||||
- Select files or directories
|
||||
|
|
@ -86,6 +86,9 @@ Android Requirements : Api 21 mini
|
|||
- multi layer extentions like : .a.b.c .json.cpp .vcxproj.filters etc..
|
||||
- advanced behavior regarding asterisk based filter. like : .* .*.* .vcx.* .*.filters .vcs*.filt.* etc.. (internally regex is used)
|
||||
- result modes GetFilePathName, GetFileName and GetSelection (overwrite file ext, keep file, add ext if no user ext exist)
|
||||
- you can use your own FileSystem Api
|
||||
- by default Api Dirent and std::filesystem are defined
|
||||
- you can override GetDrieveList for specify by ex on android other fs, like local and SDCards
|
||||
|
||||
### WARNINGS :
|
||||
- the nav system keyboard behavior is not working as expected, so maybe full of bug for ImGuiFileDialog
|
||||
|
|
@ -938,9 +941,28 @@ to note :
|
|||
|
||||
</blockquote></details>
|
||||
|
||||
<details open><summary><h2>Api's C/C++ :</h2></summary><blockquote>
|
||||
<details open><summary><h2>Custom FileSystem</h2></summary><blockquote>
|
||||
|
||||
### the C Api
|
||||
you can use your custom file system interface.
|
||||
|
||||
by default IGFD come with the File System Interfaces for Dirent or std::filesystem
|
||||
but you have now a FileSystem interface called IFileSystem who can be overrided with your needs
|
||||
by ex for android, emscripten, or boost
|
||||
|
||||
2 steps :
|
||||
|
||||
1) create a include file who must contain :
|
||||
- your override of IGFD::IFileSystem
|
||||
- a define of your class name in FILE_SYSTEM_OVERRIDE (ex : #define FILE_SYSTEM_OVERRIDE FileSystemBoost)
|
||||
|
||||
2) define your file system include file path in the preprocessor var "CUSTOM_FILESYSTEM_INCLUDE"
|
||||
ex : #define CUSTOM_FILESYSTEM_INCLUDE "src/FileSystemBoost.hpp"
|
||||
|
||||
you can check the DemoApp who is using an override for the Boost::filesystem
|
||||
|
||||
</blockquote></details>
|
||||
|
||||
<details open><summary><h2>C Api :</h2></summary><blockquote>
|
||||
|
||||
this api was sucessfully tested with CImGui
|
||||
|
||||
|
|
|
|||
37
story-editor-v2/libs/ImGuiFileDialog/stb/LICENSE
Normal file
37
story-editor-v2/libs/ImGuiFileDialog/stb/LICENSE
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
165
story-editor-v2/libs/ImGuiFileDialog/stb/README.md
Normal file
165
story-editor-v2/libs/ImGuiFileDialog/stb/README.md
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
<!--- THIS FILE IS AUTOMATICALLY GENERATED, DO NOT CHANGE IT BY HAND --->
|
||||
|
||||
stb
|
||||
===
|
||||
|
||||
single-file public domain (or MIT licensed) libraries for C/C++
|
||||
|
||||
Noteworthy:
|
||||
|
||||
* image loader: [stb_image.h](stb_image.h)
|
||||
* image writer: [stb_image_write.h](stb_image_write.h)
|
||||
* image resizer: [stb_image_resize.h](stb_image_resize.h)
|
||||
* font text rasterizer: [stb_truetype.h](stb_truetype.h)
|
||||
* typesafe containers: [stb_ds.h](stb_ds.h)
|
||||
|
||||
Most libraries by stb, except: stb_dxt by Fabian "ryg" Giesen, stb_image_resize
|
||||
by Jorge L. "VinoBS" Rodriguez, and stb_sprintf by Jeff Roberts.
|
||||
|
||||
<a name="stb_libs"></a>
|
||||
|
||||
library | lastest version | category | LoC | description
|
||||
--------------------- | ---- | -------- | --- | --------------------------------
|
||||
**[stb_vorbis.c](stb_vorbis.c)** | 1.20 | audio | 5563 | decode ogg vorbis files from file/memory to float/16-bit signed output
|
||||
**[stb_image.h](stb_image.h)** | 2.26 | graphics | 7762 | image loading/decoding from file/memory: JPG, PNG, TGA, BMP, PSD, GIF, HDR, PIC
|
||||
**[stb_truetype.h](stb_truetype.h)** | 1.24 | graphics | 5011 | parse, decode, and rasterize characters from truetype fonts
|
||||
**[stb_image_write.h](stb_image_write.h)** | 1.15 | graphics | 1690 | image writing to disk: PNG, TGA, BMP
|
||||
**[stb_image_resize.h](stb_image_resize.h)** | 0.96 | graphics | 2631 | resize images larger/smaller with good quality
|
||||
**[stb_rect_pack.h](stb_rect_pack.h)** | 1.00 | graphics | 628 | simple 2D rectangle packer with decent quality
|
||||
**[stb_ds.h](stb_ds.h)** | 0.65 | utility | 1880 | typesafe dynamic array and hash tables for C, will compile in C++
|
||||
**[stb_sprintf.h](stb_sprintf.h)** | 1.09 | utility | 1879 | fast sprintf, snprintf for C/C++
|
||||
**[stretchy_buffer.h](stretchy_buffer.h)** | 1.04 | utility | 263 | typesafe dynamic array for C (i.e. approximation to vector<>), doesn't compile as C++
|
||||
**[stb_textedit.h](stb_textedit.h)** | 1.13 | user interface | 1404 | guts of a text editor for games etc implementing them from scratch
|
||||
**[stb_voxel_render.h](stb_voxel_render.h)** | 0.89 | 3D graphics | 3807 | Minecraft-esque voxel rendering "engine" with many more features
|
||||
**[stb_dxt.h](stb_dxt.h)** | 1.10 | 3D graphics | 753 | Fabian "ryg" Giesen's real-time DXT compressor
|
||||
**[stb_perlin.h](stb_perlin.h)** | 0.5 | 3D graphics | 428 | revised Perlin noise (3D input, 1D output)
|
||||
**[stb_easy_font.h](stb_easy_font.h)** | 1.1 | 3D graphics | 305 | quick-and-dirty easy-to-deploy bitmap font for printing frame rate, etc
|
||||
**[stb_tilemap_editor.h](stb_tilemap_editor.h)** | 0.41 | game dev | 4161 | embeddable tilemap editor
|
||||
**[stb_herringbone_wa...](stb_herringbone_wang_tile.h)** | 0.7 | game dev | 1221 | herringbone Wang tile map generator
|
||||
**[stb_c_lexer.h](stb_c_lexer.h)** | 0.11 | parsing | 966 | simplify writing parsers for C-like languages
|
||||
**[stb_divide.h](stb_divide.h)** | 0.93 | math | 430 | more useful 32-bit modulus e.g. "euclidean divide"
|
||||
**[stb_connected_comp...](stb_connected_components.h)** | 0.96 | misc | 1049 | incrementally compute reachability on grids
|
||||
**[stb.h](stb.h)** | 2.37 | misc | 14454 | helper functions for C, mostly redundant in C++; basically author's personal stuff
|
||||
**[stb_leakcheck.h](stb_leakcheck.h)** | 0.6 | misc | 194 | quick-and-dirty malloc/free leak-checking
|
||||
**[stb_include.h](stb_include.h)** | 0.02 | misc | 295 | implement recursive #include support, particularly for GLSL
|
||||
|
||||
Total libraries: 22
|
||||
Total lines of C code: 56774
|
||||
|
||||
|
||||
FAQ
|
||||
---
|
||||
|
||||
#### What's the license?
|
||||
|
||||
These libraries are in the public domain. You can do anything you
|
||||
want with them. You have no legal obligation
|
||||
to do anything else, although I appreciate attribution.
|
||||
|
||||
They are also licensed under the MIT open source license, if you have lawyers
|
||||
who are unhappy with public domain. Every source file includes an explicit
|
||||
dual-license for you to choose from.
|
||||
|
||||
#### <a name="other_libs"></a> Are there other single-file public-domain/open source libraries with minimal dependencies out there?
|
||||
|
||||
[Yes.](https://github.com/nothings/single_file_libs)
|
||||
|
||||
#### If I wrap an stb library in a new library, does the new library have to be public domain/MIT?
|
||||
|
||||
No, because it's public domain you can freely relicense it to whatever license your new
|
||||
library wants to be.
|
||||
|
||||
#### What's the deal with SSE support in GCC-based compilers?
|
||||
|
||||
stb_image will either use SSE2 (if you compile with -msse2) or
|
||||
will not use any SIMD at all, rather than trying to detect the
|
||||
processor at runtime and handle it correctly. As I understand it,
|
||||
the approved path in GCC for runtime-detection require
|
||||
you to use multiple source files, one for each CPU configuration.
|
||||
Because stb_image is a header-file library that compiles in only
|
||||
one source file, there's no approved way to build both an
|
||||
SSE-enabled and a non-SSE-enabled variation.
|
||||
|
||||
While we've tried to work around it, we've had multiple issues over
|
||||
the years due to specific versions of gcc breaking what we're doing,
|
||||
so we've given up on it. See https://github.com/nothings/stb/issues/280
|
||||
and https://github.com/nothings/stb/issues/410 for examples.
|
||||
|
||||
#### Some of these libraries seem redundant to existing open source libraries. Are they better somehow?
|
||||
|
||||
Generally they're only better in that they're easier to integrate,
|
||||
easier to use, and easier to release (single file; good API; no
|
||||
attribution requirement). They may be less featureful, slower,
|
||||
and/or use more memory. If you're already using an equivalent
|
||||
library, there's probably no good reason to switch.
|
||||
|
||||
#### Can I link directly to the table of stb libraries?
|
||||
|
||||
You can use [this URL](https://github.com/nothings/stb#stb_libs) to link directly to that list.
|
||||
|
||||
#### Why do you list "lines of code"? It's a terrible metric.
|
||||
|
||||
Just to give you some idea of the internal complexity of the library,
|
||||
to help you manage your expectations, or to let you know what you're
|
||||
getting into. While not all the libraries are written in the same
|
||||
style, they're certainly similar styles, and so comparisons between
|
||||
the libraries are probably still meaningful.
|
||||
|
||||
Note though that the lines do include both the implementation, the
|
||||
part that corresponds to a header file, and the documentation.
|
||||
|
||||
#### Why single-file headers?
|
||||
|
||||
Windows doesn't have standard directories where libraries
|
||||
live. That makes deploying libraries in Windows a lot more
|
||||
painful than open source developers on Unix-derivates generally
|
||||
realize. (It also makes library dependencies a lot worse in Windows.)
|
||||
|
||||
There's also a common problem in Windows where a library was built
|
||||
against a different version of the runtime library, which causes
|
||||
link conflicts and confusion. Shipping the libs as headers means
|
||||
you normally just compile them straight into your project without
|
||||
making libraries, thus sidestepping that problem.
|
||||
|
||||
Making them a single file makes it very easy to just
|
||||
drop them into a project that needs them. (Of course you can
|
||||
still put them in a proper shared library tree if you want.)
|
||||
|
||||
Why not two files, one a header and one an implementation?
|
||||
The difference between 10 files and 9 files is not a big deal,
|
||||
but the difference between 2 files and 1 file is a big deal.
|
||||
You don't need to zip or tar the files up, you don't have to
|
||||
remember to attach *two* files, etc.
|
||||
|
||||
#### Why "stb"? Is this something to do with Set-Top Boxes?
|
||||
|
||||
No, they are just the initials for my name, Sean T. Barrett.
|
||||
This was not chosen out of egomania, but as a moderately sane
|
||||
way of namespacing the filenames and source function names.
|
||||
|
||||
#### Will you add more image types to stb_image.h?
|
||||
|
||||
No. As stb_image use has grown, it has become more important
|
||||
for us to focus on security of the codebase. Adding new image
|
||||
formats increases the amount of code we need to secure, so it
|
||||
is no longer worth adding new formats.
|
||||
|
||||
#### Do you have any advice on how to create my own single-file library?
|
||||
|
||||
Yes. https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
|
||||
|
||||
#### Why public domain?
|
||||
|
||||
I prefer it over GPL, LGPL, BSD, zlib, etc. for many reasons.
|
||||
Some of them are listed here:
|
||||
https://github.com/nothings/stb/blob/master/docs/why_public_domain.md
|
||||
|
||||
#### Why C?
|
||||
|
||||
Primarily, because I use C, not C++. But it does also make it easier
|
||||
for other people to use them from other languages.
|
||||
|
||||
#### Why not C99? stdint.h, declare-anywhere, etc.
|
||||
|
||||
I still use MSVC 6 (1998) as my IDE because it has better human factors
|
||||
for me than later versions of MSVC.
|
||||
7762
story-editor-v2/libs/ImGuiFileDialog/stb/stb_image.h
Normal file
7762
story-editor-v2/libs/ImGuiFileDialog/stb/stb_image.h
Normal file
File diff suppressed because it is too large
Load diff
2631
story-editor-v2/libs/ImGuiFileDialog/stb/stb_image_resize.h
Normal file
2631
story-editor-v2/libs/ImGuiFileDialog/stb/stb_image_resize.h
Normal file
File diff suppressed because it is too large
Load diff
135
story-editor-v2/src/CustomImGuiFileDialogConfig.h
Normal file
135
story-editor-v2/src/CustomImGuiFileDialogConfig.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
#pragma once
|
||||
|
||||
// uncomment and modify defines under for customize ImGuiFileDialog
|
||||
|
||||
// uncomment if you need to use your FileSystem Interface
|
||||
// if commented, you have two defualt interface, std::filesystem or dirent
|
||||
// #define USE_CUSTOM_FILESYSTEM
|
||||
|
||||
// this options need c++17
|
||||
// #define USE_STD_FILESYSTEM
|
||||
|
||||
//#define MAX_FILE_DIALOG_NAME_BUFFER 1024
|
||||
//#define MAX_PATH_BUFFER_SIZE 1024
|
||||
|
||||
// the slash's buttons in path cna be used for quick select parallles directories
|
||||
//#define USE_QUICK_PATH_SELECT
|
||||
|
||||
// the spacing between button path's can be customized.
|
||||
// if disabled the spacing is defined by the imgui theme
|
||||
// define the space between path buttons
|
||||
//#define CUSTOM_PATH_SPACING 2
|
||||
|
||||
//#define USE_THUMBNAILS
|
||||
//the thumbnail generation use the stb_image and stb_resize lib who need to define the implementation
|
||||
//btw if you already use them in your app, you can have compiler error due to "implemntation found in double"
|
||||
//so uncomment these line for prevent the creation of implementation of these libs again
|
||||
//#define DONT_DEFINE_AGAIN__STB_IMAGE_IMPLEMENTATION
|
||||
//#define DONT_DEFINE_AGAIN__STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
//#define IMGUI_RADIO_BUTTON RadioButton
|
||||
//#define DisplayMode_ThumbailsList_ImageHeight 32.0f
|
||||
//#define tableHeaderFileThumbnailsString "Thumbnails"
|
||||
//#define DisplayMode_FilesList_ButtonString "FL"
|
||||
//#define DisplayMode_FilesList_ButtonHelp "File List"
|
||||
//#define DisplayMode_ThumbailsList_ButtonString "TL"
|
||||
//#define DisplayMode_ThumbailsList_ButtonHelp "Thumbnails List"
|
||||
// todo
|
||||
//#define DisplayMode_ThumbailsGrid_ButtonString "TG"
|
||||
//#define DisplayMode_ThumbailsGrid_ButtonHelp "Thumbnails Grid"
|
||||
|
||||
//#define USE_EXPLORATION_BY_KEYS
|
||||
// this mapping by default is for GLFW but you can use another
|
||||
//#include <GLFW/glfw3.h>
|
||||
// Up key for explore to the top
|
||||
//#define IGFD_KEY_UP ImGuiKey_UpArrow
|
||||
// Down key for explore to the bottom
|
||||
//#define IGFD_KEY_DOWN ImGuiKey_DownArrow
|
||||
// Enter key for open directory
|
||||
//#define IGFD_KEY_ENTER ImGuiKey_Enter
|
||||
// BackSpace for comming back to the last directory
|
||||
//#define IGFD_KEY_BACKSPACE ImGuiKey_Backspace
|
||||
|
||||
// by ex you can quit the dialog by pressing the key excape
|
||||
//#define USE_DIALOG_EXIT_WITH_KEY
|
||||
//#define IGFD_EXIT_KEY ImGuiKey_Escape
|
||||
|
||||
// widget
|
||||
// begin combo widget
|
||||
//#define IMGUI_BEGIN_COMBO ImGui::BeginCombo
|
||||
// when auto resized, FILTER_COMBO_MIN_WIDTH will be considered has minimum width
|
||||
// FILTER_COMBO_AUTO_SIZE is enabled by default now to 1
|
||||
// uncomment if you want disable
|
||||
//#define FILTER_COMBO_AUTO_SIZE 0
|
||||
// filter combobox width
|
||||
//#define FILTER_COMBO_MIN_WIDTH 120.0f
|
||||
// button widget use for compose path
|
||||
//#define IMGUI_PATH_BUTTON ImGui::Button
|
||||
// standard button
|
||||
//#define IMGUI_BUTTON ImGui::Button
|
||||
|
||||
// locales string
|
||||
//#define createDirButtonString "+"
|
||||
//#define resetButtonString "R"
|
||||
//#define drivesButtonString "Drives"
|
||||
//#define editPathButtonString "E"
|
||||
//#define searchString "Search"
|
||||
//#define dirEntryString "[DIR] "
|
||||
//#define linkEntryString "[LINK] "
|
||||
//#define fileEntryString "[FILE] "
|
||||
//#define fileNameString "File Name : "
|
||||
//#define dirNameString "Directory Path :"
|
||||
//#define buttonResetSearchString "Reset search"
|
||||
//#define buttonDriveString "Drives"
|
||||
//#define buttonEditPathString "Edit path\nYou can also right click on path buttons"
|
||||
//#define buttonResetPathString "Reset to current directory"
|
||||
//#define buttonCreateDirString "Create Directory"
|
||||
//#define OverWriteDialogTitleString "The file Already Exist !"
|
||||
//#define OverWriteDialogMessageString "Would you like to OverWrite it ?"
|
||||
//#define OverWriteDialogConfirmButtonString "Confirm"
|
||||
//#define OverWriteDialogCancelButtonString "Cancel"
|
||||
|
||||
//Validation buttons
|
||||
//#define okButtonString " OK"
|
||||
//#define okButtonWidth 0.0f
|
||||
//#define cancelButtonString " Cancel"
|
||||
//#define cancelButtonWidth 0.0f
|
||||
//alignement [0:1], 0.0 is left, 0.5 middle, 1.0 right, and other ratios
|
||||
//#define okCancelButtonAlignement 0.0f
|
||||
//#define invertOkAndCancelButtons 0
|
||||
|
||||
// DateTimeFormat
|
||||
// see strftime functionin <ctime> for customize
|
||||
// "%Y/%m/%d %H:%M" give 2021:01:22 11:47
|
||||
// "%Y/%m/%d %i:%M%p" give 2021:01:22 11:45PM
|
||||
//#define DateTimeFormat "%Y/%m/%d %i:%M%p"
|
||||
|
||||
// theses icons will appear in table headers
|
||||
//#define USE_CUSTOM_SORTING_ICON
|
||||
//#define tableHeaderAscendingIcon "A|"
|
||||
//#define tableHeaderDescendingIcon "D|"
|
||||
//#define tableHeaderFileNameString " File name"
|
||||
//#define tableHeaderFileTypeString " Type"
|
||||
//#define tableHeaderFileSizeString " Size"
|
||||
//#define tableHeaderFileDateTimeString " Date"
|
||||
//#define fileSizeBytes "o"
|
||||
//#define fileSizeKiloBytes "Ko"
|
||||
//#define fileSizeMegaBytes "Mo"
|
||||
//#define fileSizeGigaBytes "Go"
|
||||
|
||||
// default table sort field (must be FIELD_FILENAME, FIELD_TYPE, FIELD_SIZE, FIELD_DATE or FIELD_THUMBNAILS)
|
||||
//#define defaultSortField FIELD_FILENAME
|
||||
|
||||
// default table sort order for each field (true => Descending, false => Ascending)
|
||||
//#define defaultSortOrderFilename true
|
||||
//#define defaultSortOrderType true
|
||||
//#define defaultSortOrderSize true
|
||||
//#define defaultSortOrderDate true
|
||||
//#define defaultSortOrderThumbnails true
|
||||
|
||||
//#define USE_BOOKMARK
|
||||
//#define bookmarkPaneWith 150.0f
|
||||
//#define IMGUI_TOGGLE_BUTTON ToggleButton
|
||||
//#define bookmarksButtonString "Bookmark"
|
||||
//#define bookmarksButtonHelpString "Bookmark"
|
||||
//#define addBookmarkButtonString "+"
|
||||
//#define removeBookmarkButtonString "-"
|
||||
|
|
@ -1,19 +1,17 @@
|
|||
#include "base_node.h"
|
||||
#include "uuid.h"
|
||||
|
||||
#include "IconsMaterialDesignIcons.h"
|
||||
|
||||
int BaseNode::s_nextId = 1;
|
||||
|
||||
BaseNode::BaseNode(const std::string &title)
|
||||
BaseNode::BaseNode(const std::string &title, StoryProject &proj)
|
||||
: m_project(proj)
|
||||
{
|
||||
m_id = UUID().String();
|
||||
// m_id = UUID().String();
|
||||
|
||||
m_id = -1;
|
||||
m_node = std::make_unique<Node>(GetNextId(), title.c_str());
|
||||
|
||||
// m_node->Inputs.emplace_back(GetNextId(), "", PinType::Flow);
|
||||
// m_node->Inputs.emplace_back(GetNextId(), "Condition", PinType::Bool);
|
||||
// m_node->Outputs.emplace_back(GetNextId(), "True", PinType::Flow);
|
||||
// m_node->Outputs.emplace_back(GetNextId(), "False", PinType::Flow);
|
||||
}
|
||||
|
||||
void BaseNode::AddInput()
|
||||
|
|
@ -21,10 +19,28 @@ void BaseNode::AddInput()
|
|||
m_node->Inputs.emplace_back(GetNextId(), "", PinType::Flow);
|
||||
}
|
||||
|
||||
void BaseNode::AddOutput()
|
||||
void BaseNode::AddOutputs(int num)
|
||||
{
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
m_node->Outputs.emplace_back(GetNextId(), "", PinType::Flow);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseNode::SetOutputs(uint32_t num)
|
||||
{
|
||||
if (num > Outputs())
|
||||
{
|
||||
AddOutputs(num - Outputs());
|
||||
}
|
||||
else if (num < Outputs())
|
||||
{
|
||||
for (unsigned int i = 0; i < (Outputs() - num); i++)
|
||||
{
|
||||
DeleteOutput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseNode::DeleteOutput()
|
||||
{
|
||||
|
|
@ -33,28 +49,20 @@ void BaseNode::DeleteOutput()
|
|||
|
||||
void BaseNode::SetPosition(int x, int y)
|
||||
{
|
||||
ed::SetNodePosition(m_node->ID, ImVec2(0, 0));
|
||||
m_pos.x = x;
|
||||
m_pos.y = y;
|
||||
m_firstFrame = true;
|
||||
}
|
||||
|
||||
void BaseNode::FrameStart()
|
||||
{
|
||||
ed::BeginNode(m_node->ID);
|
||||
|
||||
// ImGui::Text("Node A");
|
||||
// for (auto& input : m_node->Inputs)
|
||||
// {
|
||||
// ed::BeginPin(input.ID, ed::PinKind::Input);
|
||||
// ImGui::Text("-> In");
|
||||
// ed::EndPin();
|
||||
// }
|
||||
|
||||
// for (auto& output : m_node->Outputs)
|
||||
// {
|
||||
// ed::BeginPin(output.ID, ed::PinKind::Output);
|
||||
// ImGui::Text("Out ->");
|
||||
// ed::EndPin();
|
||||
// }
|
||||
|
||||
if (m_firstFrame)
|
||||
{
|
||||
ed::SetNodePosition(m_node->ID, ImVec2(m_pos.x, m_pos.y));
|
||||
}
|
||||
m_firstFrame = false;
|
||||
}
|
||||
|
||||
void BaseNode::FrameEnd()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <random>
|
||||
#include <string>
|
||||
|
||||
#include "json.hpp"
|
||||
#include "story_project.h"
|
||||
|
||||
#include <imgui_node_editor.h>
|
||||
|
|
@ -100,7 +101,7 @@ public:
|
|||
int y;
|
||||
};
|
||||
|
||||
BaseNode(const std::string &title);
|
||||
BaseNode(const std::string &title, StoryProject &proj);
|
||||
|
||||
|
||||
virtual void Draw() = 0;
|
||||
|
|
@ -114,12 +115,16 @@ public:
|
|||
|
||||
uint32_t Outputs() const { return m_node->Outputs.size(); }
|
||||
|
||||
void SetId(const std::string &id) { m_id = id; }
|
||||
std::string GetId() const { return m_id; }
|
||||
void SetId(const int id) { m_id = id; }
|
||||
int GetId() const { return m_id; }
|
||||
|
||||
void seTitle(const std::string &title) { m_title = title; }
|
||||
std::string getTitle() const { return m_title; }
|
||||
|
||||
virtual void FromJson(nlohmann::json &) {
|
||||
// default implementation does nothing
|
||||
}
|
||||
|
||||
virtual nlohmann::json ToJson() const {
|
||||
nlohmann::json j;
|
||||
|
||||
|
|
@ -132,17 +137,51 @@ public:
|
|||
return s_nextId++;
|
||||
}
|
||||
|
||||
static void InitId() {
|
||||
s_nextId = 1;
|
||||
}
|
||||
|
||||
|
||||
ed::PinId GetInputPinAt(int index)
|
||||
{
|
||||
ed::PinId id = -1;
|
||||
|
||||
if (index < static_cast<int>(m_node->Inputs.size()))
|
||||
{
|
||||
id = m_node->Inputs[index].ID;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
ed::PinId GetOutputPinAt(int index)
|
||||
{
|
||||
ed::PinId id = -1;
|
||||
|
||||
if (index < static_cast<int>(m_node->Outputs.size()))
|
||||
{
|
||||
id = m_node->Outputs[index].ID;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
void AddInput();
|
||||
void AddOutput();
|
||||
void AddOutputs(int num = 1);
|
||||
void SetOutputs(uint32_t num);
|
||||
void DeleteOutput();
|
||||
|
||||
private:
|
||||
StoryProject &m_project;
|
||||
|
||||
std::unique_ptr<Node> m_node;
|
||||
|
||||
std::string m_title{"Base node"};
|
||||
std::string m_type;
|
||||
std::string m_id;
|
||||
int m_id;
|
||||
NodePosition m_pos;
|
||||
|
||||
bool m_firstFrame{true};
|
||||
|
||||
static int s_nextId;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <fstream>
|
||||
|
||||
CodeEditor::CodeEditor()
|
||||
: WindowBase("Code editor")
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -33,15 +34,15 @@ void CodeEditor::Initialize()
|
|||
}
|
||||
}
|
||||
|
||||
void CodeEditor::Draw(const char* title, bool* p_open)
|
||||
void CodeEditor::Draw()
|
||||
{
|
||||
if (!IsVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
WindowBase::BeginDraw();
|
||||
|
||||
|
||||
auto cpos = mEditor.GetCursorPosition();
|
||||
ImGui::Begin(title, p_open, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_MenuBar);
|
||||
|
||||
|
||||
|
||||
ImGui::SetWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
|
|
@ -104,5 +105,5 @@ void CodeEditor::Draw(const char* title, bool* p_open)
|
|||
mEditor.GetLanguageDefinition().mName.c_str(), mFileToEdit.c_str());
|
||||
|
||||
mEditor.Render("TextEditor");
|
||||
ImGui::End();
|
||||
WindowBase::EndDraw();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class CodeEditor : public WindowBase
|
|||
public:
|
||||
CodeEditor();
|
||||
|
||||
void Draw(const char *title, bool *p_open);
|
||||
virtual void Draw() override;
|
||||
|
||||
void Initialize();
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "gui.h"
|
||||
|
||||
EmulatorWindow::EmulatorWindow()
|
||||
: WindowBase("Emulator")
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -13,19 +14,17 @@ void EmulatorWindow::Initialize() {
|
|||
|
||||
}
|
||||
|
||||
void EmulatorWindow::Draw(const char *title, bool *p_open)
|
||||
void EmulatorWindow::Draw()
|
||||
{
|
||||
if (!IsVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// if (!IsVisible())
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
|
||||
if (!ImGui::Begin(title, p_open))
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
WindowBase::BeginDraw();
|
||||
ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
|
||||
|
||||
// ImGui::Image((void*)(intptr_t)my_image_texture, ImVec2(313, 367));
|
||||
|
||||
|
|
@ -33,5 +32,5 @@ void EmulatorWindow::Draw(const char *title, bool *p_open)
|
|||
ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x + sz, p.y + sz), ImGui::GetColorU32(ImVec4(1.0, 1.0, 1.0, 1.0)));
|
||||
|
||||
ImGui::End();
|
||||
WindowBase::EndDraw();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ public:
|
|||
EmulatorWindow();
|
||||
|
||||
void Initialize();
|
||||
void Draw(const char* title, bool* p_open);
|
||||
virtual void Draw() override;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ your use of the corresponding standard functions.
|
|||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "imgui_impl_sdl3.h"
|
||||
#include "imgui_impl_sdlrenderer3.h"
|
||||
#include "imgui_impl_sdl2.h"
|
||||
#include "imgui_impl_sdlrenderer2.h"
|
||||
#include <stdio.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
#include <SDL3/SDL_opengles2.h>
|
||||
#include <SDL2/SDL_opengles2.h>
|
||||
#else
|
||||
#include <SDL3/SDL_opengl.h>
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#endif
|
||||
|
||||
#include "IconsMaterialDesignIcons.h"
|
||||
|
|
@ -46,7 +46,13 @@ bool LoadTextureFromFile(const char* filename, Gui::Image &img)
|
|||
return false;
|
||||
}
|
||||
|
||||
SDL_Surface* surface = SDL_CreateSurfaceFrom((void*)data, img.w, img.h, 4 * img.w, SDL_PIXELFORMAT_RGBA8888);
|
||||
// SDL3
|
||||
// SDL_Surface* surface = SDL_CreateSurfaceFrom((void*)data, img.w, img.h, 4 * img.w, SDL_PIXELFORMAT_RGBA8888);
|
||||
|
||||
// SDL2
|
||||
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom((void*)data, img.w, img.h, channels * 8, channels * img.w,
|
||||
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
|
||||
|
||||
if (surface == nullptr) {
|
||||
fprintf(stderr, "Failed to create SDL surface: %s\n", SDL_GetError());
|
||||
|
|
@ -59,7 +65,8 @@ bool LoadTextureFromFile(const char* filename, Gui::Image &img)
|
|||
fprintf(stderr, "Failed to create SDL texture: %s\n", SDL_GetError());
|
||||
}
|
||||
|
||||
SDL_DestroySurface(surface);
|
||||
// SDL_DestroySurface(surface); // SDL3
|
||||
SDL_FreeSurface(surface); // SDL2
|
||||
stbi_image_free(data);
|
||||
|
||||
return true;
|
||||
|
|
@ -76,7 +83,7 @@ Gui::Gui()
|
|||
bool Gui::Initialize()
|
||||
{
|
||||
// Setup SDL
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMEPAD) != 0)
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
|
|
@ -87,13 +94,19 @@ bool Gui::Initialize()
|
|||
|
||||
// Create window with SDL_Renderer graphics context
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN);
|
||||
window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", 1280, 720, window_flags);
|
||||
|
||||
// SDL3
|
||||
//window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", 1280, 720, window_flags);
|
||||
|
||||
// SDL2
|
||||
window = SDL_CreateWindow("Story Editor", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
||||
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
if (renderer == nullptr)
|
||||
{
|
||||
SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError());
|
||||
|
|
@ -139,8 +152,15 @@ bool Gui::Initialize()
|
|||
//ImGui::StyleColorsLight();
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL3_InitForSDLRenderer(window, renderer);
|
||||
ImGui_ImplSDLRenderer3_Init(renderer);
|
||||
|
||||
// SDL3
|
||||
// ImGui_ImplSDL3_InitForSDLRenderer(window, renderer);
|
||||
// ImGui_ImplSDLRenderer3_Init(renderer);
|
||||
|
||||
|
||||
// SDL2
|
||||
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
||||
ImGui_ImplSDLRenderer2_Init(renderer);
|
||||
|
||||
// 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.
|
||||
|
|
@ -169,11 +189,22 @@ bool Gui::PollEvent()
|
|||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
// SDL3
|
||||
/*
|
||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||
if (event.type == SDL_EVENT_QUIT)
|
||||
done = true;
|
||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||
done = true;
|
||||
*/
|
||||
|
||||
// SLD2
|
||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
if (event.type == SDL_QUIT)
|
||||
done = true;
|
||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
|
||||
done = true;
|
||||
|
||||
}
|
||||
return done;
|
||||
|
||||
|
|
@ -182,8 +213,15 @@ bool Gui::PollEvent()
|
|||
void Gui::StartFrame()
|
||||
{
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplSDLRenderer3_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
|
||||
// SDL3
|
||||
// ImGui_ImplSDLRenderer3_NewFrame();
|
||||
// ImGui_ImplSDL3_NewFrame();
|
||||
|
||||
// SDL2
|
||||
ImGui_ImplSDLRenderer2_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame();
|
||||
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
|
|
@ -192,19 +230,32 @@ void Gui::EndFrame()
|
|||
static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
// Rendering
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
|
||||
//SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
|
||||
SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255));
|
||||
SDL_RenderClear(renderer);
|
||||
ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
//ImGui_ImplSDLRenderer3_RenderDrawData(ImGui::GetDrawData()); // SDL3
|
||||
ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData()); // SDL2
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
void Gui::Destroy()
|
||||
{
|
||||
// Cleanup
|
||||
ImGui_ImplSDLRenderer3_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
|
||||
// SDL3
|
||||
// ImGui_ImplSDLRenderer3_Shutdown();
|
||||
// ImGui_ImplSDL3_Shutdown();
|
||||
|
||||
// SDL2
|
||||
ImGui_ImplSDLRenderer2_Shutdown();
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
|
||||
|
||||
ImGui::DestroyContext();
|
||||
|
||||
SDL_DestroyRenderer(renderer);
|
||||
|
|
|
|||
|
|
@ -18,11 +18,14 @@ public:
|
|||
int w;
|
||||
int h;
|
||||
|
||||
std::string name;
|
||||
|
||||
bool valid() const {
|
||||
return (w && h);
|
||||
}
|
||||
|
||||
Image();
|
||||
|
||||
};
|
||||
|
||||
struct Size {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
#include <filesystem>
|
||||
#include <random>
|
||||
|
||||
#include "platform_folders.h"
|
||||
#include "uuid.h"
|
||||
|
||||
#ifdef USE_WINDOWS_OS
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
|
|
@ -17,6 +20,7 @@
|
|||
|
||||
MainWindow::MainWindow()
|
||||
: m_resourcesWindow(m_project)
|
||||
, m_nodeEditorWindow(m_project)
|
||||
{
|
||||
m_project.Clear();
|
||||
}
|
||||
|
|
@ -26,7 +30,34 @@ MainWindow::~MainWindow()
|
|||
|
||||
}
|
||||
|
||||
void MainWindow::SetupMainMenuBar()
|
||||
void MainWindow::DrawStatusBar()
|
||||
{
|
||||
float statusWindowHeight = ImGui::GetFrameHeight() * 1.4f;
|
||||
ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(ImVec2(viewport->Pos.x, viewport->Pos.y + viewport->Size.y - statusWindowHeight));
|
||||
ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, statusWindowHeight));
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
|
||||
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoDocking;
|
||||
ImGui::Begin("StatusBar", nullptr, windowFlags);
|
||||
|
||||
|
||||
|
||||
if (true)
|
||||
{
|
||||
float dy = ImGui::GetFontSize() * 0.15f;
|
||||
|
||||
ImGui::SameLine(ImGui::GetIO().DisplaySize.x - 14.f * ImGui::GetFontSize());
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - dy);
|
||||
ImGui::Text("FPS: %.1f", 1000.0f / ImGui::GetIO().Framerate);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void MainWindow::DrawMainMenuBar()
|
||||
{
|
||||
bool showAboutPopup = false;
|
||||
bool showParameters = false;
|
||||
|
|
@ -89,7 +120,13 @@ void MainWindow::SetupMainMenuBar()
|
|||
|
||||
if (showOpenProject)
|
||||
{
|
||||
ImGuiFileDialog::Instance()->OpenDialog("OpenProjectDlgKey", "Choose File", "project.json", ".", 1, nullptr, ImGuiFileDialogFlags_Modal);
|
||||
std::string home = pf::getUserHome() + "/";
|
||||
|
||||
#ifdef DEBUG
|
||||
home = "/home/anthony/ostproj/ba869e4b-03d6-4249-9202-85b4cec767a7/";
|
||||
#endif
|
||||
|
||||
ImGuiFileDialog::Instance()->OpenDialog("OpenProjectDlgKey", "Choose File", ".json", home, 1, nullptr, ImGuiFileDialogFlags_Modal);
|
||||
}
|
||||
|
||||
// Always center this window when appearing
|
||||
|
|
@ -268,7 +305,6 @@ void MainWindow::OpenProjectDialog()
|
|||
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
|
||||
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
|
||||
|
||||
bool success = false;
|
||||
|
||||
m_project.Initialize(filePathName);
|
||||
|
||||
|
|
@ -276,38 +312,16 @@ void MainWindow::OpenProjectDialog()
|
|||
|
||||
if (m_project.Load(filePathName, model))
|
||||
{
|
||||
m_model.Load(model);
|
||||
m_nodeEditorWindow.Load(model);
|
||||
EnableProject();
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << errorMsg;
|
||||
QMessageBox::critical(this, tr("Open project error"), errorMsg);
|
||||
m_consoleWindow.AddMessage("Open project error");
|
||||
}
|
||||
|
||||
m_resourceModel.EndChange();
|
||||
RefreshProjectInformation();
|
||||
|
||||
/*
|
||||
|
||||
// action
|
||||
|
||||
|
||||
std::filesystem::path p(filePathName);
|
||||
std::filesystem::path p2 = m_project.AssetsPath() / p.filename().generic_string();
|
||||
std::filesystem::copy(p, p2, std::filesystem::copy_options::overwrite_existing);
|
||||
|
||||
Resource res;
|
||||
|
||||
std::string ext = p.extension().string();
|
||||
ext.erase(ext.begin()); // remove '.' dot sign
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), ::toupper);
|
||||
|
||||
res.format = ext;
|
||||
res.type = m_soundFile ? "sound" : "image";
|
||||
res.file = p.filename().generic_string();
|
||||
m_project.AppendResource(res);
|
||||
*/
|
||||
// RefreshProjectInformation();
|
||||
}
|
||||
|
||||
// close
|
||||
|
|
@ -317,17 +331,17 @@ void MainWindow::OpenProjectDialog()
|
|||
|
||||
void MainWindow::EnableProject()
|
||||
{
|
||||
auto proj = m_project.GetProjectFilePath();
|
||||
// Add to recent if not exists
|
||||
if (!m_recentProjects.contains(m_project.GetProjectFilePath().c_str()))
|
||||
if (std::find(m_recentProjects.begin(), m_recentProjects.end(), proj) != m_recentProjects.end())
|
||||
{
|
||||
m_recentProjects.push_front(m_project.GetProjectFilePath().c_str());
|
||||
m_recentProjects.push_back(proj);
|
||||
// Limit to 10 recent projects
|
||||
if (m_recentProjects.size() > 10) {
|
||||
m_recentProjects.pop_back();
|
||||
}
|
||||
m_toolbar->GenerateRecentProjectsMenu(m_recentProjects);
|
||||
}
|
||||
|
||||
/*
|
||||
m_ostHmiDock->Open();
|
||||
m_resourcesDock->Open();
|
||||
m_scriptEditorDock->Open();
|
||||
|
|
@ -338,6 +352,7 @@ void MainWindow::EnableProject()
|
|||
|
||||
m_toolbar->SetActionsActive(true);
|
||||
m_view->setEnabled(true);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -570,14 +585,19 @@ void MainWindow::Loop()
|
|||
gui.StartFrame();
|
||||
|
||||
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
|
||||
SetupMainMenuBar();
|
||||
DrawMainMenuBar();
|
||||
// DrawStatusBar();
|
||||
|
||||
// ------------ Draw all windows
|
||||
m_consoleWindow.Draw("Console", nullptr);
|
||||
m_emulatorWindow.Draw();
|
||||
editor.Draw();
|
||||
m_resourcesWindow.Draw();
|
||||
m_nodeEditorWindow.Draw();
|
||||
|
||||
|
||||
|
||||
console.Draw("Console", nullptr);
|
||||
m_emulatorWindow.Draw("Emulator", nullptr);
|
||||
editor.Draw("Code Editor", nullptr);
|
||||
|
||||
m_resourcesWindow.Draw("Resources", nullptr);
|
||||
m_nodeEditorWindow.Draw("Blueprint", nullptr);
|
||||
ShowOptionsWindow();
|
||||
|
||||
NewProjectPopup();
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ private:
|
|||
|
||||
Gui gui;
|
||||
EmulatorWindow m_emulatorWindow;
|
||||
ConsoleWindow console;
|
||||
ConsoleWindow m_consoleWindow;
|
||||
CodeEditor editor;
|
||||
|
||||
ResourcesWindow m_resourcesWindow;
|
||||
|
|
@ -118,7 +118,7 @@ private:
|
|||
void SaveParams();
|
||||
void LoadParams();
|
||||
|
||||
void SetupMainMenuBar();
|
||||
void DrawMainMenuBar();
|
||||
void ShowOptionsWindow();
|
||||
bool ShowQuitConfirm();
|
||||
|
||||
|
|
@ -127,6 +127,7 @@ private:
|
|||
void EnableProject();
|
||||
void CloseProject();
|
||||
void OpenProjectDialog();
|
||||
void DrawStatusBar();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
|||
|
|
@ -2,16 +2,17 @@
|
|||
|
||||
namespace ed = ax::NodeEditor;
|
||||
#include "IconsMaterialDesignIcons.h"
|
||||
#include "IconsFontAwesome5_c.h"
|
||||
|
||||
MediaNode::MediaNode(const std::string &title)
|
||||
: BaseNode(title)
|
||||
|
||||
MediaNode::MediaNode(const std::string &title, StoryProject &proj)
|
||||
: BaseNode(title, proj)
|
||||
, m_project(proj)
|
||||
{
|
||||
Gui::LoadRawImage("fairy.png", m_image);
|
||||
|
||||
// Create defaut one input and one output
|
||||
AddInput();
|
||||
AddOutput();
|
||||
AddOutputs(1);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -24,7 +25,8 @@ void MediaNode::Draw()
|
|||
ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_SizingFixedFit;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(10.0f, 10.0f));
|
||||
if (ImGui::BeginTable("table1", 1, flags)) {
|
||||
if (ImGui::BeginTable("table1", 1, flags))
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImU32 bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.3f, 0.7f, 1.0f));
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, bg_color);
|
||||
|
|
@ -52,12 +54,12 @@ void MediaNode::Draw()
|
|||
ImGui::Text("Image");
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::Text("image.png");
|
||||
ImGui::Text("%s", m_image.name.c_str());
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
bool do_select = false;
|
||||
if (ImGui::Button("Select")) {
|
||||
if (ImGui::Button("Select...")) {
|
||||
do_select = true; // Instead of saying OpenPopup() here, we set this bool, which is used later in the Deferred Pop-up Section
|
||||
}
|
||||
|
||||
|
|
@ -68,15 +70,19 @@ void MediaNode::Draw()
|
|||
ImGui::Text("Sound");
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::Text("sound.mp3");
|
||||
ImGui::Text("%s", m_soundName.c_str());
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
bool do_select_sound = false;
|
||||
if (ImGui::Button("Select")) {
|
||||
do_select_sound = true; // Instead of saying OpenPopup() here, we set this bool, which is used later in the Deferred Pop-up Section
|
||||
if (ImGui::Button("Play " ICON_MDI_PLAY))
|
||||
{
|
||||
m_project.PlaySoundFile(m_soundPath);
|
||||
}
|
||||
|
||||
bool do_select_sound = false;
|
||||
if (ImGui::Button("Select...")) {
|
||||
do_select_sound = true; // Instead of saying OpenPopup() here, we set this bool, which is used later in the Deferred Pop-up Section
|
||||
}
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Hold to repeat:");
|
||||
|
|
@ -87,11 +93,11 @@ void MediaNode::Draw()
|
|||
uint32_t counter = Outputs();
|
||||
float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
|
||||
ImGui::PushButtonRepeat(true);
|
||||
std::string leftSingle = "##left" + GetId();
|
||||
std::string leftSingle = "##left" + std::to_string(GetId());
|
||||
if (ImGui::ArrowButton(leftSingle.c_str(), ImGuiDir_Left)) { if (counter > 1) counter--; }
|
||||
ImGui::SameLine(0.0f, spacing);
|
||||
|
||||
std::string rightSingle = "##right" + GetId();
|
||||
std::string rightSingle = "##right" + std::to_string(GetId());
|
||||
if (ImGui::ArrowButton(rightSingle.c_str(), ImGuiDir_Right))
|
||||
{
|
||||
counter++;
|
||||
|
|
@ -100,23 +106,27 @@ void MediaNode::Draw()
|
|||
ImGui::SameLine();
|
||||
ImGui::Text("%d", counter);
|
||||
|
||||
if (counter > Outputs())
|
||||
{
|
||||
for (int i = 0; i < (counter - Outputs()); i++)
|
||||
{
|
||||
AddOutput();
|
||||
}
|
||||
}
|
||||
else if (counter < Outputs())
|
||||
{
|
||||
for (int i = 0; i < (Outputs() - counter); i++)
|
||||
{
|
||||
DeleteOutput();
|
||||
}
|
||||
}
|
||||
|
||||
SetOutputs(counter);
|
||||
|
||||
DrawPins();
|
||||
|
||||
BaseNode::FrameEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
"internal-data": {
|
||||
"image": "fairy.png",
|
||||
"sound": "la_fee_luminelle.mp3"
|
||||
},
|
||||
|
||||
*/
|
||||
void MediaNode::FromJson(nlohmann::json &j)
|
||||
{
|
||||
m_image.name = j["image"].get<std::string>();
|
||||
|
||||
Gui::LoadRawImage(m_project.BuildFullAssetsPath(m_image.name), m_image);
|
||||
|
||||
m_soundName = j["sound"].get<std::string>();
|
||||
m_soundPath = m_project.BuildFullAssetsPath(m_soundName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,11 +13,16 @@
|
|||
class MediaNode : public BaseNode
|
||||
{
|
||||
public:
|
||||
MediaNode(const std::string &title);
|
||||
MediaNode(const std::string &title, StoryProject &proj);
|
||||
|
||||
void Draw() override;
|
||||
|
||||
virtual void FromJson(nlohmann::json &j) override;
|
||||
|
||||
private:
|
||||
StoryProject &m_project;
|
||||
Gui::Image m_image;
|
||||
std::string m_soundName;
|
||||
std::string m_soundPath;
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,15 +1,21 @@
|
|||
#include "node_editor_window.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
#include "IconsFontAwesome5_c.h"
|
||||
|
||||
#include "media_node.h"
|
||||
#include "gui.h"
|
||||
|
||||
|
||||
NodeEditorWindow::NodeEditorWindow()
|
||||
NodeEditorWindow::NodeEditorWindow(StoryProject &proj)
|
||||
: WindowBase("Node editor")
|
||||
, m_project(proj)
|
||||
{
|
||||
|
||||
registerNode<MediaNode>("media-node");
|
||||
}
|
||||
|
||||
NodeEditorWindow::~NodeEditorWindow()
|
||||
|
|
@ -24,15 +30,6 @@ void NodeEditorWindow::Initialize()
|
|||
m_context = ed::CreateEditor(&config);
|
||||
|
||||
ed::SetCurrentEditor(m_context);
|
||||
|
||||
auto n1 = std::make_shared<MediaNode>("Branch");
|
||||
n1->SetPosition(0, 0);
|
||||
m_nodes.push_back(n1);
|
||||
|
||||
auto n2 = std::make_shared<MediaNode>("Branch 2");
|
||||
n2->SetPosition(100, 100);
|
||||
m_nodes.push_back(n2);
|
||||
|
||||
}
|
||||
|
||||
void NodeEditorWindow::Clear()
|
||||
|
|
@ -40,45 +37,123 @@ void NodeEditorWindow::Clear()
|
|||
m_nodes.clear();
|
||||
}
|
||||
|
||||
void NodeEditorWindow::Draw(const char *title, bool *p_open)
|
||||
{
|
||||
static bool resetDockspace = true;
|
||||
|
||||
float menuHeight = 0;
|
||||
|
||||
if(ImGui::BeginMainMenuBar())
|
||||
void NodeEditorWindow::LoadNode(const nlohmann::json &nodeJson)
|
||||
{
|
||||
menuHeight = ImGui::GetWindowSize().y;
|
||||
try
|
||||
{
|
||||
int restoredNodeId = nodeJson["id"].get<int>();
|
||||
nlohmann::json internalDataJson = nodeJson["internal-data"];
|
||||
std::string type = nodeJson["type"].get<std::string>();
|
||||
|
||||
if (ImGui::BeginMenu("Actions"))
|
||||
auto n = createNode(type, "", m_project);
|
||||
if (n)
|
||||
{
|
||||
if(ImGui::MenuItem("Quit"))
|
||||
{
|
||||
// mEvent.ExitGame();
|
||||
n->SetId(restoredNodeId);
|
||||
nlohmann::json posJson = nodeJson["position"];
|
||||
n->SetOutputs(nodeJson["outPortCount"].get<int>());
|
||||
n->SetPosition(posJson["x"].get<int>(), posJson["y"].get<int>());
|
||||
n->FromJson(internalDataJson);
|
||||
|
||||
m_nodes[restoredNodeId] = n;
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
else
|
||||
{
|
||||
throw std::logic_error(std::string("No registered model with name ") + type);
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "ERROR: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
static ImGuiWindowFlags window_flags = ImGuiWindowFlags_None;
|
||||
|
||||
ed::PinId NodeEditorWindow::GetInputPin(int modelNodeId, int pinIndex)
|
||||
{
|
||||
ed::PinId id = -1;
|
||||
|
||||
for (auto & n : m_nodes)
|
||||
{
|
||||
if (n.first == modelNodeId)
|
||||
{
|
||||
id = n.second->GetInputPinAt(pinIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
ed::PinId NodeEditorWindow::GetOutputPin(int modelNodeId, int pinIndex)
|
||||
{
|
||||
ed::PinId id = -1;
|
||||
|
||||
for (auto & n : m_nodes)
|
||||
{
|
||||
if (n.first == modelNodeId)
|
||||
{
|
||||
id = n.second->GetOutputPinAt(pinIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void NodeEditorWindow::Load(const nlohmann::json &model)
|
||||
{
|
||||
nlohmann::json nodesJsonArray = model["nodes"];
|
||||
|
||||
BaseNode::InitId();
|
||||
m_nodes.clear();
|
||||
m_links.clear();
|
||||
|
||||
for (auto& element : nodesJsonArray) {
|
||||
LoadNode(element);
|
||||
}
|
||||
|
||||
std::cout << model.dump(4) << std::endl;
|
||||
|
||||
nlohmann::json connectionJsonArray = model["connections"];
|
||||
|
||||
for (auto& connection : connectionJsonArray)
|
||||
{
|
||||
auto conn = std::make_shared<LinkInfo>();
|
||||
|
||||
// our model
|
||||
conn->model = connection.get<Connection>();
|
||||
|
||||
|
||||
if (ImGui::Begin("EditorView", NULL, window_flags))
|
||||
// ImGui stuff for links
|
||||
conn->Id = 100000 + BaseNode::GetNextId();
|
||||
conn->InputId = GetInputPin(conn->model.inNodeId, conn->model.inPortIndex);
|
||||
conn->OutputId = GetOutputPin(conn->model.outNodeId, conn->model.outPortIndex);
|
||||
|
||||
// Since we accepted new link, lets add one to our list of links.
|
||||
m_links.push_back(conn);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void NodeEditorWindow::Draw()
|
||||
{
|
||||
if (WindowBase::BeginDraw())
|
||||
{
|
||||
|
||||
ed::SetCurrentEditor(m_context);
|
||||
ed::Begin("My Editor", ImVec2(0.0, 0.0f));
|
||||
|
||||
for (auto & n : m_nodes)
|
||||
|
||||
for (const auto & n : m_nodes)
|
||||
{
|
||||
n->Draw();
|
||||
n.second->Draw();
|
||||
}
|
||||
|
||||
for (auto& linkInfo : m_Links)
|
||||
for (const auto& linkInfo : m_links)
|
||||
{
|
||||
ed::Link(linkInfo.Id, linkInfo.InputId, linkInfo.OutputId);
|
||||
ed::Link(linkInfo->Id, linkInfo->OutputId, linkInfo->InputId);
|
||||
}
|
||||
|
||||
// Handle creation action, returns true if editor want to create new object (node or link)
|
||||
|
|
@ -105,10 +180,10 @@ void NodeEditorWindow::Draw(const char *title, bool *p_open)
|
|||
if (ed::AcceptNewItem())
|
||||
{
|
||||
// Since we accepted new link, lets add one to our list of links.
|
||||
m_Links.push_back({ ed::LinkId(m_NextLinkId++), inputPinId, outputPinId });
|
||||
// m_Links.push_back({ ed::LinkId(BaseNode::GetNextId()), inputPinId, outputPinId });
|
||||
|
||||
// Draw new link.
|
||||
ed::Link(m_Links.back().Id, m_Links.back().InputId, m_Links.back().OutputId);
|
||||
// ed::Link(m_Links.back().Id, m_Links.back().InputId, m_Links.back().OutputId);
|
||||
}
|
||||
|
||||
// You may choose to reject connection between these nodes
|
||||
|
|
@ -130,15 +205,10 @@ void NodeEditorWindow::Draw(const char *title, bool *p_open)
|
|||
// If you agree that link can be deleted, accept deletion.
|
||||
if (ed::AcceptDeletedItem())
|
||||
{
|
||||
// Then remove link from your data.
|
||||
for (auto& link : m_Links)
|
||||
{
|
||||
if (link.Id == deletedLinkId)
|
||||
{
|
||||
m_Links.erase(&link);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_links.erase(std::remove_if(m_links.begin(),
|
||||
m_links.end(),
|
||||
[deletedLinkId](std::shared_ptr<LinkInfo> inf) { return inf->Id == deletedLinkId; }));
|
||||
}
|
||||
|
||||
// You may reject link deletion by calling:
|
||||
|
|
@ -153,7 +223,7 @@ void NodeEditorWindow::Draw(const char *title, bool *p_open)
|
|||
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
WindowBase::EndDraw();
|
||||
}
|
||||
|
||||
void NodeEditorWindow::ToolbarUI()
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include <imgui_node_editor.h>
|
||||
#include "base_node.h"
|
||||
#include "window_base.h"
|
||||
#include "story_project.h"
|
||||
#include "json.hpp"
|
||||
|
||||
namespace ed = ax::NodeEditor;
|
||||
|
||||
|
|
@ -27,26 +29,31 @@ class NodeEditorWindow : public WindowBase
|
|||
public:
|
||||
struct LinkInfo
|
||||
{
|
||||
// Stuff from ImGuiNodeEditor
|
||||
ed::LinkId Id;
|
||||
ed::PinId InputId;
|
||||
ed::PinId OutputId;
|
||||
|
||||
// Stuff from the project.json file, our model
|
||||
Connection model;
|
||||
};
|
||||
|
||||
NodeEditorWindow();
|
||||
NodeEditorWindow(StoryProject &proj);
|
||||
~NodeEditorWindow();
|
||||
void Draw(const char *title, bool *p_open);
|
||||
virtual void Draw() override;
|
||||
|
||||
void Initialize();
|
||||
void Clear();
|
||||
void Load(const nlohmann::json &model);
|
||||
|
||||
private:
|
||||
StoryProject &m_project;
|
||||
|
||||
ed::EditorContext* m_context = nullptr;
|
||||
|
||||
std::vector<std::shared_ptr<BaseNode>> m_nodes;
|
||||
|
||||
|
||||
|
||||
ImVector<LinkInfo> m_Links; // List of live links. It is dynamic unless you want to create read-only view over nodes.
|
||||
int m_NextLinkId = 100; // Counter to help generate link ids. In real application this will probably based on pointer to user data structure.
|
||||
// key: Id
|
||||
std::map<int, std::shared_ptr<BaseNode>> m_nodes;
|
||||
std::vector<std::shared_ptr<LinkInfo>> m_links; // List of live links. It is dynamic unless you want to create read-only view over nodes.
|
||||
void ToolbarUI();
|
||||
|
||||
|
||||
|
|
@ -64,26 +71,34 @@ private:
|
|||
output.Kind = PinKind::Output;
|
||||
}
|
||||
}
|
||||
/*
|
||||
void BuildNodes()
|
||||
{
|
||||
for (auto& node : m_Nodes)
|
||||
BuildNode(&node);
|
||||
|
||||
template<class NodeType>
|
||||
struct Factory {
|
||||
static std::shared_ptr<BaseNode> create_func(const std::string &title, StoryProject &proj) {
|
||||
return std::make_shared<NodeType>(title, proj);
|
||||
}
|
||||
|
||||
Node* SpawnBranchNode()
|
||||
{
|
||||
m_Nodes.emplace_back(GetNextId(), "Branch");
|
||||
m_Nodes.back().Inputs.emplace_back(GetNextId(), "", PinType::Flow);
|
||||
m_Nodes.back().Inputs.emplace_back(GetNextId(), "Condition", PinType::Bool);
|
||||
m_Nodes.back().Outputs.emplace_back(GetNextId(), "True", PinType::Flow);
|
||||
m_Nodes.back().Outputs.emplace_back(GetNextId(), "False", PinType::Flow);
|
||||
|
||||
BuildNode(&m_Nodes.back());
|
||||
|
||||
return &m_Nodes.back();
|
||||
}
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<BaseNode> (*GenericCreator)(const std::string &title, StoryProject &proj);
|
||||
typedef std::map<std::string, GenericCreator> Registry;
|
||||
Registry m_registry;
|
||||
|
||||
template<class Derived>
|
||||
void registerNode(const std::string& key) {
|
||||
m_registry.insert(typename Registry::value_type(key, Factory<Derived>::create_func));
|
||||
}
|
||||
|
||||
std::shared_ptr<BaseNode> createNode(const std::string& key, const std::string &title, StoryProject &proj) {
|
||||
typename Registry::const_iterator i = m_registry.find(key);
|
||||
if (i == m_registry.end()) {
|
||||
throw std::invalid_argument(std::string(__PRETTY_FUNCTION__) +
|
||||
": key not registered");
|
||||
}
|
||||
else return i->second(title, proj);
|
||||
}
|
||||
|
||||
void LoadNode(const nlohmann::json &nodeJson);
|
||||
ed::PinId GetInputPin(int modelNodeId, int pinIndex);
|
||||
ed::PinId GetOutputPin(int modelNodeId, int pinIndex);
|
||||
};
|
||||
|
||||
|
|
|
|||
468
story-editor-v2/src/platform_folders.cpp
Normal file
468
story-editor-v2/src/platform_folders.cpp
Normal file
|
|
@ -0,0 +1,468 @@
|
|||
/*
|
||||
Its is under the MIT license, to encourage reuse by cut-and-paste.
|
||||
|
||||
The original files are hosted here: https://github.com/sago007/PlatformFolders
|
||||
|
||||
Copyright (c) 2015-2016 Poul Sander
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "platform_folders.h"
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/**
|
||||
* Retrives the effective user's home dir.
|
||||
* If the user is running as root we ignore the HOME environment. It works badly with sudo.
|
||||
* Writing to $HOME as root implies security concerns that a multiplatform program cannot be assumed to handle.
|
||||
* @return The home directory. HOME environment is respected for non-root users if it exists.
|
||||
*/
|
||||
static std::string getHome() {
|
||||
std::string res;
|
||||
int uid = getuid();
|
||||
const char* homeEnv = std::getenv("HOME");
|
||||
if ( uid != 0 && homeEnv) {
|
||||
//We only acknowlegde HOME if not root.
|
||||
res = homeEnv;
|
||||
return res;
|
||||
}
|
||||
struct passwd* pw = nullptr;
|
||||
struct passwd pwd;
|
||||
long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
if (bufsize < 0) {
|
||||
bufsize = 16384;
|
||||
}
|
||||
std::vector<char> buffer;
|
||||
buffer.resize(bufsize);
|
||||
int error_code = getpwuid_r(uid, &pwd, buffer.data(), buffer.size(), &pw);
|
||||
if (error_code) {
|
||||
throw std::runtime_error("Unable to get passwd struct.");
|
||||
}
|
||||
const char* tempRes = pw->pw_dir;
|
||||
if (!tempRes) {
|
||||
throw std::runtime_error("User has no home directory");
|
||||
}
|
||||
res = tempRes;
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// Make sure we don't bring in all the extra junk with windows.h
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
// stringapiset.h depends on this
|
||||
#include <windows.h>
|
||||
// For SUCCEEDED macro
|
||||
#include <winerror.h>
|
||||
// For WideCharToMultiByte
|
||||
#include <stringapiset.h>
|
||||
// For SHGetFolderPathW and various CSIDL "magic numbers"
|
||||
#include <shlobj.h>
|
||||
|
||||
namespace pf {
|
||||
namespace internal {
|
||||
|
||||
std::string win32_utf16_to_utf8(const wchar_t* wstr) {
|
||||
std::string res;
|
||||
// If the 6th parameter is 0 then WideCharToMultiByte returns the number of bytes needed to store the result.
|
||||
int actualSize = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr);
|
||||
if (actualSize > 0) {
|
||||
//If the converted UTF-8 string could not be in the initial buffer. Allocate one that can hold it.
|
||||
std::vector<char> buffer(actualSize);
|
||||
actualSize = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &buffer[0], static_cast<int>(buffer.size()), nullptr, nullptr);
|
||||
res = buffer.data();
|
||||
}
|
||||
if (actualSize == 0) {
|
||||
// WideCharToMultiByte return 0 for errors.
|
||||
throw std::runtime_error("UTF16 to UTF8 failed with error code: " + std::to_string(GetLastError()));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namesapce internal
|
||||
} // namespace pf
|
||||
|
||||
class FreeCoTaskMemory {
|
||||
LPWSTR pointer = NULL;
|
||||
public:
|
||||
explicit FreeCoTaskMemory(LPWSTR pointer) : pointer(pointer) {};
|
||||
~FreeCoTaskMemory() {
|
||||
CoTaskMemFree(pointer);
|
||||
}
|
||||
};
|
||||
|
||||
static std::string GetKnownWindowsFolder(REFKNOWNFOLDERID folderId, const char* errorMsg) {
|
||||
LPWSTR wszPath = NULL;
|
||||
HRESULT hr;
|
||||
hr = SHGetKnownFolderPath(folderId, KF_FLAG_CREATE, NULL, &wszPath);
|
||||
FreeCoTaskMemory scopeBoundMemory(wszPath);
|
||||
|
||||
if (!SUCCEEDED(hr)) {
|
||||
throw std::runtime_error(errorMsg);
|
||||
}
|
||||
return pf::internal::win32_utf16_to_utf8(wszPath);
|
||||
}
|
||||
|
||||
static std::string GetAppData() {
|
||||
return GetKnownWindowsFolder(FOLDERID_RoamingAppData, "RoamingAppData could not be found");
|
||||
}
|
||||
|
||||
static std::string GetAppDataCommon() {
|
||||
return GetKnownWindowsFolder(FOLDERID_ProgramData, "ProgramData could not be found");
|
||||
}
|
||||
|
||||
static std::string GetAppDataLocal() {
|
||||
return GetKnownWindowsFolder(FOLDERID_LocalAppData, "LocalAppData could not be found");
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
#else
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#include <sys/types.h>
|
||||
// For strlen and strtok
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
//Typically Linux. For easy reading the comments will just say Linux but should work with most *nixes
|
||||
|
||||
static void throwOnRelative(const char* envName, const char* envValue) {
|
||||
if (envValue[0] != '/') {
|
||||
char buffer[200];
|
||||
std::snprintf(buffer, sizeof(buffer), "Environment \"%s\" does not start with an '/'. XDG specifies that the value must be absolute. The current value is: \"%s\"", envName, envValue);
|
||||
throw std::runtime_error(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static std::string getLinuxFolderDefault(const char* envName, const char* defaultRelativePath) {
|
||||
std::string res;
|
||||
const char* tempRes = std::getenv(envName);
|
||||
if (tempRes) {
|
||||
throwOnRelative(envName, tempRes);
|
||||
res = tempRes;
|
||||
return res;
|
||||
}
|
||||
res = getHome() + "/" + defaultRelativePath;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void appendExtraFolders(const char* envName, const char* defaultValue, std::vector<std::string>& folders) {
|
||||
const char* envValue = std::getenv(envName);
|
||||
if (!envValue) {
|
||||
envValue = defaultValue;
|
||||
}
|
||||
pf::internal::appendExtraFoldersTokenizer(envName, envValue, folders);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
namespace pf {
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
namespace internal {
|
||||
void appendExtraFoldersTokenizer(const char* envName, const char* envValue, std::vector<std::string>& folders) {
|
||||
std::stringstream ss(envValue);
|
||||
std::string value;
|
||||
while (std::getline(ss, value, ':')) {
|
||||
if (value[0] == '/') {
|
||||
folders.push_back(value);
|
||||
}
|
||||
else {
|
||||
//Unless the system is wrongly configured this should never happen... But of course some systems will be incorectly configured.
|
||||
//The XDG documentation indicates that the folder should be ignored but that the program should continue.
|
||||
std::cerr << "Skipping path \"" << value << "\" in \"" << envName << "\" because it does not start with a \"/\"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string getDataHome() {
|
||||
#ifdef _WIN32
|
||||
return GetAppData();
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Library/Application Support";
|
||||
#else
|
||||
return getLinuxFolderDefault("XDG_DATA_HOME", ".local/share");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string getConfigHome() {
|
||||
#ifdef _WIN32
|
||||
return GetAppData();
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Library/Application Support";
|
||||
#else
|
||||
return getLinuxFolderDefault("XDG_CONFIG_HOME", ".config");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string getCacheDir() {
|
||||
#ifdef _WIN32
|
||||
return GetAppDataLocal();
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Library/Caches";
|
||||
#else
|
||||
return getLinuxFolderDefault("XDG_CACHE_HOME", ".cache");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string getUserHome()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return std::getenv("USERPROFILE");
|
||||
#else
|
||||
return getHome();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
std::string getStateDir() {
|
||||
#ifdef _WIN32
|
||||
return GetAppDataLocal();
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Library/Application Support";
|
||||
#else
|
||||
return getLinuxFolderDefault("XDG_STATE_HOME", ".local/state");
|
||||
#endif
|
||||
}
|
||||
|
||||
void appendAdditionalDataDirectories(std::vector<std::string>& homes) {
|
||||
#ifdef _WIN32
|
||||
homes.push_back(GetAppDataCommon());
|
||||
#elif !defined(__APPLE__)
|
||||
appendExtraFolders("XDG_DATA_DIRS", "/usr/local/share/:/usr/share/", homes);
|
||||
#endif
|
||||
}
|
||||
|
||||
void appendAdditionalConfigDirectories(std::vector<std::string>& homes) {
|
||||
#ifdef _WIN32
|
||||
homes.push_back(GetAppDataCommon());
|
||||
#elif !defined(__APPLE__)
|
||||
appendExtraFolders("XDG_CONFIG_DIRS", "/etc/xdg", homes);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
struct PlatformFolders::PlatformFoldersData {
|
||||
std::map<std::string, std::string> folders;
|
||||
};
|
||||
|
||||
static void PlatformFoldersAddFromFile(const std::string& filename, std::map<std::string, std::string>& folders) {
|
||||
std::ifstream infile(filename.c_str());
|
||||
std::string line;
|
||||
while (std::getline(infile, line)) {
|
||||
if (line.length() == 0 || line.at(0) == '#' || line.substr(0, 4) != "XDG_" || line.find("_DIR") == std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
std::size_t splitPos = line.find('=');
|
||||
std::string key = line.substr(0, splitPos);
|
||||
std::size_t valueStart = line.find('"', splitPos);
|
||||
std::size_t valueEnd = line.find('"', valueStart+1);
|
||||
std::string value = line.substr(valueStart+1, valueEnd - valueStart - 1);
|
||||
folders[key] = value;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
std::cerr << "WARNING: Failed to process \"" << line << "\" from \"" << filename << "\". Error: "<< e.what() << "\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PlatformFoldersFillData(std::map<std::string, std::string>& folders) {
|
||||
folders["XDG_DOCUMENTS_DIR"] = "$HOME/Documents";
|
||||
folders["XDG_DESKTOP_DIR"] = "$HOME/Desktop";
|
||||
folders["XDG_DOWNLOAD_DIR"] = "$HOME/Downloads";
|
||||
folders["XDG_MUSIC_DIR"] = "$HOME/Music";
|
||||
folders["XDG_PICTURES_DIR"] = "$HOME/Pictures";
|
||||
folders["XDG_PUBLICSHARE_DIR"] = "$HOME/Public";
|
||||
folders["XDG_TEMPLATES_DIR"] = "$HOME/.Templates";
|
||||
folders["XDG_VIDEOS_DIR"] = "$HOME/Videos";
|
||||
PlatformFoldersAddFromFile( getConfigHome()+"/user-dirs.dirs", folders);
|
||||
for (std::map<std::string, std::string>::iterator itr = folders.begin() ; itr != folders.end() ; ++itr ) {
|
||||
std::string& value = itr->second;
|
||||
if (value.compare(0, 5, "$HOME") == 0) {
|
||||
value = getHome() + value.substr(5, std::string::npos);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PlatformFolders::PlatformFolders() {
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
this->data = new PlatformFolders::PlatformFoldersData();
|
||||
try {
|
||||
PlatformFoldersFillData(data->folders);
|
||||
}
|
||||
catch (...) {
|
||||
delete this->data;
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PlatformFolders::~PlatformFolders() {
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
delete this->data;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string PlatformFolders::getDocumentsFolder() const {
|
||||
#ifdef _WIN32
|
||||
return GetKnownWindowsFolder(FOLDERID_Documents, "Failed to find My Documents folder");
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Documents";
|
||||
#else
|
||||
return data->folders["XDG_DOCUMENTS_DIR"];
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string PlatformFolders::getDesktopFolder() const {
|
||||
#ifdef _WIN32
|
||||
return GetKnownWindowsFolder(FOLDERID_Desktop, "Failed to find Desktop folder");
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Desktop";
|
||||
#else
|
||||
return data->folders["XDG_DESKTOP_DIR"];
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string PlatformFolders::getPicturesFolder() const {
|
||||
#ifdef _WIN32
|
||||
return GetKnownWindowsFolder(FOLDERID_Pictures, "Failed to find My Pictures folder");
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Pictures";
|
||||
#else
|
||||
return data->folders["XDG_PICTURES_DIR"];
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string PlatformFolders::getPublicFolder() const {
|
||||
#ifdef _WIN32
|
||||
return GetKnownWindowsFolder(FOLDERID_Public, "Failed to find the Public folder");
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Public";
|
||||
#else
|
||||
return data->folders["XDG_PUBLICSHARE_DIR"];
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string PlatformFolders::getDownloadFolder1() const {
|
||||
#ifdef _WIN32
|
||||
return GetKnownWindowsFolder(FOLDERID_Downloads, "Failed to find My Downloads folder");
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Downloads";
|
||||
#else
|
||||
return data->folders["XDG_DOWNLOAD_DIR"];
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string PlatformFolders::getMusicFolder() const {
|
||||
#ifdef _WIN32
|
||||
return GetKnownWindowsFolder(FOLDERID_Music, "Failed to find My Music folder");
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Music";
|
||||
#else
|
||||
return data->folders["XDG_MUSIC_DIR"];
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string PlatformFolders::getVideoFolder() const {
|
||||
#ifdef _WIN32
|
||||
return GetKnownWindowsFolder(FOLDERID_Videos, "Failed to find My Video folder");
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Movies";
|
||||
#else
|
||||
return data->folders["XDG_VIDEOS_DIR"];
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string PlatformFolders::getSaveGamesFolder1() const {
|
||||
#ifdef _WIN32
|
||||
//A dedicated Save Games folder was not introduced until Vista. For XP and older save games are most often saved in a normal folder named "My Games".
|
||||
//Data that should not be user accessible should be placed under GetDataHome() instead
|
||||
return GetKnownWindowsFolder(FOLDERID_Documents, "Failed to find My Documents folder")+"\\My Games";
|
||||
#elif defined(__APPLE__)
|
||||
return getHome()+"/Library/Application Support";
|
||||
#else
|
||||
return getDataHome();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string getDesktopFolder() {
|
||||
return PlatformFolders().getDesktopFolder();
|
||||
}
|
||||
|
||||
std::string getDocumentsFolder() {
|
||||
return PlatformFolders().getDocumentsFolder();
|
||||
}
|
||||
|
||||
std::string getDownloadFolder() {
|
||||
return PlatformFolders().getDownloadFolder1();
|
||||
}
|
||||
|
||||
std::string getDownloadFolder1() {
|
||||
return getDownloadFolder();
|
||||
}
|
||||
|
||||
std::string getPicturesFolder() {
|
||||
return PlatformFolders().getPicturesFolder();
|
||||
}
|
||||
|
||||
std::string getPublicFolder() {
|
||||
return PlatformFolders().getPublicFolder();
|
||||
}
|
||||
|
||||
std::string getMusicFolder() {
|
||||
return PlatformFolders().getMusicFolder();
|
||||
}
|
||||
|
||||
std::string getVideoFolder() {
|
||||
return PlatformFolders().getVideoFolder();
|
||||
}
|
||||
|
||||
std::string getSaveGamesFolder1() {
|
||||
return PlatformFolders().getSaveGamesFolder1();
|
||||
}
|
||||
|
||||
std::string getSaveGamesFolder2() {
|
||||
#ifdef _WIN32
|
||||
return GetKnownWindowsFolder(FOLDERID_SavedGames, "Failed to find Saved Games folder");
|
||||
#else
|
||||
return PlatformFolders().getSaveGamesFolder1();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} //namespace pf
|
||||
290
story-editor-v2/src/platform_folders.h
Normal file
290
story-editor-v2/src/platform_folders.h
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
Its is under the MIT license, to encourage reuse by cut-and-paste.
|
||||
|
||||
The original files are hosted here: https://github.com/sago007/PlatformFolders
|
||||
|
||||
Copyright (c) 2015 Poul Sander
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_FOLDERS_H
|
||||
#define PLATFORM_FOLDERS_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* The namespace I use for common function. Nothing special about it.
|
||||
*/
|
||||
namespace pf {
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
namespace internal {
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
void appendExtraFoldersTokenizer(const char* envName, const char* envValue, std::vector<std::string>& folders);
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
std::string win32_utf16_to_utf8(const wchar_t* wstr);
|
||||
#endif
|
||||
}
|
||||
#endif //DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
/**
|
||||
* Retrives the base folder for storing data files.
|
||||
* You must add the program name yourself like this:
|
||||
* @code{.cpp}
|
||||
* string data_home = getDataHome()+"/My Program Name/";
|
||||
* @endcode
|
||||
* On Windows this defaults to %APPDATA% (Roaming profile)
|
||||
* On Linux this defaults to ~/.local/share but can be configured by the user
|
||||
* @return The base folder for storing program data.
|
||||
*/
|
||||
std::string getDataHome();
|
||||
|
||||
|
||||
std::string getUserHome();
|
||||
|
||||
/**
|
||||
* Retrives the base folder for storing config files.
|
||||
* You must add the program name yourself like this:
|
||||
* @code{.cpp}
|
||||
* string data_home = getConfigHome()+"/My Program Name/";
|
||||
* @endcode
|
||||
* On Windows this defaults to %APPDATA% (Roaming profile)
|
||||
* On Linux this defaults to ~/.config but can be configured by the user
|
||||
* @return The base folder for storing config data.
|
||||
*/
|
||||
std::string getConfigHome();
|
||||
|
||||
/**
|
||||
* Retrives the base folder for storing cache files.
|
||||
* You must add the program name yourself like this:
|
||||
* @code{.cpp}
|
||||
* string data_home = getCacheDir()+"/My Program Name/cache/";
|
||||
* @endcode
|
||||
* On Windows this defaults to %APPDATALOCAL%
|
||||
* On Linux this defaults to ~/.cache but can be configured by the user
|
||||
* Note that it is recommended to append "cache" after the program name to prevent conflicting with "StateDir" under Windows
|
||||
* @return The base folder for storing data that do not need to be backed up and might be deleted.
|
||||
*/
|
||||
std::string getCacheDir();
|
||||
|
||||
/**
|
||||
* Retrives the base folder used for state files.
|
||||
* You must add the program name yourself like this:
|
||||
* @code{.cpp}
|
||||
* string data_home = getStateDir()+"/My Program Name/";
|
||||
* @endcode
|
||||
* On Windows this defaults to %APPDATALOCAL%
|
||||
* On Linux this defaults to ~/.local/state but can be configured by the user
|
||||
* On OS X this is the same as getDataHome()
|
||||
* @return The base folder for storing data that do not need to be backed up but should not be reguarly deleted either.
|
||||
*/
|
||||
std::string getStateDir();
|
||||
|
||||
/**
|
||||
* This will append extra folders that your program should be looking for data files in.
|
||||
* This does not normally include the path returned by GetDataHome().
|
||||
* If you want all the folders you should do something like:
|
||||
* @code{.cpp}
|
||||
* vector<string> folders;
|
||||
* folders.push_back(getDataHome());
|
||||
* appendAdditionalDataDirectories(folders);
|
||||
* for (string s& : folders) {
|
||||
* s+="/My Program Name/";
|
||||
* }
|
||||
* @endcode
|
||||
* You must apply "/My Program Name/" to all the strings.
|
||||
* The string at the lowest index has the highest priority.
|
||||
* @param homes A vector that extra folders will be appended to.
|
||||
*/
|
||||
void appendAdditionalDataDirectories(std::vector<std::string>& homes);
|
||||
|
||||
/**
|
||||
* This will append extra folders that your program should be looking for config files in.
|
||||
* This does not normally include the path returned by GetConfigHome().
|
||||
* If you want all the folders you should do something like:
|
||||
* @code{.cpp}
|
||||
* std::vector<std::string> folders;
|
||||
* folders.push_back(pf::getConfigHome());
|
||||
* pf::appendAdditionalConfigDirectories(folders);
|
||||
* for (std::string s& : folders) {
|
||||
* s+="/My Program Name/";
|
||||
* }
|
||||
* @endcode
|
||||
* You must apply "/My Program Name/" to all the strings.
|
||||
* The string at the lowest index has the highest priority.
|
||||
* @param homes A vector that extra folders will be appended to.
|
||||
*/
|
||||
void appendAdditionalConfigDirectories(std::vector<std::string>& homes);
|
||||
|
||||
/**
|
||||
* The folder that represents the desktop.
|
||||
* Normally you should try not to use this folder.
|
||||
* @return Absolute path to the user's desktop
|
||||
*/
|
||||
std::string getDesktopFolder();
|
||||
|
||||
/**
|
||||
* The folder to store user documents to
|
||||
* @return Absolute path to the "Documents" folder
|
||||
*/
|
||||
std::string getDocumentsFolder();
|
||||
|
||||
/**
|
||||
* The folder where files are downloaded.
|
||||
* @return Absolute path to the folder where files are downloaded to.
|
||||
*/
|
||||
std::string getDownloadFolder();
|
||||
|
||||
/**
|
||||
* The folder where files are downloaded.
|
||||
* @note This is provided for backward compatibility. Use getDownloadFolder instead.
|
||||
* @return Absolute path to the folder where files are downloaded to.
|
||||
*/
|
||||
std::string getDownloadFolder1();
|
||||
|
||||
/**
|
||||
* The folder for storing the user's pictures.
|
||||
* @return Absolute path to the "Picture" folder
|
||||
*/
|
||||
std::string getPicturesFolder();
|
||||
|
||||
/**
|
||||
* This returns the folder that can be used for sharing files with other users on the same system.
|
||||
* @return Absolute path to the "Public" folder
|
||||
*/
|
||||
std::string getPublicFolder();
|
||||
|
||||
/**
|
||||
* The folder where music is stored
|
||||
* @return Absolute path to the music folder
|
||||
*/
|
||||
std::string getMusicFolder();
|
||||
|
||||
/**
|
||||
* The folder where video is stored
|
||||
* @return Absolute path to the video folder
|
||||
*/
|
||||
std::string getVideoFolder();
|
||||
|
||||
/**
|
||||
* A base folder for storing saved games.
|
||||
* You must add the program name to it like this:
|
||||
* @code{.cpp}
|
||||
* string saved_games_folder = pf::getSaveGamesFolder1()+"/My Program Name/";
|
||||
* @endcode
|
||||
* @note Windows: This is an XP compatible version and returns the path to "My Games" in Documents. Vista and later has an official folder.
|
||||
* @note Linux: XDF does not define a folder for saved games. This will just return the same as GetDataHome()
|
||||
* @return The folder base folder for storing save games.
|
||||
*/
|
||||
std::string getSaveGamesFolder1();
|
||||
|
||||
/**
|
||||
* A base folder for storing saved games.
|
||||
* You must add the program name to it like this:
|
||||
* @code{.cpp}
|
||||
* string saved_games_folder = pf::getSaveGamesFolder2()+"/My Program Name/";
|
||||
* @endcode
|
||||
* @note PlatformFolders provide different folders to for saved games as not all operating systems has support for Saved Games yet.
|
||||
* It is recommended to pick the highest number (currently getSaveGamesFolder2) at the time your product enters production and stick with it
|
||||
* @note Windows: This returns the "Saved Games" folder. This folder exist in Vista and later
|
||||
* @note Linux: XDF does not define a folder for saved games. This will just return the same as GetDataHome()
|
||||
* @return The folder base folder for storing save games.
|
||||
*/
|
||||
std::string getSaveGamesFolder2();
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
/**
|
||||
* This class contains methods for finding the system depended special folders.
|
||||
* For Windows these folders are either by convention or given by CSIDL.
|
||||
* For Linux XDG convention is used.
|
||||
* The Linux version has very little error checking and assumes that the config is correct
|
||||
*/
|
||||
class PlatformFolders {
|
||||
public:
|
||||
PlatformFolders();
|
||||
~PlatformFolders();
|
||||
/**
|
||||
* The folder that represents the desktop.
|
||||
* Normally you should try not to use this folder.
|
||||
* @return Absolute path to the user's desktop
|
||||
*/
|
||||
std::string getDesktopFolder() const;
|
||||
/**
|
||||
* The folder to store user documents to
|
||||
* @return Absolute path to the "Documents" folder
|
||||
*/
|
||||
std::string getDocumentsFolder() const;
|
||||
/**
|
||||
* The folder for storing the user's pictures.
|
||||
* @return Absolute path to the "Picture" folder
|
||||
*/
|
||||
std::string getPicturesFolder() const;
|
||||
/**
|
||||
* Use pf::getPublicFolder() instead!
|
||||
*/
|
||||
std::string getPublicFolder() const;
|
||||
/**
|
||||
* The folder where files are downloaded.
|
||||
* @note Windows: This version is XP compatible and returns the Desktop. Vista and later has a dedicated folder.
|
||||
* @return Absolute path to the folder where files are downloaded to.
|
||||
*/
|
||||
std::string getDownloadFolder1() const;
|
||||
/**
|
||||
* The folder where music is stored
|
||||
* @return Absolute path to the music folder
|
||||
*/
|
||||
std::string getMusicFolder() const;
|
||||
/**
|
||||
* The folder where video is stored
|
||||
* @return Absolute path to the video folder
|
||||
*/
|
||||
std::string getVideoFolder() const;
|
||||
/**
|
||||
* The base folder for storing saved games.
|
||||
* You must add the program name to it like this:
|
||||
* @code{.cpp}
|
||||
* PlatformFolders pf;
|
||||
* string saved_games_folder = pf.getSaveGamesFolder1()+"/My Program Name/";
|
||||
* @endcode
|
||||
* @note Windows: This is an XP compatible version and returns the path to "My Games" in Documents. Vista and later has an official folder.
|
||||
* @note Linux: XDF does not define a folder for saved games. This will just return the same as GetDataHome()
|
||||
* @return The folder base folder for storing save games.
|
||||
*/
|
||||
std::string getSaveGamesFolder1() const;
|
||||
private:
|
||||
PlatformFolders(const PlatformFolders&);
|
||||
PlatformFolders& operator=(const PlatformFolders&);
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
struct PlatformFoldersData;
|
||||
PlatformFoldersData* data;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // skip doxygen
|
||||
|
||||
|
||||
} //namespace pf
|
||||
|
||||
#endif /* PLATFORM_FOLDERS_H */
|
||||
|
|
@ -7,7 +7,8 @@
|
|||
//static thread_pool pool;
|
||||
|
||||
ResourcesWindow::ResourcesWindow(StoryProject &project)
|
||||
: m_project(project)
|
||||
: WindowBase("Resources")
|
||||
, m_project(project)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -62,11 +63,9 @@ void ResourcesWindow::ChooseFile()
|
|||
}
|
||||
|
||||
|
||||
void ResourcesWindow::Draw(const char *title, bool *p_open)
|
||||
void ResourcesWindow::Draw()
|
||||
{
|
||||
(void) p_open;
|
||||
|
||||
ImGui::Begin(title, nullptr);
|
||||
WindowBase::BeginDraw();
|
||||
|
||||
|
||||
if (ImGui::Button("Add sound"))
|
||||
|
|
@ -99,9 +98,11 @@ void ResourcesWindow::Draw(const char *title, bool *p_open)
|
|||
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Delete", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (auto & r : m_project)
|
||||
{
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", r.file.c_str());
|
||||
|
||||
|
|
@ -121,6 +122,6 @@ void ResourcesWindow::Draw(const char *title, bool *p_open)
|
|||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
WindowBase::EndDraw();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@
|
|||
#include <map>
|
||||
#include <mutex>
|
||||
#include "story_project.h"
|
||||
#include "window_base.h"
|
||||
|
||||
class ResourcesWindow
|
||||
class ResourcesWindow : public WindowBase
|
||||
{
|
||||
public:
|
||||
ResourcesWindow(StoryProject &project);
|
||||
~ResourcesWindow();
|
||||
void Draw(const char *title, bool *p_open);
|
||||
virtual void Draw() override;
|
||||
|
||||
private:
|
||||
StoryProject &m_project;
|
||||
|
|
|
|||
|
|
@ -444,3 +444,24 @@ std::string StoryProject::GetWorkingDir() const
|
|||
return m_working_dir.string();
|
||||
}
|
||||
|
||||
std::string StoryProject::BuildFullAssetsPath(const std::string &fileName) const
|
||||
{
|
||||
return (AssetsPath() / fileName).generic_string();
|
||||
}
|
||||
|
||||
|
||||
void to_json(nlohmann::json &j, const Connection &p) {
|
||||
j = nlohmann::json{
|
||||
{"outNodeId", static_cast<int64_t>(p.outNodeId)},
|
||||
{"outPortIndex", static_cast<int64_t>(p.outPortIndex)},
|
||||
{"inNodeId", static_cast<int64_t>(p.inNodeId)},
|
||||
{"inPortIndex", static_cast<int64_t>(p.inPortIndex)},
|
||||
};
|
||||
}
|
||||
|
||||
void from_json(const nlohmann::json &j, Connection &p) {
|
||||
j.at("outNodeId").get_to(p.outNodeId);
|
||||
j.at("outPortIndex").get_to(p.outPortIndex);
|
||||
j.at("inNodeId").get_to(p.inNodeId);
|
||||
j.at("inPortIndex").get_to(p.inPortIndex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,53 +48,34 @@ struct AudioCommand {
|
|||
};
|
||||
|
||||
|
||||
// Encaasulate the genaeration of a Version 4 UUID object
|
||||
// A Version 4 UUID is a universally unique identifier that is generated using random numbers.
|
||||
class UUID
|
||||
struct Connection
|
||||
{
|
||||
public:
|
||||
|
||||
UUID() { New(); }
|
||||
|
||||
// Factory method for creating UUID object.
|
||||
void New()
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 engine{rd()};
|
||||
std::uniform_int_distribution<int> dist{0, 256}; //Limits of the interval
|
||||
|
||||
for (int index = 0; index < 16; ++index)
|
||||
{
|
||||
_data[index] = (unsigned char)dist(engine);
|
||||
}
|
||||
|
||||
_data[6] = ((_data[6] & 0x0f) | 0x40); // Version 4
|
||||
_data[8] = ((_data[8] & 0x3f) | 0x80); // Variant is 10
|
||||
}
|
||||
|
||||
// Returns UUID as formatted string
|
||||
std::string String()
|
||||
{
|
||||
// Formats to "0065e7d7-418c-4da4-b4d6-b54b6cf7466a"
|
||||
char buffer[256] = {0};
|
||||
std::snprintf(buffer, 255,
|
||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
_data[0], _data[1], _data[2], _data[3],
|
||||
_data[4], _data[5],
|
||||
_data[6], _data[7],
|
||||
_data[8], _data[9],
|
||||
_data[10], _data[11], _data[12], _data[13], _data[14], _data[15]);
|
||||
|
||||
std::string uuid = buffer;
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
|
||||
unsigned char _data[16] = {0};
|
||||
int outNodeId;
|
||||
int outPortIndex;
|
||||
int inNodeId;
|
||||
int inPortIndex;
|
||||
};
|
||||
|
||||
inline bool operator==(Connection const &a, Connection const &b)
|
||||
{
|
||||
return a.outNodeId == b.outNodeId && a.outPortIndex == b.outPortIndex
|
||||
&& a.inNodeId == b.inNodeId && a.inPortIndex == b.inPortIndex;
|
||||
}
|
||||
|
||||
inline bool operator!=(Connection const &a, Connection const &b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline void invertConnection(Connection &id)
|
||||
{
|
||||
std::swap(id.outNodeId, id.inNodeId);
|
||||
std::swap(id.outPortIndex, id.inPortIndex);
|
||||
}
|
||||
|
||||
void to_json(nlohmann::json& j, const Connection& p);
|
||||
|
||||
void from_json(const nlohmann::json& j, Connection& p);
|
||||
|
||||
|
||||
// FIXME : Structure très Lunii style, à utiliser pour la conversion peut-être ...
|
||||
|
|
@ -173,6 +154,8 @@ struct StoryProject
|
|||
std::string GetName() const { return m_name; }
|
||||
std::string GetUuid() const { return m_uuid; }
|
||||
|
||||
std::string BuildFullAssetsPath(const std::string &fileName) const;
|
||||
|
||||
std::filesystem::path AssetsPath() const { return m_assetsPath; }
|
||||
|
||||
static std::string GetFileExtension(const std::string &FileName);
|
||||
|
|
|
|||
54
story-editor-v2/src/uuid.h
Normal file
54
story-editor-v2/src/uuid.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef UUID_H
|
||||
#define UUID_H
|
||||
|
||||
#include <string>
|
||||
#include <random>
|
||||
|
||||
// Encaasulate the genaeration of a Version 4 UUID object
|
||||
// A Version 4 UUID is a universally unique identifier that is generated using random numbers.
|
||||
class UUID
|
||||
{
|
||||
public:
|
||||
|
||||
UUID() { New(); }
|
||||
|
||||
// Factory method for creating UUID object.
|
||||
void New()
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 engine{rd()};
|
||||
std::uniform_int_distribution<int> dist{0, 256}; //Limits of the interval
|
||||
|
||||
for (int index = 0; index < 16; ++index)
|
||||
{
|
||||
_data[index] = (unsigned char)dist(engine);
|
||||
}
|
||||
|
||||
_data[6] = ((_data[6] & 0x0f) | 0x40); // Version 4
|
||||
_data[8] = ((_data[8] & 0x3f) | 0x80); // Variant is 10
|
||||
}
|
||||
|
||||
// Returns UUID as formatted string
|
||||
std::string String()
|
||||
{
|
||||
// Formats to "0065e7d7-418c-4da4-b4d6-b54b6cf7466a"
|
||||
char buffer[256] = {0};
|
||||
std::snprintf(buffer, 255,
|
||||
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
_data[0], _data[1], _data[2], _data[3],
|
||||
_data[4], _data[5],
|
||||
_data[6], _data[7],
|
||||
_data[8], _data[9],
|
||||
_data[10], _data[11], _data[12], _data[13], _data[14], _data[15]);
|
||||
|
||||
std::string uuid = buffer;
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
|
||||
unsigned char _data[16] = {0};
|
||||
};
|
||||
|
||||
|
||||
#endif // UUID_H
|
||||
31
story-editor-v2/src/window_base.cpp
Normal file
31
story-editor-v2/src/window_base.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#include "window_base.h"
|
||||
#include "imgui.h"
|
||||
|
||||
WindowBase::WindowBase(const std::string &title)
|
||||
: m_title(title)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool WindowBase::BeginDraw()
|
||||
{
|
||||
bool ok = ImGui::Begin(m_title.c_str(), nullptr);
|
||||
|
||||
if (m_disabled)
|
||||
{
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void WindowBase::EndDraw()
|
||||
{
|
||||
ImGui::End();
|
||||
|
||||
|
||||
if (m_disabled)
|
||||
{
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,25 +1,26 @@
|
|||
#ifndef WINDOW_BASE_H
|
||||
#define WINDOW_BASE_H
|
||||
#ifndef WINDOWBASE_H
|
||||
#define WINDOWBASE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class WindowBase
|
||||
{
|
||||
public:
|
||||
WindowBase(bool display = false)
|
||||
{
|
||||
mDisplay = display;
|
||||
WindowBase(const std::string &title);
|
||||
|
||||
bool IsDisabled() const {
|
||||
return m_disabled;
|
||||
}
|
||||
|
||||
void SetVisible(bool enable)
|
||||
{
|
||||
mDisplay = enable;
|
||||
}
|
||||
virtual void Draw() = 0;
|
||||
|
||||
bool BeginDraw();
|
||||
void EndDraw();
|
||||
|
||||
bool IsVisible() const {
|
||||
return mDisplay;
|
||||
}
|
||||
private:
|
||||
bool mDisplay;
|
||||
|
||||
bool m_disabled{false};
|
||||
std::string m_title;
|
||||
};
|
||||
|
||||
#endif // WINDOW_BASE_H
|
||||
|
||||
#endif // WINDOWBASE_H
|
||||
|
|
|
|||
Loading…
Reference in a new issue