From ceb4c6c4cabcb2fb0a445dd185872af1ffb62e12 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Tue, 18 Oct 2022 22:34:46 +0800 Subject: [PATCH] Added Range Attribute --- SHADE_Engine/src/Editor/SHEditorUI.cpp | 19 ------ SHADE_Engine/src/Editor/SHEditorUI.h | 3 +- SHADE_Engine/src/Editor/SHEditorUI.hpp | 25 +++++++- SHADE_Managed/src/Editor/Editor.cxx | 47 +++++++++++--- SHADE_Managed/src/Editor/RangeAttribute.cxx | 39 ++++++++++++ SHADE_Managed/src/Editor/RangeAttribute.hxx | 61 +++++++++++++++++++ SHADE_Managed/src/Editor/TooltipAttribute.hxx | 2 +- TempScriptsFolder/RaccoonShowcase.cs | 4 ++ 8 files changed, 166 insertions(+), 34 deletions(-) create mode 100644 SHADE_Managed/src/Editor/RangeAttribute.cxx create mode 100644 SHADE_Managed/src/Editor/RangeAttribute.hxx diff --git a/SHADE_Engine/src/Editor/SHEditorUI.cpp b/SHADE_Engine/src/Editor/SHEditorUI.cpp index 76f7bac6..cbbd6d1d 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.cpp +++ b/SHADE_Engine/src/Editor/SHEditorUI.cpp @@ -214,25 +214,6 @@ namespace SHADE ImGuiInputTextFlags_EnterReturnsTrue); } - bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered) - { - float val = static_cast(value); - ImGui::Text(label.c_str()); - if (isHovered) - *isHovered = ImGui::IsItemHovered(); - ImGui::SameLine(); - const bool CHANGED = ImGui::SliderFloat("#", &val, - static_cast(min), static_cast(max), "%.3f", - ImGuiInputTextFlags_EnterReturnsTrue); - - if (CHANGED) - { - value = val; - } - - return CHANGED; - } - bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered) { static const std::vector COMPONENT_LABELS = { "X", "Y" }; diff --git a/SHADE_Engine/src/Editor/SHEditorUI.h b/SHADE_Engine/src/Editor/SHEditorUI.h index b8451765..276bc9f9 100644 --- a/SHADE_Engine/src/Editor/SHEditorUI.h +++ b/SHADE_Engine/src/Editor/SHEditorUI.h @@ -240,7 +240,8 @@ namespace SHADE /// Reference to the variable to store the result. /// (min), static_cast(max), "%.3f", + ImGuiInputTextFlags_EnterReturnsTrue); + if (CHANGED) + { + value = static_cast(val); + } + + //return CHANGED; + return false; + } template inline bool SHEditorUI::InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function toStrFn, bool* isHovered) { diff --git a/SHADE_Managed/src/Editor/Editor.cxx b/SHADE_Managed/src/Editor/Editor.cxx index 8d105fce..f0690c06 100644 --- a/SHADE_Managed/src/Editor/Editor.cxx +++ b/SHADE_Managed/src/Editor/Editor.cxx @@ -30,6 +30,7 @@ of DigiPen Institute of Technology is prohibited. #include "Editor/Command/SHCommandManager.h" #include "Editor/Command/SHCommand.hpp" #include "TooltipAttribute.hxx" +#include "RangeAttribute.hxx" // Using Directives using namespace System; @@ -61,6 +62,31 @@ using namespace System::Collections::Generic; } \ } \ /// +/// Alternative to RENDER_FIELD that checks for RangeAttribute and switches to a slider +/// instead. +/// +/// The managed type of the object to edit. +/// The native type of the object to edit. +/// The SHEditorUI:: function to use for editing. +#define RENDER_FIELD_RANGE(MANAGED_TYPE, NATIVE_TYPE, FUNC) \ +(field->FieldType == MANAGED_TYPE::typeid) \ +{ \ + NATIVE_TYPE val = safe_cast(field->GetValue(object)); \ + NATIVE_TYPE oldVal = val; \ + \ + RangeAttribute^ rangeAttrib = hasAttribute(field); \ + std::string fieldName = Convert::ToNative(field->Name); \ + if ( \ + (rangeAttrib && SHEditorUI::InputSlider(fieldName, rangeAttrib->Min, rangeAttrib->Max, val, &isHovered)) \ + || \ + SHEditorUI::FUNC(fieldName, val, &isHovered) \ + ) \ + { \ + field->SetValue(object, val); \ + registerUndoAction(object, field, val, oldVal); \ + } \ +} \ +/// /// 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:: @@ -77,6 +103,7 @@ using namespace System::Collections::Generic; { \ NATIVE_TYPE val = Convert::ToNative(safe_cast(field->GetValue(object))); \ NATIVE_TYPE oldVal = val; \ + \ if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val, &isHovered)) \ { \ field->SetValue(object, Convert::ToCLI(val)); \ @@ -197,18 +224,18 @@ namespace SHADE } void Editor::renderFieldInInspector(Reflection::FieldInfo^ field, Object^ object) { - bool isHovered = false; + bool isHovered = false; - 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) + if RENDER_FIELD_RANGE (Int16, int, InputInt) + else if RENDER_FIELD_RANGE (Int32, int, InputInt) + else if RENDER_FIELD_RANGE (Int64, int, InputInt) + else if RENDER_FIELD_RANGE (UInt16, unsigned int, InputUnsignedInt) + else if RENDER_FIELD_RANGE (UInt32, unsigned int, InputUnsignedInt) + else if RENDER_FIELD_RANGE (UInt64, unsigned int, InputUnsignedInt) + else if RENDER_FIELD_RANGE (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 RENDER_FIELD_RANGE (float, float, InputFloat) + else if RENDER_FIELD_RANGE (double, double, InputDouble) else if (field->FieldType->IsSubclassOf(Enum::typeid)) { // Get all the names of the enums diff --git a/SHADE_Managed/src/Editor/RangeAttribute.cxx b/SHADE_Managed/src/Editor/RangeAttribute.cxx new file mode 100644 index 00000000..0d548cf7 --- /dev/null +++ b/SHADE_Managed/src/Editor/RangeAttribute.cxx @@ -0,0 +1,39 @@ +/************************************************************************************//*! +\file RangeAttribute.cxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 18, 2022 +\brief Contains the definition of the functions of the managed Range Attribute + 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. +*//*************************************************************************************/ +#include "SHpch.h" +#include "RangeAttribute.hxx" + +namespace SHADE +{ + /*---------------------------------------------------------------------------------*/ + /* Properties */ + /*---------------------------------------------------------------------------------*/ + float RangeAttribute::Min::get() + { + return minVal; + } + float RangeAttribute::Max::get() + { + return maxVal; + } + + /*---------------------------------------------------------------------------------*/ + /* Constructors */ + /*---------------------------------------------------------------------------------*/ + RangeAttribute::RangeAttribute(float min, float max) + : minVal { min } + , maxVal { max } + {} +} diff --git a/SHADE_Managed/src/Editor/RangeAttribute.hxx b/SHADE_Managed/src/Editor/RangeAttribute.hxx new file mode 100644 index 00000000..a724816d --- /dev/null +++ b/SHADE_Managed/src/Editor/RangeAttribute.hxx @@ -0,0 +1,61 @@ +/************************************************************************************//*! +\file RangeAttribute.hxx +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Oct 18, 2022 +\brief Contains the definition of the managed Range Attribute 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 + +namespace SHADE +{ + /// + /// Simple attribute to constrain the range of values for a field on the editor. + /// + [System::AttributeUsage(System::AttributeTargets::Field)] + public ref class RangeAttribute : public System::Attribute + { + public: + /*-----------------------------------------------------------------------------*/ + /* Properties */ + /*-----------------------------------------------------------------------------*/ + /// + /// Minimum value for the Ranged field. + /// + property float Min + { + float get(); + } + /// + /// Maximum value for the Ranged field. + /// + property float Max + { + float get(); + } + + /*-----------------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------------*/ + /// + /// Constructor for a Tooltip attribute that fills in the description. + /// + /// Text to be shown when a field is hovered. + RangeAttribute(float min, float max); + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + float minVal; + float maxVal; + }; +} + diff --git a/SHADE_Managed/src/Editor/TooltipAttribute.hxx b/SHADE_Managed/src/Editor/TooltipAttribute.hxx index e7cd168c..18cbec3a 100644 --- a/SHADE_Managed/src/Editor/TooltipAttribute.hxx +++ b/SHADE_Managed/src/Editor/TooltipAttribute.hxx @@ -17,7 +17,7 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { /// - /// Simple attribute to mark that a field in a Script should be serialised. + /// Simple attribute to provide a field in a script with a tooltip. /// [System::AttributeUsage(System::AttributeTargets::Field)] public ref class TooltipAttribute : public System::Attribute diff --git a/TempScriptsFolder/RaccoonShowcase.cs b/TempScriptsFolder/RaccoonShowcase.cs index 93ea53eb..4191a6e5 100644 --- a/TempScriptsFolder/RaccoonShowcase.cs +++ b/TempScriptsFolder/RaccoonShowcase.cs @@ -5,7 +5,11 @@ public class RaccoonShowcase : Script { [SerializeField] [Tooltip("Speed of the rotation in radians per second.")] + [Range(-1.0f, 2.0f)] private double RotateSpeed = 1.0; + //[SerializeField] + //[Range(-5, 20)] + //private int test = 5; [SerializeField] [Tooltip("Speed of the scaling in radians per second around each axis.")] private Vector3 ScaleSpeed = new Vector3(1.0, 1.0, 0.0);