From e027318d22dbc5682a0ea116762734e03290d5bc Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Fri, 14 Oct 2022 14:35:09 +0800 Subject: [PATCH] Inspector View - Collider Component --- .../Inspector/SHEditorComponentView.hpp | 138 ++++++--- .../Inspector/SHEditorInspector.cpp | 22 +- SHADE_Engine/src/Editor/SHEditor.cpp | 2 +- SHADE_Engine/src/Editor/SHEditorWidgets.hpp | 278 ++++++++++++------ 4 files changed, 311 insertions(+), 129 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index a546504b..93f6984e 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -12,19 +12,20 @@ #include "Editor/IconsMaterialDesign.h" #include "ECS_Base/Components/SHComponent.h" #include "Editor/SHEditorWidgets.hpp" +#include "Physics/Components/SHColliderComponent.h" #include "Reflection/SHReflectionMetadata.h" namespace SHADE { template::value, bool> = true> static void DrawContextMenu(T* component) { - if(!component) + if (!component) return; rttr::string_view componentName = rttr::type::get().get_name(); if (ImGui::BeginPopupContextItem(componentName.data())) { - + if (ImGui::Selectable(std::format("{} Copy {}", ICON_MD_CONTENT_COPY, componentName.data()).data())) { //SHClipboardUtil::WriteStringToClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT, SHComponentToString(component)); @@ -45,7 +46,7 @@ namespace SHADE { if (!component) return; - auto componentType = rttr::type::get(*component); + const auto componentType = rttr::type::get(*component); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }); ImGui::SameLine(); if (ImGui::CollapsingHeader(componentType.get_name().data())) @@ -56,26 +57,26 @@ namespace SHADE { auto const& type = property.get_type(); - if(type.is_enumeration()) + if (type.is_enumeration()) { auto enumAlign = type.get_enumeration(); auto names = enumAlign.get_names(); std::vector list; - for(auto const& name : names) + for (auto const& name : names) list.push_back(name.data()); - 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(); - auto it = std::next(values.begin(), idx); - property.set_value(component, *it); - }); + 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(); + auto it = std::next(values.begin(), idx); + property.set_value(component, *it); + }); } - else if(type.is_arithmetic()) + else if (type.is_arithmetic()) { if (type == rttr::type::get()) { - 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);}); + 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()) //{ @@ -85,39 +86,39 @@ namespace SHADE { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin && metaMax) + if (metaMin && metaMax) { - SHEditorWidgets::SliderInt(property.get_name().data(), metaMin.template get_value(), metaMin.template get_value(), [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(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_int(); }, [component, property](int const& result) {property.set_value(component, result); }); } else { - 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);}); + 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()) { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin.is_valid() && metaMax.is_valid()) + if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value(), metaMax.template get_value(), [component, property]{return property.get_value(component).to_uint8();}, [component, property](uint8_t const& result){property.set_value(component, result);},"%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U8, metaMin.template get_value(), metaMax.template get_value(), [component, property] {return property.get_value(component).to_uint8(); }, [component, property](uint8_t const& result) {property.set_value(component, result); }, "%zu"); } else { - SHEditorWidgets::DragScalar(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(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()) { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin.is_valid() && metaMax.is_valid()) + if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_uint16();}, [component, property](uint16_t const& result){property.set_value(component, result);},"%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U16, metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_uint16(); }, [component, property](uint16_t const& result) {property.set_value(component, result); }, "%zu"); } else { - SHEditorWidgets::DragScalar(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(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()) @@ -126,50 +127,50 @@ namespace SHADE auto metaMax = property.get_metadata(META::max); if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value(), metaMin.template get_value(), [component, property]{ return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result){property.set_value(component, result); },"%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U32, metaMin.template get_value(), metaMin.template get_value(), [component, property] { return property.get_value(component).to_uint32(); }, [component, property](uint32_t const& result) {property.set_value(component, result); }, "%zu"); } else { - SHEditorWidgets::DragScalar(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(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()) { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin.is_valid() && metaMax.is_valid()) + if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_uint64();}, [component, property](uint64_t const& result){property.set_value(component, result);},"%zu"); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_U64, metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_uint64(); }, [component, property](uint64_t const& result) {property.set_value(component, result); }, "%zu"); } else { - SHEditorWidgets::DragScalar(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(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()) { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin.is_valid() && metaMax.is_valid()) + if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderFloat(property.get_name().data(), metaMin.template get_value(), metaMin.template get_value(), [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(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_float(); }, [component, property](float const& result) {property.set_value(component, result); }); } else { - 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);}); + 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()) { auto metaMin = property.get_metadata(META::min); auto metaMax = property.get_metadata(META::max); - if(metaMin.is_valid() && metaMax.is_valid()) + if (metaMin.is_valid() && metaMax.is_valid()) { - SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value(), metaMin.template get_value(), [component, property]{return property.get_value(component).to_double();}, [component, property](double const& result){property.set_value(component, result);}); + SHEditorWidgets::SliderScalar(property.get_name().data(), ImGuiDataType_Double, metaMin.template get_value(), metaMin.template get_value(), [component, property] {return property.get_value(component).to_double(); }, [component, property](double const& result) {property.set_value(component, result); }); } else { - SHEditorWidgets::DragScalar(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(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); } } } @@ -183,9 +184,74 @@ namespace SHADE } else if (type == rttr::type::get()) { - SHEditorWidgets::DragVec2(property.get_name().data(), { "X", "Y"}, [component, property]() {return property.get_value(component).template convert(); }, [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(); }, [component, property](SHVec2 vec) {return property.set_value(component, vec); }); } - + + } + } + else DrawContextMenu(component); + } + + template<> + static void DrawComponent(SHColliderComponent* component) + { + if (!component) + return; + const auto componentType = rttr::type::get(*component); + SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }); + ImGui::SameLine(); + if (ImGui::CollapsingHeader(componentType.get_name().data())) + { + DrawContextMenu(component); + + auto& colliders = component->GetColliders(); + int const size = static_cast(colliders.size()); + ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true); + for (int i{}; i < size; ++i) + { + SHCollider& collider = component->GetCollider(i); + auto cursorPos = ImGui::GetCursorPos(); + + if (collider.GetType() == SHCollider::Type::BOX) + { + SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_MD_VIEW_IN_AR, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); + auto box = reinterpret_cast(collider.GetShape()); + SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);}); + } + else if (collider.GetType() == SHCollider::Type::SPHERE) + { + SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); + auto sphere = reinterpret_cast(collider.GetShape()); + SHEditorWidgets::DragFloat("Radius", [sphere] {return sphere->GetRadius(); }, [sphere](float const& value) {sphere->SetRadius(value);}); + } + else if (collider.GetType() == SHCollider::Type::CAPSULE) + { + + } + { + SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f }); + SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider.GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider.SetPositionOffset(vec); }); + SHEditorWidgets::EndPanel(); + } + if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data())) + { + component->RemoveCollider(i); + } + SHEditorWidgets::EndPanel(); + } + ImGui::EndChild(); + + if (ImGui::BeginMenu("Add Collider")) + { + if(ImGui::Selectable("Box Collider")) + { + component->AddBoundingBox(); + } + if(ImGui::Selectable("Sphere Collider")) + { + component->AddBoundingSphere(); + } + ImGui::EndMenu(); } } else DrawContextMenu(component); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index 3d00ac4b..4fc097be 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -24,12 +24,15 @@ namespace SHADE { template, bool> = true> - void DrawAddComponentButton(EntityID const& eid) + bool DrawAddComponentButton(EntityID const& eid) { - if(!SHComponentManager::HasComponent(eid) && ImGui::Selectable(std::format("Add {}", rttr::type::get().get_name().data()).data())) + bool selected = false; + if(!SHComponentManager::HasComponent(eid)) { - SHComponentManager::AddComponent(eid); + if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get().get_name().data()).data()); selected) + SHComponentManager::AddComponent(eid); } + return selected; } SHEditorInspector::SHEditorInspector() @@ -47,11 +50,6 @@ namespace SHADE SHEditorWindow::Update(); if (Begin()) { - if (ImGui::Button("AUDIO")) - { - auto audioSystem = SHSystemManager::GetSystem(); - audioSystem->PlayEventOnce("event:/Characters/sfx_footsteps_raccoon"); - } if (!SHEditor::selectedEntities.empty()) { @@ -90,7 +88,13 @@ namespace SHADE DrawAddComponentButton(eid); DrawAddComponentButton(eid); DrawAddComponentButton(eid); - DrawAddComponentButton(eid); + if(DrawAddComponentButton(eid)) + { + if(SHComponentManager::GetComponent_s(eid) == nullptr) + { + SHComponentManager::AddComponent(eid); + } + } ImGui::EndMenu(); } diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index e94f7398..e1c309b4 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -147,7 +147,7 @@ namespace SHADE ImFont* mainFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; - ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.PixelSnapH = true; + ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f; ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path io.Fonts->Build(); diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index 8d2adcc6..3fa1789e 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -26,7 +26,7 @@ namespace SHADE { class SH_API SHEditorWidgets { - public: + public: //#==============================================================# //|| Constructor || //#==============================================================# @@ -35,6 +35,118 @@ namespace SHADE //#==============================================================# //|| Custom Widgets || //#==============================================================# + inline static ImVector panelStack{}; + static void BeginPanel(std::string_view const& name, const ImVec2& size) + { + ImGui::BeginGroup(); + + auto cursorPos = ImGui::GetCursorScreenPos(); + auto itemSpacing = ImGui::GetStyle().ItemSpacing; + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); + + auto frameHeight = ImGui::GetFrameHeight(); + ImGui::BeginGroup(); + + ImVec2 effectiveSize = size; + if (size.x < 0.0f) + effectiveSize.x = ImGui::GetContentRegionAvail().x; + else + effectiveSize.x = size.x; + ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f)); + + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::SameLine(0.0f, 0.0f); + ImGui::BeginGroup(); + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::SameLine(0.0f, 0.0f); + ImGui::TextUnformatted(name.data()); + auto labelMin = ImGui::GetItemRectMin(); + auto labelMax = ImGui::GetItemRectMax(); + ImGui::SameLine(0.0f, 0.0f); + ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y)); + ImGui::BeginGroup(); + + ImGui::PopStyleVar(2); + + ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f; + ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f; + ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f; + + ImGui::GetCurrentWindow()->Size.x -= frameHeight; + + auto itemWidth = ImGui::CalcItemWidth(); + ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight)); + + panelStack.push_back(ImRect(labelMin, labelMax)); + } + + static void EndPanel() + { + ImGui::PopItemWidth(); + + auto itemSpacing = ImGui::GetStyle().ItemSpacing; + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); + + auto frameHeight = ImGui::GetFrameHeight(); + + ImGui::EndGroup(); + + ImGui::EndGroup(); + + ImGui::SameLine(0.0f, 0.0f); + ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); + ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y)); + + ImGui::EndGroup(); + + auto itemMin = ImGui::GetItemRectMin(); + auto itemMax = ImGui::GetItemRectMax(); + + auto labelRect = panelStack.back(); + panelStack.pop_back(); + + ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f; + ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f)); + labelRect.Min.x -= itemSpacing.x; + labelRect.Max.x += itemSpacing.x; + for (int i = 0; i < 4; ++i) + { + switch (i) + { + // left half-plane + case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break; + // right half-plane + case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break; + // top + case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, -FLT_MAX), ImVec2(labelRect.Max.x, labelRect.Min.y), true); break; + // bottom + case 3: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break; + } + + ImGui::GetWindowDrawList()->AddRect( + frameRect.Min, frameRect.Max, + ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Button)), + halfFrame.x); + + ImGui::PopClipRect(); + } + + ImGui::PopStyleVar(2); + + ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f; + ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f; + ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f; + + ImGui::GetCurrentWindow()->Size.x += frameHeight; + + ImGui::Dummy(ImVec2(0.0f, 0.0f)); + + ImGui::EndGroup(); + } + static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f) { ImGuiWindow* window = ImGui::GetCurrentWindow(); @@ -44,7 +156,7 @@ namespace SHADE 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); } - + template static bool DragN(const std::string& fieldLabel, std::vectorconst& componentLabels, std::vector values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(), @@ -53,7 +165,7 @@ namespace SHADE const ImGuiWindow* const window = ImGui::GetCurrentWindow(); if (window->SkipItems) return false; - + const ImGuiContext& g = *GImGui; bool valueChanged = false; ImGui::BeginGroup(); @@ -69,15 +181,15 @@ namespace SHADE 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(); @@ -85,10 +197,10 @@ namespace SHADE ImGui::EndColumns(); ImGui::PopID(); ImGui::EndGroup(); - + return valueChanged; } - + static bool DragVec2(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, std::function set, float speed = 0.1f, const char* displayFormat = "%.3f", float valueMin = 0.0f, float valueMax = 0.0f, ImGuiSliderFlags flags = 0) @@ -99,98 +211,98 @@ namespace SHADE { changed = true; } - + if (changed) { if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); } - + return changed; } - + static bool DragVec3(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, std::function 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(fieldLabel, componentLabels, { &values.x, &values.y, &values.z }, speed, displayFormat, valueMin, valueMax, flags)) + if (DragN(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(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); } - + return changed; } - + static bool DragVec4(const std::string& fieldLabel, std::vectorconst& componentLabels, std::function get, std::function 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(fieldLabel, componentLabels, { &values.x, &values.y, &values.z, &values.w }, speed, displayFormat, valueMin, valueMax, flags)) + if (DragN(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(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), values, set)), false); } - + return changed; } - + //#==============================================================# //|| Widget Extensions || //#==============================================================# - + static bool CheckBox(std::string const& label, std::function get, std::function set) { bool value = get(); if (ImGui::Checkbox(label.c_str(), &value)) { - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); return true; } return false; } - + template - static bool RadioButton(std::vector const& listLabels, std::vector const& listTypes, std::function get, std::function set) + static bool RadioButton(std::vector const& listLabels, std::vector const& listTypes, std::function get, std::function set) { 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(std::make_shared>(get(), listTypes[i], set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), listTypes[i], set)), false); } ImGui::SameLine(); } return true; } - + static bool InputText(const std::string& label, const std::function get, const std::function set, ImGuiInputTextFlags flag = 0, ImGuiInputTextCallback callback = (ImGuiInputTextCallback)0, void* userData = (void*)0) @@ -199,35 +311,35 @@ namespace SHADE if (ImGui::InputText(label.c_str(), &text, flag, callback, userData)) { if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), text, set)), false); - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), text, set)), false); + return true; } return false; } - + template static bool DragScalar(const std::string& fieldLabel, ImGuiDataType data_type, std::function get, std::function 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"; + 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(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + return true; } return false; } - + static bool DragFloat(const std::string& fieldLabel, std::function get, std::function set, float speed = 0.1f, float p_min = float(), float p_max = float(), const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { @@ -236,18 +348,18 @@ namespace SHADE 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(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + return true; } - + return false; } - + static bool DragInt(const std::string& fieldLabel, std::function get, std::function set, float speed = 1.0f, int p_min = int(), int p_max = int(), const char* displayFormat = "%d", ImGuiSliderFlags flags = 0) { @@ -256,35 +368,35 @@ namespace SHADE 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(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); else if (ImGui::IsItemDeactivatedAfterEdit()) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + return true; } - + return false; } - template - static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function get, std::function set, + template + static bool SliderScalar(const std::string& fieldLabel, ImGuiDataType data_type, T min, T max, std::function get, std::function set, const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) + { + T value = get(); + if (ImGui::SliderScalar(fieldLabel.c_str(), data_type, &value, &min, &max, displayFormat, flags)) { - 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(std::make_shared>(get(), value, set)), false); - else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); - - return true; - } - - return false; + if (ImGui::IsMouseClicked(ImGuiMouseButton_Left, false) && !ImGui::IsMouseDragging(ImGuiMouseButton_Left, -0.2f)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + + return true; } - + + return false; + } + static bool SliderFloat(const std::string& fieldLabel, float min, float max, std::function get, std::function set, const char* displayFormat = "%.3f", ImGuiSliderFlags flags = 0) { @@ -292,17 +404,17 @@ namespace SHADE 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(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); - - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + + return true; } - + return false; } - + static bool SliderInt(const std::string& fieldLabel, int min, int max, std::function get, std::function set, const char* displayFormat = "%d", ImGuiSliderFlags flags = 0) { @@ -310,26 +422,26 @@ namespace SHADE 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(std::make_shared>(get(), value, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); - + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), true); + return true; } - + return false; } - + static bool ComboBox(const std::string& fieldLabel, std::vector list, std::function get, std::function 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(), static_cast(list.size()))) { - SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), selected, set)), false); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), selected, set)), false); } ImGui::PopID(); return edited;