diff --git a/Deer/Include/Deer/DataStore.h b/Deer/Include/Deer/DataStore.h index b09da32..a8d2167 100755 --- a/Deer/Include/Deer/DataStore.h +++ b/Deer/Include/Deer/DataStore.h @@ -7,6 +7,7 @@ #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" @@ -20,8 +21,19 @@ #define DEER_NULL_PATH "null" namespace Deer { + struct DirectoryData { + std::vector subDirs; + std::vector elements; + }; + // Namespace to manage memory interactions namespace DataStore { + // Clears the cache of dir data + 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); + void createFolder(const Path& path); void saveFile(const Path&, uint8_t* data, uint32_t size); diff --git a/Deer/Include/Deer/Log.h b/Deer/Include/Deer/Log.h index 059610f..e104906 100755 --- a/Deer/Include/Deer/Log.h +++ b/Deer/Include/Deer/Log.h @@ -26,11 +26,15 @@ namespace Deer { static inline Ref& getScriptLogger() { return scriptLogger; } + static inline Ref& getUiEngineLogger() { + return uiEngineLogger; + } private: static Ref coreLogger; static Ref clientLogger; static Ref scriptLogger; + static Ref uiEngineLogger; }; } // namespace Deer @@ -44,6 +48,12 @@ namespace Deer { #define DEER_SCRIPT_WARN(...) Deer::Log::getScriptLogger()->warn(__VA_ARGS__) #define DEER_SCRIPT_ERROR(...) Deer::Log::getScriptLogger()->error(__VA_ARGS__) + +#define DEER_UI_ENGINE_TRACE(...) Deer::Log::getUiEngineLogger()->trace(__VA_ARGS__) +#define DEER_UI_ENGINE_INFO(...) Deer::Log::getUiEngineLogger()->info(__VA_ARGS__) +#define DEER_UI_ENGINE_WARN(...) Deer::Log::getUiEngineLogger()->warn(__VA_ARGS__) +#define DEER_UI_ENGINE_ERROR(...) Deer::Log::getUiEngineLogger()->error(__VA_ARGS__) + #ifdef LINUX #define DEER_CORE_ASSERT(condition, ...) \ if (!(condition)) { \ diff --git a/Deer/Include/DeerRender/UIEngine.h b/Deer/Include/DeerRender/UIEngine.h new file mode 100644 index 0000000..8a76c79 --- /dev/null +++ b/Deer/Include/DeerRender/UIEngine.h @@ -0,0 +1,11 @@ +#pragma once + +namespace Deer { + // This namespace implements all interface ported from c++ ImGui to an easier lua aproach with simplifications + namespace UIEngine { + void initialize(); + void deinitialize(); + + void execute(); + } +} \ No newline at end of file diff --git a/Deer/src/Deer/Core/Log.cpp b/Deer/src/Deer/Core/Log.cpp index b91e89d..48483c0 100755 --- a/Deer/src/Deer/Core/Log.cpp +++ b/Deer/src/Deer/Core/Log.cpp @@ -4,6 +4,7 @@ namespace Deer { std::shared_ptr Log::coreLogger; std::shared_ptr Log::clientLogger; std::shared_ptr Log::scriptLogger; + std::shared_ptr Log::uiEngineLogger; void Log::init() { @@ -12,16 +13,19 @@ namespace Deer { coreLogger = spdlog::stdout_color_mt("Core"); clientLogger = spdlog::stdout_color_mt("Client"); scriptLogger = spdlog::stdout_color_mt("Script"); + uiEngineLogger = spdlog::stdout_color_mt("UI Engine"); coreLogger->set_level(spdlog::level::level_enum::trace); clientLogger->set_level(spdlog::level::level_enum::trace); scriptLogger->set_level(spdlog::level::level_enum::trace); + uiEngineLogger->set_level(spdlog::level::level_enum::trace); } void Log::shutdown() { coreLogger.reset(); clientLogger.reset(); scriptLogger.reset(); + uiEngineLogger.reset(); spdlog::drop_all(); } diff --git a/Deer/src/Deer/DataStore/DataStore.cpp b/Deer/src/Deer/DataStore/DataStore.cpp index 4027322..f4279ab 100755 --- a/Deer/src/Deer/DataStore/DataStore.cpp +++ b/Deer/src/Deer/DataStore/DataStore.cpp @@ -14,9 +14,37 @@ #include #include #include +#include namespace Deer { - Path DataStore::rootPath; + namespace DataStore { + Path rootPath; + std::unordered_map dirData_cache; + } + + const DirectoryData& DataStore::getDirData(const Path& id, const Path& subDir, const char* extension) { + std::string dirId = std::string(id) + "&" + std::string(subDir) + "&" + std::string(extension); + if (dirData_cache.contains(dirId)) { + return dirData_cache[dirId]; + } + + Path idPath = rootPath; + if (id != "") + idPath /= id; + Path searchPath = idPath; + if (subDir != "") + searchPath /= subDir; + + 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)); + else if (entry.path().extension() == extension) + dirData.elements.push_back(entry.path().lexically_relative(idPath)); + } + + return dirData; + } void DataStore::deleteFile(const Path& path) { Path filePath = rootPath / toLowerCasePath(path); diff --git a/Deer/src/DeerRender/UIEngine/DockPanelObject.cpp b/Deer/src/DeerRender/UIEngine/DockPanelObject.cpp new file mode 100644 index 0000000..3c351d4 --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/DockPanelObject.cpp @@ -0,0 +1,106 @@ +#include "DeerRender/UIEngine/DockPanelObject.h" +#include "DeerRender/UIEngine/UIEngine.h" +#include "DeerRender/UIEngine/ErrorHandle.h" + +#include "angelscript.h" +#include + +#include "imgui.h" + +namespace Deer { + UIEngine::DockPanelObject::DockPanelObject(asITypeInfo* _type) + : type (_type), isValid(false) { + + // Constructor + // "type@ type()" + std::string callString(type->GetName()); + callString += " @"; + callString += type->GetName(); + callString += "()"; + + asIScriptFunction* factory = type->GetFactoryByDecl(callString.c_str()); + + AS_CHECK_ADDITIONAL_INFO( + scriptContext->Prepare(factory), + type->GetName() + ); + + AS_CHECK_ADDITIONAL_INFO( + scriptContext->Execute(), + type->GetName() + ); + + // Return value contains the ref to a asIScriptObject in the location provided + object = *(asIScriptObject**)scriptContext->GetAddressOfReturnValue(); + if (!object){ + DEER_UI_ENGINE_ERROR("Could not create object", _type->GetName()); + return; + } + object->AddRef(); + + renderFunction = type->GetMethodByDecl("void onRender()"); + if (!renderFunction) { + DEER_UI_ENGINE_ERROR("Could not load void onRender() from {0}", _type->GetName()); + return; + } + + isValid = true; + } + + UIEngine::DockPanelObject::~DockPanelObject() { + if (object) + object->Release(); + } + + void UIEngine::DockPanelObject::executeRender() { + ImGui::Begin(type->GetName()); + + if (!isValid) { + ImGui::TextColored(ImVec4(1, 0.3f, 0.3f, 1), "There was an error, please check the logs or reload the interface"); + ImGui::End(); + return; + } + + AS_CHECK_ADDITIONAL_INFO( + scriptContext->Prepare(renderFunction), + type->GetName() + ); + + AS_CHECK_ADDITIONAL_INFO( + scriptContext->SetObject(object), + type->GetName() + ); + + AS_CHECK_ADDITIONAL_INFO( + scriptContext->Execute(), + type->GetName() + ); + + ImGui::End(); + } + + UIEngine::DockPanelObject::DockPanelObject(DockPanelObject&& other) noexcept + : isValid(other.isValid), renderFunction(other.renderFunction), type(other.type), object(other.object) { + + other.isValid = false; + other.renderFunction = nullptr; + other.type = nullptr; + other.object = nullptr; + } + + UIEngine::DockPanelObject& UIEngine::DockPanelObject::operator=(UIEngine::DockPanelObject&& other) noexcept { + if (this != &other) { + isValid = other.isValid; + renderFunction = other.renderFunction; + type = other.type; + object = other.object; + + other.isValid = false; + other.renderFunction = nullptr; + other.type = nullptr; + other.object = nullptr; + } + + return *this; + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/DockPanelObject.h b/Deer/src/DeerRender/UIEngine/DockPanelObject.h new file mode 100644 index 0000000..aaa52ae --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/DockPanelObject.h @@ -0,0 +1,30 @@ +#pragma once +class asITypeInfo; +class asIScriptObject; +class asIScriptFunction; + +namespace Deer { + namespace UIEngine { + struct DockPanelObject { + private: + asITypeInfo* type = nullptr; + asIScriptObject* object = nullptr; + asIScriptFunction* renderFunction = nullptr; + bool isValid = false; + + + public: + DockPanelObject(asITypeInfo*); + ~DockPanelObject(); + // Delete copy constructor + DockPanelObject(const DockPanelObject&) = delete; + DockPanelObject& operator=(const DockPanelObject&) = delete; + + DockPanelObject(DockPanelObject&& other) noexcept; + DockPanelObject& operator=(DockPanelObject&& other) noexcept; + + void executeRender(); + inline void invalidate() { isValid = false; } + }; + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/ErrorHandle.cpp b/Deer/src/DeerRender/UIEngine/ErrorHandle.cpp new file mode 100644 index 0000000..8cf04fd --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/ErrorHandle.cpp @@ -0,0 +1,36 @@ +#include "DeerRender/UIEngine/ErrorHandle.h" + +#include "angelscript.h" + +namespace Deer { + namespace UIEngine { + const char* getAngelScriptReturnCodeString(int code) + { + switch (code) + { + case asSUCCESS: return "SUCCESS (The operation was successful)"; + case asERROR: return "ERROR (A generic error occurred)"; + case asCONTEXT_ACTIVE: return "CONTEXT_ACTIVE (A context was active during an invalid operation)"; + case asCONTEXT_NOT_FINISHED: return "CONTEXT_NOT_FINISHED (Context has not finished execution)"; + case asCONTEXT_NOT_PREPARED: return "CONTEXT_NOT_PREPARED (Context is not prepared)"; + case asINVALID_ARG: return "INVALID_ARG (An invalid argument was provided)"; + case asNO_FUNCTION: return "NO_FUNCTION (Function not found)"; + case asNOT_SUPPORTED: return "NOT_SUPPORTED (Feature not supported by build configuration)"; + case asINVALID_NAME: return "INVALID_NAME (Name is not allowed or invalid)"; + case asNAME_TAKEN: return "NAME_TAKEN (Name is already taken by another entity)"; + case asINVALID_DECLARATION: return "INVALID_DECLARATION (The declaration is invalid)"; + case asINVALID_OBJECT: return "INVALID_OBJECT (Invalid object handle or object type)"; + case asINVALID_TYPE: return "INVALID_TYPE (Invalid type provided)"; + case asALREADY_REGISTERED: return "ALREADY_REGISTERED (Item is already registered)"; + case asMULTIPLE_FUNCTIONS: return "MULTIPLE_FUNCTIONS (More than one matching function found)"; + case asNO_MODULE: return "NO_MODULE (Module was not found)"; + case asNO_GLOBAL_VAR: return "NO_GLOBAL_VAR (Global variable was not found)"; + case asINVALID_CONFIGURATION: return "INVALID_CONFIGURATION (Invalid configuration, likely during registration)"; + case asINVALID_INTERFACE: return "INVALID_INTERFACE (Invalid interface registration)"; + case asCANT_BIND_ALL_FUNCTIONS: return "CANT_BIND_ALL_FUNCTIONS (Couldn't bind all functions for a virtual interface)"; + case asLOWER_ARRAY_DIMENSION_NOT_REGISTERED: return "LOWER_ARRAY_DIMENSION_NOT_REGISTERED (Lower dimension type for array not registered)"; + default: return "Unknown AngelScript error code"; + } + } + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/ErrorHandle.h b/Deer/src/DeerRender/UIEngine/ErrorHandle.h new file mode 100644 index 0000000..dc74d45 --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/ErrorHandle.h @@ -0,0 +1,31 @@ +#pragma once +#include "Deer/Log.h" +#include + +namespace Deer { + namespace UIEngine { + const char* getAngelScriptReturnCodeString(int code); + } +} + +#define AS_CHECK(f) { \ + int __r = f; \ + if (__r < 0) { \ + DEER_UI_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::UIEngine::getAngelScriptReturnCodeString(__r)); \ + } \ +} +#define AS_CHECK_ADDITIONAL_INFO(f, i) { \ + int __r = f; \ + if (__r < 0) { \ + DEER_UI_ENGINE_ERROR("Error at line: {0}:{1} -> {2} \n {3}", __FILE__, __LINE__, Deer::UIEngine::getAngelScriptReturnCodeString(__r), i); \ + } \ + } +#define AS_RET_CHECK(f) { \ + int __r = f; \ + if (__r < 0) { \ + DEER_UI_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::UIEngine::getAngelScriptReturnCodeString(__r)); \ + return; \ + } \ +} + + diff --git a/Deer/src/DeerRender/UIEngine/LoadPanels.cpp b/Deer/src/DeerRender/UIEngine/LoadPanels.cpp new file mode 100644 index 0000000..6fba1b7 --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/LoadPanels.cpp @@ -0,0 +1,32 @@ +#include "angelscript.h" +#include "DeerRender/UIEngine/UIEngine.h" +#include "DeerRender/UIEngine/DockPanelObject.h" +#include "DeerRender/UIEngine/ErrorHandle.h" + +namespace Deer { + void UIEngine::registerDockPanel() { + AS_RET_CHECK(scriptEngine->RegisterInterface("DockPanel")); + + AS_RET_CHECK(scriptEngine->RegisterInterfaceMethod("DockPanel", "void onRender()")); + } + + void UIEngine::extractDockPanels() { + size_t nScripts = scriptModule->GetObjectTypeCount(); + + asITypeInfo* dockPanelType = scriptEngine->GetTypeInfoByName("DockPanel"); + if (!dockPanelType) { + DEER_UI_ENGINE_ERROR("Could not load DockPanel interface type"); + return; + } + + for (size_t i = 0; i < nScripts; i++) { + asITypeInfo* info = scriptModule->GetObjectTypeByIndex(i); + + // If it does not implement dock panel we are not interested int it + if (!info->Implements(dockPanelType)) + continue; + + dockPanels.push_back({info}); + } + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/LoadScripts.cpp b/Deer/src/DeerRender/UIEngine/LoadScripts.cpp new file mode 100644 index 0000000..3acc4ce --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/LoadScripts.cpp @@ -0,0 +1,38 @@ +#include "DeerRender/UIEngine/UIEngine.h" +#include "DeerRender/UIEngine/ErrorHandle.h" + +#include "Deer/Path.h" +#include "Deer/DataStore.h" + +#include "angelscript.h" +#include "scriptbuilder.h" + +#include +#include +#include +#include + +namespace fs = std::filesystem; + +namespace Deer { + void UIEngine::loadScripts() { + Path path = DataStore::rootPath / DEER_UI_SCRIPT_PATH; + CScriptBuilder builder; + + AS_RET_CHECK(builder.StartNewModule(scriptEngine, "DeerModule")); + + DEER_UI_ENGINE_INFO("=== Extracting UI Engine Scripts ==="); + for (const auto& entry : fs::recursive_directory_iterator(path)) { + if (entry.is_regular_file() && entry.path().extension() == ".as") { + DEER_UI_ENGINE_TRACE("\t{0}", entry.path().stem().string().c_str()); + // We add aditional info to check who caused the error + AS_CHECK_ADDITIONAL_INFO( + builder.AddSectionFromFile(entry.path().string().c_str());, + entry.path().string().c_str() + ); + } + } + + AS_RET_CHECK(builder.BuildModule()); + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/RegisterFunctions.cpp b/Deer/src/DeerRender/UIEngine/RegisterFunctions.cpp new file mode 100644 index 0000000..7d50c89 --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/RegisterFunctions.cpp @@ -0,0 +1,120 @@ +#include "DeerRender/UIEngine/UIEngineFunctions.h" +#include "DeerRender/UIEngine/UIEngine.h" +#include "DeerRender/UIEngine/ErrorHandle.h" + +namespace Deer { + void UIEngine::registerUIEngineFunctions() { + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "void coloredText(float, float, float, const string& in)", + asFUNCTION( + Deer::UIEngine::coloredText + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "void text(const string& in)", + asFUNCTION( + text + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "bool isMouseClicked(int)", + asFUNCTION( + isMouseClicked + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "bool isMouseDoubleClicked(int)", + asFUNCTION( + isMouseDoubleClicked + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "void setupAutomaticColumns(int)", + asFUNCTION( + setupAutomaticColumns + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "void endColumns()", + asFUNCTION( + endColumns + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "void nextColumn()", + asFUNCTION( + nextColumn + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "void print(const string& in)", + asFUNCTION ( + Deer::UIEngine::print + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "int getMeshCount(const string& in)", + asFUNCTION( + Deer::UIEngine::getMeshCount + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "string getMeshPath(const string& in, int)", + asFUNCTION( + Deer::UIEngine::getMeshPath + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "string getMeshName(const string& in, int)", + asFUNCTION( + Deer::UIEngine::getMeshName + ), + asCALL_CDECL + )); + + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "int getMeshDirCount(const string& in)", + asFUNCTION( + Deer::UIEngine::getMeshDirCount + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "string getMeshDirPath(const string& in, int)", + asFUNCTION( + Deer::UIEngine::getMeshDirPath + ), + asCALL_CDECL + )); + + AS_CHECK(scriptEngine->RegisterGlobalFunction( + "string getMeshDirName(const string& in, int)", + asFUNCTION( + Deer::UIEngine::getMeshDirName + ), + asCALL_CDECL + )); + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/UIEngine.cpp b/Deer/src/DeerRender/UIEngine/UIEngine.cpp new file mode 100644 index 0000000..33c1572 --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/UIEngine.cpp @@ -0,0 +1,74 @@ +#include "DeerRender/UIEngine.h" +#include "DeerRender/UIEngine/ErrorHandle.h" +#include "DeerRender/UIEngine/UIEngineFunctions.h" +#include "DeerRender/UIEngine/UIEngine.h" +#include "DeerRender/UIEngine/DockPanelObject.h" + +#include "Deer/Log.h" +#include + +#include "angelscript.h" +#include "scriptbuilder.h" +#include "scriptstdstring.h" + +namespace Deer { + namespace UIEngine { + asIScriptEngine* scriptEngine = nullptr; + asIScriptModule* scriptModule = nullptr; + asIScriptContext* scriptContext = nullptr; + + std::vector dockPanels; + DockPanelObject* currentDockPanelExecution = nullptr; + + bool active = false; + } + + void UIEngine::initialize() { + int err = 0; + + // If it exist we will reload it + deinitialize(); + + scriptEngine = asCreateScriptEngine(); + RegisterStdString(scriptEngine); + + AS_RET_CHECK(scriptEngine->SetMessageCallback(asFUNCTION(Deer::UIEngine::errorCallback), 0, asCALL_CDECL)); + + registerUIEngineFunctions(); + registerDockPanel(); + loadScripts(); + + scriptModule = scriptEngine->GetModule("DeerModule"); + scriptContext = scriptEngine->CreateContext(); + + extractDockPanels(); + + active = true; + } + + void UIEngine::deinitialize() { + dockPanels.clear(); + + if (scriptContext) + scriptContext->Release(); + if (scriptEngine) + scriptEngine->ShutDownAndRelease(); + + scriptEngine = nullptr; + scriptModule = nullptr; + scriptContext = nullptr; + + active = false; + } + + void UIEngine::execute() { + if (!active) + return; + + for (auto& panel : dockPanels) { + currentDockPanelExecution = &panel; + panel.executeRender(); + } + currentDockPanelExecution = nullptr; + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/UIEngine.h b/Deer/src/DeerRender/UIEngine/UIEngine.h new file mode 100644 index 0000000..63c9ff0 --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/UIEngine.h @@ -0,0 +1,24 @@ +#pragma once +#include + +class asIScriptEngine; +class asIScriptObject; +class asIScriptModule; +class asIScriptContext; + +namespace Deer { + namespace UIEngine { + struct DockPanelObject; + + extern asIScriptEngine* scriptEngine; + extern asIScriptModule* scriptModule; + extern asIScriptContext* scriptContext; + extern std::vector dockPanels; + extern DockPanelObject* currentDockPanelExecution; + + void loadScripts(); + void registerUIEngineFunctions(); + void registerDockPanel(); + void extractDockPanels(); + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/UIEngineFunctions.cpp b/Deer/src/DeerRender/UIEngine/UIEngineFunctions.cpp new file mode 100644 index 0000000..dd329cb --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/UIEngineFunctions.cpp @@ -0,0 +1,118 @@ +#include "DeerRender/UIEngine/UIEngineFunctions.h" +#include "DeerRender/UIEngine/UIEngine.h" +#include "DeerRender/UIEngine/DockPanelObject.h" +#include "Deer/Log.h" +#include "Deer/DataStore.h" + +#include "angelscript.h" +#include "imgui.h" + +namespace Deer { + namespace UIEngine { + int getMeshCount(std::string& dir) { + return DataStore::getDirData(DEER_MESH_PATH, dir, ".dmesh").elements.size(); + } + 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()); + if (currentDockPanelExecution) { + currentDockPanelExecution->invalidate(); + } + return ""; + } + return dirData.elements[i].string(); + } + 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()); + if (currentDockPanelExecution) { + currentDockPanelExecution->invalidate(); + } + return ""; + } + return dirData.elements[i].stem().string(); + } + + int getMeshDirCount(std::string& dir) { + return DataStore::getDirData(DEER_MESH_PATH, dir, ".dmesh").subDirs.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 (currentDockPanelExecution) { + currentDockPanelExecution->invalidate(); + } + return ""; + } + return dirData.subDirs[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 (currentDockPanelExecution) { + currentDockPanelExecution->invalidate(); + } + return ""; + } + return dirData.subDirs[i].filename().string(); + } + + void coloredText(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 + } + + // Interaction + bool isMouseClicked(int mouse) { + return ImGui::IsItemClicked(mouse); + } + + bool isMouseDoubleClicked(int mouse) { + return ImGui::IsMouseDoubleClicked(mouse); + } + + void setupAutomaticColumns(int pixelSize) { + float width = ImGui::GetWindowContentRegionWidth(); + + if (width < pixelSize) { + ImGui::Columns(); + return; + } + + int cols = (int)(width / (pixelSize)); + float componentWidth = width / (float)cols; + + ImGui::Columns(cols, 0, false); + } + + void endColumns() { + ImGui::Columns(); + } + + void nextColumn() { + ImGui::NextColumn(); + } + + void errorCallback(const asSMessageInfo *msg, void *param) { + if (msg->type == asMSGTYPE_WARNING) { + DEER_UI_ENGINE_WARN("{0} : ({1}, {2}) : {3}", msg->section, msg->row, msg->col, msg->message); + } else if( msg->type == asMSGTYPE_INFORMATION ) { + DEER_UI_ENGINE_ERROR("{0} : ({1}, {2}) : {3}", msg->section, msg->row, msg->col, msg->message); + } + } + + void print(std::string& msg) { + DEER_UI_ENGINE_INFO("{0}", msg.c_str()); + } + } +} \ No newline at end of file diff --git a/Deer/src/DeerRender/UIEngine/UIEngineFunctions.h b/Deer/src/DeerRender/UIEngine/UIEngineFunctions.h new file mode 100644 index 0000000..829cbbc --- /dev/null +++ b/Deer/src/DeerRender/UIEngine/UIEngineFunctions.h @@ -0,0 +1,54 @@ +#pragma once +#include + +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 + int getMeshCount(std::string& dir); + // Returns the path to the mesh with id i + std::string getMeshPath(std::string& dir, int i); + // Returns the name of the mesh with id i + std::string getMeshName(std::string& dir, int i); + + // Returns the count of sub dirs in the dir relative to the mesh root dir + int getMeshDirCount(std::string& dir); + // Returns the path to the subDir in the dir relative to the mesh root dir + std::string getMeshDirPath(std::string& dir, int i); + // Returns the name of the subDir in the dir relative to the mesh root dir + std::string getMeshDirName(std::string& dir, int i); + + // --- 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 + void print(std::string& msg); + } +} \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/DeerStudio.cpp b/DeerStudio/src/DeerStudio/DeerStudio.cpp index ac8237c..444091a 100755 --- a/DeerStudio/src/DeerStudio/DeerStudio.cpp +++ b/DeerStudio/src/DeerStudio/DeerStudio.cpp @@ -8,14 +8,16 @@ #include "Deer/Voxel.h" #include "Deer/VoxelWorld.h" #include "DeerRender/Mesh.h" +#include "DeerRender/UIEngine.h" + #include "DeerStudio/Editor/Fonts.h" -#include "DeerStudio/Editor/GamePannel.h" +#include "DeerStudio/Editor/GamePanel.h" #include "DeerStudio/Editor/Icons.h" #include "DeerStudio/Editor/MeshExplorer/MeshExplorer.h" -#include "DeerStudio/Editor/PropertiesPannel.h" +#include "DeerStudio/Editor/PropertiesPanel.h" #include "DeerStudio/Editor/SceneExplorer.h" #include "DeerStudio/Editor/Terrain/TerrainEditor.h" -#include "DeerStudio/Editor/TreePannel.h" +#include "DeerStudio/Editor/TreePanel.h" #include "DeerStudio/Editor/Viewport.h" #include "DeerStudio/Project.h" #include "Style.h" @@ -26,10 +28,10 @@ namespace Deer { if (projectPath.empty()) return 1; DataStore::rootPath = projectPath; - DataStore::createExampleVoxelData(); - DataStore::createExampleVoxelAspect(); DataStore::loadVoxelsData(); DataStore::loadVoxelsAspect(); + + UIEngine::initialize(); return 0; } @@ -53,8 +55,8 @@ namespace Deer { setNatureStyle(); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20)); - auto m_gamePannel = Ref(new GamePannel()); - pannels.push_back(m_gamePannel); + auto m_gamePanel = Ref(new GamePanel()); + Panels.push_back(m_gamePanel); Environment& env = Project::m_scene.getMainEnviroment(); @@ -75,12 +77,13 @@ namespace Deer { Project::m_scene.endExecution(); ScriptEngine::shutdownScriptEngine(); - pannels.clear(); + Panels.clear(); + UIEngine::deinitialize(); } void DeerStudioApplication::onRender(Timestep delta) { - for (auto pannel : pannels) { - pannel->onRender(delta); + for (auto Panel : Panels) { + Panel->onRender(delta); } int windowWidth = Application::s_application->m_window->getWitdth(); @@ -95,7 +98,7 @@ namespace Deer { } void DeerStudioApplication::onEvent(Event& e) { - for (auto& pannel : pannels) pannel->onEventCallback(e); + for (auto& Panel : Panels) Panel->onEventCallback(e); viewport_onEvent(e); } @@ -137,18 +140,19 @@ namespace Deer { ImGui::EndMenuBar(); } - for (auto pannel : pannels) { - pannel->onImGui(); + for (auto Panel : Panels) { + Panel->onImGui(); } - // ---- PANNELS ----- + // ---- PanelS ----- // sceneExplorer_onImGUI(); - TreePannel::onImgui(); - PropertiesPannel::onImgui(); + UIEngine::execute(); + TreePanel::onImgui(); + PropertiesPanel::onImgui(); MeshExplorer::onImGui(); TerrainEditor::onImGui(); viewport_onImGui(); - // ---- PANNELS ----- + // ---- PanelS ----- Project::m_scene.getMainGizmoRenderer().refresh(); ImGui::End(); @@ -215,13 +219,20 @@ namespace Deer { } if (ImGui::BeginMenu("Voxel")) { - if (ImGui::MenuItem("Voxel Pannel")) { + if (ImGui::MenuItem("Voxel Panel")) { // TODO } ImGui::EndMenu(); } + if (ImGui::BeginMenu("Interface")) { + if (ImGui::MenuItem("Reload interface")) { + UIEngine::initialize(); + } + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Scripts")) { if (ImGui::MenuItem("Reload scripts") && !Project::m_scene.getExecutingState()) { diff --git a/DeerStudio/src/DeerStudio/DeerStudio.h b/DeerStudio/src/DeerStudio/DeerStudio.h index b0dc636..c916f80 100755 --- a/DeerStudio/src/DeerStudio/DeerStudio.h +++ b/DeerStudio/src/DeerStudio/DeerStudio.h @@ -5,7 +5,7 @@ #include "DeerRender/Events/Event.h" #include "DeerStudio/Editor/ActiveEntity.h" -#include "DeerStudio/Editor/EditorPannel.h" +#include "DeerStudio/Editor/EditorPanel.h" namespace Deer { class DeerStudioApplication : public Deer::Application { @@ -27,7 +27,7 @@ namespace Deer { void drawMenuBar(); void onChangeScene(); - std::vector> pannels; + std::vector> Panels; }; } diff --git a/DeerStudio/src/DeerStudio/Editor/AssetManagerPannel.cpp b/DeerStudio/src/DeerStudio/Editor/AssetManagerPanel.cpp similarity index 95% rename from DeerStudio/src/DeerStudio/Editor/AssetManagerPannel.cpp rename to DeerStudio/src/DeerStudio/Editor/AssetManagerPanel.cpp index a74bdb7..b73f5f4 100755 --- a/DeerStudio/src/DeerStudio/Editor/AssetManagerPannel.cpp +++ b/DeerStudio/src/DeerStudio/Editor/AssetManagerPanel.cpp @@ -1,4 +1,4 @@ -#include "AssetManagerPannel.h" +#include "AssetManagerPanel.h" #include "DeerStudio/Project.h" #include "Deer/Log.h" @@ -32,7 +32,7 @@ namespace Deer { namespace fs = std::filesystem; - AssetManagerPannel::AssetManagerPannel() + AssetManagerPanel::AssetManagerPanel() : m_currentPath(DataStore::rootPath / "assets"){ m_folderIcon = Texture2D::create("editor/icons/folder.png"); @@ -42,7 +42,7 @@ namespace Deer { m_shaderIcon = Texture2D::create("editor/icons/shader.png"); } - void AssetManagerPannel::onImGui() { + void AssetManagerPanel::onImGui() { m_clickHandled = false; ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(30, 30)); ImGui::Begin("Assets"); @@ -103,7 +103,7 @@ namespace Deer { ImGui::End(); } - void AssetManagerPannel::drawFolder(const std::filesystem::path& path) { + void AssetManagerPanel::drawFolder(const std::filesystem::path& path) { ImGui::Image((void*)(uint64_t)m_folderIcon->getTextureID(), ImVec2(m_iconMinSize , m_iconMinSize), ImVec2(0, 1), ImVec2(1, 0)); if (ImGui::IsItemClicked(0) && ImGui::IsMouseDoubleClicked(0)) { @@ -111,7 +111,7 @@ namespace Deer { } } - void AssetManagerPannel::updateContextMenu() { + void AssetManagerPanel::updateContextMenu() { if (ImGui::BeginPopup("AssetManagerPopUp")) { if (ImGui::MenuItem("New Folder")) { @@ -125,7 +125,7 @@ namespace Deer { } - void AssetManagerPannel::drawFile(const std::filesystem::path& path) { + void AssetManagerPanel::drawFile(const std::filesystem::path& path) { std::string extension = path.filename().extension().string(); if (extension == ".dscn") { diff --git a/DeerStudio/src/DeerStudio/Editor/AssetManagerPannel.h b/DeerStudio/src/DeerStudio/Editor/AssetManagerPanel.h similarity index 84% rename from DeerStudio/src/DeerStudio/Editor/AssetManagerPannel.h rename to DeerStudio/src/DeerStudio/Editor/AssetManagerPanel.h index 10d277c..c3dc104 100755 --- a/DeerStudio/src/DeerStudio/Editor/AssetManagerPannel.h +++ b/DeerStudio/src/DeerStudio/Editor/AssetManagerPanel.h @@ -1,5 +1,5 @@ #pragma once -#include "DeerStudio/Editor/EditorPannel.h" +#include "DeerStudio/Editor/EditorPanel.h" #include "Deer/Memory.h" @@ -10,9 +10,9 @@ namespace Deer { class DeerStudioLayer; class SceneSerializer; - class AssetManagerPannel : public EditorPannel{ + class AssetManagerPanel : public EditorPanel{ public: - AssetManagerPannel(); + AssetManagerPanel(); void onImGui() override; private: void drawFolder(const std::filesystem::path&); diff --git a/DeerStudio/src/DeerStudio/Editor/EditorPannel.h b/DeerStudio/src/DeerStudio/Editor/EditorPanel.h similarity index 78% rename from DeerStudio/src/DeerStudio/Editor/EditorPannel.h rename to DeerStudio/src/DeerStudio/Editor/EditorPanel.h index 92f0c06..92eb23f 100755 --- a/DeerStudio/src/DeerStudio/Editor/EditorPannel.h +++ b/DeerStudio/src/DeerStudio/Editor/EditorPanel.h @@ -4,9 +4,9 @@ namespace Deer { class Event; - class EditorPannel { + class EditorPanel { public: - virtual ~EditorPannel() = default; + virtual ~EditorPanel() = default; virtual void onRender(Timestep timestep) { } virtual void onEventCallback(Event& e) { } virtual void onImGui() { } diff --git a/DeerStudio/src/DeerStudio/Editor/GamePannel.cpp b/DeerStudio/src/DeerStudio/Editor/GamePanel.cpp similarity index 96% rename from DeerStudio/src/DeerStudio/Editor/GamePannel.cpp rename to DeerStudio/src/DeerStudio/Editor/GamePanel.cpp index 92eb83a..3a51648 100755 --- a/DeerStudio/src/DeerStudio/Editor/GamePannel.cpp +++ b/DeerStudio/src/DeerStudio/Editor/GamePanel.cpp @@ -1,4 +1,4 @@ -#include "GamePannel.h" +#include "GamePanel.h" #include @@ -9,13 +9,13 @@ #include "imgui.h" namespace Deer { - GamePannel::GamePannel() { + GamePanel::GamePanel() { FrameBufferSpecification fbSpecs = FrameBufferSpecification( 100, 100, {TextureBufferType::RGBA8}, 1, false); m_frameBuffer = FrameBuffer::create(fbSpecs); } - void GamePannel::onImGui() { + void GamePanel::onImGui() { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::Begin("Game Window"); ImGui::PopStyleVar(); diff --git a/DeerStudio/src/DeerStudio/Editor/GamePannel.h b/DeerStudio/src/DeerStudio/Editor/GamePanel.h similarity index 73% rename from DeerStudio/src/DeerStudio/Editor/GamePannel.h rename to DeerStudio/src/DeerStudio/Editor/GamePanel.h index ffb32d5..6973f75 100755 --- a/DeerStudio/src/DeerStudio/Editor/GamePannel.h +++ b/DeerStudio/src/DeerStudio/Editor/GamePanel.h @@ -1,7 +1,7 @@ #pragma once #include "Deer/Memory.h" -#include "DeerStudio/Editor/EditorPannel.h" +#include "DeerStudio/Editor/EditorPanel.h" #include "DeerStudio/Editor/ActiveEntity.h" #include "glm/glm.hpp" @@ -10,9 +10,9 @@ namespace Deer { class Scene; class FrameBuffer; - class GamePannel : public EditorPannel { + class GamePanel : public EditorPanel { public: - GamePannel(); + GamePanel(); void onImGui() override; private: diff --git a/DeerStudio/src/DeerStudio/Editor/PropertiesPannel.cpp b/DeerStudio/src/DeerStudio/Editor/PropertiesPanel.cpp similarity index 96% rename from DeerStudio/src/DeerStudio/Editor/PropertiesPannel.cpp rename to DeerStudio/src/DeerStudio/Editor/PropertiesPanel.cpp index 2d1cc07..ce1e59d 100755 --- a/DeerStudio/src/DeerStudio/Editor/PropertiesPannel.cpp +++ b/DeerStudio/src/DeerStudio/Editor/PropertiesPanel.cpp @@ -1,4 +1,4 @@ -#include "PropertiesPannel.h" +#include "PropertiesPanel.h" #include "Deer/Asset.h" #include "Deer/ScriptEngine.h" @@ -9,7 +9,7 @@ #include "imgui.h" namespace Deer { - namespace PropertiesPannel { + namespace PropertiesPanel { void addComponentContext(); template @@ -24,7 +24,7 @@ namespace Deer { void drawMagicSlider(const std::string& text, float* value); void drawMagicSlider3f(const std::string& text, float* value, float defaultValue = 0); - } // namespace PropertiesPannel + } // namespace PropertiesPanel bool* getIsEditingState(ImGuiID id) { ImGuiStorage* storage = ImGui::GetStateStorage(); @@ -37,7 +37,7 @@ namespace Deer { return state; } - void PropertiesPannel::onImgui() { + void PropertiesPanel::onImgui() { ImGui::Begin("Properties"); if (ActiveEntity::count() == 0) { @@ -262,7 +262,7 @@ namespace Deer { ImGui::End(); } - void PropertiesPannel::drawMagicSlider(const std::string& text, + void PropertiesPanel::drawMagicSlider(const std::string& text, float* value) { ImGuiID id = ImGui::GetID(text.c_str()); @@ -286,7 +286,7 @@ namespace Deer { *isEditing = true; } - void PropertiesPannel::drawMagicSlider3f(const std::string& text, + void PropertiesPanel::drawMagicSlider3f(const std::string& text, float* value, float defaultValue) { ImGui::Columns(4, 0, false); @@ -353,7 +353,7 @@ namespace Deer { ImGui::PopStyleVar(2); } - void PropertiesPannel::addComponentContext() { + void PropertiesPanel::addComponentContext() { float buttonWidth = ImGui::CalcTextSize(" + add Component ").x; // Example button width float windowWidth = ImGui::GetWindowSize().x; @@ -392,7 +392,7 @@ namespace Deer { } template - inline bool PropertiesPannel::collapsingComponentHeader( + inline bool PropertiesPanel::collapsingComponentHeader( const std::string& componentName, bool canDelete) { if (!ActiveEntity::shareComponent()) return false; @@ -433,7 +433,7 @@ namespace Deer { return collapsingHeader; } - void PropertiesPannel::addScriptButton(const std::string& scriptID) { + void PropertiesPanel::addScriptButton(const std::string& scriptID) { ImGuiSelectableFlags selectableFlag = (ActiveEntity::shareComponent()) ? ImGuiSelectableFlags_Disabled @@ -449,7 +449,7 @@ namespace Deer { } template - void PropertiesPannel::addComponentButton( + void PropertiesPanel::addComponentButton( const std::string& componentName) { ImGuiSelectableFlags selectableFlag = (ActiveEntity::shareComponent()) ? ImGuiSelectableFlags_Disabled diff --git a/DeerStudio/src/DeerStudio/Editor/PropertiesPannel.h b/DeerStudio/src/DeerStudio/Editor/PropertiesPanel.h similarity index 56% rename from DeerStudio/src/DeerStudio/Editor/PropertiesPannel.h rename to DeerStudio/src/DeerStudio/Editor/PropertiesPanel.h index 087a7d4..862f769 100755 --- a/DeerStudio/src/DeerStudio/Editor/PropertiesPannel.h +++ b/DeerStudio/src/DeerStudio/Editor/PropertiesPanel.h @@ -1,10 +1,10 @@ #pragma once #include "Deer/Memory.h" #include "DeerStudio/Editor/ActiveEntity.h" -#include "DeerStudio/Editor/EditorPannel.h" +#include "DeerStudio/Editor/EditorPanel.h" namespace Deer { - namespace PropertiesPannel { + namespace PropertiesPanel { void onImgui(); - } // namespace PropertiesPannel + } // namespace PropertiesPanel } // namespace Deer \ No newline at end of file diff --git a/DeerStudio/src/DeerStudio/Editor/TreePannel.cpp b/DeerStudio/src/DeerStudio/Editor/TreePanel.cpp similarity index 94% rename from DeerStudio/src/DeerStudio/Editor/TreePannel.cpp rename to DeerStudio/src/DeerStudio/Editor/TreePanel.cpp index 92ab708..b4a438f 100755 --- a/DeerStudio/src/DeerStudio/Editor/TreePannel.cpp +++ b/DeerStudio/src/DeerStudio/Editor/TreePanel.cpp @@ -1,4 +1,4 @@ -#include "TreePannel.h" +#include "TreePanel.h" #include "Deer/Enviroment.h" #include "Deer/Scene.h" @@ -8,7 +8,7 @@ #include "imgui.h" namespace Deer { - namespace TreePannel { + namespace TreePanel { void updateEntity(Entity& entity); void updateReciveDragPayload(Entity& entity); bool updateDragPayload(Entity* entity, const std::string& name); @@ -17,10 +17,10 @@ namespace Deer { bool m_isRightClickHandled; Entity* m_contextMenuEntity = nullptr; - } // namespace TreePannel + } // namespace TreePanel - void TreePannel::onImgui() { - ImGui::Begin("Tree Pannel", (bool*)0, ImGuiWindowFlags_MenuBar); + void TreePanel::onImgui() { + ImGui::Begin("Tree Panel", (bool*)0, ImGuiWindowFlags_MenuBar); m_isRightClickHandled = false; Entity& root = Project::m_scene.getMainEnviroment().getRoot(); @@ -83,7 +83,7 @@ namespace Deer { ImGui::End(); } - void TreePannel::updateEntity(Entity& entity) { + void TreePanel::updateEntity(Entity& entity) { auto& tag = entity.getComponent(); auto& relationship = entity.getComponent(); @@ -162,7 +162,7 @@ namespace Deer { } } - void TreePannel::updateReciveDragPayload(Entity& entity) { + void TreePanel::updateReciveDragPayload(Entity& entity) { if (ImGui::BeginDragDropTarget()) { if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_ENTITY")) { @@ -176,7 +176,7 @@ namespace Deer { } } - bool TreePannel::updateDragPayload(Entity* entity, + bool TreePanel::updateDragPayload(Entity* entity, const std::string& name) { if (!ImGui::BeginDragDropSource()) return false; @@ -187,7 +187,7 @@ namespace Deer { return true; } - void TreePannel::clickEntity(Entity& entity) { + void TreePanel::clickEntity(Entity& entity) { if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) { if (!(Input::isKeyPressed(DEER_KEY_LEFT_CONTROL) || Input::isKeyPressed(DEER_KEY_LEFT_ALT))) @@ -200,7 +200,7 @@ namespace Deer { } } - void TreePannel::updateContextMenu() { + void TreePanel::updateContextMenu() { bool callRename = false; if (ImGui::BeginPopup("Entity Context Menu")) { diff --git a/DeerStudio/src/DeerStudio/Editor/TreePannel.h b/DeerStudio/src/DeerStudio/Editor/TreePanel.h similarity index 68% rename from DeerStudio/src/DeerStudio/Editor/TreePannel.h rename to DeerStudio/src/DeerStudio/Editor/TreePanel.h index 2cd0e05..f4dcfcb 100755 --- a/DeerStudio/src/DeerStudio/Editor/TreePannel.h +++ b/DeerStudio/src/DeerStudio/Editor/TreePanel.h @@ -1,7 +1,7 @@ #pragma once namespace Deer { - namespace TreePannel { + namespace TreePanel { void onImgui(); } } \ No newline at end of file diff --git a/roe/imgui.ini b/roe/imgui.ini index 8aa709a..5231052 100644 --- a/roe/imgui.ini +++ b/roe/imgui.ini @@ -1,6 +1,6 @@ [Window][DockSpace Demo] Pos=0,0 -Size=2560,1371 +Size=1280,720 Collapsed=0 [Window][Debug##Default] @@ -9,32 +9,32 @@ Size=400,400 Collapsed=0 [Window][Properties] -Pos=2191,24 -Size=369,531 +Pos=968,24 +Size=312,214 Collapsed=0 DockId=0x00000009,0 [Window][Game Window] -Pos=368,24 -Size=1821,1093 +Pos=304,24 +Size=662,368 Collapsed=0 DockId=0x00000006,1 -[Window][Tree Pannel] +[Window][Tree Panel] Pos=0,24 -Size=366,1093 +Size=302,368 Collapsed=0 DockId=0x00000005,0 [Window][Terrain Editor] -Pos=2191,557 -Size=369,560 +Pos=968,240 +Size=312,152 Collapsed=0 DockId=0x0000000A,0 [Window][Viewport] -Pos=368,24 -Size=1821,1093 +Pos=304,24 +Size=662,368 Collapsed=0 DockId=0x00000006,0 @@ -45,21 +45,33 @@ Collapsed=0 DockId=0x00000002,0 [Window][Mesh Explorer] -Pos=0,1119 -Size=2560,252 +Pos=0,394 +Size=1280,326 Collapsed=0 DockId=0x00000008,0 -[Docking][Data] -DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=2560,1347 Split=Y - DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,442 Split=Y - DockNode ID=0x00000001 Parent=0x00000007 SizeRef=2560,363 Split=X Selected=0x13926F0B - DockNode ID=0x00000003 Parent=0x00000001 SizeRef=909,779 Split=X Selected=0x13926F0B - DockNode ID=0x00000005 Parent=0x00000003 SizeRef=366,779 Selected=0xBD1B42A3 - DockNode ID=0x00000006 Parent=0x00000003 SizeRef=541,779 CentralNode=1 Selected=0x13926F0B - DockNode ID=0x00000004 Parent=0x00000001 SizeRef=369,779 Split=Y Selected=0x199AB496 - DockNode ID=0x00000009 Parent=0x00000004 SizeRef=392,214 Selected=0x199AB496 - DockNode ID=0x0000000A Parent=0x00000004 SizeRef=392,226 Selected=0x2A2C795E - DockNode ID=0x00000002 Parent=0x00000007 SizeRef=2560,331 Selected=0xCF339702 - DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,252 Selected=0x7F7E0F9C +[Window][MeshSearcher] +Pos=0,493 +Size=1280,227 +Collapsed=0 +DockId=0x00000008,1 + +[Window][MeshExplorer] +Pos=0,394 +Size=1280,326 +Collapsed=0 +DockId=0x00000008,1 + +[Docking][Data] +DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y + DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,368 Split=Y + DockNode ID=0x00000001 Parent=0x00000007 SizeRef=2560,363 Split=X Selected=0x13926F0B + DockNode ID=0x00000003 Parent=0x00000001 SizeRef=966,779 Split=X Selected=0x13926F0B + DockNode ID=0x00000005 Parent=0x00000003 SizeRef=302,779 Selected=0xF278DC36 + DockNode ID=0x00000006 Parent=0x00000003 SizeRef=662,779 CentralNode=1 Selected=0x13926F0B + DockNode ID=0x00000004 Parent=0x00000001 SizeRef=312,779 Split=Y Selected=0x199AB496 + 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 diff --git a/roe/ui_scripts/mesh_searcher.as b/roe/ui_scripts/mesh_searcher.as new file mode 100644 index 0000000..97e399b --- /dev/null +++ b/roe/ui_scripts/mesh_searcher.as @@ -0,0 +1,25 @@ + +class MeshExplorer : DockPanel { + string currentPath = ""; + + void onRender() { + coloredText(0.5, 0.5, 0.5, currentPath); + + setupAutomaticColumns(180); + + int dirCount = getMeshDirCount(currentPath); + for (int i = 0; i < dirCount; i++) { + text(getMeshDirName(currentPath, i)); + + nextColumn(); + } + + int meshCount = getMeshCount(currentPath); + for (int i = 0; i < meshCount; i++) { + text(getMeshName(currentPath, i)); + + nextColumn(); + } + endColumns(); + } +} \ No newline at end of file