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/imgui.ini
|
||||||
|
|
||||||
story-editor-v2/src/.vscode/
|
story-editor-v2/src/.vscode/
|
||||||
|
|
||||||
|
build-story-editor-v2-Desktop-Debug/
|
||||||
|
|
||||||
|
build-story-editor-Desktop-Debug/
|
||||||
|
|
|
||||||
|
|
@ -22,64 +22,79 @@ if(POLICY CMP0072)
|
||||||
endif()
|
endif()
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
|
|
||||||
set(IMGUI_VERSION 1.89.9)
|
set(IMGUI_VERSION 1.90)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
|
|
||||||
|
#=========================================================================================================================
|
||||||
|
# IMGUI and plugins
|
||||||
|
#=========================================================================================================================
|
||||||
FetchContent_Declare(imgui
|
FetchContent_Declare(imgui
|
||||||
URL https://github.com/ocornut/imgui/archive/refs/tags/v${IMGUI_VERSION}-docking.zip
|
URL https://github.com/ocornut/imgui/archive/refs/tags/v${IMGUI_VERSION}-docking.zip
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
FetchContent_GetProperties(imgui)
|
FetchContent_GetProperties(imgui)
|
||||||
if (NOT imgui_POPULATED) # Have we downloaded raylib yet?
|
if (NOT imgui_POPULATED)
|
||||||
set(FETCHCONTENT_QUIET NO)
|
set(FETCHCONTENT_QUIET NO)
|
||||||
FetchContent_Populate(imgui)
|
FetchContent_Populate(imgui)
|
||||||
endif()
|
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)
|
Set(FETCHCONTENT_QUIET FALSE)
|
||||||
|
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
SDL3
|
sdl2
|
||||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
||||||
GIT_TAG origin/main
|
GIT_TAG origin/SDL2
|
||||||
GIT_SHALLOW TRUE
|
GIT_SHALLOW TRUE
|
||||||
GIT_PROGRESS TRUE
|
GIT_PROGRESS TRUE
|
||||||
)
|
)
|
||||||
|
|
||||||
set(BUILD_SHARED_LIBS TRUE)
|
set(BUILD_SHARED_LIBS TRUE)
|
||||||
set(SDL_STATIC TRUE)
|
set(SDL_STATIC TRUE)
|
||||||
FetchContent_MakeAvailable(SDL3)
|
FetchContent_MakeAvailable(sdl2)
|
||||||
|
#add_subdirectory(libs/SDL)
|
||||||
|
#include_directories(libs/SDL/include)
|
||||||
|
|
||||||
|
|
||||||
#=========================================================================================================================
|
#=========================================================================================================================
|
||||||
# SDL3-Image
|
# SDL3-Image
|
||||||
#=========================================================================================================================
|
#=========================================================================================================================
|
||||||
FetchContent_Declare(
|
#FetchContent_Declare(
|
||||||
SDL2_image
|
# SDL2_image
|
||||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git
|
# GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git
|
||||||
GIT_TAG origin/main
|
# GIT_TAG origin/main
|
||||||
GIT_SHALLOW TRUE
|
# GIT_SHALLOW TRUE
|
||||||
GIT_PROGRESS TRUE
|
# GIT_PROGRESS TRUE
|
||||||
)
|
#)
|
||||||
|
|
||||||
# START ADDITION
|
## START ADDITION
|
||||||
set(SDL2IMAGE_INSTALL OFF)
|
#set(SDL2IMAGE_INSTALL OFF)
|
||||||
set(BUILD_SHARED_LIBS FALSE)
|
#set(BUILD_SHARED_LIBS FALSE)
|
||||||
# END ADDITION
|
## END ADDITION
|
||||||
|
|
||||||
FetchContent_MakeAvailable(SDL2_image)
|
#FetchContent_MakeAvailable(SDL2_image)
|
||||||
|
|
||||||
|
|
||||||
set(SRCS
|
set(SRCS
|
||||||
|
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
|
|
||||||
src/window_base.h
|
src/window_base.h
|
||||||
|
src/window_base.cpp
|
||||||
|
|
||||||
src/console_window.cpp
|
src/console_window.cpp
|
||||||
src/console_window.h
|
src/console_window.h
|
||||||
|
|
||||||
|
|
@ -95,6 +110,9 @@ set(SRCS
|
||||||
src/media_node.h
|
src/media_node.h
|
||||||
src/media_node.cpp
|
src/media_node.cpp
|
||||||
|
|
||||||
|
src/platform_folders.cpp
|
||||||
|
src/platform_folders.h
|
||||||
|
|
||||||
src/base_node.h
|
src/base_node.h
|
||||||
src/base_node.cpp
|
src/base_node.cpp
|
||||||
|
|
||||||
|
|
@ -115,8 +133,8 @@ set(SRCS
|
||||||
libs/imgui-node-editor/crude_json.cpp
|
libs/imgui-node-editor/crude_json.cpp
|
||||||
libs/ImGuiFileDialog/ImGuiFileDialog.cpp
|
libs/ImGuiFileDialog/ImGuiFileDialog.cpp
|
||||||
|
|
||||||
${imgui_SOURCE_DIR}/backends/imgui_impl_sdl3.cpp
|
${imgui_SOURCE_DIR}/backends/imgui_impl_sdl2.cpp
|
||||||
${imgui_SOURCE_DIR}/backends/imgui_impl_sdlrenderer3.cpp
|
${imgui_SOURCE_DIR}/backends/imgui_impl_sdlrenderer2.cpp
|
||||||
${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
|
${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
|
||||||
${imgui_SOURCE_DIR}/imgui.cpp
|
${imgui_SOURCE_DIR}/imgui.cpp
|
||||||
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
${imgui_SOURCE_DIR}/imgui_widgets.cpp
|
||||||
|
|
@ -144,11 +162,13 @@ endif()
|
||||||
|
|
||||||
add_executable(${STORY_EDITOR_PROJECT}
|
add_executable(${STORY_EDITOR_PROJECT}
|
||||||
${SRCS}
|
${SRCS}
|
||||||
|
src/uuid.h
|
||||||
|
src/window_base.h src/window_base.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(${STORY_EDITOR_PROJECT} PUBLIC
|
target_include_directories(${STORY_EDITOR_PROJECT} PUBLIC
|
||||||
${imgui_SOURCE_DIR}
|
${imgui_SOURCE_DIR}
|
||||||
${sdl3_SOURCE_DIR}/include
|
${sdl2_SOURCE_DIR}/include
|
||||||
libs/ImGuiColorTextEdit/
|
libs/ImGuiColorTextEdit/
|
||||||
${imgui_SOURCE_DIR}/backends
|
${imgui_SOURCE_DIR}/backends
|
||||||
libs/ImGuiFileDialog
|
libs/ImGuiFileDialog
|
||||||
|
|
@ -159,21 +179,23 @@ target_include_directories(${STORY_EDITOR_PROJECT} PUBLIC
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_definitions(-DIMGUI_USE_WCHAR32)
|
add_definitions(-DIMGUI_USE_WCHAR32)
|
||||||
add_link_options(-static-libgcc -static-libstdc++)
|
add_link_options(-static-libgcc -static-libstdc++)
|
||||||
|
|
||||||
target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC cimg_display=0)
|
target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC cimg_display=0)
|
||||||
|
|
||||||
target_link_directories(${STORY_EDITOR_PROJECT} PUBLIC ${sdl3_BINARY_DIR})
|
target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC "$<$<CONFIG:DEBUG>:DEBUG>")
|
||||||
message(${sdl3_BINARY_DIR})
|
|
||||||
|
target_link_directories(${STORY_EDITOR_PROJECT} PUBLIC ${sdl2_BINARY_DIR})
|
||||||
|
message(${sdl2_BINARY_DIR})
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
target_link_libraries(${STORY_EDITOR_PROJECT}
|
target_link_libraries(${STORY_EDITOR_PROJECT}
|
||||||
pthread
|
pthread
|
||||||
udev
|
udev
|
||||||
glfw
|
|
||||||
OpenGL::GL
|
OpenGL::GL
|
||||||
dl
|
dl
|
||||||
SDL3
|
SDL2
|
||||||
)
|
)
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
target_link_libraries(${STORY_EDITOR_PROJECT}
|
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
File diff suppressed because it is too large
Load diff
|
|
@ -2,8 +2,12 @@
|
||||||
|
|
||||||
// uncomment and modify defines under for customize ImGuiFileDialog
|
// uncomment and modify defines under for customize ImGuiFileDialog
|
||||||
|
|
||||||
//this options need c++17
|
// uncomment if you need to use your FileSystem Interface
|
||||||
//#define USE_STD_FILESYSTEM
|
// 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_FILE_DIALOG_NAME_BUFFER 1024
|
||||||
//#define MAX_PATH_BUFFER_SIZE 1024
|
//#define MAX_PATH_BUFFER_SIZE 1024
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Win.yml)
|
[](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/Linux.yml)
|
||||||
[](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Osx.yml)
|
[](https://github.com/aiekick/ImGuiFileDialog/actions/workflows/Osx.yml)
|
||||||
[](https://github.com/ocornut/imgui)
|
[](https://github.com/ocornut/imgui)
|
||||||
|
|
||||||
# ImGuiFileDialog
|
# ImGuiFileDialog
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ solutions.
|
||||||
|
|
||||||
## ImGui Supported Version
|
## 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
|
## Structure
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ Android Requirements : Api 21 mini
|
||||||
- 0 => Infinite
|
- 0 => Infinite
|
||||||
- 1 => One file (default)
|
- 1 => One file (default)
|
||||||
- n => n files
|
- n => n files
|
||||||
- Compatible with MacOs, Linux, Windows
|
- Compatible with MacOs, Linux, Windows, Emscripten
|
||||||
- Windows version can list drives
|
- Windows version can list drives
|
||||||
- Supports modal or standard dialog types
|
- Supports modal or standard dialog types
|
||||||
- Select files or directories
|
- 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..
|
- 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)
|
- 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)
|
- 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 :
|
### WARNINGS :
|
||||||
- the nav system keyboard behavior is not working as expected, so maybe full of bug for ImGuiFileDialog
|
- 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>
|
</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
|
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 "base_node.h"
|
||||||
|
#include "uuid.h"
|
||||||
|
|
||||||
#include "IconsMaterialDesignIcons.h"
|
#include "IconsMaterialDesignIcons.h"
|
||||||
|
|
||||||
int BaseNode::s_nextId = 1;
|
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 = 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()
|
void BaseNode::AddInput()
|
||||||
|
|
@ -21,9 +19,27 @@ void BaseNode::AddInput()
|
||||||
m_node->Inputs.emplace_back(GetNextId(), "", PinType::Flow);
|
m_node->Inputs.emplace_back(GetNextId(), "", PinType::Flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseNode::AddOutput()
|
void BaseNode::AddOutputs(int num)
|
||||||
{
|
{
|
||||||
m_node->Outputs.emplace_back(GetNextId(), "", PinType::Flow);
|
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()
|
void BaseNode::DeleteOutput()
|
||||||
|
|
@ -33,28 +49,20 @@ void BaseNode::DeleteOutput()
|
||||||
|
|
||||||
void BaseNode::SetPosition(int x, int y)
|
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()
|
void BaseNode::FrameStart()
|
||||||
{
|
{
|
||||||
ed::BeginNode(m_node->ID);
|
ed::BeginNode(m_node->ID);
|
||||||
|
|
||||||
// ImGui::Text("Node A");
|
if (m_firstFrame)
|
||||||
// for (auto& input : m_node->Inputs)
|
{
|
||||||
// {
|
ed::SetNodePosition(m_node->ID, ImVec2(m_pos.x, m_pos.y));
|
||||||
// ed::BeginPin(input.ID, ed::PinKind::Input);
|
}
|
||||||
// ImGui::Text("-> In");
|
m_firstFrame = false;
|
||||||
// ed::EndPin();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (auto& output : m_node->Outputs)
|
|
||||||
// {
|
|
||||||
// ed::BeginPin(output.ID, ed::PinKind::Output);
|
|
||||||
// ImGui::Text("Out ->");
|
|
||||||
// ed::EndPin();
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseNode::FrameEnd()
|
void BaseNode::FrameEnd()
|
||||||
|
|
@ -71,7 +79,7 @@ void BaseNode::DrawPins()
|
||||||
{
|
{
|
||||||
ed::BeginPin(input.ID, ed::PinKind::Input);
|
ed::BeginPin(input.ID, ed::PinKind::Input);
|
||||||
|
|
||||||
ImGui::Text( ICON_MDI_OCTAGON_OUTLINE " In" );
|
ImGui::Text( ICON_MDI_OCTAGON_OUTLINE " In" );
|
||||||
ed::EndPin();
|
ed::EndPin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "json.hpp"
|
||||||
#include "story_project.h"
|
#include "story_project.h"
|
||||||
|
|
||||||
#include <imgui_node_editor.h>
|
#include <imgui_node_editor.h>
|
||||||
|
|
@ -100,7 +101,7 @@ public:
|
||||||
int y;
|
int y;
|
||||||
};
|
};
|
||||||
|
|
||||||
BaseNode(const std::string &title);
|
BaseNode(const std::string &title, StoryProject &proj);
|
||||||
|
|
||||||
|
|
||||||
virtual void Draw() = 0;
|
virtual void Draw() = 0;
|
||||||
|
|
@ -114,12 +115,16 @@ public:
|
||||||
|
|
||||||
uint32_t Outputs() const { return m_node->Outputs.size(); }
|
uint32_t Outputs() const { return m_node->Outputs.size(); }
|
||||||
|
|
||||||
void SetId(const std::string &id) { m_id = id; }
|
void SetId(const int id) { m_id = id; }
|
||||||
std::string GetId() const { return m_id; }
|
int GetId() const { return m_id; }
|
||||||
|
|
||||||
void seTitle(const std::string &title) { m_title = title; }
|
void seTitle(const std::string &title) { m_title = title; }
|
||||||
std::string getTitle() const { return m_title; }
|
std::string getTitle() const { return m_title; }
|
||||||
|
|
||||||
|
virtual void FromJson(nlohmann::json &) {
|
||||||
|
// default implementation does nothing
|
||||||
|
}
|
||||||
|
|
||||||
virtual nlohmann::json ToJson() const {
|
virtual nlohmann::json ToJson() const {
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
|
|
||||||
|
|
@ -132,17 +137,51 @@ public:
|
||||||
return s_nextId++;
|
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 AddInput();
|
||||||
void AddOutput();
|
void AddOutputs(int num = 1);
|
||||||
|
void SetOutputs(uint32_t num);
|
||||||
void DeleteOutput();
|
void DeleteOutput();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
StoryProject &m_project;
|
||||||
|
|
||||||
std::unique_ptr<Node> m_node;
|
std::unique_ptr<Node> m_node;
|
||||||
|
|
||||||
std::string m_title{"Base node"};
|
std::string m_title{"Base node"};
|
||||||
std::string m_type;
|
std::string m_type;
|
||||||
std::string m_id;
|
int m_id;
|
||||||
NodePosition m_pos;
|
NodePosition m_pos;
|
||||||
|
bool m_firstFrame{true};
|
||||||
|
|
||||||
static int s_nextId;
|
static int s_nextId;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
CodeEditor::CodeEditor()
|
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())
|
WindowBase::BeginDraw();
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cpos = mEditor.GetCursorPosition();
|
auto cpos = mEditor.GetCursorPosition();
|
||||||
ImGui::Begin(title, p_open, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_MenuBar);
|
|
||||||
|
|
||||||
|
|
||||||
ImGui::SetWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
|
ImGui::SetWindowSize(ImVec2(800, 600), ImGuiCond_FirstUseEver);
|
||||||
if (ImGui::BeginMenuBar())
|
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.GetLanguageDefinition().mName.c_str(), mFileToEdit.c_str());
|
||||||
|
|
||||||
mEditor.Render("TextEditor");
|
mEditor.Render("TextEditor");
|
||||||
ImGui::End();
|
WindowBase::EndDraw();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ class CodeEditor : public WindowBase
|
||||||
public:
|
public:
|
||||||
CodeEditor();
|
CodeEditor();
|
||||||
|
|
||||||
void Draw(const char *title, bool *p_open);
|
virtual void Draw() override;
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
|
||||||
EmulatorWindow::EmulatorWindow()
|
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())
|
// if (!IsVisible())
|
||||||
{
|
// {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
ImGui::SetNextWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
|
|
||||||
if (!ImGui::Begin(title, p_open))
|
|
||||||
{
|
WindowBase::BeginDraw();
|
||||||
ImGui::End();
|
ImGui::SetWindowSize(ImVec2(626, 744), ImGuiCond_FirstUseEver);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ImGui::Image((void*)(intptr_t)my_image_texture, ImVec2(313, 367));
|
// 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();
|
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::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();
|
EmulatorWindow();
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Draw(const char* title, bool* p_open);
|
virtual void Draw() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@ your use of the corresponding standard functions.
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#include "imgui_impl_sdl3.h"
|
#include "imgui_impl_sdl2.h"
|
||||||
#include "imgui_impl_sdlrenderer3.h"
|
#include "imgui_impl_sdlrenderer2.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||||
#include <SDL3/SDL_opengles2.h>
|
#include <SDL2/SDL_opengles2.h>
|
||||||
#else
|
#else
|
||||||
#include <SDL3/SDL_opengl.h>
|
#include <SDL2/SDL_opengl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "IconsMaterialDesignIcons.h"
|
#include "IconsMaterialDesignIcons.h"
|
||||||
|
|
@ -46,7 +46,13 @@ bool LoadTextureFromFile(const char* filename, Gui::Image &img)
|
||||||
return false;
|
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) {
|
if (surface == nullptr) {
|
||||||
fprintf(stderr, "Failed to create SDL surface: %s\n", SDL_GetError());
|
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());
|
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);
|
stbi_image_free(data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -76,7 +83,7 @@ Gui::Gui()
|
||||||
bool Gui::Initialize()
|
bool Gui::Initialize()
|
||||||
{
|
{
|
||||||
// Setup SDL
|
// 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());
|
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -87,13 +94,19 @@ bool Gui::Initialize()
|
||||||
|
|
||||||
// Create window with SDL_Renderer graphics context
|
// Create window with SDL_Renderer graphics context
|
||||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN);
|
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN);
|
||||||
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)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
renderer = SDL_CreateRenderer(window, 0, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||||
if (renderer == nullptr)
|
if (renderer == nullptr)
|
||||||
{
|
{
|
||||||
SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError());
|
SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError());
|
||||||
|
|
@ -139,8 +152,15 @@ bool Gui::Initialize()
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// 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
|
// Load Fonts
|
||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
|
|
@ -169,11 +189,22 @@ bool Gui::PollEvent()
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event))
|
while (SDL_PollEvent(&event))
|
||||||
{
|
{
|
||||||
|
// SDL3
|
||||||
|
/*
|
||||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||||
if (event.type == SDL_EVENT_QUIT)
|
if (event.type == SDL_EVENT_QUIT)
|
||||||
done = true;
|
done = true;
|
||||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||||
done = true;
|
done = true;
|
||||||
|
*/
|
||||||
|
|
||||||
|
// SLD2
|
||||||
|
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;
|
return done;
|
||||||
|
|
||||||
|
|
@ -182,8 +213,15 @@ bool Gui::PollEvent()
|
||||||
void Gui::StartFrame()
|
void Gui::StartFrame()
|
||||||
{
|
{
|
||||||
// Start the Dear ImGui frame
|
// 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();
|
ImGui::NewFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,19 +230,32 @@ void Gui::EndFrame()
|
||||||
static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||||
// Rendering
|
// Rendering
|
||||||
// Rendering
|
// Rendering
|
||||||
ImGui::Render();
|
|
||||||
//SDL_RenderSetScale(renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
|
//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_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);
|
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);
|
SDL_RenderPresent(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gui::Destroy()
|
void Gui::Destroy()
|
||||||
{
|
{
|
||||||
// Cleanup
|
// Cleanup
|
||||||
ImGui_ImplSDLRenderer3_Shutdown();
|
|
||||||
ImGui_ImplSDL3_Shutdown();
|
// SDL3
|
||||||
|
// ImGui_ImplSDLRenderer3_Shutdown();
|
||||||
|
// ImGui_ImplSDL3_Shutdown();
|
||||||
|
|
||||||
|
// SDL2
|
||||||
|
ImGui_ImplSDLRenderer2_Shutdown();
|
||||||
|
ImGui_ImplSDL2_Shutdown();
|
||||||
|
|
||||||
|
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(renderer);
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,14 @@ public:
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
|
||||||
bool valid() const {
|
bool valid() const {
|
||||||
return (w && h);
|
return (w && h);
|
||||||
}
|
}
|
||||||
|
|
||||||
Image();
|
Image();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Size {
|
struct Size {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
|
#include "platform_folders.h"
|
||||||
|
#include "uuid.h"
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_OS
|
#ifdef USE_WINDOWS_OS
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
|
|
@ -17,6 +20,7 @@
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
: m_resourcesWindow(m_project)
|
: m_resourcesWindow(m_project)
|
||||||
|
, m_nodeEditorWindow(m_project)
|
||||||
{
|
{
|
||||||
m_project.Clear();
|
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 showAboutPopup = false;
|
||||||
bool showParameters = false;
|
bool showParameters = false;
|
||||||
|
|
@ -89,7 +120,13 @@ void MainWindow::SetupMainMenuBar()
|
||||||
|
|
||||||
if (showOpenProject)
|
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
|
// Always center this window when appearing
|
||||||
|
|
@ -268,7 +305,6 @@ void MainWindow::OpenProjectDialog()
|
||||||
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
|
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
|
||||||
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
|
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
m_project.Initialize(filePathName);
|
m_project.Initialize(filePathName);
|
||||||
|
|
||||||
|
|
@ -276,38 +312,16 @@ void MainWindow::OpenProjectDialog()
|
||||||
|
|
||||||
if (m_project.Load(filePathName, model))
|
if (m_project.Load(filePathName, model))
|
||||||
{
|
{
|
||||||
m_model.Load(model);
|
m_nodeEditorWindow.Load(model);
|
||||||
EnableProject();
|
EnableProject();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qWarning() << errorMsg;
|
m_consoleWindow.AddMessage("Open project error");
|
||||||
QMessageBox::critical(this, tr("Open project error"), errorMsg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_resourceModel.EndChange();
|
|
||||||
RefreshProjectInformation();
|
|
||||||
|
|
||||||
/*
|
// 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);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// close
|
// close
|
||||||
|
|
@ -317,17 +331,17 @@ void MainWindow::OpenProjectDialog()
|
||||||
|
|
||||||
void MainWindow::EnableProject()
|
void MainWindow::EnableProject()
|
||||||
{
|
{
|
||||||
|
auto proj = m_project.GetProjectFilePath();
|
||||||
// Add to recent if not exists
|
// 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
|
// Limit to 10 recent projects
|
||||||
if (m_recentProjects.size() > 10) {
|
if (m_recentProjects.size() > 10) {
|
||||||
m_recentProjects.pop_back();
|
m_recentProjects.pop_back();
|
||||||
}
|
}
|
||||||
m_toolbar->GenerateRecentProjectsMenu(m_recentProjects);
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
m_ostHmiDock->Open();
|
m_ostHmiDock->Open();
|
||||||
m_resourcesDock->Open();
|
m_resourcesDock->Open();
|
||||||
m_scriptEditorDock->Open();
|
m_scriptEditorDock->Open();
|
||||||
|
|
@ -338,6 +352,7 @@ void MainWindow::EnableProject()
|
||||||
|
|
||||||
m_toolbar->SetActionsActive(true);
|
m_toolbar->SetActionsActive(true);
|
||||||
m_view->setEnabled(true);
|
m_view->setEnabled(true);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -570,14 +585,19 @@ void MainWindow::Loop()
|
||||||
gui.StartFrame();
|
gui.StartFrame();
|
||||||
|
|
||||||
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
|
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();
|
ShowOptionsWindow();
|
||||||
|
|
||||||
NewProjectPopup();
|
NewProjectPopup();
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ private:
|
||||||
|
|
||||||
Gui gui;
|
Gui gui;
|
||||||
EmulatorWindow m_emulatorWindow;
|
EmulatorWindow m_emulatorWindow;
|
||||||
ConsoleWindow console;
|
ConsoleWindow m_consoleWindow;
|
||||||
CodeEditor editor;
|
CodeEditor editor;
|
||||||
|
|
||||||
ResourcesWindow m_resourcesWindow;
|
ResourcesWindow m_resourcesWindow;
|
||||||
|
|
@ -118,7 +118,7 @@ private:
|
||||||
void SaveParams();
|
void SaveParams();
|
||||||
void LoadParams();
|
void LoadParams();
|
||||||
|
|
||||||
void SetupMainMenuBar();
|
void DrawMainMenuBar();
|
||||||
void ShowOptionsWindow();
|
void ShowOptionsWindow();
|
||||||
bool ShowQuitConfirm();
|
bool ShowQuitConfirm();
|
||||||
|
|
||||||
|
|
@ -127,6 +127,7 @@ private:
|
||||||
void EnableProject();
|
void EnableProject();
|
||||||
void CloseProject();
|
void CloseProject();
|
||||||
void OpenProjectDialog();
|
void OpenProjectDialog();
|
||||||
|
void DrawStatusBar();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,17 @@
|
||||||
|
|
||||||
namespace ed = ax::NodeEditor;
|
namespace ed = ax::NodeEditor;
|
||||||
#include "IconsMaterialDesignIcons.h"
|
#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);
|
Gui::LoadRawImage("fairy.png", m_image);
|
||||||
|
|
||||||
// Create defaut one input and one output
|
// Create defaut one input and one output
|
||||||
AddInput();
|
AddInput();
|
||||||
AddOutput();
|
AddOutputs(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -24,7 +25,8 @@ void MediaNode::Draw()
|
||||||
ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_SizingFixedFit;
|
ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_SizingFixedFit;
|
||||||
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(10.0f, 10.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(10.0f, 10.0f));
|
||||||
if (ImGui::BeginTable("table1", 1, flags)) {
|
if (ImGui::BeginTable("table1", 1, flags))
|
||||||
|
{
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImU32 bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.3f, 0.7f, 1.0f));
|
ImU32 bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.3f, 0.7f, 1.0f));
|
||||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, bg_color);
|
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, bg_color);
|
||||||
|
|
@ -52,12 +54,12 @@ void MediaNode::Draw()
|
||||||
ImGui::Text("Image");
|
ImGui::Text("Image");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::Text("image.png");
|
ImGui::Text("%s", m_image.name.c_str());
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
bool do_select = false;
|
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
|
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::Text("Sound");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::Text("sound.mp3");
|
ImGui::Text("%s", m_soundName.c_str());
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
bool do_select_sound = false;
|
if (ImGui::Button("Play " ICON_MDI_PLAY))
|
||||||
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
|
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::AlignTextToFramePadding();
|
||||||
ImGui::Text("Hold to repeat:");
|
ImGui::Text("Hold to repeat:");
|
||||||
|
|
@ -87,11 +93,11 @@ void MediaNode::Draw()
|
||||||
uint32_t counter = Outputs();
|
uint32_t counter = Outputs();
|
||||||
float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
|
float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
|
||||||
ImGui::PushButtonRepeat(true);
|
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--; }
|
if (ImGui::ArrowButton(leftSingle.c_str(), ImGuiDir_Left)) { if (counter > 1) counter--; }
|
||||||
ImGui::SameLine(0.0f, spacing);
|
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))
|
if (ImGui::ArrowButton(rightSingle.c_str(), ImGuiDir_Right))
|
||||||
{
|
{
|
||||||
counter++;
|
counter++;
|
||||||
|
|
@ -100,23 +106,27 @@ void MediaNode::Draw()
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Text("%d", counter);
|
ImGui::Text("%d", counter);
|
||||||
|
|
||||||
if (counter > Outputs())
|
SetOutputs(counter);
|
||||||
{
|
|
||||||
for (int i = 0; i < (counter - Outputs()); i++)
|
|
||||||
{
|
|
||||||
AddOutput();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (counter < Outputs())
|
|
||||||
{
|
|
||||||
for (int i = 0; i < (Outputs() - counter); i++)
|
|
||||||
{
|
|
||||||
DeleteOutput();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DrawPins();
|
DrawPins();
|
||||||
|
|
||||||
BaseNode::FrameEnd();
|
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
|
class MediaNode : public BaseNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MediaNode(const std::string &title);
|
MediaNode(const std::string &title, StoryProject &proj);
|
||||||
|
|
||||||
void Draw() override;
|
void Draw() override;
|
||||||
|
|
||||||
|
virtual void FromJson(nlohmann::json &j) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
StoryProject &m_project;
|
||||||
Gui::Image m_image;
|
Gui::Image m_image;
|
||||||
|
std::string m_soundName;
|
||||||
|
std::string m_soundPath;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,21 @@
|
||||||
#include "node_editor_window.h"
|
#include "node_editor_window.h"
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <algorithm>
|
||||||
#include "IconsFontAwesome5_c.h"
|
#include "IconsFontAwesome5_c.h"
|
||||||
|
|
||||||
#include "media_node.h"
|
#include "media_node.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
|
||||||
|
|
||||||
NodeEditorWindow::NodeEditorWindow()
|
NodeEditorWindow::NodeEditorWindow(StoryProject &proj)
|
||||||
|
: WindowBase("Node editor")
|
||||||
|
, m_project(proj)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
registerNode<MediaNode>("media-node");
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeEditorWindow::~NodeEditorWindow()
|
NodeEditorWindow::~NodeEditorWindow()
|
||||||
|
|
@ -24,15 +30,6 @@ void NodeEditorWindow::Initialize()
|
||||||
m_context = ed::CreateEditor(&config);
|
m_context = ed::CreateEditor(&config);
|
||||||
|
|
||||||
ed::SetCurrentEditor(m_context);
|
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()
|
void NodeEditorWindow::Clear()
|
||||||
|
|
@ -40,45 +37,123 @@ void NodeEditorWindow::Clear()
|
||||||
m_nodes.clear();
|
m_nodes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeEditorWindow::Draw(const char *title, bool *p_open)
|
|
||||||
|
|
||||||
|
void NodeEditorWindow::LoadNode(const nlohmann::json &nodeJson)
|
||||||
{
|
{
|
||||||
static bool resetDockspace = true;
|
try
|
||||||
|
|
||||||
float menuHeight = 0;
|
|
||||||
|
|
||||||
if(ImGui::BeginMainMenuBar())
|
|
||||||
{
|
{
|
||||||
menuHeight = ImGui::GetWindowSize().y;
|
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"))
|
n->SetId(restoredNodeId);
|
||||||
{
|
nlohmann::json posJson = nodeJson["position"];
|
||||||
// mEvent.ExitGame();
|
n->SetOutputs(nodeJson["outPortCount"].get<int>());
|
||||||
}
|
n->SetPosition(posJson["x"].get<int>(), posJson["y"].get<int>());
|
||||||
ImGui::EndMenu();
|
n->FromJson(internalDataJson);
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndMainMenuBar();
|
m_nodes[restoredNodeId] = n;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::logic_error(std::string("No registered model with name ") + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::cout << "ERROR: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImGuiWindowFlags window_flags = ImGuiWindowFlags_None;
|
}
|
||||||
|
|
||||||
|
|
||||||
if (ImGui::Begin("EditorView", NULL, window_flags))
|
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>();
|
||||||
|
|
||||||
|
|
||||||
|
// 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::SetCurrentEditor(m_context);
|
||||||
ed::Begin("My Editor", ImVec2(0.0, 0.0f));
|
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)
|
// 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())
|
if (ed::AcceptNewItem())
|
||||||
{
|
{
|
||||||
// Since we accepted new link, lets add one to our list of links.
|
// 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.
|
// 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
|
// 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 you agree that link can be deleted, accept deletion.
|
||||||
if (ed::AcceptDeletedItem())
|
if (ed::AcceptDeletedItem())
|
||||||
{
|
{
|
||||||
// Then remove link from your data.
|
|
||||||
for (auto& link : m_Links)
|
m_links.erase(std::remove_if(m_links.begin(),
|
||||||
{
|
m_links.end(),
|
||||||
if (link.Id == deletedLinkId)
|
[deletedLinkId](std::shared_ptr<LinkInfo> inf) { return inf->Id == deletedLinkId; }));
|
||||||
{
|
|
||||||
m_Links.erase(&link);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// You may reject link deletion by calling:
|
// 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()
|
void NodeEditorWindow::ToolbarUI()
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
#include <imgui_node_editor.h>
|
#include <imgui_node_editor.h>
|
||||||
#include "base_node.h"
|
#include "base_node.h"
|
||||||
#include "window_base.h"
|
#include "window_base.h"
|
||||||
|
#include "story_project.h"
|
||||||
|
#include "json.hpp"
|
||||||
|
|
||||||
namespace ed = ax::NodeEditor;
|
namespace ed = ax::NodeEditor;
|
||||||
|
|
||||||
|
|
@ -27,26 +29,31 @@ class NodeEditorWindow : public WindowBase
|
||||||
public:
|
public:
|
||||||
struct LinkInfo
|
struct LinkInfo
|
||||||
{
|
{
|
||||||
|
// Stuff from ImGuiNodeEditor
|
||||||
ed::LinkId Id;
|
ed::LinkId Id;
|
||||||
ed::PinId InputId;
|
ed::PinId InputId;
|
||||||
ed::PinId OutputId;
|
ed::PinId OutputId;
|
||||||
|
|
||||||
|
// Stuff from the project.json file, our model
|
||||||
|
Connection model;
|
||||||
};
|
};
|
||||||
|
|
||||||
NodeEditorWindow();
|
NodeEditorWindow(StoryProject &proj);
|
||||||
~NodeEditorWindow();
|
~NodeEditorWindow();
|
||||||
void Draw(const char *title, bool *p_open);
|
virtual void Draw() override;
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Clear();
|
void Clear();
|
||||||
|
void Load(const nlohmann::json &model);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
StoryProject &m_project;
|
||||||
|
|
||||||
ed::EditorContext* m_context = nullptr;
|
ed::EditorContext* m_context = nullptr;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<BaseNode>> m_nodes;
|
// 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.
|
||||||
|
|
||||||
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.
|
|
||||||
void ToolbarUI();
|
void ToolbarUI();
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -64,26 +71,34 @@ private:
|
||||||
output.Kind = PinKind::Output;
|
output.Kind = PinKind::Output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void BuildNodes()
|
template<class NodeType>
|
||||||
{
|
struct Factory {
|
||||||
for (auto& node : m_Nodes)
|
static std::shared_ptr<BaseNode> create_func(const std::string &title, StoryProject &proj) {
|
||||||
BuildNode(&node);
|
return std::make_shared<NodeType>(title, proj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* SpawnBranchNode()
|
std::shared_ptr<BaseNode> createNode(const std::string& key, const std::string &title, StoryProject &proj) {
|
||||||
{
|
typename Registry::const_iterator i = m_registry.find(key);
|
||||||
m_Nodes.emplace_back(GetNextId(), "Branch");
|
if (i == m_registry.end()) {
|
||||||
m_Nodes.back().Inputs.emplace_back(GetNextId(), "", PinType::Flow);
|
throw std::invalid_argument(std::string(__PRETTY_FUNCTION__) +
|
||||||
m_Nodes.back().Inputs.emplace_back(GetNextId(), "Condition", PinType::Bool);
|
": key not registered");
|
||||||
m_Nodes.back().Outputs.emplace_back(GetNextId(), "True", PinType::Flow);
|
}
|
||||||
m_Nodes.back().Outputs.emplace_back(GetNextId(), "False", PinType::Flow);
|
else return i->second(title, proj);
|
||||||
|
|
||||||
BuildNode(&m_Nodes.back());
|
|
||||||
|
|
||||||
return &m_Nodes.back();
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
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;
|
//static thread_pool pool;
|
||||||
|
|
||||||
ResourcesWindow::ResourcesWindow(StoryProject &project)
|
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;
|
WindowBase::BeginDraw();
|
||||||
|
|
||||||
ImGui::Begin(title, nullptr);
|
|
||||||
|
|
||||||
|
|
||||||
if (ImGui::Button("Add sound"))
|
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("Type", ImGuiTableColumnFlags_WidthFixed);
|
||||||
ImGui::TableSetupColumn("Delete", ImGuiTableColumnFlags_WidthStretch);
|
ImGui::TableSetupColumn("Delete", ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
|
||||||
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
for (auto & r : m_project)
|
for (auto & r : m_project)
|
||||||
{
|
{
|
||||||
ImGui::TableHeadersRow();
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("%s", r.file.c_str());
|
ImGui::Text("%s", r.file.c_str());
|
||||||
|
|
||||||
|
|
@ -121,6 +122,6 @@ void ResourcesWindow::Draw(const char *title, bool *p_open)
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::End();
|
WindowBase::EndDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,14 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include "story_project.h"
|
#include "story_project.h"
|
||||||
|
#include "window_base.h"
|
||||||
|
|
||||||
class ResourcesWindow
|
class ResourcesWindow : public WindowBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ResourcesWindow(StoryProject &project);
|
ResourcesWindow(StoryProject &project);
|
||||||
~ResourcesWindow();
|
~ResourcesWindow();
|
||||||
void Draw(const char *title, bool *p_open);
|
virtual void Draw() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StoryProject &m_project;
|
StoryProject &m_project;
|
||||||
|
|
|
||||||
|
|
@ -444,3 +444,24 @@ std::string StoryProject::GetWorkingDir() const
|
||||||
return m_working_dir.string();
|
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
|
struct Connection
|
||||||
// A Version 4 UUID is a universally unique identifier that is generated using random numbers.
|
|
||||||
class UUID
|
|
||||||
{
|
{
|
||||||
public:
|
int outNodeId;
|
||||||
|
int outPortIndex;
|
||||||
UUID() { New(); }
|
int inNodeId;
|
||||||
|
int inPortIndex;
|
||||||
// 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};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 ...
|
// 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 GetName() const { return m_name; }
|
||||||
std::string GetUuid() const { return m_uuid; }
|
std::string GetUuid() const { return m_uuid; }
|
||||||
|
|
||||||
|
std::string BuildFullAssetsPath(const std::string &fileName) const;
|
||||||
|
|
||||||
std::filesystem::path AssetsPath() const { return m_assetsPath; }
|
std::filesystem::path AssetsPath() const { return m_assetsPath; }
|
||||||
|
|
||||||
static std::string GetFileExtension(const std::string &FileName);
|
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
|
#ifndef WINDOWBASE_H
|
||||||
#define WINDOW_BASE_H
|
#define WINDOWBASE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class WindowBase
|
class WindowBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WindowBase(bool display = false)
|
WindowBase(const std::string &title);
|
||||||
{
|
|
||||||
mDisplay = display;
|
bool IsDisabled() const {
|
||||||
|
return m_disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVisible(bool enable)
|
virtual void Draw() = 0;
|
||||||
{
|
|
||||||
mDisplay = enable;
|
bool BeginDraw();
|
||||||
}
|
void EndDraw();
|
||||||
|
|
||||||
bool IsVisible() const {
|
|
||||||
return mDisplay;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
bool mDisplay;
|
|
||||||
|
bool m_disabled{false};
|
||||||
|
std::string m_title;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WINDOW_BASE_H
|
#endif // WINDOWBASE_H
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue