diff --git a/Deer/Include/Deer/DataStore.h b/Deer/Include/Deer/DataStore.h index a8d2167..b0e5901 100755 --- a/Deer/Include/Deer/DataStore.h +++ b/Deer/Include/Deer/DataStore.h @@ -7,13 +7,15 @@ #define DEER_SCENE_PATH "scenes" #define DEER_SCRIPT_PATH "scripts" -#define DEER_UI_SCRIPT_PATH "ui_scripts" #define DEER_SHADER_PATH "shaders" #define DEER_VOXEL_PATH "voxels" #define DEER_VOXEL_DATA_PATH "voxels/data" #define DEER_VOXEL_ASPECT_PATH "voxels/aspect" #define DEER_VOXEL_TEXTURE_PATH "voxels/textures" #define DEER_VOXEL_SHADER_PATH "voxels/shaders" +#define DEER_DOCK_PANEL_PATH "editor" +#define DEER_UI_SCRIPT_PATH DEER_DOCK_PANEL_PATH +#define DEER_UI_ICON_PATH DEER_DOCK_PANEL_PATH #define DEER_MESH_PATH "meshes" #define DEER_BIN_PATH "bin" @@ -22,7 +24,7 @@ namespace Deer { struct DirectoryData { - std::vector subDirs; + std::vector dirs; std::vector elements; }; @@ -32,7 +34,14 @@ namespace Deer { void clearCache(); // Rerturns a directory data with the elements relative to the id - const DirectoryData& getDirData(const Path& id, const Path& subDir, const char* extension); + const DirectoryData& getDirData(const Path& id, const Path& dir, const char* extension); + + // TODO: Add safety + // Returns the data of the specified file path + bool loadFileData(const Path& id, const Path& name,uint8_t** data, uint32_t* size); + // Returns the data of the specified file path avoiding extension + bool loadGlobalFileData(const Path& id, const Path& name,uint8_t** data, uint32_t* size); + void freeFileData(uint8_t*); void createFolder(const Path& path); diff --git a/Deer/Include/DeerRender/UIEngine.h b/Deer/Include/DeerRender/UIEngine.h index 8a76c79..1f0fcfa 100644 --- a/Deer/Include/DeerRender/UIEngine.h +++ b/Deer/Include/DeerRender/UIEngine.h @@ -1,4 +1,5 @@ #pragma once +#include namespace Deer { // This namespace implements all interface ported from c++ ImGui to an easier lua aproach with simplifications @@ -7,5 +8,10 @@ namespace Deer { void deinitialize(); void execute(); + + } + + namespace DataStore { + int getIconId(const std::string& name); } } \ No newline at end of file diff --git a/Deer/src/Deer/DataStore/DataStore.cpp b/Deer/src/Deer/DataStore/DataStore.cpp index f4279ab..2487fe2 100755 --- a/Deer/src/Deer/DataStore/DataStore.cpp +++ b/Deer/src/Deer/DataStore/DataStore.cpp @@ -38,7 +38,7 @@ namespace Deer { DirectoryData& dirData = dirData_cache[dirId]; for (const auto& entry : std::filesystem::directory_iterator(searchPath)) { if (entry.is_directory()) - dirData.subDirs.push_back(entry.path().lexically_relative(idPath)); + dirData.dirs.push_back(entry.path().lexically_relative(idPath)); else if (entry.path().extension() == extension) dirData.elements.push_back(entry.path().lexically_relative(idPath)); } @@ -46,6 +46,67 @@ namespace Deer { return dirData; } + bool DataStore::loadFileData(const Path& id, const Path& name, uint8_t** data, uint32_t* size) { + Path filePath = rootPath / id / name; + std::ifstream file(filePath, std::ios::in | std::ios::binary); + + if (!file) { + file.close(); + return false; + } + + file.seekg(0, std::ios::end); + *size = (size_t)file.tellg(); + file.seekg(0, std::ios::beg); + + *data = new uint8_t[*size]; + + if (!file.read(reinterpret_cast(*data), *size)) { + DEER_CORE_ERROR("Failed to read file: {0}", filePath.generic_string().c_str()); + delete[] *data; + return false; + } + + file.close(); + return true; + } + + bool DataStore::loadGlobalFileData(const Path& id, const Path& name, uint8_t** data, uint32_t* size) { + Path filePath = rootPath / id; + for (auto& f : std::filesystem::recursive_directory_iterator(filePath)) { + if (f.path().stem() == name) { + std::ifstream file(f.path(), std::ios::in | std::ios::binary); + + if (!file) { + file.close(); + return false; + } + + file.seekg(0, std::ios::end); + *size = (size_t)file.tellg(); + file.seekg(0, std::ios::beg); + + *data = new uint8_t[*size]; + + if (!file.read(reinterpret_cast(*data), *size)) { + DEER_CORE_ERROR("Failed to read file: {0}", filePath.generic_string().c_str()); + delete[] *data; + return false; + } + + file.close(); + return true; + } + } + + DEER_CORE_ERROR("File {0} not found", filePath.string().c_str()); + return false; + } + + void DataStore::freeFileData(uint8_t* data) { + delete[] data; + } + void DataStore::deleteFile(const Path& path) { Path filePath = rootPath / toLowerCasePath(path); std::filesystem::remove(filePath); diff --git a/Deer/src/DeerRender/UIEngine/DockPanelObject.cpp b/Deer/src/DeerRender/UIEngine/DockPanelObject.cpp index 3c351d4..385bc26 100644 --- a/Deer/src/DeerRender/UIEngine/DockPanelObject.cpp +++ b/Deer/src/DeerRender/UIEngine/DockPanelObject.cpp @@ -1,6 +1,6 @@ #include "DeerRender/UIEngine/DockPanelObject.h" #include "DeerRender/UIEngine/UIEngine.h" -#include "DeerRender/UIEngine/ErrorHandle.h" +#include "DeerRender/UIEngine/UIEngine_ErrorHandle.h" #include "angelscript.h" #include diff --git a/Deer/src/DeerRender/UIEngine/Functions/UIEngine_ButtonFunctions.h b/Deer/src/DeerRender/UIEngine/Functions/UIEngine_ButtonFunctions.h new file mode 100644 index 0000000..537ec6a --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/Functions/UIEngine_ButtonFunctions.h @@ -0,0 +1,9 @@ +#pragma once +#include + +namespace Deer { + namespace UIEngine { + // TO IMPLEMENT + bool button(std::string&); + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/Functions/UIEngine_ColumnFunctions.h b/Deer/src/DeerRender/UIEngine/Functions/UIEngine_ColumnFunctions.h new file mode 100644 index 0000000..5735e0d --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/Functions/UIEngine_ColumnFunctions.h @@ -0,0 +1,12 @@ +#pragma once + +namespace Deer { + namespace UIEngine { + // Set up the colums to fit the pixelSize elements + void setupAutomaticColumns(int pixelSize); + // Iterates to the next column + void nextColumn(); + // Ends the columns made with setupColumns + void endColumns(); + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/Functions/UIEngine_InputFunctions.h b/Deer/src/DeerRender/UIEngine/Functions/UIEngine_InputFunctions.h new file mode 100644 index 0000000..41b562d --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/Functions/UIEngine_InputFunctions.h @@ -0,0 +1,11 @@ +#pragma once + +namespace Deer { + namespace UIEngine { + // Returns if the specified mouse button is clicked on the last element + bool isMouseClicked(int mouse); + + // Returns if the specified mouse button is double clicked + bool isMouseDoubleClicked(int mouse); + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/Functions/UIEngine_TextFunctions.h b/Deer/src/DeerRender/UIEngine/Functions/UIEngine_TextFunctions.h new file mode 100644 index 0000000..ea5bf24 --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/Functions/UIEngine_TextFunctions.h @@ -0,0 +1,14 @@ +#pragma once +#include + +namespace Deer { + namespace UIEngine { + + // Renders a text with the defined rgb values from range [0.0, 1.0] + void textColor(float r, float g, float b, std::string& msg); + + // Renders a text + void text(std::string& msg); + + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/UIEngine.cpp b/Deer/src/DeerRender/UIEngine/UIEngine.cpp index 33c1572..f7a943c 100644 --- a/Deer/src/DeerRender/UIEngine/UIEngine.cpp +++ b/Deer/src/DeerRender/UIEngine/UIEngine.cpp @@ -1,6 +1,6 @@ #include "DeerRender/UIEngine.h" -#include "DeerRender/UIEngine/ErrorHandle.h" -#include "DeerRender/UIEngine/UIEngineFunctions.h" +#include "DeerRender/UIEngine/UIEngine_ErrorHandle.h" +#include "DeerRender/UIEngine/UIEngine_Functions.h" #include "DeerRender/UIEngine/UIEngine.h" #include "DeerRender/UIEngine/DockPanelObject.h" diff --git a/Deer/src/DeerRender/UIEngine/ErrorHandle.cpp b/Deer/src/DeerRender/UIEngine/UIEngine_ErrorHandle.cpp similarity index 97% rename from Deer/src/DeerRender/UIEngine/ErrorHandle.cpp rename to Deer/src/DeerRender/UIEngine/UIEngine_ErrorHandle.cpp index 8cf04fd..e1e72d1 100644 --- a/Deer/src/DeerRender/UIEngine/ErrorHandle.cpp +++ b/Deer/src/DeerRender/UIEngine/UIEngine_ErrorHandle.cpp @@ -1,4 +1,4 @@ -#include "DeerRender/UIEngine/ErrorHandle.h" +#include "DeerRender/UIEngine/UIEngine_ErrorHandle.h" #include "angelscript.h" diff --git a/Deer/src/DeerRender/UIEngine/ErrorHandle.h b/Deer/src/DeerRender/UIEngine/UIEngine_ErrorHandle.h similarity index 100% rename from Deer/src/DeerRender/UIEngine/ErrorHandle.h rename to Deer/src/DeerRender/UIEngine/UIEngine_ErrorHandle.h diff --git a/Deer/src/DeerRender/UIEngine/UIEngineFunctions.cpp b/Deer/src/DeerRender/UIEngine/UIEngine_Functions.cpp similarity index 77% rename from Deer/src/DeerRender/UIEngine/UIEngineFunctions.cpp rename to Deer/src/DeerRender/UIEngine/UIEngine_Functions.cpp index dd329cb..710aa0c 100644 --- a/Deer/src/DeerRender/UIEngine/UIEngineFunctions.cpp +++ b/Deer/src/DeerRender/UIEngine/UIEngine_Functions.cpp @@ -1,5 +1,6 @@ -#include "DeerRender/UIEngine/UIEngineFunctions.h" +#include "DeerRender/UIEngine/UIEngine_Functions.h" #include "DeerRender/UIEngine/UIEngine.h" +#include "DeerRender/UIEngine.h" #include "DeerRender/UIEngine/DockPanelObject.h" #include "Deer/Log.h" #include "Deer/DataStore.h" @@ -15,7 +16,7 @@ namespace Deer { std::string getMeshPath(std::string& dir, int i) { const DirectoryData& dirData = DataStore::getDirData(DEER_MESH_PATH, dir, ".dmesh"); if (i < 0 || i >= dirData.elements.size()){ - DEER_UI_ENGINE_ERROR("Invalid id {0} calling getMeshPath(..), mas size {1}", i, dirData.subDirs.size()); + DEER_UI_ENGINE_ERROR("Invalid id {0} calling getMeshPath(..), mas size {1}", i, dirData.dirs.size()); if (currentDockPanelExecution) { currentDockPanelExecution->invalidate(); } @@ -26,7 +27,7 @@ namespace Deer { std::string getMeshName(std::string& dir, int i) { const DirectoryData& dirData = DataStore::getDirData(DEER_MESH_PATH, dir, ".dmesh"); if (i < 0 || i >= dirData.elements.size()){ - DEER_UI_ENGINE_ERROR("Invalid id {0} calling getMeshName(..), mas size {1}", i, dirData.subDirs.size()); + DEER_UI_ENGINE_ERROR("Invalid id {0} calling getMeshName(..), mas size {1}", i, dirData.dirs.size()); if (currentDockPanelExecution) { currentDockPanelExecution->invalidate(); } @@ -36,40 +37,52 @@ namespace Deer { } int getMeshDirCount(std::string& dir) { - return DataStore::getDirData(DEER_MESH_PATH, dir, ".dmesh").subDirs.size(); + return DataStore::getDirData(DEER_MESH_PATH, dir, ".dmesh").dirs.size(); } std::string getMeshDirPath(std::string& dir, int i) { const DirectoryData& dirData = DataStore::getDirData(DEER_MESH_PATH, dir, ".dmesh"); - if (i < 0 || i >= dirData.subDirs.size()){ - DEER_UI_ENGINE_ERROR("Invalid id {0} calling getMeshDirPath(..), mas size {1}", i, dirData.subDirs.size()); + if (i < 0 || i >= dirData.dirs.size()){ + DEER_UI_ENGINE_ERROR("Invalid id {0} calling getMeshDirPath(..), mas size {1}", i, dirData.dirs.size()); if (currentDockPanelExecution) { currentDockPanelExecution->invalidate(); } return ""; } - return dirData.subDirs[i].string(); + return dirData.dirs[i].string(); } std::string getMeshDirName(std::string& dir, int i) { const DirectoryData& dirData = DataStore::getDirData(DEER_MESH_PATH, dir, ".dmesh"); - if (i < 0 || i >= dirData.subDirs.size()){ - DEER_UI_ENGINE_ERROR("Invalid id {0} calling getMeshDirName(..), mas size {1}", i, dirData.subDirs.size()); + if (i < 0 || i >= dirData.dirs.size()){ + DEER_UI_ENGINE_ERROR("Invalid id {0} calling getMeshDirName(..), mas size {1}", i, dirData.dirs.size()); if (currentDockPanelExecution) { currentDockPanelExecution->invalidate(); } return ""; } - return dirData.subDirs[i].filename().string(); + return dirData.dirs[i].filename().string(); } - void coloredText(float r, float g, float b, std::string& msg) { + void textColor(float r, float g, float b, std::string& msg) { ImGui::TextColored(ImVec4(r, g, b, 1.0f), "%s", msg.c_str()); } void text(std::string& msg) { ImGui::Text("%s", msg.c_str()); } - void drawIcon(std::string& , int size) { - // TODO + void drawIcon(std::string& name, int size) { + int iconId = DataStore::getIconId(name); + + if (iconId < 0) { + DEER_UI_ENGINE_ERROR("Invalid icon name {0}", name.c_str()); + if (currentDockPanelExecution) { + currentDockPanelExecution->invalidate(); + } + return; + } + + ImGui::Image((void*)(uint64_t)iconId, + ImVec2(size, size), ImVec2(0, 1), + ImVec2(1, 0)); } // Interaction diff --git a/Deer/src/DeerRender/UIEngine/UIEngineFunctions.h b/Deer/src/DeerRender/UIEngine/UIEngine_Functions.h similarity index 60% rename from Deer/src/DeerRender/UIEngine/UIEngineFunctions.h rename to Deer/src/DeerRender/UIEngine/UIEngine_Functions.h index 829cbbc..638d3f1 100644 --- a/Deer/src/DeerRender/UIEngine/UIEngineFunctions.h +++ b/Deer/src/DeerRender/UIEngine/UIEngine_Functions.h @@ -1,12 +1,14 @@ #pragma once #include +#include "DeerRender/UIEngine/Functions/UIEngine_TextFunctions.h" +#include "DeerRender/UIEngine/Functions/UIEngine_ColumnFunctions.h" +#include "DeerRender/UIEngine/Functions/UIEngine_ButtonFunctions.h" +#include "DeerRender/UIEngine/Functions/UIEngine_ButtonFunctions.h" + class asSMessageInfo; namespace Deer { namespace UIEngine { - // TODO: Detect if it has menu bar - // TODO: Make icon an enum - // --- Mesh Data Store --- // Returns the count of meshes in the dir relative to the mesh root dir @@ -26,26 +28,11 @@ namespace Deer { // --- RENDERING --- // TEXT - // Renders a text with the defined rgb values from range [0.0, 1.0] - void coloredText(float r, float g, float b, std::string& msg); - // Renders a text - void text(std::string& msg); - // Images // TODO: Implement void drawIcon(std::string& iconId, int size); - // Returns if the specified mouse button is clicked - bool isMouseClicked(int mouse); - // Returns if the specified mouse button is double clicked - bool isMouseDoubleClicked(int mouse); - // Set up the colums to fit the pixelSize elements - void setupAutomaticColumns(int pixelSize); - // Iterates to the next column - void nextColumn(); - // Ends the columns made with setupColumns - void endColumns(); void errorCallback(const asSMessageInfo *msg, void *param); // Prints in console a mesage diff --git a/Deer/src/DeerRender/UIEngine/UIEngine_IconManagment.cpp b/Deer/src/DeerRender/UIEngine/UIEngine_IconManagment.cpp new file mode 100644 index 0000000..13aa560 --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/UIEngine_IconManagment.cpp @@ -0,0 +1,28 @@ +#include "DeerRender/UIEngine.h" +#include "DeerRender/Render/Texture.h" +#include "Deer/DataStore.h" + +#include + +namespace Deer { + namespace DataStore { + std::unordered_map> icons; + } + + int DataStore::getIconId(const std::string& name) { + if (icons.contains(name)) + return icons[name]->getTextureID(); + + uint8_t* data; + uint32_t size; + + if (!DataStore::loadGlobalFileData(DEER_UI_ICON_PATH, name, &data, &size)) + return -1; + + icons[name] = Texture2D::create(data, size); + DataStore::freeFileData(data); + + return icons[name]->getTextureID(); + } + +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/LoadPanels.cpp b/Deer/src/DeerRender/UIEngine/UIEngine_LoadPanels.cpp similarity index 94% rename from Deer/src/DeerRender/UIEngine/LoadPanels.cpp rename to Deer/src/DeerRender/UIEngine/UIEngine_LoadPanels.cpp index 6fba1b7..9a0ef86 100644 --- a/Deer/src/DeerRender/UIEngine/LoadPanels.cpp +++ b/Deer/src/DeerRender/UIEngine/UIEngine_LoadPanels.cpp @@ -1,7 +1,7 @@ #include "angelscript.h" #include "DeerRender/UIEngine/UIEngine.h" #include "DeerRender/UIEngine/DockPanelObject.h" -#include "DeerRender/UIEngine/ErrorHandle.h" +#include "DeerRender/UIEngine/UIEngine_ErrorHandle.h" namespace Deer { void UIEngine::registerDockPanel() { diff --git a/Deer/src/DeerRender/UIEngine/LoadScripts.cpp b/Deer/src/DeerRender/UIEngine/UIEngine_LoadScripts.cpp similarity index 95% rename from Deer/src/DeerRender/UIEngine/LoadScripts.cpp rename to Deer/src/DeerRender/UIEngine/UIEngine_LoadScripts.cpp index 3acc4ce..2f4335e 100644 --- a/Deer/src/DeerRender/UIEngine/LoadScripts.cpp +++ b/Deer/src/DeerRender/UIEngine/UIEngine_LoadScripts.cpp @@ -1,5 +1,5 @@ #include "DeerRender/UIEngine/UIEngine.h" -#include "DeerRender/UIEngine/ErrorHandle.h" +#include "DeerRender/UIEngine/UIEngine_ErrorHandle.h" #include "Deer/Path.h" #include "Deer/DataStore.h" diff --git a/Deer/src/DeerRender/UIEngine/RegisterFunctions.cpp b/Deer/src/DeerRender/UIEngine/UIEngine_RegisterFunctions.cpp similarity index 87% rename from Deer/src/DeerRender/UIEngine/RegisterFunctions.cpp rename to Deer/src/DeerRender/UIEngine/UIEngine_RegisterFunctions.cpp index 7d50c89..edb4e6b 100644 --- a/Deer/src/DeerRender/UIEngine/RegisterFunctions.cpp +++ b/Deer/src/DeerRender/UIEngine/UIEngine_RegisterFunctions.cpp @@ -1,13 +1,13 @@ -#include "DeerRender/UIEngine/UIEngineFunctions.h" +#include "DeerRender/UIEngine/UIEngine_Functions.h" #include "DeerRender/UIEngine/UIEngine.h" -#include "DeerRender/UIEngine/ErrorHandle.h" +#include "DeerRender/UIEngine/UIEngine_ErrorHandle.h" namespace Deer { void UIEngine::registerUIEngineFunctions() { AS_CHECK(scriptEngine->RegisterGlobalFunction( - "void coloredText(float, float, float, const string& in)", + "void textColor(float, float, float, const string& in)", asFUNCTION( - Deer::UIEngine::coloredText + Deer::UIEngine::textColor ), asCALL_CDECL )); @@ -20,6 +20,14 @@ namespace Deer { asCALL_CDECL )); + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "void drawIcon(const string& in, int)", + asFUNCTION( + Deer::UIEngine::drawIcon + ), + asCALL_CDECL + )); + AS_CHECK(scriptEngine->RegisterGlobalFunction( "bool isMouseClicked(int)", asFUNCTION( diff --git a/roe/editor/icons/file.png b/roe/editor/icons/file.png index bb135e6..88672d9 100755 Binary files a/roe/editor/icons/file.png and b/roe/editor/icons/file.png differ diff --git a/roe/editor/icons/folder.png b/roe/editor/icons/folder.png index 649ce48..8540d75 100755 Binary files a/roe/editor/icons/folder.png and b/roe/editor/icons/folder.png differ diff --git a/roe/ui_scripts/mesh_searcher.as b/roe/editor/mesh_explorer/mesh_searcher.as similarity index 81% rename from roe/ui_scripts/mesh_searcher.as rename to roe/editor/mesh_explorer/mesh_searcher.as index 97e399b..72dc979 100644 --- a/roe/ui_scripts/mesh_searcher.as +++ b/roe/editor/mesh_explorer/mesh_searcher.as @@ -3,12 +3,14 @@ class MeshExplorer : DockPanel { string currentPath = ""; void onRender() { - coloredText(0.5, 0.5, 0.5, currentPath); + textColor(0.5, 0.5, 0.5, currentPath); setupAutomaticColumns(180); int dirCount = getMeshDirCount(currentPath); for (int i = 0; i < dirCount; i++) { + + drawIcon("folder", 64); text(getMeshDirName(currentPath, i)); nextColumn(); @@ -16,6 +18,7 @@ class MeshExplorer : DockPanel { int meshCount = getMeshCount(currentPath); for (int i = 0; i < meshCount; i++) { + drawIcon("file", 64); text(getMeshName(currentPath, i)); nextColumn(); diff --git a/roe/imgui.ini b/roe/imgui.ini index 5231052..e816ef4 100644 --- a/roe/imgui.ini +++ b/roe/imgui.ini @@ -73,5 +73,5 @@ DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y DockNode ID=0x00000009 Parent=0x00000004 SizeRef=392,214 Selected=0x199AB496 DockNode ID=0x0000000A Parent=0x00000004 SizeRef=392,152 Selected=0x2A2C795E DockNode ID=0x00000002 Parent=0x00000007 SizeRef=2560,331 Selected=0xCF339702 - DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,326 Selected=0x7F7E0F9C + DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,326 Selected=0xD962995A