Added widget drawer for module settings
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "../../Commands/Commands/Commands.h"
|
||||
#include <Nuake/Audio/AudioManager.h>
|
||||
#include <Nuake/Modules/ModuleDB.h>
|
||||
#include "Nuake/UI/WidgetDrawer.h"
|
||||
|
||||
ProjectSettingsCategoryWindowGeneral::ProjectSettingsCategoryWindowGeneral(Ref<Nuake::Project> project) :
|
||||
m_Project(project)
|
||||
@@ -212,6 +213,7 @@ ProjectSettingsModuleWindow::ProjectSettingsModuleWindow(const std::string& inMo
|
||||
void ProjectSettingsModuleWindow::Draw()
|
||||
{
|
||||
auto meta = entt::resolve(entt::hashed_string(Name.c_str()));
|
||||
auto instance = ModuleDB::Get().GetBaseImpl(Name).instance;
|
||||
for (auto [id, data] : meta.data())
|
||||
{
|
||||
auto propDisplayName = data.prop(HashedName::DisplayName);
|
||||
@@ -220,59 +222,12 @@ void ProjectSettingsModuleWindow::Draw()
|
||||
auto propVal = propDisplayName.value();
|
||||
const char* settingName = *propVal.try_cast<const char*>();
|
||||
|
||||
auto& drawer = WidgetDrawer::Get();
|
||||
drawer.DrawWidget(data, instance);
|
||||
|
||||
ImGui::Text(settingName);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto [id, func] : meta.func())
|
||||
{
|
||||
auto propDisplayName = func.prop(HashedName::DisplayName);
|
||||
|
||||
if (propDisplayName)
|
||||
{
|
||||
auto propVal = propDisplayName.value();
|
||||
const char* settingName = *propVal.try_cast<const char*>();
|
||||
|
||||
ImGui::Text(settingName);
|
||||
}
|
||||
|
||||
|
||||
// Setting
|
||||
//std::string funcName = "UnknownFunc";
|
||||
//if (propDisplayName)
|
||||
//{
|
||||
// funcName = std::string(*propDisplayName.value().try_cast<const char*>());
|
||||
//}
|
||||
//
|
||||
//std::string msg = std::string(returnType) + " " + std::string(funcName) + "(";
|
||||
//std::vector<std::string_view> args;
|
||||
//
|
||||
//if (func.arity() > 0)
|
||||
//{
|
||||
// auto propArgsName = func.prop(HashedName::ArgsName);
|
||||
// if (propArgsName)
|
||||
// {
|
||||
// std::vector<std::string> argsName = *propArgsName.value().try_cast<std::vector<std::string>>();
|
||||
// for (int i = 0; i < func.arity(); i++)
|
||||
// {
|
||||
// const std::string argType = std::string(func.arg(i).info().name());
|
||||
// args.push_back(argType);
|
||||
//
|
||||
// msg += argType + " " + argsName[i];
|
||||
//
|
||||
// if (i < func.arity() - 1)
|
||||
// {
|
||||
// msg += ", ";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//
|
||||
//msg += ")";
|
||||
//
|
||||
//Logger::Log(msg, "", VERBOSE);
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectSettingsCategoryAudio::Draw()
|
||||
|
||||
@@ -62,7 +62,7 @@ void ExampleModuleLog(const std::string& hi)
|
||||
Nuake::Logger::Log(hi, "ExampleModule", Nuake::VERBOSE);
|
||||
}
|
||||
|
||||
float mySetting = 1.0f;
|
||||
float mySetting = 8.0f;
|
||||
|
||||
NUAKEMODULE(ExampleModule)
|
||||
void ExampleModule_Startup()
|
||||
@@ -76,7 +76,7 @@ void ExampleModule_Startup()
|
||||
|
||||
module.Description = "This is an example module";
|
||||
|
||||
module.RegisterSetting<&mySetting>("Hello World!");
|
||||
module.RegisterSetting<&mySetting>("mySetting");
|
||||
|
||||
// This is to expose functions to the rest of the engine
|
||||
module.BindFunction<ExampleFunction>("ExampleFunction");
|
||||
|
||||
@@ -185,7 +185,9 @@ namespace Nuake
|
||||
template<typename T>
|
||||
T& RegisterModule()
|
||||
{
|
||||
Modules[typeid(T).name()] = (ModuleInstance*)(new T());
|
||||
T* newInstance = new T();
|
||||
newInstance->instance = entt::resolve<T>().construct();
|
||||
Modules[typeid(T).name()] = (ModuleInstance*)newInstance;
|
||||
return *(T*)std::any_cast<ModuleInstance*>(Modules[typeid(T).name()]);
|
||||
}
|
||||
|
||||
@@ -202,6 +204,18 @@ namespace Nuake
|
||||
return *(T*)std::any_cast<ModuleInstance*>(Modules[typeName]);
|
||||
}
|
||||
|
||||
ModuleInstance& GetBaseImpl(const std::string& moduleName)
|
||||
{
|
||||
for (auto& [name, _] : Modules)
|
||||
{
|
||||
if (name == moduleName)
|
||||
{
|
||||
return *std::any_cast<ModuleInstance*>(Modules[name]);
|
||||
}
|
||||
}
|
||||
|
||||
assert(false && "Module not found.");
|
||||
}
|
||||
|
||||
entt::meta_type GetModuleMeta(const std::string& moduleName)
|
||||
{
|
||||
|
||||
@@ -5,10 +5,64 @@
|
||||
#include "AudioModule/AudioModule.h"
|
||||
#include "ExampleModule/ExampleModule.h"
|
||||
|
||||
#include "Nuake/UI/WidgetDrawer.h"
|
||||
|
||||
#include "Nuake/Core/Object/Object.h"
|
||||
#include "Nuake/Core/Logger.h"
|
||||
|
||||
void DrawFloatWidget(entt::meta_data& type, entt::meta_any& instance)
|
||||
{
|
||||
using namespace Nuake;
|
||||
|
||||
float stepSize = 1.f;
|
||||
if (auto prop = type.prop(HashedFieldPropName::FloatStep))
|
||||
stepSize = *prop.value().try_cast<float>();
|
||||
|
||||
float min = 0.f;
|
||||
if (auto prop = type.prop(HashedFieldPropName::FloatMin))
|
||||
min = *prop.value().try_cast<float>();
|
||||
|
||||
float max = 0.f;
|
||||
if (auto prop = type.prop(HashedFieldPropName::FloatMax))
|
||||
max = *prop.value().try_cast<float>();
|
||||
|
||||
auto propDisplayName = type.prop(HashedName::DisplayName);
|
||||
const char* displayName = *propDisplayName.value().try_cast<const char*>();
|
||||
if (displayName != nullptr)
|
||||
{
|
||||
ImGui::Text(displayName);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
auto fieldVal = type.get(instance);
|
||||
float* floatPtr = fieldVal.try_cast<float>();
|
||||
if (floatPtr != nullptr)
|
||||
{
|
||||
float floatProxy = *floatPtr;
|
||||
const std::string controlId = std::string("##") + displayName;
|
||||
if (ImGui::DragFloat(controlId.c_str(), &floatProxy, stepSize, min, max))
|
||||
{
|
||||
type.set(instance, floatProxy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text("ERR");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBoolWidget(entt::meta_type& type, entt::meta_any& instance)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Nuake::Modules::StartupModules()
|
||||
{
|
||||
auto& drawer = WidgetDrawer::Get();
|
||||
drawer.RegisterTypeDrawer<float, &WidgetDrawer::DrawFloat>(&drawer);
|
||||
|
||||
//drawer.RegisterTypeDrawer<bool, DrawBoolWidget>(&DrawBoolWidget);
|
||||
|
||||
Logger::Log("Starting AssimpModule", "modules");
|
||||
AssimpModule_Startup();
|
||||
Logger::Log("Starting AudioModule", "modules");
|
||||
|
||||
88
Nuake/Source/Nuake/UI/WidgetDrawer.h
Normal file
88
Nuake/Source/Nuake/UI/WidgetDrawer.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
#include "Nuake/Core/Object/Object.h"
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
using DrawWidgetTypeFn = std::function<void(entt::meta_data& fieldMeta, entt::meta_any& instance)>;
|
||||
class WidgetDrawer
|
||||
{
|
||||
public:
|
||||
WidgetDrawer() = default;
|
||||
~WidgetDrawer() = default;
|
||||
|
||||
static WidgetDrawer& Get()
|
||||
{
|
||||
static WidgetDrawer instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void DrawFloat(entt::meta_data& type, entt::meta_any& instance)
|
||||
{
|
||||
float stepSize = 1.f;
|
||||
if (auto prop = type.prop(HashedFieldPropName::FloatStep))
|
||||
stepSize = *prop.value().try_cast<float>();
|
||||
|
||||
float min = 0.f;
|
||||
if (auto prop = type.prop(HashedFieldPropName::FloatMin))
|
||||
min = *prop.value().try_cast<float>();
|
||||
|
||||
float max = 0.f;
|
||||
if (auto prop = type.prop(HashedFieldPropName::FloatMax))
|
||||
max = *prop.value().try_cast<float>();
|
||||
|
||||
auto propDisplayName = type.prop(HashedName::DisplayName);
|
||||
const char* displayName = *propDisplayName.value().try_cast<const char*>();
|
||||
if (displayName != nullptr)
|
||||
{
|
||||
ImGui::Text(displayName);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
auto fieldVal = type.get(instance);
|
||||
float* floatPtr = fieldVal.try_cast<float>();
|
||||
if (floatPtr != nullptr)
|
||||
{
|
||||
float floatProxy = *floatPtr;
|
||||
const std::string controlId = std::string("##") + displayName;
|
||||
if (ImGui::DragFloat(controlId.c_str(), &floatProxy, stepSize, min, max))
|
||||
{
|
||||
type.set(instance, floatProxy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text("ERR");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWidget(entt::meta_data& dataType, entt::meta_any& instance)
|
||||
{
|
||||
entt::id_type dataId = dataType.type().id();
|
||||
if (WidgetTypeDrawers.contains(dataId))
|
||||
{
|
||||
auto& drawerFn = WidgetTypeDrawers[dataId];
|
||||
drawerFn(dataType, instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text("ERR");
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, auto Func, class O>
|
||||
void RegisterTypeDrawer(O* o)
|
||||
{
|
||||
WidgetTypeDrawers[entt::type_id<T>().hash()] = std::bind(Func, o, std::placeholders::_1, std::placeholders::_2);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<entt::id_type, DrawWidgetTypeFn> WidgetTypeDrawers;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user