Merge remote-tracking branch 'origin/main' into SP3-2-Physics
This commit is contained in:
commit
e956797441
|
@ -42,6 +42,8 @@
|
|||
|
||||
#include "Assets/SHAssetManager.h"
|
||||
|
||||
#include "Tools/SHLogger.h"
|
||||
|
||||
using namespace SHADE;
|
||||
|
||||
namespace Sandbox
|
||||
|
@ -97,6 +99,11 @@ namespace Sandbox
|
|||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
|
||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
|
||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/TD_Checker_Base_Color.dds");
|
||||
|
||||
|
||||
auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
||||
auto id2 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
||||
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
||||
//TODO: REMOVE AFTER PRESENTATION
|
||||
|
||||
//SHADE::SHSystemManager::RegisterRoutine<SHADE::SHAudioSystem, SHADE::SHAudioSystem::AudioRoutine>();
|
||||
|
@ -112,7 +119,9 @@ namespace Sandbox
|
|||
#else
|
||||
#endif
|
||||
|
||||
|
||||
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
|
||||
|
||||
SHFrameRateController::UpdateFRC();
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ namespace Sandbox
|
|||
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||
// Create temp meshes
|
||||
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
|
||||
//graphicsSystem->BuildMeshBuffers();
|
||||
|
||||
//Test Racoon mesh
|
||||
auto meshes = SHADE::SHAssetManager::GetAllMeshes();
|
||||
|
@ -45,7 +44,7 @@ namespace Sandbox
|
|||
{
|
||||
if (mesh.meshName == "Cube.012")
|
||||
{
|
||||
handles.push_back(graphicsSystem->AddMesh(
|
||||
handles.push_back(graphicsSystem->AddMesh(
|
||||
mesh.header.vertexCount,
|
||||
mesh.vertexPosition.data(),
|
||||
mesh.texCoords.data(),
|
||||
|
@ -108,9 +107,9 @@ namespace Sandbox
|
|||
stressTestObjects.emplace_back(entity);
|
||||
}
|
||||
|
||||
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
|
||||
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
|
||||
auto raccoonSpin = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonSpin);
|
||||
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonSpin);
|
||||
|
||||
renderable.Mesh = handles.front();
|
||||
renderable.SetMaterial(customMat);
|
||||
|
@ -138,7 +137,21 @@ namespace Sandbox
|
|||
//testObjRenderable.SetMaterial(matInst);
|
||||
|
||||
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
|
||||
scriptEngine->AddScript(testObj, "TestScript");
|
||||
scriptEngine->AddScript(raccoonSpin, "RaccoonSpin");
|
||||
|
||||
auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
|
||||
auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
|
||||
auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase);
|
||||
|
||||
renderableShowcase.Mesh = handles.front();
|
||||
renderableShowcase.SetMaterial(customMat);
|
||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
|
||||
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 1);
|
||||
|
||||
transformShowcase.SetWorldPosition({ 3.0f, -1.0f, -1.0f });
|
||||
transformShowcase.SetLocalScale({ 5.0f, 5.0f, 5.0f });
|
||||
scriptEngine->AddScript(raccoonShowcase, "RaccoonShowcase");
|
||||
}
|
||||
|
||||
void SBTestScene::Update(float dt)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "SHpch.h"
|
||||
#include "../SHECSMacros.h"
|
||||
#include "SH_API.h"
|
||||
#include "ECS_Base/General/SHFamily.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -117,4 +118,7 @@ namespace SHADE
|
|||
|
||||
|
||||
};
|
||||
|
||||
|
||||
template class SH_API SHFamilyID<SHComponent>;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHComponentAddedEvent
|
||||
{
|
||||
EntityID eid;
|
||||
ComponentTypeID addedComponentType;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
struct SHComponentRemovedEvent
|
||||
{
|
||||
EntityID eid;
|
||||
ComponentTypeID removedComponentType;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
#include "SHFamily.h"
|
||||
#include "SHpch.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
//initialize currentID as 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -14,16 +14,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "../SHECSMacros.h"
|
||||
#include "SH_API.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
||||
template<typename BaseClass>
|
||||
class SHFamilyID
|
||||
class SH_API SHFamilyID
|
||||
{
|
||||
private:
|
||||
//this is used to keep track of the new current ID to be assign to a new Derived class type.
|
||||
static ComponentTypeID currentID;
|
||||
|
||||
|
||||
/*!*************************************************************************
|
||||
* \brief Construct a new SHFamilyID object
|
||||
|
@ -46,6 +47,9 @@ namespace SHADE
|
|||
}
|
||||
public:
|
||||
|
||||
//this is used to keep track of the new current ID to be assign to a new Derived class type.
|
||||
static inline ComponentTypeID currentID = 0;
|
||||
|
||||
/*!*************************************************************************
|
||||
* \brief
|
||||
* Checks if this identifier is cuurrently in use / valid.
|
||||
|
@ -59,7 +63,6 @@ namespace SHADE
|
|||
{
|
||||
return(id < currentID);
|
||||
}
|
||||
|
||||
/*!*************************************************************************
|
||||
* \brief
|
||||
* Get the ID of a derived class type.
|
||||
|
@ -68,16 +71,27 @@ namespace SHADE
|
|||
* @tparam DerivedClass
|
||||
* The derived class type that we are trying to get the ID of.
|
||||
***************************************************************************/
|
||||
#ifdef SH_API_EXPORT
|
||||
template<typename DerivedClass>
|
||||
static ENABLE_IF_DERIVED(ComponentTypeID, BaseClass, DerivedClass) GetID() noexcept
|
||||
static SH_API ENABLE_IF_DERIVED(ComponentTypeID, BaseClass, DerivedClass) GetID() noexcept
|
||||
{
|
||||
//The first time a new derived class type call this get id, it will initialize id using the currentID from familyID class.
|
||||
static ComponentTypeID id = currentID++;
|
||||
static ComponentTypeID id = SHFamilyID<BaseClass>::currentID++;
|
||||
return id;
|
||||
//return 0;
|
||||
}
|
||||
#else
|
||||
template<typename DerivedClass>
|
||||
static SH_API ENABLE_IF_DERIVED(ComponentTypeID, BaseClass, DerivedClass) GetID() noexcept;
|
||||
#endif // SH_API_EXPORT
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
//initialize currentID as 0
|
||||
template<typename BaseClass>
|
||||
ComponentTypeID SHFamilyID<BaseClass>::currentID = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -17,8 +17,11 @@
|
|||
#include "../General/SHSparseSetContainer.h"
|
||||
#include "../Components/SHComponent.h"
|
||||
#include "../Components/SHComponentGroup.h"
|
||||
#include "../Events/SHComponentAddedEvent.h"
|
||||
#include "../Events/SHComponentRemovedEvent.h"
|
||||
//#include "Scene/SHSceneNode.h"
|
||||
#include "SH_API.h"
|
||||
#include "Events/SHEventManager.hpp"
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
@ -216,6 +219,11 @@ namespace SHADE
|
|||
comp->OnCreate();
|
||||
}
|
||||
|
||||
SHComponentAddedEvent eventData;
|
||||
eventData.eid = entityID;
|
||||
eventData.addedComponentType = ComponentFamily::GetID<T>();
|
||||
|
||||
SHEventManager::BroadcastEvent<SHComponentAddedEvent>(eventData, SH_COMPONENT_ADDED_EVENT);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -247,6 +255,13 @@ namespace SHADE
|
|||
{
|
||||
comp->OnCreate();
|
||||
}
|
||||
|
||||
SHComponentAddedEvent eventData;
|
||||
eventData.eid = entityID;
|
||||
eventData.addedComponentType = componentTypeID;
|
||||
|
||||
SHEventManager::BroadcastEvent<SHComponentAddedEvent>(eventData, SH_COMPONENT_ADDED_EVENT);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -313,6 +328,12 @@ namespace SHADE
|
|||
|
||||
|
||||
componentSet.GetSparseSet<T>()->Remove(EntityHandleGenerator::GetIndex(entityID));
|
||||
|
||||
SHComponentRemovedEvent eventData;
|
||||
eventData.eid = entityID;
|
||||
eventData.removedComponentType = ComponentFamily::GetID<T>();
|
||||
|
||||
SHEventManager::BroadcastEvent<SHComponentRemovedEvent>(eventData, SH_COMPONENT_REMOVED_EVENT);
|
||||
}
|
||||
|
||||
/*!*************************************************************************
|
||||
|
@ -464,11 +485,6 @@ namespace SHADE
|
|||
return componentGroups[index];
|
||||
}
|
||||
|
||||
static void AddScriptComponent(EntityID eid, std::string const& scriptClassName) noexcept;
|
||||
|
||||
static void RemoveScriptComponent(EntityID eid, std::string const& scriptClassName) noexcept;
|
||||
|
||||
|
||||
};// end SHComponentManager
|
||||
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@ namespace SHADE
|
|||
id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID;
|
||||
}
|
||||
systemContainer.emplace(id, std::make_unique<T>());
|
||||
|
||||
auto size = systemContainer.size();
|
||||
|
||||
systemContainer[id].get()->systemID = id;
|
||||
|
||||
return id;
|
||||
|
|
|
@ -26,4 +26,6 @@ const EntityIndex MAX_EID = 51000;
|
|||
#define ENABLE_IF_UINT(_TYPE, _RETURN)\
|
||||
typename std::enable_if<(std::is_integral<_TYPE>::value && !std::is_signed<_TYPE>::value),_RETURN>::type
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "../SHECSMacros.h"
|
||||
#include "SH_API.h"
|
||||
#include "ECS_Base/General/SHFamily.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -69,5 +70,9 @@ namespace SHADE
|
|||
};
|
||||
|
||||
|
||||
template class SH_API SHFamilyID<SHSystem>;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -46,7 +46,7 @@ namespace SHADE
|
|||
if (!component)
|
||||
return;
|
||||
auto componentType = rttr::type::get(*component);
|
||||
CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
|
||||
ImGui::SameLine();
|
||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
||||
{
|
||||
|
@ -63,7 +63,7 @@ namespace SHADE
|
|||
std::vector<const char*> list;
|
||||
for(auto const& name : names)
|
||||
list.push_back(name.data());
|
||||
ComboBox(property.get_name().data(), list, [component, property]{return property.get_value(component).to_int();}, [component, property](int const& idx)
|
||||
SHEditorWidgets::ComboBox(property.get_name().data(), list, [component, property]{return property.get_value(component).to_int();}, [component, property](int const& idx)
|
||||
{
|
||||
auto enumAlign = property.get_enumeration();
|
||||
auto values = enumAlign.get_values();
|
||||
|
@ -75,7 +75,7 @@ namespace SHADE
|
|||
{
|
||||
if (type == rttr::type::get<bool>())
|
||||
{
|
||||
CheckBox(property.get_name().data(), [component, property]{return property.get_value(component).to_bool();}, [component, property](bool const& result){property.set_value(component, result);});
|
||||
SHEditorWidgets::CheckBox(property.get_name().data(), [component, property]{return property.get_value(component).to_bool();}, [component, property](bool const& result){property.set_value(component, result);});
|
||||
}
|
||||
//else if (type == rttr::type::get<char>())
|
||||
//{
|
||||
|
@ -87,11 +87,11 @@ namespace SHADE
|
|||
auto metaMax = property.get_metadata(META::max);
|
||||
if(metaMin && metaMax)
|
||||
{
|
||||
SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMin.template get_value<int>(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);});
|
||||
SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value<int>(), metaMin.template get_value<int>(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);});
|
||||
}
|
||||
else
|
||||
{
|
||||
DragInt(property.get_name().data(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);});
|
||||
SHEditorWidgets::DragInt(property.get_name().data(), [component, property]{return property.get_value(component).to_int();}, [component, property](int const& result){property.set_value(component, result);});
|
||||
}
|
||||
}
|
||||
else if (type == rttr::type::get<uint8_t>())
|
||||
|
@ -100,11 +100,11 @@ namespace SHADE
|
|||
auto metaMax = property.get_metadata(META::max);
|
||||
if(metaMin.is_valid() && metaMax.is_valid())
|
||||
{
|
||||
SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},"%zu");
|
||||
SHEditorWidgets::SliderScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value<uint8_t>(), metaMax.template get_value<uint8_t>(), [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},"%zu");
|
||||
}
|
||||
else
|
||||
{
|
||||
DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
|
||||
SHEditorWidgets::DragScalar<uint8_t>(property.get_name().data(), ImGuiDataType_U8, [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
|
||||
}
|
||||
}
|
||||
else if (type == rttr::type::get<uint16_t>())
|
||||
|
@ -113,11 +113,11 @@ namespace SHADE
|
|||
auto metaMax = property.get_metadata(META::max);
|
||||
if(metaMin.is_valid() && metaMax.is_valid())
|
||||
{
|
||||
SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMin.template get_value<uint16_t>(), [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},"%zu");
|
||||
SHEditorWidgets::SliderScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value<uint16_t>(), metaMin.template get_value<uint16_t>(), [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},"%zu");
|
||||
}
|
||||
else
|
||||
{
|
||||
DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
|
||||
SHEditorWidgets::DragScalar<uint16_t>(property.get_name().data(), ImGuiDataType_U16, [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
|
||||
}
|
||||
}
|
||||
else if (type == rttr::type::get<uint32_t>())
|
||||
|
@ -126,11 +126,11 @@ namespace SHADE
|
|||
auto metaMax = property.get_metadata(META::max);
|
||||
if (metaMin.is_valid() && metaMax.is_valid())
|
||||
{
|
||||
SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMin.template get_value<uint32_t>(), [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },"%zu");
|
||||
SHEditorWidgets::SliderScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value<uint32_t>(), metaMin.template get_value<uint32_t>(), [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },"%zu");
|
||||
}
|
||||
else
|
||||
{
|
||||
DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },0.1f,0,0,"%zu");
|
||||
SHEditorWidgets::DragScalar<uint32_t>(property.get_name().data(), ImGuiDataType_U32, [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },0.1f,0,0,"%zu");
|
||||
}
|
||||
}
|
||||
else if (type == rttr::type::get<uint64_t>())
|
||||
|
@ -139,11 +139,11 @@ namespace SHADE
|
|||
auto metaMax = property.get_metadata(META::max);
|
||||
if(metaMin.is_valid() && metaMax.is_valid())
|
||||
{
|
||||
SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMin.template get_value<uint64_t>(), [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},"%zu");
|
||||
SHEditorWidgets::SliderScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value<uint64_t>(), metaMin.template get_value<uint64_t>(), [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},"%zu");
|
||||
}
|
||||
else
|
||||
{
|
||||
DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
|
||||
SHEditorWidgets::DragScalar<uint64_t>(property.get_name().data(), ImGuiDataType_U64, [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},0.1f,0,0,"%zu");
|
||||
}
|
||||
}
|
||||
else if (type == rttr::type::get<float>())
|
||||
|
@ -152,11 +152,11 @@ namespace SHADE
|
|||
auto metaMax = property.get_metadata(META::max);
|
||||
if(metaMin.is_valid() && metaMax.is_valid())
|
||||
{
|
||||
SliderFloat(property.get_name().data(), metaMin.template get_value<float>(), metaMin.template get_value<float>(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);});
|
||||
SHEditorWidgets::SliderFloat(property.get_name().data(), metaMin.template get_value<float>(), metaMin.template get_value<float>(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);});
|
||||
}
|
||||
else
|
||||
{
|
||||
DragFloat(property.get_name().data(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);});
|
||||
SHEditorWidgets::DragFloat(property.get_name().data(), [component, property]{return property.get_value(component).to_float();}, [component, property](float const& result){property.set_value(component, result);});
|
||||
}
|
||||
}
|
||||
else if (type == rttr::type::get<double>())
|
||||
|
@ -165,25 +165,25 @@ namespace SHADE
|
|||
auto metaMax = property.get_metadata(META::max);
|
||||
if(metaMin.is_valid() && metaMax.is_valid())
|
||||
{
|
||||
SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMin.template get_value<double>(), [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);});
|
||||
SHEditorWidgets::SliderScalar<double>(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value<double>(), metaMin.template get_value<double>(), [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);});
|
||||
}
|
||||
else
|
||||
{
|
||||
DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);}, 0.1f);
|
||||
SHEditorWidgets::DragScalar<double>(property.get_name().data(), ImGuiDataType_Double, [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);}, 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == rttr::type::get<SHVec4>())
|
||||
{
|
||||
DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); });
|
||||
SHEditorWidgets::DragVec4(property.get_name().data(), { "X", "Y", "Z", "W" }, [component, property]() {return property.get_value(component).template convert<SHVec4>(); }, [component, property](SHVec4 vec) {return property.set_value(component, vec); });
|
||||
}
|
||||
else if (type == rttr::type::get<SHVec3>())
|
||||
{
|
||||
DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); });
|
||||
SHEditorWidgets::DragVec3(property.get_name().data(), { "X", "Y", "Z" }, [component, property]() {return property.get_value(component).template convert<SHVec3>(); }, [component, property](SHVec3 vec) {return property.set_value(component, vec); });
|
||||
}
|
||||
else if (type == rttr::type::get<SHVec2>())
|
||||
{
|
||||
DragVec2(property.get_name().data(), { "X", "Y"}, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); });
|
||||
SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y"}, [component, property]() {return property.get_value(component).template convert<SHVec2>(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "SHEditorComponentView.hpp"
|
||||
#include "ECS_Base/UnitTesting/SHTestComponents.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||
#include "Scripting/SHScriptEngine.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "AudioSystem/SHAudioSystem.h"
|
||||
|
@ -49,7 +51,7 @@ namespace SHADE
|
|||
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||
|
||||
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
||||
CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
|
||||
SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::InputText("##EntityName", &entity->name);
|
||||
|
@ -74,6 +76,11 @@ namespace SHADE
|
|||
DrawAddComponentButton<SHComponent_ENUM>(eid);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
// Render Scripts
|
||||
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||
scriptEngine->RenderScriptsInInspector(eid);
|
||||
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#include "SHEditorMenuBar.h"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "Editor/Command/SHCommandManager.h"
|
||||
#include "Scripting/SHScriptEngine.h"
|
||||
#include "Editor/SHEditor.hpp"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
|
@ -14,9 +17,6 @@
|
|||
#include <imgui_internal.h>
|
||||
#include <rttr/type>
|
||||
|
||||
#include "Editor/SHEditor.hpp"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||
|
@ -100,6 +100,25 @@ namespace SHADE
|
|||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Scripts"))
|
||||
{
|
||||
if (ImGui::Selectable("Generate Visual Studio Project"))
|
||||
{
|
||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||
scriptEngine->GenerateScriptsCsProjFile();
|
||||
}
|
||||
if (ImGui::Selectable("Build Scripts - Debug"))
|
||||
{
|
||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||
scriptEngine->BuildScriptAssembly(true, true);
|
||||
}
|
||||
if (ImGui::Selectable("Build Scripts - Release"))
|
||||
{
|
||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||
scriptEngine->BuildScriptAssembly(false, true);
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "SHEditor.hpp"
|
||||
#include "SHEditorWidgets.hpp"
|
||||
|
||||
#include "Math/Transform/SHTransformSystem.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Editor Window Includes ||
|
||||
//#==============================================================#
|
||||
|
@ -87,6 +89,11 @@ namespace SHADE
|
|||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
||||
|
||||
InitFonts();
|
||||
|
||||
|
||||
auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
||||
auto id2 = SHFamilyID<SHSystem>::GetID<SHTransformSystem>();
|
||||
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
|
||||
InitBackend(sdlWindow);
|
||||
|
||||
SetStyle(Style::SHADE);
|
||||
|
@ -104,7 +111,6 @@ namespace SHADE
|
|||
{
|
||||
(void)dt;
|
||||
NewFrame();
|
||||
|
||||
for (const auto& window : editorWindows | std::views::values)
|
||||
{
|
||||
if(window->isOpen)
|
||||
|
|
|
@ -0,0 +1,259 @@
|
|||
/************************************************************************************//*!
|
||||
\file EditorUI.cpp
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Nov 7, 2021
|
||||
\brief Contains the implementation of the EditorUI class.
|
||||
|
||||
Copyright (C) 2021 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Header
|
||||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "SHEditorUI.h"
|
||||
// External Dependencies
|
||||
#include <imgui.h>
|
||||
#include "SHEditorWidgets.hpp"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - ID Stack */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHEditorUI::PushID(const std::string& id)
|
||||
{
|
||||
ImGui::PushID(id.c_str());
|
||||
}
|
||||
|
||||
void SHEditorUI::PushID(int id)
|
||||
{
|
||||
ImGui::PushID(id);
|
||||
}
|
||||
|
||||
void SHEditorUI::PopID()
|
||||
{
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Indent */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHEditorUI::Indent()
|
||||
{
|
||||
ImGui::Indent();
|
||||
}
|
||||
void SHEditorUI::Unindent()
|
||||
{
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Organizers */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
bool SHEditorUI::CollapsingHeader(const std::string& title)
|
||||
{
|
||||
return ImGui::CollapsingHeader(title.c_str());
|
||||
}
|
||||
|
||||
void SHEditorUI::SameLine()
|
||||
{
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
void SHEditorUI::Separator()
|
||||
{
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
bool SHEditorUI::BeginMenu(const std::string& label)
|
||||
{
|
||||
return ImGui::BeginMenu(label.data());
|
||||
}
|
||||
|
||||
bool SHEditorUI::BeginMenu(const std::string& label, const char* icon)
|
||||
{
|
||||
return ImGui::BeginMenu(std::format("{} {}", icon, label.data()).data());
|
||||
}
|
||||
|
||||
void SHEditorUI::EndMenu()
|
||||
{
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Pop Ups */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
bool SHEditorUI::BeginPopup(const std::string& label)
|
||||
{
|
||||
return ImGui::BeginPopup(label.c_str());
|
||||
}
|
||||
|
||||
bool SHEditorUI::BeginPopupContextItem(const std::string& label)
|
||||
{
|
||||
return ImGui::BeginPopupContextItem(label.data());
|
||||
}
|
||||
|
||||
void SHEditorUI::EndPopup()
|
||||
{
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
void SHEditorUI::OpenPopup(const std::string& label)
|
||||
{
|
||||
ImGui::OpenPopup(label.c_str());
|
||||
}
|
||||
|
||||
bool SHEditorUI::MenuItem(const std::string& label)
|
||||
{
|
||||
return ImGui::MenuItem(label.c_str());
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Widgets */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHEditorUI::Text(const std::string& title)
|
||||
{
|
||||
ImGui::Text(title.c_str());
|
||||
}
|
||||
bool SHEditorUI::SmallButton(const std::string& title)
|
||||
{
|
||||
return ImGui::SmallButton(title.c_str());
|
||||
}
|
||||
bool SHEditorUI::Button(const std::string& title)
|
||||
{
|
||||
return ImGui::Button(title.c_str());
|
||||
}
|
||||
|
||||
bool SHEditorUI::Selectable(const std::string& label)
|
||||
{
|
||||
return ImGui::Selectable(label.data());
|
||||
}
|
||||
|
||||
bool SHEditorUI::Selectable(const std::string& label, const char* icon)
|
||||
{
|
||||
return ImGui::Selectable(std::format("{} {}", icon, label).data());
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputCheckbox(const std::string& label, bool& value)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
ImGui::SameLine();
|
||||
return ImGui::Checkbox("#", &value);
|
||||
}
|
||||
bool SHEditorUI::InputInt(const std::string& label, int& value)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputInt("#", &value,
|
||||
1, 10,
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value)
|
||||
{
|
||||
int signedVal = static_cast<int>(value);
|
||||
ImGui::Text(label.c_str());
|
||||
ImGui::SameLine();
|
||||
const bool CHANGED = InputInt("#", signedVal);
|
||||
if (CHANGED)
|
||||
{
|
||||
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max());
|
||||
value = static_cast<unsigned int>(signedVal);
|
||||
}
|
||||
return CHANGED;
|
||||
}
|
||||
bool SHEditorUI::InputFloat(const std::string& label, float& value)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputFloat("#", &value,
|
||||
0.1f, 1.0f, "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
bool SHEditorUI::InputDouble(const std::string& label, double& value)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputDouble("#", &value,
|
||||
0.1, 1.0, "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
bool SHEditorUI::InputAngle(const std::string& label, double& value)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
ImGui::SameLine();
|
||||
return ImGui::InputDouble("#", &value,
|
||||
1.0, 45.0, "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value)
|
||||
{
|
||||
float val = static_cast<float>(value);
|
||||
ImGui::Text(label.c_str());
|
||||
ImGui::SameLine();
|
||||
const bool CHANGED = ImGui::SliderFloat("#", &val,
|
||||
static_cast<float>(min), static_cast<float>(max), "%.3f",
|
||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||
|
||||
if (CHANGED)
|
||||
{
|
||||
value = val;
|
||||
}
|
||||
|
||||
return CHANGED;
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value)
|
||||
{
|
||||
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y" };
|
||||
return SHEditorWidgets::DragN<float, 2>(label, COMPONENT_LABELS, { &value.x, &value.y });
|
||||
}
|
||||
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, float speed)
|
||||
{
|
||||
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"};
|
||||
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f");
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputTextField(const std::string& label, std::string& value)
|
||||
{
|
||||
std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' };
|
||||
strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str());
|
||||
ImGui::Text(label.c_str());
|
||||
ImGui::SameLine();
|
||||
const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
||||
if (CHANGED)
|
||||
{
|
||||
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
|
||||
}
|
||||
return CHANGED;
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames)
|
||||
{
|
||||
// Clamp input value
|
||||
const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v];
|
||||
bool b = false;
|
||||
|
||||
ImGui::Text(label.c_str());
|
||||
ImGui::SameLine();
|
||||
if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
||||
{
|
||||
for (int i = 0; i < enumNames.size(); ++i)
|
||||
{
|
||||
const bool IS_SELECTED = v == i;
|
||||
if (ImGui::Selectable(enumNames[i].c_str(), IS_SELECTED))
|
||||
{
|
||||
v = i;
|
||||
b = true;
|
||||
}
|
||||
if (IS_SELECTED)
|
||||
{
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
return b;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,286 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHEditorUI.h
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\par email: t.yanchongclarence\@digipen.edu
|
||||
\date Sep 27, 2022
|
||||
\brief Defines a class that contains wrapper functions for ImGui.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
// Standard Library
|
||||
#include <functional> // std::function
|
||||
#include <string> // std::string
|
||||
// Project Includes
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/Vector/SHVec4.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class that contains useful functions for Editor UI using ImGui.
|
||||
/// </summary>
|
||||
class SH_API SHEditorUI final
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Constants */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Maximum length of a string supported by InputTextField()
|
||||
/// </summary>
|
||||
static constexpr size_t TEXT_FIELD_MAX_LENGTH = 256;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - ID Stack */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Marks the start of a stack of ImGui widgets with the specified id.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::PushID().
|
||||
/// </summary>
|
||||
/// <param name="id">String-based ID.</param>
|
||||
static void PushID(const std::string& id);
|
||||
/// <summary>
|
||||
/// Marks the start of a stack of ImGui widgets with the specified id.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::PushID().
|
||||
/// </summary>
|
||||
/// <param name="id">Integer-based ID.</param>
|
||||
static void PushID(int id);
|
||||
/// <summary>
|
||||
/// Marks the end of a stack of ImGui widgets from the last PushID() call.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::PopID().
|
||||
/// </summary>
|
||||
static void PopID();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Indent */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Indents the widgets rendered after this call.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::Indent().
|
||||
/// </summary>
|
||||
static void Indent();
|
||||
/// <summary>
|
||||
/// Unindents the widgets rendered after this call.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::Unindent().
|
||||
/// </summary>
|
||||
static void Unindent();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Organizers */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Creates a collapsing title header.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::CollapsingHeader().
|
||||
/// </summary>
|
||||
/// <param name="title">Label for the header.</param>
|
||||
/// <returns>True if the header is open, false otherwise.</returns>
|
||||
static bool CollapsingHeader(const std::string& title);
|
||||
static void SameLine();
|
||||
static void Separator();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Menu */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static bool BeginMenu(const std::string& label);
|
||||
static bool BeginMenu(const std::string& label, const char* icon);
|
||||
static void EndMenu();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Pop Ups */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Marks the start of a definition of a mini pop up that can show options.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::BeginPopup().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <returns>Whether or not the pop up is open.</returns>
|
||||
static bool BeginPopup(const std::string& label);
|
||||
static bool BeginPopupContextItem(const std::string& label);
|
||||
/// <summary>
|
||||
/// Marks the end of a definition of a mini pop up that can show options.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::EndPopup().
|
||||
/// </summary>
|
||||
static void EndPopup();
|
||||
/// <summary>
|
||||
/// Opens the popup that was defined with the specified label.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::OpenPopup().
|
||||
/// </summary>
|
||||
static void OpenPopup(const std::string& label);
|
||||
/// <summary>
|
||||
/// Creates a menu item in the list of items for a mini popup.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::MenuItem().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <returns>Whether or not the menu item was selected.</returns>
|
||||
static bool MenuItem(const std::string& label);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Widgets */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Creates a visual text widget.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::Text().
|
||||
/// </summary>
|
||||
/// <param name="title">Text to display.</param>
|
||||
static void Text(const std::string& title);
|
||||
/// <summary>
|
||||
/// Creates a small inline button widget.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::SmallButton().
|
||||
/// </summary>
|
||||
/// <param name="title">Text to display.</param>
|
||||
/// <returns>True if button was pressed.</returns>
|
||||
static bool SmallButton(const std::string& title);
|
||||
/// <summary>
|
||||
/// Creates a inline button widget.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::Button().
|
||||
/// </summary>
|
||||
/// <param name="title">Text to display.</param>
|
||||
/// <returns>True if button was pressed.</returns>
|
||||
static bool Button(const std::string& title);
|
||||
static bool Selectable(const std::string& label);
|
||||
static bool Selectable(const std::string& label, const char* icon);
|
||||
/// <summary>
|
||||
/// Creates a checkbox widget for boolean input.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::Checkbox().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputCheckbox(const std::string& label, bool& value);
|
||||
/// <summary>
|
||||
/// Creates a integer field widget for integer input.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::InputInt().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputInt(const std::string& label, int& value);
|
||||
/// <summary>
|
||||
/// Creates a integer field widget for unsigned integer input.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::InputInt() with an additional clamping of values.
|
||||
/// <br/>
|
||||
/// Note: As a result, the range of this function limits it to the maximum
|
||||
/// value of a 32-bit signed integer instead of a 32-bit unsigned integer.
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputUnsignedInt(const std::string& label, unsigned int& value);
|
||||
/// <summary>
|
||||
/// Creates a decimal field widget for single precision float input.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::InputFloat().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputFloat(const std::string& label, float& value);
|
||||
/// <summary>
|
||||
/// Creates a decimal field widget for double precision float input.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::InputDouble().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputDouble(const std::string& label, double& value);
|
||||
/// <summary>
|
||||
/// Creates a decimal field widget for double input with increments of higher
|
||||
/// steps meant for angle variables.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::InputDouble().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputAngle(const std::string& label, double& value);
|
||||
/// <summary>
|
||||
/// Creates a double slider field widget for double input.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::InputSliderFloat().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="min">Minimum value of the slider.</param>
|
||||
/// <param name="max">Maximum value of the slider.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputSlider(const std::string& label, double min, double max, double& value);
|
||||
/// <summary>
|
||||
/// Creates a 2x double field widget for Vector2 input.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::InputFloat2().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputVec2(const std::string& label, SHVec2& value);
|
||||
/// <summary>
|
||||
/// Creates a 3x double field widget for Vector3 input.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::InputFloat3().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputVec3(const std::string& label, SHVec3& value, float speed = 0.1f);
|
||||
/// <summary>
|
||||
/// Creates a text field widget for string input.
|
||||
/// <br/>
|
||||
/// Wraps up ImGui::InputText().
|
||||
/// </summary>
|
||||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputTextField(const std::string& label, std::string& value);
|
||||
/// <summary>
|
||||
/// Creates a combo box for enumeration input.
|
||||
/// </summary>
|
||||
/// <typeparam name="Enum">The type of enum to input.</typeparam>
|
||||
/// <param name="label">The name of the input.</param>
|
||||
/// <param name="v">The reference to the value to modify.</param>
|
||||
/// <param name="maxVal">The maximum value of the enum.</param>
|
||||
/// <param name="toStrFn">
|
||||
/// Conversion function from the type of enum to C-style string.
|
||||
/// </param>
|
||||
/// <returns>Whether the value was modified.</returns>
|
||||
template<typename Enum>
|
||||
static bool InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char*(Enum)> toStrFn);
|
||||
/// <summary>
|
||||
/// Creates a combo box for enumeration input using a specified list of names.
|
||||
/// </summary>
|
||||
/// <param name="label">The name of the input.</param>
|
||||
/// <param name="v">The reference to the value to modify.</param>
|
||||
/// <param name="enumNames">Vector of names for each enumeration value.</param>
|
||||
/// <returns>Whether the value was modified.</returns>
|
||||
static bool InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames);
|
||||
|
||||
|
||||
private:
|
||||
// Prevent instantiation of this static class
|
||||
SHEditorUI() = delete;
|
||||
};
|
||||
}
|
||||
|
||||
#include "SHEditorUI.hpp"
|
|
@ -0,0 +1,51 @@
|
|||
/************************************************************************************//*!
|
||||
\file SHEditorUI.hpp
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 27, 2022
|
||||
\brief Contains the implementation of editor inspector template functions.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
// Primary Header
|
||||
#include "SHEditorUI.h"
|
||||
// External Dependencies
|
||||
#include <imgui.h>
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* ImGui Wrapper Functions - Widgets */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
template<typename Enum>
|
||||
inline bool SHEditorUI::InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char* (Enum)> toStrFn)
|
||||
{
|
||||
std::vector<Enum> values;
|
||||
for (int i = 0; i <= maxVal; ++i)
|
||||
{
|
||||
values.emplace_back(static_cast<Enum>(i));
|
||||
}
|
||||
bool b = false;
|
||||
if (ImGui::BeginCombo(label.c_str(), toStrFn(v), ImGuiComboFlags_None))
|
||||
{
|
||||
for (int i = 0; i <= maxVal; ++i)
|
||||
{
|
||||
const auto VALUE = values[i];
|
||||
const bool IS_SELECTED = v == VALUE;
|
||||
if (ImGui::Selectable(toStrFn(VALUE), IS_SELECTED))
|
||||
{
|
||||
v = VALUE;
|
||||
b = true;
|
||||
}
|
||||
if (IS_SELECTED)
|
||||
{
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
return b;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@
|
|||
#include "Math/SHMath.h"
|
||||
#include "Command/SHCommandManager.h"
|
||||
#include "SHImGuiHelpers.hpp"
|
||||
#include "SH_API.h"
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
|
@ -23,308 +24,315 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
//#==============================================================#
|
||||
//|| Custom Widgets ||
|
||||
//#==============================================================#
|
||||
static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f)
|
||||
class SH_API SHEditorWidgets
|
||||
{
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
const ImGuiID id = window->GetID("##Splitter");
|
||||
ImRect bb;
|
||||
bb.Min = window->DC.CursorPos + (verticalSplit ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1));
|
||||
bb.Max = bb.Min + (verticalSplit ? ImVec2(thickness, splitterAxisSize) : ImVec2(splitterAxisSize, thickness));
|
||||
return ImGui::SplitterBehavior(bb, id, verticalSplit ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, minSize1, minSize2, 0.0f);
|
||||
}
|
||||
public:
|
||||
//#==============================================================#
|
||||
//|| Constructor ||
|
||||
//#==============================================================#
|
||||
SHEditorWidgets() = delete;
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
static bool DragN(const std::string& fieldLabel, std::vector<std::string>const& componentLabels,
|
||||
std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(),
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
const ImGuiContext& g = *GImGui;
|
||||
bool valueChanged = false;
|
||||
ImGui::BeginGroup();
|
||||
ImGui::PushID(fieldLabel.c_str());
|
||||
PushMultiItemsWidthsAndLabels(componentLabels, 0.0f);
|
||||
ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize);
|
||||
ImGui::SetColumnWidth(-1, 80.0f);
|
||||
ImGui::Text(fieldLabel.c_str());
|
||||
ImGui::NextColumn();
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
//#==============================================================#
|
||||
//|| Custom Widgets ||
|
||||
//#==============================================================#
|
||||
static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f)
|
||||
{
|
||||
ImGui::PushID(static_cast<int>(i));
|
||||
ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str())); ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(80.0f);
|
||||
valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags);
|
||||
|
||||
const ImVec2 min = ImGui::GetItemRectMin();
|
||||
const ImVec2 max = ImGui::GetItemRectMax();
|
||||
const float spacing = g.Style.FrameRounding;
|
||||
const float halfSpacing = spacing / 2;
|
||||
|
||||
window->DrawList->AddLine({ min.x + spacing, max.y - halfSpacing }, { max.x - spacing, max.y - halfSpacing },
|
||||
ImGuiColors::colors[i], 4);
|
||||
|
||||
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
ImGui::PopID();
|
||||
ImGui::PopItemWidth();
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
const ImGuiID id = window->GetID("##Splitter");
|
||||
ImRect bb;
|
||||
bb.Min = window->DC.CursorPos + (verticalSplit ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1));
|
||||
bb.Max = bb.Min + (verticalSplit ? ImVec2(thickness, splitterAxisSize) : ImVec2(splitterAxisSize, thickness));
|
||||
return ImGui::SplitterBehavior(bb, id, verticalSplit ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, minSize1, minSize2, 0.0f);
|
||||
}
|
||||
ImGui::EndColumns();
|
||||
ImGui::PopID();
|
||||
ImGui::EndGroup();
|
||||
|
||||
return valueChanged;
|
||||
}
|
||||
|
||||
static bool DragVec2(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec2(void)> get,
|
||||
std::function<void(SHVec2)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
SHVec2 values = get();
|
||||
bool changed = false;
|
||||
if (DragN<float, 2>(fieldLabel, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags))
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
static bool DragN(const std::string& fieldLabel, std::vector<std::string>const& componentLabels,
|
||||
std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(),
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DragVec3(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec3(void)> get,
|
||||
std::function<void(SHVec3)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
SHVec3 values = get();
|
||||
bool changed = false;
|
||||
if (DragN<float, 3>(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DragVec4(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec4(void)> get,
|
||||
std::function<void(SHVec4)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
SHVec4 values = get();
|
||||
bool changed = false;
|
||||
if (DragN<float, 4>(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
//#==============================================================#
|
||||
//|| Widget Extensions ||
|
||||
//#==============================================================#
|
||||
|
||||
static bool CheckBox(std::string const& label, std::function<bool(void)> get, std::function<void(bool const&)> set)
|
||||
{
|
||||
bool value = get();
|
||||
if (ImGui::Checkbox(label.c_str(), &value))
|
||||
{
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static bool RadioButton(std::vector<std::string> const& listLabels, std::vector<T> const& listTypes, std::function<T(void)> get, std::function<void(T const&)> set)
|
||||
{
|
||||
T type = get();
|
||||
for (size_t i = 0; i < listTypes.size(); i++)
|
||||
{
|
||||
if (ImGui::RadioButton(listLabels[i].c_str(), type == listTypes[i]))
|
||||
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
|
||||
const ImGuiContext& g = *GImGui;
|
||||
bool valueChanged = false;
|
||||
ImGui::BeginGroup();
|
||||
ImGui::PushID(fieldLabel.c_str());
|
||||
PushMultiItemsWidthsAndLabels(componentLabels, 0.0f);
|
||||
ImGui::BeginColumns("DragVecCol", 2, ImGuiOldColumnFlags_NoBorder | ImGuiOldColumnFlags_NoResize);
|
||||
ImGui::SetColumnWidth(-1, 80.0f);
|
||||
ImGui::Text(fieldLabel.c_str());
|
||||
ImGui::NextColumn();
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
{
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), listTypes[i], set)), false);
|
||||
ImGui::PushID(static_cast<int>(i));
|
||||
ImGui::TextUnformatted(componentLabels[i].c_str(), ImGui::FindRenderedTextEnd(componentLabels[i].c_str())); ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(80.0f);
|
||||
valueChanged |= ImGui::DragFloat("##v", values[i], speed, valueMin, valueMax, displayFormat, flags);
|
||||
|
||||
const ImVec2 min = ImGui::GetItemRectMin();
|
||||
const ImVec2 max = ImGui::GetItemRectMax();
|
||||
const float spacing = g.Style.FrameRounding;
|
||||
const float halfSpacing = spacing / 2;
|
||||
|
||||
window->DrawList->AddLine({ min.x + spacing, max.y - halfSpacing }, { max.x - spacing, max.y - halfSpacing },
|
||||
ImGuiColors::colors[i], 4);
|
||||
|
||||
ImGui::SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
ImGui::PopID();
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::EndColumns();
|
||||
ImGui::PopID();
|
||||
ImGui::EndGroup();
|
||||
|
||||
return valueChanged;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool InputText(const std::string& label, const std::function<std::string(void)> get,
|
||||
const std::function<void(std::string)> set, ImGuiInputTextFlags flag = 0,
|
||||
ImGuiInputTextCallback callback = (ImGuiInputTextCallback)0, void* userData = (void*)0)
|
||||
{
|
||||
std::string text = get();
|
||||
if (ImGui::InputText(label.c_str(), &text, flag, callback, userData))
|
||||
|
||||
static bool DragVec2(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec2(void)> get,
|
||||
std::function<void(SHVec2)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<std::string>>(get(), text, set)), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool DragScalar(const std::string& fieldLabel, ImGuiDataType data_type, std::function<T(void)> get, std::function<void(T const&)> set,
|
||||
float speed = 1.0f, T p_min = T(), T p_max = T(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
T value = get();
|
||||
std::cout << value <<" \n";
|
||||
//bool hasChange = ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags);
|
||||
|
||||
if (ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool DragFloat(const std::string& fieldLabel, std::function<float(void)> get, std::function<void(float const&)> set,
|
||||
float speed = 0.1f, float p_min = float(), float p_max = float(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
float value = get();
|
||||
//bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags);
|
||||
if (ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool DragInt(const std::string& fieldLabel, std::function<int(void)> get, std::function<void(int const&)> set,
|
||||
float speed = 1.0f, int p_min = int(), int p_max = int(), const char* displayFormat = "%d", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
int value = get();
|
||||
//bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags);
|
||||
if (ImGui::DragInt(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
template <typename T>
|
||||
static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function<T(void)> get, std::function<void(T const&)> set,
|
||||
const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
T value = get();
|
||||
if (ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||
SHVec2 values = get();
|
||||
bool changed = false;
|
||||
if (DragN<float, 2>(fieldLabel, componentLabels, { &values.x, &values.y }, speed, displayFormat, valueMin, valueMax, flags))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
|
||||
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec2>>(get(), values, set)), false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DragVec3(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec3(void)> get,
|
||||
std::function<void(SHVec3)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
SHVec3 values = get();
|
||||
bool changed = false;
|
||||
if (DragN<float, 3>(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec3>>(get(), values, set)), false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static bool DragVec4(const std::string& fieldLabel, std::vector<std::string>const& componentLabels, std::function<SHVec4(void)> get,
|
||||
std::function<void(SHVec4)> set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f,
|
||||
ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
SHVec4 values = get();
|
||||
bool changed = false;
|
||||
if (DragN<float, 4>(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHVec4>>(get(), values, set)), false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
//#==============================================================#
|
||||
//|| Widget Extensions ||
|
||||
//#==============================================================#
|
||||
|
||||
static bool CheckBox(std::string const& label, std::function<bool(void)> get, std::function<void(bool const&)> set)
|
||||
{
|
||||
bool value = get();
|
||||
if (ImGui::Checkbox(label.c_str(), &value))
|
||||
{
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<bool>>(get(), value, set)), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool SliderFloat(const std::string& fieldLabel, float min, float max, std::function<float(void)> get, std::function<void(float const&)> set,
|
||||
const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
float value = get();
|
||||
if (ImGui::SliderFloat(fieldLabel.c_str(), &value, min, max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool SliderInt(const std::string& fieldLabel, int min, int max, std::function<int(void)> get, std::function<void(int const&)> set,
|
||||
const char* displayFormat = "%d", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
int value = get();
|
||||
if (ImGui::SliderInt(fieldLabel.c_str(), &value, min, max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ComboBox(const std::string& fieldLabel, std::vector<const char*> list, std::function<int(void)> get, std::function<void(int const&)> set)
|
||||
{
|
||||
bool edited = false;
|
||||
int selected = get();
|
||||
ImGui::PushID(fieldLabel.c_str());
|
||||
ImGui::Text(fieldLabel.c_str()); ImGui::SameLine();
|
||||
|
||||
if (edited = ImGui::Combo("##Combo", &selected, list.data(), list.size()))
|
||||
template<typename T>
|
||||
static bool RadioButton(std::vector<std::string> const& listLabels, std::vector<T> const& listTypes, std::function<T(void)> get, std::function<void(T const&)> set)
|
||||
{
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), selected, set)), false);
|
||||
T type = get();
|
||||
for (size_t i = 0; i < listTypes.size(); i++)
|
||||
{
|
||||
if (ImGui::RadioButton(listLabels[i].c_str(), type == listTypes[i]))
|
||||
{
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), listTypes[i], set)), false);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
ImGui::PopID();
|
||||
return edited;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool InputText(const std::string& label, const std::function<std::string(void)> get,
|
||||
const std::function<void(std::string)> set, ImGuiInputTextFlags flag = 0,
|
||||
ImGuiInputTextCallback callback = (ImGuiInputTextCallback)0, void* userData = (void*)0)
|
||||
{
|
||||
std::string text = get();
|
||||
if (ImGui::InputText(label.c_str(), &text, flag, callback, userData))
|
||||
{
|
||||
if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<std::string>>(get(), text, set)), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool DragScalar(const std::string& fieldLabel, ImGuiDataType data_type, std::function<T(void)> get, std::function<void(T const&)> set,
|
||||
float speed = 1.0f, T p_min = T(), T p_max = T(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
T value = get();
|
||||
std::cout << value <<" \n";
|
||||
//bool hasChange = ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags);
|
||||
|
||||
if (ImGui::DragScalar(fieldLabel.c_str(), data_type, &value, speed, &p_min, &p_max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool DragFloat(const std::string& fieldLabel, std::function<float(void)> get, std::function<void(float const&)> set,
|
||||
float speed = 0.1f, float p_min = float(), float p_max = float(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
float value = get();
|
||||
//bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags);
|
||||
if (ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool DragInt(const std::string& fieldLabel, std::function<int(void)> get, std::function<void(int const&)> set,
|
||||
float speed = 1.0f, int p_min = int(), int p_max = int(), const char* displayFormat = "%d", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
int value = get();
|
||||
//bool hasChange = ImGui::DragFloat(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags);
|
||||
if (ImGui::DragInt(fieldLabel.c_str(), &value, speed, p_min, p_max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
|
||||
else if (ImGui::IsItemDeactivatedAfterEdit())
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
template <typename T>
|
||||
static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function<T(void)> get, std::function<void(T const&)> set,
|
||||
const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
T value = get();
|
||||
if (ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool SliderFloat(const std::string& fieldLabel, float min, float max, std::function<float(void)> get, std::function<void(float const&)> set,
|
||||
const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
float value = get();
|
||||
if (ImGui::SliderFloat(fieldLabel.c_str(), &value, min, max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<float>>(get(), value, set)), true);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool SliderInt(const std::string& fieldLabel, int min, int max, std::function<int(void)> get, std::function<void(int const&)> set,
|
||||
const char* displayFormat = "%d", ImGuiSliderFlags flags = 0)
|
||||
{
|
||||
int value = get();
|
||||
if (ImGui::SliderInt(fieldLabel.c_str(), &value, min, max, displayFormat, flags))
|
||||
{
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), false);
|
||||
else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), value, set)), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ComboBox(const std::string& fieldLabel, std::vector<const char*> list, std::function<int(void)> get, std::function<void(int const&)> set)
|
||||
{
|
||||
bool edited = false;
|
||||
int selected = get();
|
||||
ImGui::PushID(fieldLabel.c_str());
|
||||
ImGui::Text(fieldLabel.c_str()); ImGui::SameLine();
|
||||
|
||||
if (edited = ImGui::Combo("##Combo", &selected, list.data(), list.size()))
|
||||
{
|
||||
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<int>>(get(), selected, set)), false);
|
||||
}
|
||||
ImGui::PopID();
|
||||
return edited;
|
||||
}
|
||||
};
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -8,3 +8,5 @@ typedef uint32_t SHEventHandle;
|
|||
constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0};
|
||||
constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT{ 1 };
|
||||
constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT{ 2 };
|
||||
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT{ 3 };
|
||||
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT{ 4 };
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
|
||||
// Project Headers
|
||||
#include "SH_API.h"
|
||||
#include "Math/SHMath.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
#include "Math/SHMatrix.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <string>
|
||||
#include "SHSceneGraph.h"
|
||||
#include "ECS_Base/General/SHFamily.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -42,6 +43,7 @@ namespace SHADE
|
|||
virtual void Unload() = 0;
|
||||
};
|
||||
|
||||
template class SH_API SHFamilyID<SHScene>;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,8 @@ namespace SHADE
|
|||
{
|
||||
//prevSceneCreate = newScene;
|
||||
newScene = [sceneName]() { currentScene = new T(); currentScene->sceneName = sceneName; };
|
||||
nextSceneID = SHFamilyID<SHScene>::template GetID<T>();
|
||||
//nextSceneID = SHFamilyID<SHScene>::GetID<T>();
|
||||
nextSceneID = 0;
|
||||
|
||||
sceneChanged = true;
|
||||
}
|
||||
|
@ -101,13 +102,13 @@ namespace SHADE
|
|||
static std::enable_if_t<std::is_base_of_v<SHScene, T>, void> ChangeScene(std::string const& sceneName) noexcept
|
||||
{
|
||||
//check if this new Scene is current Scene (Use RestartScene instead)
|
||||
if (currentSceneID == SHFamilyID<SHScene>::template GetID<T>())
|
||||
if (currentSceneID == SHFamilyID<SHScene>::GetID<T>())
|
||||
{
|
||||
return;
|
||||
}
|
||||
//prevSceneCreate = newScene;
|
||||
newScene = [sceneName]() { currentScene = new T(); currentScene->sceneName; };
|
||||
nextSceneID = SHFamilyID<SHScene>::template GetID<T>();
|
||||
nextSceneID = SHFamilyID<SHScene>::GetID<T>();
|
||||
sceneChanged = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,22 +82,18 @@ namespace SHADE
|
|||
|
||||
void SHScriptEngine::Exit()
|
||||
{
|
||||
// Do not allow deinitialization if not initialised
|
||||
if (!dotNet.IsLoaded())
|
||||
{
|
||||
SHLOG_ERROR("[ScriptEngine] Attempted to clean up an unloaded DotNetRuntime.");
|
||||
return;
|
||||
}
|
||||
// Do not allow deinitialization if not initialised
|
||||
if (!dotNet.IsLoaded())
|
||||
{
|
||||
SHLOG_ERROR("[ScriptEngine] Attempted to clean up an unloaded DotNetRuntime.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Unlink events
|
||||
/*ECS::OnEntityCreated -= onEntityCreate;
|
||||
ECS::OnEntityDestroy -= onEntityDestroy;*/
|
||||
// Clean up the CSharp Engine
|
||||
csEngineExit();
|
||||
|
||||
// Clean up the CSharp Engine
|
||||
csEngineExit();
|
||||
|
||||
// Shut down the CLR
|
||||
dotNet.Exit();
|
||||
// Shut down the CLR
|
||||
dotNet.Exit();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -105,15 +101,15 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
bool SHScriptEngine::AddScript(EntityID entity, const std::string_view& scriptName)
|
||||
{
|
||||
return csScriptsAdd(entity, scriptName.data());
|
||||
return csScriptsAdd(entity, scriptName.data());
|
||||
}
|
||||
void SHScriptEngine::RemoveAllScripts(EntityID entity)
|
||||
{
|
||||
csScriptsRemoveAll(entity);
|
||||
csScriptsRemoveAll(entity);
|
||||
}
|
||||
void SHScriptEngine::RemoveAllScriptsImmediately(EntityID entity, bool callOnDestroy)
|
||||
{
|
||||
csScriptsRemoveAllImmediately(entity, callOnDestroy);
|
||||
csScriptsRemoveAllImmediately(entity, callOnDestroy);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -121,24 +117,24 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity) const
|
||||
{
|
||||
// Create buffer needed to store serialised script data
|
||||
constexpr int BUFFER_SIZE = 10240;
|
||||
std::unique_ptr<char> buffer { new char[BUFFER_SIZE] };
|
||||
std::memset(buffer.get(), 0, BUFFER_SIZE);
|
||||
// Create buffer needed to store serialised script data
|
||||
constexpr int BUFFER_SIZE = 10240;
|
||||
std::unique_ptr<char> buffer { new char[BUFFER_SIZE] };
|
||||
std::memset(buffer.get(), 0, BUFFER_SIZE);
|
||||
|
||||
// Attempt to serialise the script
|
||||
std::string result;
|
||||
if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE))
|
||||
{
|
||||
result = std::string(buffer.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts as string buffer is too small!");
|
||||
}
|
||||
// Attempt to serialise the script
|
||||
std::string result;
|
||||
if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE))
|
||||
{
|
||||
result = std::string(buffer.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts as string buffer is too small!");
|
||||
}
|
||||
|
||||
// Return an empty string since we failed to serialise
|
||||
return result;
|
||||
// Return an empty string since we failed to serialise
|
||||
return result;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -152,18 +148,24 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Script Editor Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void SHScriptEngine::RenderScriptsInInspector(const SHEntity& entity) const
|
||||
void SHScriptEngine::RenderScriptsInInspector(EntityID entity) const
|
||||
{
|
||||
csEditorRenderScripts(entity.GetEID());
|
||||
csEditorRenderScripts(entity);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Static Utility Functions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
bool SHScriptEngine::BuildScriptAssembly(bool debug) const
|
||||
bool SHScriptEngine::BuildScriptAssembly(bool debug, bool reload)
|
||||
{
|
||||
static const std::string BUILD_LOG_PATH = "../Build.log";
|
||||
|
||||
// Unload if we need to reload
|
||||
if (reload)
|
||||
{
|
||||
UnloadScriptAssembly();
|
||||
}
|
||||
|
||||
// Generate csproj file if it doesn't exist
|
||||
if (!std::filesystem::exists(CSPROJ_PATH))
|
||||
{
|
||||
|
@ -209,6 +211,12 @@ namespace SHADE
|
|||
// Delete the build log file since we no longer need it
|
||||
deleteFile(BUILD_LOG_PATH);
|
||||
|
||||
// If reloading, we need to load
|
||||
if (reload)
|
||||
{
|
||||
LoadScriptAssembly();
|
||||
}
|
||||
|
||||
return BUILD_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -255,7 +263,7 @@ namespace SHADE
|
|||
// Attempt to create the file
|
||||
std::ofstream file(path);
|
||||
if (!file.is_open())
|
||||
throw std::runtime_error("Unable to create CsProj file!");
|
||||
throw std::runtime_error("Unable to create CsProj file!");
|
||||
|
||||
// Fill the file
|
||||
file << FILE_CONTENTS;
|
||||
|
@ -269,9 +277,9 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr)
|
||||
{
|
||||
auto eventData = reinterpret_cast<const SHEventSpec<SHEntityDestroyedEvent>*>(eventPtr.get());
|
||||
csScriptsRemoveAll(eventData->data->eid);
|
||||
return eventData->handle;
|
||||
auto eventData = reinterpret_cast<const SHEventSpec<SHEntityDestroyedEvent>*>(eventPtr.get());
|
||||
csScriptsRemoveAll(eventData->data->eid);
|
||||
return eventData->handle;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -385,13 +393,13 @@ namespace SHADE
|
|||
DEFAULT_CSHARP_LIB_NAME,
|
||||
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||
"SerialiseScriptsYaml"
|
||||
);
|
||||
);*/
|
||||
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
|
||||
(
|
||||
DEFAULT_CSHARP_LIB_NAME,
|
||||
DEFAULT_CSHARP_NAMESPACE + ".Editor",
|
||||
"RenderScriptsInInspector"
|
||||
);*/
|
||||
);
|
||||
}
|
||||
|
||||
void SHScriptEngine::registerEvents()
|
||||
|
|
|
@ -170,7 +170,7 @@ namespace SHADE
|
|||
/// rendering code.
|
||||
/// </summary>
|
||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||
void RenderScriptsInInspector(const SHEntity& entity) const;
|
||||
void RenderScriptsInInspector(EntityID entity) const;
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Static Utility Functions */
|
||||
|
@ -184,13 +184,16 @@ namespace SHADE
|
|||
/// Whether or not a debug build will be built. Only debug built C# assemblies
|
||||
/// can be debugged.
|
||||
/// </param>
|
||||
/// <param name="reload">
|
||||
/// Whether or not we are reloading the assembly, if so, unload and then reload it.
|
||||
/// </param>
|
||||
/// <returns>Whether or not the build succeeded.</returns>
|
||||
bool BuildScriptAssembly(bool debug = false) const;
|
||||
bool BuildScriptAssembly(bool debug = false, bool reload = false);
|
||||
/// <summary>
|
||||
/// Generates a .csproj file for editing and compiling the C# scripts.
|
||||
/// </summary>
|
||||
/// <param name="path">File path to the generated file.</param>
|
||||
void GenerateScriptsCsProjFile(const std::filesystem::path& path) const;
|
||||
void GenerateScriptsCsProjFile(const std::filesystem::path& path = CSPROJ_PATH) const;
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -33,6 +33,11 @@ project "SHADE_Managed"
|
|||
"%{IncludeDir.RTTR}/include",
|
||||
"%{wks.location}/SHADE_Engine/src"
|
||||
}
|
||||
|
||||
libdirs
|
||||
{
|
||||
"%{IncludeDir.RTTR}/lib"
|
||||
}
|
||||
|
||||
links
|
||||
{
|
||||
|
@ -68,7 +73,9 @@ project "SHADE_Managed"
|
|||
filter "configurations:Debug"
|
||||
symbols "On"
|
||||
defines {"_DEBUG"}
|
||||
links{"librttr_core_d.lib"}
|
||||
|
||||
filter "configurations:Release"
|
||||
optimize "On"
|
||||
defines{"_RELEASE"}
|
||||
links{"librttr_core.lib"}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/************************************************************************************//*!
|
||||
\file Transform.cxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 23, 2022
|
||||
\brief Contains the definition of the functions of the managed Transform class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Headers
|
||||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "Transform.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Properties */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
Vector3 Transform::LocalPosition::get()
|
||||
{
|
||||
return Convert::ToCLI(GetNativeComponent()->GetLocalPosition());
|
||||
}
|
||||
void Transform::LocalPosition::set(Vector3 val)
|
||||
{
|
||||
GetNativeComponent()->SetLocalPosition(Convert::ToNative(val));
|
||||
}
|
||||
Vector3 Transform::LocalRotation::get()
|
||||
{
|
||||
return Convert::ToCLI(GetNativeComponent()->GetLocalRotation());
|
||||
}
|
||||
void Transform::LocalRotation::set(Vector3 val)
|
||||
{
|
||||
GetNativeComponent()->SetLocalRotation(Convert::ToNative(val));
|
||||
}
|
||||
Vector3 Transform::LocalScale::get()
|
||||
{
|
||||
return Convert::ToCLI(GetNativeComponent()->GetLocalScale());
|
||||
|
||||
}
|
||||
void Transform::LocalScale::set(Vector3 val)
|
||||
{
|
||||
GetNativeComponent()->SetLocalScale(Convert::ToNative(val));
|
||||
}
|
||||
Vector3 Transform::GlobalPosition::get()
|
||||
{
|
||||
return Convert::ToCLI(GetNativeComponent()->GetWorldPosition());
|
||||
}
|
||||
void Transform::GlobalPosition::set(Vector3 val)
|
||||
{
|
||||
GetNativeComponent()->SetWorldPosition(Convert::ToNative(val));
|
||||
}
|
||||
Vector3 Transform::GlobalRotation::get()
|
||||
{
|
||||
return Convert::ToCLI(GetNativeComponent()->GetWorldRotation());
|
||||
}
|
||||
void Transform::GlobalRotation::set(Vector3 val)
|
||||
{
|
||||
GetNativeComponent()->SetWorldRotation(Convert::ToNative(val));
|
||||
}
|
||||
Vector3 Transform::GlobalScale::get()
|
||||
{
|
||||
return Convert::ToCLI(GetNativeComponent()->GetWorldScale());
|
||||
|
||||
}
|
||||
void Transform::GlobalScale::set(Vector3 val)
|
||||
{
|
||||
GetNativeComponent()->SetWorldScale(Convert::ToNative(val));
|
||||
}
|
||||
Transform^ Transform::Parent::get()
|
||||
{
|
||||
auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(owner.GetEntity());
|
||||
if (!node)
|
||||
throw gcnew System::InvalidOperationException("[Transform] Unable to retrieve SceneGraphNode for an Entity.");
|
||||
|
||||
const auto PARENT = node->GetParent();
|
||||
return PARENT ? gcnew Transform(PARENT->GetEntityID()) : nullptr;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
Transform::Transform(Entity entity)
|
||||
: Component(entity)
|
||||
{}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void Transform::SetParent(Transform^ parent, bool worldPositionStays)
|
||||
{
|
||||
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
auto node = sceneGraph.GetNode(owner.GetEntity());
|
||||
if (!node)
|
||||
throw gcnew System::InvalidOperationException("[Transform] Unable to retrieve SceneGraphNode for an Entity.");
|
||||
|
||||
if (parent)
|
||||
node->SetParent(sceneGraph.GetNode(parent->owner.GetEntity()));
|
||||
else
|
||||
sceneGraph.SetParent(parent->owner.GetEntity(), nullptr);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/************************************************************************************//*!
|
||||
\file Transform.hxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 23, 2022
|
||||
\brief Contains the definition of the managed Transform class with the
|
||||
declaration of functions for working with it.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
// Project Includes
|
||||
#include "Components/Component.hxx"
|
||||
#include "Math/Vector3.hxx"
|
||||
#include "Utility/Convert.hxx"
|
||||
// External Dependencies
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// CLR version of the the SHADE Engine's TransformComponent.
|
||||
/// </summary>
|
||||
public ref class Transform : public Component<SHTransformComponent>
|
||||
{
|
||||
internal:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Constructors */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Constructs a Transform Component that represents a native Transform component
|
||||
/// tied to the specified Entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">Entity that this Component will be tied to.</param>
|
||||
Transform(Entity entity);
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Properties */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Local position stored by this Transform.
|
||||
/// </summary>
|
||||
property Vector3 LocalPosition
|
||||
{
|
||||
Vector3 get();
|
||||
void set(Vector3 val);
|
||||
}
|
||||
/// <summary>
|
||||
/// Local Z-axis rotation angle stored by this Transform in Radians.
|
||||
/// </summary>
|
||||
property Vector3 LocalRotation
|
||||
{
|
||||
Vector3 get();
|
||||
void set(Vector3 val);
|
||||
}
|
||||
/// <summary>
|
||||
/// Local scale stored by this Transform.
|
||||
/// </summary>
|
||||
property Vector3 LocalScale
|
||||
{
|
||||
Vector3 get();
|
||||
void set(Vector3 val);
|
||||
}
|
||||
/// <summary>
|
||||
/// Global position stored by this Transform.
|
||||
/// </summary>
|
||||
property Vector3 GlobalPosition
|
||||
{
|
||||
Vector3 get();
|
||||
void set(Vector3 val);
|
||||
}
|
||||
/// <summary>
|
||||
/// Global Z-axis rotation angle stored by this Transform in Radians.
|
||||
/// </summary>
|
||||
property Vector3 GlobalRotation
|
||||
{
|
||||
Vector3 get();
|
||||
void set(Vector3 val);
|
||||
}
|
||||
/// <summary>
|
||||
/// Global scale stored by this Transform.
|
||||
/// Note that this operation is expensive.
|
||||
/// </summary>
|
||||
property Vector3 GlobalScale
|
||||
{
|
||||
Vector3 get();
|
||||
void set(Vector3 val);
|
||||
}
|
||||
/// <summary>
|
||||
/// Parent Transform that affects this Transform.
|
||||
/// </summary>
|
||||
property Transform^ Parent
|
||||
{
|
||||
Transform^ get();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Usage Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Sets the parent of this Transform component.
|
||||
/// </summary>
|
||||
/// <param name="parent">
|
||||
/// Entity that contains the Transform component that this Transform will be
|
||||
/// parented to. If null, unparenting will occur.
|
||||
/// </param>
|
||||
/// <param name="worldPositionStays">
|
||||
/// If true, the transform values of this Transform component will retain their
|
||||
/// pre-parent-change global transforms. The local transform values will be
|
||||
/// modified to ensure that the global transforms do not change.
|
||||
/// </param>
|
||||
void SetParent(Transform^ parent, bool worldPositionStays);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
/************************************************************************************//*!
|
||||
\file Editor.cxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 27, 2022
|
||||
\brief Contains the definition of the functions for the ScriptStore managed
|
||||
static class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
// Precompiled Headers
|
||||
#include "SHpch.h"
|
||||
// Primary Header
|
||||
#include "Editor/Editor.hxx"
|
||||
// External Dependencies
|
||||
#include "Editor/SHEditorUI.h"
|
||||
// Project Headers
|
||||
#include "Components/Component.hxx"
|
||||
#include "Scripts/ScriptStore.hxx"
|
||||
#include "Utility/Convert.hxx"
|
||||
#include "Utility/Debug.hxx"
|
||||
#include "Serialisation/ReflectionUtilities.hxx"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
|
||||
// Using Directives
|
||||
using namespace System;
|
||||
using namespace System::Collections::Generic;
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/* Macro Functions */
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Macro expansion that is used in renderFieldInInspector() to check the type of a field
|
||||
/// named "field" against the specified type and if it matches, retrieves the value of
|
||||
/// that field from an object named "object" and pass it into the specified SHEditorUI::
|
||||
/// function named "FUNC" by casting it into the NATIVE_TYPE specified.
|
||||
/// <br/>
|
||||
/// This only works for primitive types that have the same types for managed and native.
|
||||
/// </summary>
|
||||
/// <param name="MANAGED_TYPE">The managed type of the object to edit.</param>
|
||||
/// <param name="NATIVE_TYPE">The native type of the object to edit.</param>
|
||||
/// <param name="FUNC">The SHEditorUI:: function to use for editing.</param>
|
||||
#define RENDER_FIELD(MANAGED_TYPE, NATIVE_TYPE, FUNC) \
|
||||
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||
{ \
|
||||
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
|
||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
|
||||
{ \
|
||||
field->SetValue(object, val); \
|
||||
} \
|
||||
} \
|
||||
/// <summary>
|
||||
/// Macro expansion that is used in renderFieldInInspector() to check the type of a field
|
||||
/// named "field" against the specified type and if it matches, retrieves the value of
|
||||
/// that field from an object named "object" and pass it into the specified SHEditorUI::
|
||||
/// function named "FUNC" by casting it into the NATIVE_TYPE specified.
|
||||
/// <br/>
|
||||
/// This only works for types that have an implementation of Convert::ToNative and
|
||||
/// Convert::ToCLI.
|
||||
/// </summary>
|
||||
/// <param name="MANAGED_TYPE">The managed type of the object to edit.</param>
|
||||
/// <param name="NATIVE_TYPE">The native type of the object to edit.</param>
|
||||
/// <param name="FUNC">The SHEditorUI:: function to use for editing.</param>
|
||||
#define RENDER_FIELD_CASTED(MANAGED_TYPE, NATIVE_TYPE, FUNC) \
|
||||
(field->FieldType == MANAGED_TYPE::typeid) \
|
||||
{ \
|
||||
NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \
|
||||
if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
|
||||
{ \
|
||||
field->SetValue(object, Convert::ToCLI(val)); \
|
||||
} \
|
||||
} \
|
||||
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
/* Function Definitions */
|
||||
/*-------------------------------------------------------------------------------------*/
|
||||
namespace SHADE
|
||||
{
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Script Rendering Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void Editor::RenderScriptsInInspector(Entity entity)
|
||||
{
|
||||
SAFE_NATIVE_CALL_BEGIN
|
||||
// Get scripts
|
||||
IEnumerable<Script^>^ scripts = ScriptStore::GetAllScripts(entity);
|
||||
|
||||
// Skip if no scripts
|
||||
if (scripts != nullptr)
|
||||
{
|
||||
// Display each script if any
|
||||
int index = 0;
|
||||
for each (Script^ script in scripts)
|
||||
{
|
||||
renderScriptInInspector(entity, script, index++);
|
||||
}
|
||||
}
|
||||
|
||||
// Render Add Script
|
||||
RenderScriptAddButton(entity);
|
||||
SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.RenderScriptsInInspector")
|
||||
}
|
||||
|
||||
void Editor::RenderScriptAddButton(Entity entity)
|
||||
{
|
||||
// Get list of Scripts
|
||||
auto scriptTypes = ScriptStore::GetAvailableScriptList();
|
||||
|
||||
// Define pop up
|
||||
if (SHEditorUI::BeginMenu("Add Script", ICON_MD_LIBRARY_ADD))
|
||||
{
|
||||
for each (Type ^ type in scriptTypes)
|
||||
{
|
||||
if (SHEditorUI::Selectable(Convert::ToNative(type->Name)))
|
||||
{
|
||||
// Add the script
|
||||
ScriptStore::AddScriptViaName(entity, type->Name);
|
||||
}
|
||||
}
|
||||
|
||||
SHEditorUI::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
void Editor::renderScriptInInspector(Entity entity, Script^ script, int index)
|
||||
{
|
||||
// Constants
|
||||
const std::string LABEL = Convert::ToNative(script->GetType()->Name);
|
||||
|
||||
// Header
|
||||
SHEditorUI::PushID(index);
|
||||
if (SHEditorUI::CollapsingHeader(LABEL))
|
||||
{
|
||||
SHEditorUI::PushID(LABEL);
|
||||
SHEditorUI::Indent();
|
||||
{
|
||||
// Right Click Menu
|
||||
renderScriptContextMenu(entity, script);
|
||||
|
||||
// Go through all fields and output them
|
||||
auto fields = ReflectionUtilities::GetInstanceFields(script);
|
||||
int id = 0;
|
||||
for each (auto field in fields)
|
||||
{
|
||||
// Ignore non-serialisable fields
|
||||
if (!ReflectionUtilities::FieldIsSerialisable(field))
|
||||
continue;
|
||||
|
||||
// Render the input field for this field
|
||||
SHEditorUI::PushID(LABEL + std::to_string(id++));
|
||||
renderFieldInInspector(field, script);
|
||||
SHEditorUI::PopID();
|
||||
}
|
||||
|
||||
}
|
||||
SHEditorUI::Unindent();
|
||||
SHEditorUI::PopID();
|
||||
}
|
||||
else
|
||||
{
|
||||
renderScriptContextMenu(entity, script);
|
||||
}
|
||||
SHEditorUI::PopID();
|
||||
}
|
||||
void Editor::renderFieldInInspector(Reflection::FieldInfo^ field, Object^ object)
|
||||
{
|
||||
if RENDER_FIELD (Int16, int, InputInt)
|
||||
else if RENDER_FIELD (Int32, int, InputInt)
|
||||
else if RENDER_FIELD (Int64, int, InputInt)
|
||||
else if RENDER_FIELD (UInt16, unsigned int, InputUnsignedInt)
|
||||
else if RENDER_FIELD (UInt32, unsigned int, InputUnsignedInt)
|
||||
else if RENDER_FIELD (UInt64, unsigned int, InputUnsignedInt)
|
||||
else if RENDER_FIELD (Byte, int, InputInt)
|
||||
else if RENDER_FIELD (bool, bool, InputCheckbox)
|
||||
else if RENDER_FIELD (float, float, InputFloat)
|
||||
else if RENDER_FIELD (double, double, InputDouble)
|
||||
else if (field->FieldType->IsSubclassOf(Enum::typeid))
|
||||
{
|
||||
// Get all the names of the enums
|
||||
const array<String^>^ ENUM_NAMES = field->FieldType->GetEnumNames();
|
||||
std::vector<std::string> nativeEnumNames;
|
||||
for each (String^ str in ENUM_NAMES)
|
||||
{
|
||||
nativeEnumNames.emplace_back(Convert::ToNative(str));
|
||||
}
|
||||
|
||||
int val = safe_cast<int>(field->GetValue(object));
|
||||
if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames))
|
||||
{
|
||||
field->SetValue(object, val);
|
||||
}
|
||||
}
|
||||
else if RENDER_FIELD_CASTED(Vector2, SHVec2, InputVec2)
|
||||
else if RENDER_FIELD_CASTED(Vector3, SHVec3, InputVec3)
|
||||
else if (field->FieldType == String::typeid)
|
||||
{
|
||||
// Prevent issues where String^ is null due to being empty
|
||||
String^ stringVal = safe_cast<String^>(field->GetValue(object));
|
||||
if (stringVal == nullptr)
|
||||
{
|
||||
stringVal = "";
|
||||
}
|
||||
|
||||
// Actual Field
|
||||
std::string val = Convert::ToNative(stringVal);
|
||||
if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val))
|
||||
{
|
||||
field->SetValue(object, Convert::ToCLI(val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::renderScriptContextMenu(Entity entity, Script^ script)
|
||||
{
|
||||
// Right Click Menu
|
||||
if (SHEditorUI::BeginPopupContextItem("scriptContextMenu"))
|
||||
{
|
||||
if (SHEditorUI::Selectable("Delete Script", ICON_MD_DELETE))
|
||||
{
|
||||
// Mark script for removal
|
||||
ScriptStore::RemoveScript(entity, script);
|
||||
}
|
||||
SHEditorUI::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/************************************************************************************//*!
|
||||
\file Editor.hxx
|
||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||
\par email: kahwei.tng\@digipen.edu
|
||||
\date Sep 27, 2022
|
||||
\brief Contains the definition of the managed Editor static class.
|
||||
|
||||
Note: This file is written in C++17/CLI.
|
||||
|
||||
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||
of DigiPen Institute of Technology is prohibited.
|
||||
*//*************************************************************************************/
|
||||
#pragma once
|
||||
|
||||
// Project Includes
|
||||
#include "Engine/Entity.hxx"
|
||||
#include "Scripts/Script.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class for Editor-related functions
|
||||
/// </summary>
|
||||
public ref class Editor abstract sealed
|
||||
{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Script Rendering Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Renders the set of attached Scripts for the specified Entity into the
|
||||
/// inspector.
|
||||
/// <br/>
|
||||
/// This function is meant for consumption from native code in the inspector
|
||||
/// rendering code.
|
||||
/// </summary>
|
||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||
static void RenderScriptsInInspector(Entity entity);
|
||||
/// <summary>
|
||||
/// Renders a dropdown button that allows for the addition of PlushieScripts
|
||||
/// onto the specified Entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The Entity to add PlushieScripts to.</param>
|
||||
static void RenderScriptAddButton(Entity entity);
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Helper Functions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Renders a single specified Script's inspector.
|
||||
/// </summary>
|
||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||
/// <param name="script">The Script to render the inspector for.</param>
|
||||
/// <param name="index">
|
||||
/// Indices used internally to differentiate each rendered Script
|
||||
/// inspector. This is required to open and close each Script's inspector
|
||||
/// independently from each other.
|
||||
/// </param>
|
||||
static void renderScriptInInspector(Entity entity, Script^ script, int index);
|
||||
/// <summary>
|
||||
/// Renders a field specified into the inspector.
|
||||
/// </summary>
|
||||
/// <param name="field">The field to render.</param>
|
||||
/// <param name="object">
|
||||
/// The object that contains the data of the field to render.
|
||||
/// </param>
|
||||
static void renderFieldInInspector(System::Reflection::FieldInfo^ field, Object^ object);
|
||||
/// <summary>
|
||||
/// Renders a context menu when right clicked for the scripts
|
||||
/// </summary>
|
||||
/// <param name="entity">The Entity to render the Scripts of.</param>
|
||||
/// <param name="script">The Script to render the inspector for.</param>
|
||||
static void renderScriptContextMenu(Entity entity, Script^ script);
|
||||
};
|
||||
}
|
|
@ -21,12 +21,14 @@ of DigiPen Institute of Technology is prohibited.
|
|||
#include <msclr\marshal_cppstd.h>
|
||||
// External Dependencies
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
#include "Scene/SHSceneManager.h"
|
||||
#include "Scene/SHSceneGraph.h"
|
||||
#include "Tools/SHLog.h"
|
||||
// Project Headers
|
||||
#include "Utility/Convert.hxx"
|
||||
#include "Utility/Debug.hxx"
|
||||
#include "Components/Transform.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -239,8 +241,7 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
static ECS::ECS()
|
||||
{
|
||||
// TODO
|
||||
// componentMap.Add(createComponentSet<Transform, Transform>());
|
||||
componentMap.Add(createComponentSet<SHTransformComponent, Transform>());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -28,15 +28,8 @@ namespace SHADE
|
|||
template <typename NativeComponent>
|
||||
NativeComponent* ECS::GetNativeComponent(Entity entity)
|
||||
{
|
||||
// Get native Entity
|
||||
SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity);
|
||||
|
||||
// Entity Validity Check
|
||||
if (nativeEntity == nullptr)
|
||||
throw gcnew System::InvalidOperationException("Attempted to get native Component to an invalid Entity.");
|
||||
|
||||
// Null Check
|
||||
NativeComponent* component = SHComponentManager::GetComponent_s<NativeComponent>(nativeEntity);
|
||||
NativeComponent* component = SHComponentManager::GetComponent_s<NativeComponent>(entity);
|
||||
if (component == nullptr)
|
||||
throw gcnew System::NullReferenceException("Attempted to get a native Component that does not exist.");
|
||||
|
||||
|
@ -52,7 +45,6 @@ namespace SHADE
|
|||
{
|
||||
ManagedType::typeid,
|
||||
SHComponentManager::AddComponent<NativeType>,
|
||||
SHComponentManager::EnsureComponent<NativeType>,
|
||||
SHComponentManager::HasComponent<NativeType>,
|
||||
SHComponentManager::RemoveComponent<NativeType>
|
||||
};
|
||||
|
|
|
@ -99,8 +99,8 @@ namespace SHADE
|
|||
/// <summary>
|
||||
/// Pointer to a function for Component manipulation operations.
|
||||
/// </summary>
|
||||
using ComponentFunc = void(*)(const EntityID&);
|
||||
using ComponentHasFunc = bool(*)(const EntityID&);
|
||||
using ComponentFunc = void(*)(EntityID) noexcept;
|
||||
using ComponentHasFunc = bool(*)(EntityID) noexcept;
|
||||
/// <summary>
|
||||
/// Contains a set of Component related data used for resolving operations for
|
||||
/// each Component.
|
||||
|
@ -108,11 +108,10 @@ namespace SHADE
|
|||
value struct ComponentSet
|
||||
{
|
||||
public:
|
||||
System::Type^ Type;
|
||||
System::Type^ Type;
|
||||
ComponentFunc AddFunction;
|
||||
ComponentHasFunc HasFunction;
|
||||
ComponentFunc RemoveFunction;
|
||||
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -17,8 +17,8 @@ of DigiPen Institute of Technology is prohibited.
|
|||
// Primary Header
|
||||
#include "Convert.hxx"
|
||||
// External Dependencies
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
#include <msclr/marshal_cppstd.h>
|
||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -30,6 +30,32 @@ namespace SHADE
|
|||
return static_cast<Entity>(entity.GetEID());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Math Conversions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
SHVec3 Convert::ToNative(Vector3 vec)
|
||||
{
|
||||
const double X = vec.x;
|
||||
const double Y = vec.y;
|
||||
const double Z = vec.z;
|
||||
return SHVec3(X, Y, Z);
|
||||
}
|
||||
Vector3 Convert::ToCLI(const SHVec3& vec)
|
||||
{
|
||||
return Vector3(vec.x, vec.y, vec.z);
|
||||
}
|
||||
SHVec2 Convert::ToNative(Vector2 vec)
|
||||
{
|
||||
const double X = vec.x;
|
||||
const double Y = vec.y;
|
||||
return SHVec2(X, Y);
|
||||
}
|
||||
|
||||
Vector2 Convert::ToCLI(const SHVec2& vec)
|
||||
{
|
||||
return Vector2(vec.x, vec.y);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* String Conversions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -16,8 +16,12 @@ of DigiPen Institute of Technology is prohibited.
|
|||
|
||||
// External Dependencies
|
||||
#include "ECS_Base/Entity/SHEntity.h"
|
||||
#include "Math/Vector/SHVec2.h"
|
||||
#include "Math/Vector/SHVec3.h"
|
||||
// Project Includes
|
||||
#include "Engine/Entity.hxx"
|
||||
#include "Math/Vector2.hxx"
|
||||
#include "Math/Vector3.hxx"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -43,6 +47,34 @@ namespace SHADE
|
|||
/// <returns>Managed representation of the specified Entity.</returns>
|
||||
static Entity ToCLI(SHEntity entity);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Math Conversions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Converts from a managed Vector3 to a native Vector3.
|
||||
/// </summary>
|
||||
/// <param name="vec">The managed Vector3 to convert from.</param>
|
||||
/// <returns>Native copy of a managed Vector3.</returns>
|
||||
static SHVec3 ToNative(Vector3 vec);
|
||||
/// <summary>
|
||||
/// Converts from a native Vector3 to a managed Vector3.
|
||||
/// </summary>
|
||||
/// <param name="vec">The native Vector3 to convert from.</param>
|
||||
/// <returns>Managed copy of a native Vector3.</returns>
|
||||
static Vector3 ToCLI(const SHVec3& vec);
|
||||
/// <summary>
|
||||
/// Converts from a managed Vector2 to a native Vector2.
|
||||
/// </summary>
|
||||
/// <param name="vec">The managed Vector2 to convert from.</param>
|
||||
/// <returns>Native copy of a managed Vector2.</returns>
|
||||
static SHVec2 ToNative(Vector2 vec);
|
||||
/// <summary>
|
||||
/// Converts from a native Vector2 to a managed Vector2.
|
||||
/// </summary>
|
||||
/// <param name="vec">The native Vector2 to convert from.</param>
|
||||
/// <returns>Managed copy of a native Vector2.</returns>
|
||||
static Vector2 ToCLI(const SHVec2& vec);
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* String Conversions */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
using SHADE;
|
||||
using System;
|
||||
|
||||
public class RaccoonShowcase : Script
|
||||
{
|
||||
public double RotateSpeed = 1.0;
|
||||
public Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0);
|
||||
private Transform Transform;
|
||||
private double rotation = 0.0;
|
||||
private Vector3 scale = Vector3.Zero;
|
||||
private double originalScale = 1.0f;
|
||||
public RaccoonShowcase(GameObject gameObj) : base(gameObj) {}
|
||||
|
||||
protected override void awake()
|
||||
{
|
||||
Transform = GetComponent<Transform>();
|
||||
if (Transform == null)
|
||||
{
|
||||
Debug.LogError("Transform is NULL!");
|
||||
}
|
||||
|
||||
originalScale = Transform.LocalScale.z;
|
||||
}
|
||||
protected override void update()
|
||||
{
|
||||
rotation += RotateSpeed * 0.16;
|
||||
scale += ScaleSpeed * 0.16;
|
||||
Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f);
|
||||
Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using SHADE;
|
||||
using System;
|
||||
|
||||
public class RaccoonSpin : Script
|
||||
{
|
||||
public double RotateSpeed = 1.0;
|
||||
private double rotation = 0.0;
|
||||
private Transform Transform;
|
||||
public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
|
||||
|
||||
protected override void awake()
|
||||
{
|
||||
Transform = GetComponent<Transform>();
|
||||
if (Transform == null)
|
||||
{
|
||||
Debug.LogError("Transform is NULL!");
|
||||
}
|
||||
}
|
||||
protected override void update()
|
||||
{
|
||||
rotation += RotateSpeed * 0.16;
|
||||
Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f);
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
using SHADE;
|
||||
|
||||
public class TestScript : Script
|
||||
{
|
||||
public TestScript(GameObject gameObj) : base(gameObj) {}
|
||||
|
||||
protected override void awake()
|
||||
{
|
||||
Debug.Log("TestScript.Awake()");
|
||||
}
|
||||
protected override void start()
|
||||
{
|
||||
Debug.Log("TestScript.Start()");
|
||||
}
|
||||
protected override void update()
|
||||
{
|
||||
Debug.Log("TestScript.Update()");
|
||||
}
|
||||
protected override void onDestroy()
|
||||
{
|
||||
Debug.Log("TestScript.OnDestroy()");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue