Added initial implementation of script inspector

This commit is contained in:
Kah Wei 2022-09-28 00:06:47 +08:00
parent a57c4d0d73
commit 7010e1b688
9 changed files with 662 additions and 783 deletions

View File

@ -12,6 +12,8 @@
#include "Editor/SHEditorWidgets.hpp" #include "Editor/SHEditorWidgets.hpp"
#include "SHEditorComponentView.hpp" #include "SHEditorComponentView.hpp"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Scripting/SHScriptEngine.h"
#include "ECS_Base/Managers/SHSystemManager.h"
namespace SHADE namespace SHADE
{ {
@ -61,6 +63,11 @@ namespace SHADE
DrawAddComponentButton<SHRenderable>(eid); DrawAddComponentButton<SHRenderable>(eid);
ImGui::EndMenu(); ImGui::EndMenu();
} }
// Render Scripts
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
scriptEngine->RenderScriptsInInspector(eid);
} }
ImGui::End(); ImGui::End();
} }

View File

@ -10,412 +10,276 @@ Reproduction or disclosure of this file or its contents without the prior writte
of DigiPen Institute of Technology is prohibited. of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
// Precompiled Header // Precompiled Header
#include <pch.h> #include "SHpch.h"
// Primary Header // Primary Header
#include "Editor/EditorUI.h" #include "SHEditorUI.h"
// External Dependencies // External Dependencies
#include <imgui.h> #include <imgui.h>
// Project Headers
#include "Core/Resource/ResourceManager.h"
#include "Editor/ImGuiExtensions.h"
#include "Editor/Editor.h"
namespace Pls namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* ImGui Wrapper Functions - ID Stack */ /* ImGui Wrapper Functions - ID Stack */
/*---------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void EditorUI::PushID(const std::string& id) 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)
{
return ImGui::Checkbox(label.c_str(), &value);
}
bool SHEditorUI::InputInt(const std::string& label, int& value)
{
return ImGui::InputInt(label.c_str(), &value,
1, 10,
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value)
{
int signedVal = static_cast<int>(value);
const bool CHANGED = InputInt(label, signedVal);
if (CHANGED)
{ {
ImGui::PushID(id.c_str()); 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)
{
return ImGui::InputFloat(label.c_str(), &value,
0.1f, 1.0f, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool SHEditorUI::InputDouble(const std::string& label, double& value)
{
return ImGui::InputDouble(label.c_str(), &value,
0.1, 1.0, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool SHEditorUI::InputAngle(const std::string& label, double& value)
{
return ImGui::InputDouble(label.c_str(), &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);
const bool CHANGED = ImGui::SliderFloat(label.c_str(), &val,
static_cast<float>(min), static_cast<float>(max), "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
if (CHANGED)
{
value = val;
} }
void EditorUI::PushID(int id)
{
ImGui::PushID(id);
}
void EditorUI::PopID() return CHANGED;
{ }
ImGui::PopID();
}
/*---------------------------------------------------------------------------------*/ bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value)
/* ImGui Wrapper Functions - Indent */ {
/*---------------------------------------------------------------------------------*/ float vec[2] =
void EditorUI::Indent()
{ {
ImGui::Indent(); static_cast<float>(value.x),
} static_cast<float>(value.y)
void EditorUI::Unindent() };
const bool CHANGED = ImGui::InputFloat2(label.c_str(), vec, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
if (CHANGED)
{ {
ImGui::Unindent(); value.x = vec[0];
value.y = vec[1];
} }
return CHANGED;
}
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value)
{
float vec[3] =
{
static_cast<float>(value.x),
static_cast<float>(value.y),
static_cast<float>(value.z)
};
const bool CHANGED = ImGui::InputFloat3(label.c_str(), vec, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
if (CHANGED)
{
value.x = vec[0];
value.y = vec[1];
value.z = vec[2];
}
return CHANGED;
}
/*---------------------------------------------------------------------------------*/ bool SHEditorUI::InputSliderVec3(const std::string& label, double min, double max, SHVec3& value)
/* ImGui Wrapper Functions - Organisers */ {
/*---------------------------------------------------------------------------------*/ float vec[3] =
bool EditorUI::CollapsingHeader(const std::string& title)
{ {
return ImGui::CollapsingHeader(title.c_str()); static_cast<float>(value.x),
} static_cast<float>(value.y),
static_cast<float>(value.z)
/*---------------------------------------------------------------------------------*/ };
/* ImGui Wrapper Functions - Pop Ups */ const bool CHANGED = ImGui::SliderFloat3(label.c_str(), vec,
/*---------------------------------------------------------------------------------*/ static_cast<float>(min), static_cast<float>(max), "%.3f",
bool EditorUI::BeginPopup(const std::string& label) ImGuiInputTextFlags_EnterReturnsTrue);
if (CHANGED)
{ {
return ImGui::BeginPopup(label.c_str()); value.x = vec[0];
} value.y = vec[1];
void EditorUI::EndPopup() value.z = vec[2];
{
ImGui::EndPopup();
}
void EditorUI::OpenPopup(const std::string& label)
{
ImGui::OpenPopup(label.c_str());
} }
return CHANGED;
}
bool EditorUI::MenuItem(const std::string& label) 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());
const bool CHANGED = ImGui::InputText(label.c_str(), &buffer[0], TEXT_FIELD_MAX_LENGTH);
if (CHANGED)
{ {
return ImGui::MenuItem(label.c_str()); 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)
/* ImGui Wrapper Functions - Widgets */ {
/*---------------------------------------------------------------------------------*/
void EditorUI::Text(const std::string& title) // Clamp input value
const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v];
bool b = false;
if (ImGui::BeginCombo(label.c_str(), INITIAL_NAME.c_str(), ImGuiComboFlags_None))
{ {
ImGui::Text(title.c_str()); for (int i = 0; i < enumNames.size(); ++i)
} {
bool EditorUI::SmallButton(const std::string& title) const bool IS_SELECTED = v == i;
{ if (ImGui::Selectable(enumNames[i].c_str(), IS_SELECTED))
return ImGui::SmallButton(title.c_str());
}
bool EditorUI::Button(const std::string& title)
{
return ImGui::Button(title.c_str());
}
bool EditorUI::InputCheckbox(const std::string& label, bool& value)
{
return ImGui::Checkbox(label.c_str(), &value);
}
bool EditorUI::InputInt(const std::string& label, int& value)
{
return ImGui::InputInt(label.c_str(), &value,
1, 10,
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool EditorUI::InputUnsignedInt(const std::string& label, unsigned int& value)
{
int signedVal = static_cast<int>(value);
const bool CHANGED = InputInt(label, signedVal);
if (CHANGED)
{ {
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max()); v = i;
value = static_cast<unsigned int>(signedVal); b = true;
} }
return CHANGED; if (IS_SELECTED)
}
bool EditorUI::InputFloat(const std::string& label, float& value)
{
return ImGui::InputFloat(label.c_str(), &value,
0.1f, 1.0f, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool EditorUI::InputDouble(const std::string& label, double& value)
{
return ImGui::InputDouble(label.c_str(), &value,
0.1, 1.0, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool EditorUI::InputAngle(const std::string& label, double& value)
{
return ImGui::InputDouble(label.c_str(), &value,
1.0, 45.0, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool EditorUI::InputSlider(const std::string& label, double min, double max, double& value)
{
float val = static_cast<float>(value);
const bool CHANGED = ImGui::SliderFloat(label.c_str(), &val,
static_cast<float>(min), static_cast<float>(max), "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
if (CHANGED)
{ {
value = val; ImGui::SetItemDefaultFocus();
} }
}
ImGui::EndCombo();
return CHANGED;
} }
return b;
bool EditorUI::InputVec2(const std::string& label, vec2& value) }
{ }
float vec[2] =
{
static_cast<float>(value.x),
static_cast<float>(value.y)
};
const bool CHANGED = ImGui::InputFloat2(label.c_str(), vec, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
if (CHANGED)
{
value.x = vec[0];
value.y = vec[1];
}
return CHANGED;
}
bool EditorUI::InputVec3(const std::string& label, vec3& value)
{
float vec[3] =
{
static_cast<float>(value.x),
static_cast<float>(value.y),
static_cast<float>(value.z)
};
const bool CHANGED = ImGui::InputFloat3(label.c_str(), vec, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
if (CHANGED)
{
value.x = vec[0];
value.y = vec[1];
value.z = vec[2];
}
return CHANGED;
}
bool EditorUI::InputSliderVec3(const std::string& label, double min, double max, vec3& value)
{
float vec[3] =
{
static_cast<float>(value.x),
static_cast<float>(value.y),
static_cast<float>(value.z)
};
const bool CHANGED = ImGui::SliderFloat3(label.c_str(), vec,
static_cast<float>(min), static_cast<float>(max), "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
if (CHANGED)
{
value.x = vec[0];
value.y = vec[1];
value.z = vec[2];
}
return CHANGED;
}
bool EditorUI::InputColor(const std::string& label, GFX::Color& value)
{
float color[4] =
{
value.R,
value.G,
value.B,
value.A
};
const bool CHANGED = ImGui::ColorEdit4(label.c_str(), color,
ImGuiColorEditFlags_AlphaBar |
ImGuiColorEditFlags_AlphaPreview |
ImGuiColorEditFlags_Float);
if (CHANGED)
{
value.R = color[0];
value.G = color[1];
value.B = color[2];
value.A = std::clamp(color[3], 0.f, 1.f);
}
return CHANGED;
}
bool EditorUI::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());
const bool CHANGED = ImGui::InputText(label.c_str(), &buffer[0], TEXT_FIELD_MAX_LENGTH);
if (CHANGED)
{
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
}
return CHANGED;
}
bool EditorUI::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;
if (ImGui::BeginCombo(label.c_str(), 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;
}
bool EditorUI::InputTextureDropDown(const std::string& label, Resource::Snowflake& v)
{
static std::vector<std::reference_wrapper<Resource>> resources;
// Register texture popup
bool hasChanges = false;
if (ImGui::BeginPopup("Texture Menu"))
{
if (ImGui::Button("None"))
{
v = Resource::INVALID_SNOWFLAKE;
ImGui::CloseCurrentPopup();
hasChanges = true;
}
for (auto& rscWrapper : resources)
{
Resource& rsc = rscWrapper.get();
ImGui::PushID(static_cast<int>(rsc.GetID()));
const GFX::Texture* TEX = rsc.LoadTexture();
if (TEX == nullptr)
{
continue;
}
const ImTextureID TEX_ID = reinterpret_cast<void*>(static_cast<intptr_t>(TEX->GetHandle()));
const std::string NAME = rsc.GetPath().filename().string();
const std::string FP = rsc.GetPath().string();
if (ImGui::ImageButtonWithText(TEX_ID, NAME.c_str()))
{
v = rsc.GetID();
ImGui::CloseCurrentPopup();
hasChanges = true;
}
ImGui::TextDisabled(FP.c_str());
ImGui::PopID();
}
ImGui::EndPopup();
}
// Get texture ID of resource
ImTextureID texID = 0;
std::string texName = "None";
Resource* rsc = ResourceManager::Find(v);
if (rsc)
{
// File
if (rsc->IsType<GFX::Texture>())
{
GFX::Texture* tex = rsc->LoadTexture();
if (tex)
{
texID = reinterpret_cast<void*>(static_cast<intptr_t>(tex->GetHandle()));
}
}
else
{
// TODO (Clarence): replace with missing texture image
texID = Editor::Editor::GetInternalTexture("scene.png");
}
texName = rsc->GetPath().filename().string();
}
// Show texture selection menu
if (ImGui::ImageButtonWithText(texID, texName.c_str(), label.c_str()))
{
resources = ResourceManager::FindAllOfType<GFX::Texture>();
ImGui::OpenPopup("Texture Menu");
}
return hasChanges;
}
bool EditorUI::InputFontDropDown(const char* label, Resource::Snowflake& v)
{
static std::vector<std::reference_wrapper<Resource>> resources;
// Register texture popup
bool hasChanges = false;
if (ImGui::BeginPopup("Font Menu"))
{
if (ImGui::Button("None"))
{
v = Resource::INVALID_SNOWFLAKE;
ImGui::CloseCurrentPopup();
hasChanges = true;
}
for (auto& rscWrapper : resources)
{
Resource& rsc = rscWrapper.get();
ImGui::PushID(static_cast<int>(rsc.GetID()));
const GFX::Font* FONT = rsc.LoadFont();
if (FONT == nullptr)
{
continue;
}
const std::string NAME = rsc.GetPath().filename().string();
const std::string FP = rsc.GetPath().string();
if (ImGui::Button(NAME.c_str()))
{
v = rsc.GetID();
ImGui::CloseCurrentPopup();
hasChanges = true;
}
ImGui::TextDisabled(FP.c_str());
ImGui::PopID();
}
ImGui::EndPopup();
}
// Get font ID of resource
ImTextureID fontID = 0;
std::string fontName = "None";
Resource* rsc = ResourceManager::Find(v);
if (rsc)
{
// File
if (rsc)
{
GFX::Font* font = rsc->LoadFont();
if (font)
{
fontID = reinterpret_cast<void*>(static_cast<intptr_t>(font->GetID()));
if (font->CreatedThisFrame())
{
font->OnCreate() = false;
hasChanges = true;
}
}
}
else
{
// TODO (Clarence): replace with missing texture image
fontID = Editor::Editor::GetInternalFont("selawk.tff");
}
fontName = rsc->GetPath().filename().string();
}
// Show font selection menu
if (ImGui::ButtonWithText(fontName.c_str(), label))
{
resources = ResourceManager::FindAllOfType<GFX::Font>();
ImGui::OpenPopup("Font Menu");
}
return hasChanges;
}
} // namespace PlushieEngine

View File

@ -1,312 +1,297 @@
/************************************************************************************//*! /************************************************************************************//*!
\file EditorUI.h \file SHEditorUI.h
\author Tng Kah Wei, kahwei.tng, 390009620 (50%) \author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu \par email: kahwei.tng\@digipen.edu
\author Tay Yan Chong Clarence, t.yanchongclarence, 620008720 (50%)
\par email: t.yanchongclarence\@digipen.edu \par email: t.yanchongclarence\@digipen.edu
\date Nov 7, 2021 \date Sep 27, 2022
\brief Defines a class that encapsulates the running of a Plushie Engine \brief Defines a class that contains wrapper functions for ImGui.
application.
Copyright (C) 2021 DigiPen Institute of Technology. Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited. of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
#pragma once #pragma once
// Platform Defines
#include "PlushieDefines.h"
// Standard Library // Standard Library
#include <functional> // std::function #include <functional> // std::function
#include <string> // std::string #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"
#include "Core/Resource/Resource.h" namespace SHADE
#include "Graphics/Color.h"
#include "Math/Vector2.h"
#include "Math/Vector3.h"
namespace Pls
{ {
/// <summary>
/// Static class that contains useful functions for Editor UI using ImGui.
/// </summary>
class SH_API SHEditorUI final
{
public:
/*-----------------------------------------------------------------------------*/
/* Constants */
/*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Static class that contains useful functions for Editor UI using ImGui. /// Maximum length of a string supported by InputTextField()
/// </summary> /// </summary>
class PLS_API EditorUI final static constexpr size_t TEXT_FIELD_MAX_LENGTH = 256;
{
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 */ /* ImGui Wrapper Functions - ID Stack */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Marks the start of a stack of ImGui widgets with the specified id. /// Marks the start of a stack of ImGui widgets with the specified id.
/// <br/> /// <br/>
/// Wraps up ImGui::PushID(). /// Wraps up ImGui::PushID().
/// </summary> /// </summary>
/// <param name="id">String-based ID.</param> /// <param name="id">String-based ID.</param>
static void PushID(const std::string& id); static void PushID(const std::string& id);
/// <summary> /// <summary>
/// Marks the start of a stack of ImGui widgets with the specified id. /// Marks the start of a stack of ImGui widgets with the specified id.
/// <br/> /// <br/>
/// Wraps up ImGui::PushID(). /// Wraps up ImGui::PushID().
/// </summary> /// </summary>
/// <param name="id">Integer-based ID.</param> /// <param name="id">Integer-based ID.</param>
static void PushID(int id); static void PushID(int id);
/// <summary> /// <summary>
/// Marks the end of a stack of ImGui widgets from the last PushID() call. /// Marks the end of a stack of ImGui widgets from the last PushID() call.
/// <br/> /// <br/>
/// Wraps up ImGui::PopID(). /// Wraps up ImGui::PopID().
/// </summary> /// </summary>
static void PopID(); static void PopID();
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* ImGui Wrapper Functions - Indent */ /* ImGui Wrapper Functions - Indent */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Indents the widgets rendered after this call. /// Indents the widgets rendered after this call.
/// <br/> /// <br/>
/// Wraps up ImGui::Indent(). /// Wraps up ImGui::Indent().
/// </summary> /// </summary>
static void Indent(); static void Indent();
/// <summary> /// <summary>
/// Unindents the widgets rendered after this call. /// Unindents the widgets rendered after this call.
/// <br/> /// <br/>
/// Wraps up ImGui::Unindent(). /// Wraps up ImGui::Unindent().
/// </summary> /// </summary>
static void Unindent(); static void Unindent();
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* ImGui Wrapper Functions - Organisers */ /* ImGui Wrapper Functions - Organizers */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Creates a collapsing title header. /// Creates a collapsing title header.
/// <br/> /// <br/>
/// Wraps up ImGui::CollapsingHeader(). /// Wraps up ImGui::CollapsingHeader().
/// </summary> /// </summary>
/// <param name="title">Label for the header.</param> /// <param name="title">Label for the header.</param>
/// <returns>True if the header is open, false otherwise.</returns> /// <returns>True if the header is open, false otherwise.</returns>
static bool CollapsingHeader(const std::string& title); static bool CollapsingHeader(const std::string& title);
static void SameLine();
static void Separator();
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* ImGui Wrapper Functions - Pop Ups */ /* ImGui Wrapper Functions - Menu */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> static bool BeginMenu(const std::string& label);
/// Marks the start of a definition of a mini pop up that can show options. static bool BeginMenu(const std::string& label, const char* icon);
/// <br/> static void EndMenu();
/// 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);
/// <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 */ /* ImGui Wrapper Functions - Pop Ups */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Creates a visual text widget. /// Marks the start of a definition of a mini pop up that can show options.
/// <br/> /// <br/>
/// Wraps up ImGui::Text(). /// Wraps up ImGui::BeginPopup().
/// </summary> /// </summary>
/// <param name="title">Text to display.</param> /// <param name="label">Label used to identify this widget.</param>
static void Text(const std::string& title); /// <returns>Whether or not the pop up is open.</returns>
/// <summary> static bool BeginPopup(const std::string& label);
/// Creates a small inline button widget. static bool BeginPopupContextItem(const std::string& label);
/// <br/> /// <summary>
/// Wraps up ImGui::SmallButton(). /// Marks the end of a definition of a mini pop up that can show options.
/// </summary> /// <br/>
/// <param name="title">Text to display.</param> /// Wraps up ImGui::EndPopup().
/// <returns>True if button was pressed.</returns> /// </summary>
static bool SmallButton(const std::string& title); static void EndPopup();
/// <summary> /// <summary>
/// Creates a inline button widget. /// Opens the popup that was defined with the specified label.
/// <br/> /// <br/>
/// Wraps up ImGui::Button(). /// Wraps up ImGui::OpenPopup().
/// </summary> /// </summary>
/// <param name="title">Text to display.</param> static void OpenPopup(const std::string& label);
/// <returns>True if button was pressed.</returns> /// <summary>
static bool Button(const std::string& title); /// Creates a menu item in the list of items for a mini popup.
/// <summary> /// <br/>
/// Creates a checkbox widget for boolean input. /// Wraps up ImGui::MenuItem().
/// <br/> /// </summary>
/// Wraps up ImGui::Checkbox(). /// <param name="label">Label used to identify this widget.</param>
/// </summary> /// <returns>Whether or not the menu item was selected.</returns>
/// <param name="label">Label used to identify this widget.</param> static bool MenuItem(const std::string& label);
/// <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); /* ImGui Wrapper Functions - Widgets */
/// <summary> /*-----------------------------------------------------------------------------*/
/// Creates a integer field widget for integer input. /// <summary>
/// <br/> /// Creates a visual text widget.
/// Wraps up ImGui::InputInt(). /// <br/>
/// </summary> /// Wraps up ImGui::Text().
/// <param name="label">Label used to identify this widget.</param> /// </summary>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="title">Text to display.</param>
/// <returns>True if the value was changed.</returns> static void Text(const std::string& title);
static bool InputInt(const std::string& label, int& value); /// <summary>
/// <summary> /// Creates a small inline button widget.
/// Creates a integer field widget for unsigned integer input. /// <br/>
/// <br/> /// Wraps up ImGui::SmallButton().
/// Wraps up ImGui::InputInt() with an additional clamping of values. /// </summary>
/// <br/> /// <param name="title">Text to display.</param>
/// Note: As a result, the range of this function limits it to the maximum /// <returns>True if button was pressed.</returns>
/// value of a 32-bit signed integer instead of a 32-bit unsigned integer. static bool SmallButton(const std::string& title);
/// </summary> /// <summary>
/// <param name="label">Label used to identify this widget.</param> /// Creates a inline button widget.
/// <param name="value">Reference to the variable to store the result.</param> /// <br/>
/// <returns>True if the value was changed.</returns> /// Wraps up ImGui::Button().
static bool InputUnsignedInt(const std::string& label, unsigned int& value); /// </summary>
/// <summary> /// <param name="title">Text to display.</param>
/// Creates a decimal field widget for single precision float input. /// <returns>True if button was pressed.</returns>
/// <br/> static bool Button(const std::string& title);
/// Wraps up ImGui::InputFloat(). static bool Selectable(const std::string& label);
/// </summary> static bool Selectable(const std::string& label, const char* icon);
/// <param name="label">Label used to identify this widget.</param> /// <summary>
/// <param name="value">Reference to the variable to store the result.</param> /// Creates a checkbox widget for boolean input.
/// <returns>True if the value was changed.</returns> /// <br/>
static bool InputFloat(const std::string& label, float& value); /// Wraps up ImGui::Checkbox().
/// <summary> /// </summary>
/// Creates a decimal field widget for double precision float input. /// <param name="label">Label used to identify this widget.</param>
/// <br/> /// <param name="value">Reference to the variable to store the result.</param>
/// Wraps up ImGui::InputDouble(). /// <returns>True if the value was changed.</returns>
/// </summary> static bool InputCheckbox(const std::string& label, bool& value);
/// <param name="label">Label used to identify this widget.</param> /// <summary>
/// <param name="value">Reference to the variable to store the result.</param> /// Creates a integer field widget for integer input.
/// <returns>True if the value was changed.</returns> /// <br/>
static bool InputDouble(const std::string& label, double& value); /// Wraps up ImGui::InputInt().
/// <summary> /// </summary>
/// Creates a decimal field widget for double input with increments of higher /// <param name="label">Label used to identify this widget.</param>
/// steps meant for angle variables. /// <param name="value">Reference to the variable to store the result.</param>
/// <br/> /// <returns>True if the value was changed.</returns>
/// Wraps up ImGui::InputDouble(). static bool InputInt(const std::string& label, int& value);
/// </summary> /// <summary>
/// <param name="label">Label used to identify this widget.</param> /// Creates a integer field widget for unsigned integer input.
/// <param name="value">Reference to the variable to store the result.</param> /// <br/>
/// <returns>True if the value was changed.</returns> /// Wraps up ImGui::InputInt() with an additional clamping of values.
static bool InputAngle(const std::string& label, double& value); /// <br/>
/// <summary> /// Note: As a result, the range of this function limits it to the maximum
/// Creates a double slider field widget for double input. /// value of a 32-bit signed integer instead of a 32-bit unsigned integer.
/// <br/> /// </summary>
/// Wraps up ImGui::InputSliderFloat(). /// <param name="label">Label used to identify this widget.</param>
/// </summary> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="label">Label used to identify this widget.</param> /// <returns>True if the value was changed.</returns>
/// <param name="min">Minimum value of the slider.</param> static bool InputUnsignedInt(const std::string& label, unsigned int& value);
/// <param name="max">Maximum value of the slider.</param> /// <summary>
/// <param name="value">Reference to the variable to store the result.</param> /// Creates a decimal field widget for single precision float input.
/// <returns>True if the value was changed.</returns> /// <br/>
static bool InputSlider(const std::string& label, double min, double max, double& value); /// Wraps up ImGui::InputFloat().
/// <summary> /// </summary>
/// Creates a 2x double field widget for Vector2 input. /// <param name="label">Label used to identify this widget.</param>
/// <br/> /// <param name="value">Reference to the variable to store the result.</param>
/// Wraps up ImGui::InputFloat2(). /// <returns>True if the value was changed.</returns>
/// </summary> static bool InputFloat(const std::string& label, float& value);
/// <param name="label">Label used to identify this widget.</param> /// <summary>
/// <param name="value">Reference to the variable to store the result.</param> /// Creates a decimal field widget for double precision float input.
/// <returns>True if the value was changed.</returns> /// <br/>
static bool InputVec2(const std::string& label, vec2& value); /// Wraps up ImGui::InputDouble().
/// <summary> /// </summary>
/// Creates a 3x double field widget for Vector3 input. /// <param name="label">Label used to identify this widget.</param>
/// <br/> /// <param name="value">Reference to the variable to store the result.</param>
/// Wraps up ImGui::InputFloat3(). /// <returns>True if the value was changed.</returns>
/// </summary> static bool InputDouble(const std::string& label, double& value);
/// <param name="label">Label used to identify this widget.</param> /// <summary>
/// <param name="value">Reference to the variable to store the result.</param> /// Creates a decimal field widget for double input with increments of higher
/// <returns>True if the value was changed.</returns> /// steps meant for angle variables.
static bool InputVec3(const std::string& label, vec3& value); /// <br/>
/// <summary> /// Wraps up ImGui::InputDouble().
/// Creates a 3x double slider field widget for Vector3 input. /// </summary>
/// <br/> /// <param name="label">Label used to identify this widget.</param>
/// Wraps up ImGui::InputSliderFloat3(). /// <param name="value">Reference to the variable to store the result.</param>
/// </summary> /// <returns>True if the value was changed.</returns>
/// <param name="label">Label used to identify this widget.</param> static bool InputAngle(const std::string& label, double& value);
/// <param name="min">Minimum value of the slider.</param> /// <summary>
/// <param name="max">Maximum value of the slider.</param> /// Creates a double slider field widget for double input.
/// <param name="value">Reference to the variable to store the result.</param> /// <br/>
/// <returns>True if the value was changed.</returns> /// Wraps up ImGui::InputSliderFloat().
static bool InputSliderVec3(const std::string& label, double min, double max, vec3& value); /// </summary>
/// <summary> /// <param name="label">Label used to identify this widget.</param>
/// Creates a colour field widget for Color input. /// <param name="min">Minimum value of the slider.</param>
/// <br/> /// <param name="max">Maximum value of the slider.</param>
/// Wraps up ImGui::ColorEdit4(). /// <param name="value">Reference to the variable to store the result.</param>
/// </summary> /// <returns>True if the value was changed.</returns>
/// <param name="label">Label used to identify this widget.</param> static bool InputSlider(const std::string& label, double min, double max, double& value);
/// <param name="value">Reference to the variable to store the result.</param> /// <summary>
/// <returns>True if the value was changed.</returns> /// Creates a 2x double field widget for Vector2 input.
static bool InputColor(const std::string& label, GFX::Color& value); /// <br/>
/// <summary> /// Wraps up ImGui::InputFloat2().
/// Creates a text field widget for string input. /// </summary>
/// <br/> /// <param name="label">Label used to identify this widget.</param>
/// Wraps up ImGui::InputText(). /// <param name="value">Reference to the variable to store the result.</param>
/// </summary> /// <returns>True if the value was changed.</returns>
/// <param name="label">Label used to identify this widget.</param> static bool InputVec2(const std::string& label, SHVec2& value);
/// <param name="value">Reference to the variable to store the result.</param> /// <summary>
/// <returns>True if the value was changed.</returns> /// Creates a 3x double field widget for Vector3 input.
static bool InputTextField(const std::string& label, std::string& value); /// <br/>
/// <summary> /// Wraps up ImGui::InputFloat3().
/// Creates a combo box for enumeration input. /// </summary>
/// </summary> /// <param name="label">Label used to identify this widget.</param>
/// <typeparam name="Enum">The type of enum to input.</typeparam> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="label">The name of the input.</param> /// <returns>True if the value was changed.</returns>
/// <param name="v">The reference to the value to modify.</param> static bool InputVec3(const std::string& label, SHVec3& value);
/// <param name="maxVal">The maximum value of the enum.</param> /// <summary>
/// <param name="toStrFn"> /// Creates a 3x double slider field widget for Vector3 input.
/// Conversion function from the type of enum /// <br/>
/// to C-style string.</param> /// Wraps up ImGui::InputSliderFloat3().
/// <returns>Whether the value was modified.</returns> /// </summary>
template<typename Enum> /// <param name="label">Label used to identify this widget.</param>
static bool InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char*(Enum)> toStrFn); /// <param name="min">Minimum value of the slider.</param>
/// <summary> /// <param name="max">Maximum value of the slider.</param>
/// Creates a combo box for enumeration input using a specified list of names. /// <param name="value">Reference to the variable to store the result.</param>
/// </summary> /// <returns>True if the value was changed.</returns>
/// <param name="label">The name of the input.</param> static bool InputSliderVec3(const std::string& label, double min, double max, SHVec3& value);
/// <param name="v">The reference to the value to modify.</param> /// <summary>
/// <param name="enumNames">Vector of names for each enumeration value.</param> /// Creates a text field widget for string input.
/// <returns>Whether the value was modified.</returns> /// <br/>
static bool InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames); /// Wraps up ImGui::InputText().
/// <summary> /// </summary>
/// Creates a drop down widget for texture selection. /// <param name="label">Label used to identify this widget.</param>
/// </summary> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="label">The name of the input.</param> /// <returns>True if the value was changed.</returns>
/// <param name="v">The reference to the value to modify.</param> static bool InputTextField(const std::string& label, std::string& value);
/// <returns>Whether the value was modified.</returns> /// <summary>
static bool InputTextureDropDown(const std::string& label, Resource::Snowflake& v); /// Creates a combo box for enumeration input.
/// <summary> /// </summary>
/// Creates a drop down widget for font selection. /// <typeparam name="Enum">The type of enum to input.</typeparam>
/// </summary> /// <param name="label">The name of the input.</param>
/// <param name="label">The name of the input.</param> /// <param name="v">The reference to the value to modify.</param>
/// <param name="v">The reference to the value to modify.</param> /// <param name="maxVal">The maximum value of the enum.</param>
/// <returns>Whether the value was modified.</returns> /// <param name="toStrFn">
static bool InputFontDropDown(const char* label, Resource::Snowflake& v); /// 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: private:
// Prevent instantiation of this static class // Prevent instantiation of this static class
EditorUI() = delete; SHEditorUI() = delete;
}; };
} // namespace PlushieEngine }
#include "EditorUI.hpp" #include "SHEditorUI.hpp"

View File

@ -1,49 +1,51 @@
/************************************************************************************//*! /************************************************************************************//*!
\file EditorUI.hpp \file SHEditorUI.hpp
\author Tay Yan Chong Clarence, t.yanchongclarence, 620008720 \author Tng Kah Wei, kahwei.tng, 390009620
\par email: t.yanchongclarence\@digipen.edu \par email: kahwei.tng\@digipen.edu
\date Nov 8, 2021 \date Sep 27, 2022
\brief Contains the implementation of editor inspector template functions. \brief Contains the implementation of editor inspector template functions.
Copyright (C) 2021 DigiPen Institute of Technology. Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited. of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
// Primary Header // Primary Header
#include "EditorUI.h" #include "SHEditorUI.h"
// External Dependencies
#include <imgui.h>
namespace Pls namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ImGui Wrapper Functions - Widgets */ /* ImGui Wrapper Functions - Widgets */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
template<typename Enum> template<typename Enum>
inline bool EditorUI::InputEnumCombo(const std::string& label, Enum& v, int maxVal, std::function<const char* (Enum)> toStrFn) 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)
{ {
std::vector<Enum> values; values.emplace_back(static_cast<Enum>(i));
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;
} }
} // namespace PlushieEngine 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;
}
}

View File

@ -82,22 +82,18 @@ namespace SHADE
void SHScriptEngine::Exit() void SHScriptEngine::Exit()
{ {
// Do not allow deinitialization if not initialised // Do not allow deinitialization if not initialised
if (!dotNet.IsLoaded()) if (!dotNet.IsLoaded())
{ {
SHLOG_ERROR("[ScriptEngine] Attempted to clean up an unloaded DotNetRuntime."); SHLOG_ERROR("[ScriptEngine] Attempted to clean up an unloaded DotNetRuntime.");
return; return;
} }
// Unlink events // Clean up the CSharp Engine
/*ECS::OnEntityCreated -= onEntityCreate; csEngineExit();
ECS::OnEntityDestroy -= onEntityDestroy;*/
// Clean up the CSharp Engine // Shut down the CLR
csEngineExit(); dotNet.Exit();
// Shut down the CLR
dotNet.Exit();
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -105,15 +101,15 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
bool SHScriptEngine::AddScript(EntityID entity, const std::string_view& scriptName) 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) void SHScriptEngine::RemoveAllScripts(EntityID entity)
{ {
csScriptsRemoveAll(entity); csScriptsRemoveAll(entity);
} }
void SHScriptEngine::RemoveAllScriptsImmediately(EntityID entity, bool callOnDestroy) 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 std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity) const
{ {
// Create buffer needed to store serialised script data // Create buffer needed to store serialised script data
constexpr int BUFFER_SIZE = 10240; constexpr int BUFFER_SIZE = 10240;
std::unique_ptr<char> buffer { new char[BUFFER_SIZE] }; std::unique_ptr<char> buffer { new char[BUFFER_SIZE] };
std::memset(buffer.get(), 0, BUFFER_SIZE); std::memset(buffer.get(), 0, BUFFER_SIZE);
// Attempt to serialise the script // Attempt to serialise the script
std::string result; std::string result;
if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE)) if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE))
{ {
result = std::string(buffer.get()); result = std::string(buffer.get());
} }
else else
{ {
SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts as string buffer is too small!"); SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts as string buffer is too small!");
} }
// Return an empty string since we failed to serialise // Return an empty string since we failed to serialise
return result; return result;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -152,9 +148,9 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Script Editor Functions */ /* Script Editor Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHScriptEngine::RenderScriptsInInspector(const SHEntity& entity) const void SHScriptEngine::RenderScriptsInInspector(EntityID entity) const
{ {
csEditorRenderScripts(entity.GetEID()); csEditorRenderScripts(entity);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -267,7 +263,7 @@ namespace SHADE
// Attempt to create the file // Attempt to create the file
std::ofstream file(path); std::ofstream file(path);
if (!file.is_open()) 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 // Fill the file
file << FILE_CONTENTS; file << FILE_CONTENTS;
@ -281,9 +277,9 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr) SHEventHandle SHScriptEngine::onEntityDestroyed(SHEventPtr eventPtr)
{ {
auto eventData = reinterpret_cast<const SHEventSpec<SHEntityDestroyedEvent>*>(eventPtr.get()); auto eventData = reinterpret_cast<const SHEventSpec<SHEntityDestroyedEvent>*>(eventPtr.get());
csScriptsRemoveAll(eventData->data->eid); csScriptsRemoveAll(eventData->data->eid);
return eventData->handle; return eventData->handle;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -397,13 +393,13 @@ namespace SHADE
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore", DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
"SerialiseScriptsYaml" "SerialiseScriptsYaml"
); );*/
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr> csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".Editor", DEFAULT_CSHARP_NAMESPACE + ".Editor",
"RenderScriptsInInspector" "RenderScriptsInInspector"
);*/ );
} }
void SHScriptEngine::registerEvents() void SHScriptEngine::registerEvents()

View File

@ -170,7 +170,7 @@ namespace SHADE
/// rendering code. /// rendering code.
/// </summary> /// </summary>
/// <param name="entity">The Entity to render the Scripts of.</param> /// <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 */ /* Static Utility Functions */

View File

@ -17,15 +17,17 @@ of DigiPen Institute of Technology is prohibited.
// Primary Header // Primary Header
#include "Editor/Editor.hxx" #include "Editor/Editor.hxx"
// External Dependencies // External Dependencies
#include "Editor/SHEditorUI::.h" #include "Editor/SHEditorUI.h"
// Project Headers // Project Headers
#include "Components/Component.hxx" #include "Components/Component.hxx"
#include "Scripts/ScriptStore.hxx" #include "Scripts/ScriptStore.hxx"
#include "Utility/Convert.hxx" #include "Utility/Convert.hxx"
#include "Utility/Debug.hxx" #include "Utility/Debug.hxx"
#include "Serialisation/ReflectionUtilities.hxx" #include "Serialisation/ReflectionUtilities.hxx"
#include "Editor/IconsMaterialDesign.h"
// Using Directives // Using Directives
using namespace System;
using namespace System::Collections::Generic; using namespace System::Collections::Generic;
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
@ -46,7 +48,7 @@ using namespace System::Collections::Generic;
(field->FieldType == MANAGED_TYPE::typeid) \ (field->FieldType == MANAGED_TYPE::typeid) \
{ \ { \
NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \ NATIVE_TYPE val = safe_cast<NATIVE_TYPE>(field->GetValue(object)); \
if (SHEditorUI::::FUNC(Convert::ToNative(field->Name), val)) \ if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
{ \ { \
field->SetValue(object, val); \ field->SetValue(object, val); \
} \ } \
@ -67,7 +69,7 @@ using namespace System::Collections::Generic;
(field->FieldType == MANAGED_TYPE::typeid) \ (field->FieldType == MANAGED_TYPE::typeid) \
{ \ { \
NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \ NATIVE_TYPE val = Convert::ToNative(safe_cast<MANAGED_TYPE>(field->GetValue(object))); \
if (SHEditorUI::::FUNC(Convert::ToNative(field->Name), val)) \ if (SHEditorUI::FUNC(Convert::ToNative(field->Name), val)) \
{ \ { \
field->SetValue(object, Convert::ToCLI(val)); \ field->SetValue(object, Convert::ToCLI(val)); \
} \ } \
@ -99,10 +101,31 @@ namespace SHADE
} }
// Render Add Script // Render Add Script
//RenderScriptAddButton(entity); RenderScriptAddButton(entity);
SAFE_NATIVE_CALL_END_N("SHADE_Managed.Editor.RenderScriptsInInspector") 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 */ /* Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -110,30 +133,23 @@ namespace SHADE
{ {
// Constants // Constants
const std::string LABEL = Convert::ToNative(script->GetType()->Name); const std::string LABEL = Convert::ToNative(script->GetType()->Name);
const char* CONTEXT_MENU_ID = "scriptContextMenu";
// Header // Header
SHEditorUI::::PushID(index); SHEditorUI::PushID(index);
if (SHEditorUI::::CollapsingHeader(LABEL)) if (SHEditorUI::CollapsingHeader(LABEL))
{ {
SHEditorUI::::PushID(LABEL); SHEditorUI::PushID(LABEL);
SHEditorUI::::Indent(); SHEditorUI::Indent();
{ {
// Define context menu // Right Click Menu
if (SHEditorUI::::BeginPopup(CONTEXT_MENU_ID)) if (SHEditorUI::BeginPopupContextItem("scriptContextMenu"))
{ {
if (SHEditorUI::::MenuItem("Remove Script")) if (SHEditorUI::Selectable("Delete Script", ICON_MD_DELETE))
{ {
// Mark script for removal // Mark script for removal
ScriptStore::RemoveScript(entity, script); ScriptStore::RemoveScript(entity, script);
} }
SHEditorUI::::EndPopup(); SHEditorUI::EndPopup();
}
// Context menu button
if (SHEditorUI::::SmallButton("..."))
{
SHEditorUI::::OpenPopup(CONTEXT_MENU_ID);
} }
// Go through all fields and output them // Go through all fields and output them
@ -146,16 +162,16 @@ namespace SHADE
continue; continue;
// Render the input field for this field // Render the input field for this field
SHEditorUI::::PushID(LABEL + std::to_string(id++)); SHEditorUI::PushID(LABEL + std::to_string(id++));
renderFieldInInspector(field, script); renderFieldInInspector(field, script);
SHEditorUI::::PopID(); SHEditorUI::PopID();
} }
} }
SHEditorUI::::Unindent(); SHEditorUI::Unindent();
SHEditorUI::::PopID(); SHEditorUI::PopID();
} }
SHEditorUI::::PopID(); SHEditorUI::PopID();
} }
void Editor::renderFieldInInspector(Reflection::FieldInfo^ field, Object^ object) void Editor::renderFieldInInspector(Reflection::FieldInfo^ field, Object^ object)
{ {
@ -180,13 +196,13 @@ namespace SHADE
} }
int val = safe_cast<int>(field->GetValue(object)); int val = safe_cast<int>(field->GetValue(object));
if (SHEditorUI::::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames)) if (SHEditorUI::InputEnumCombo(Convert::ToNative(field->Name), val, nativeEnumNames))
{ {
field->SetValue(object, val); field->SetValue(object, val);
} }
} }
else if RENDER_FIELD_CASTED(Vector2, vec2, InputVec2) else if RENDER_FIELD_CASTED(Vector2, SHVec2, InputVec2)
else if RENDER_FIELD_CASTED(Vector3, vec3, InputVec3) else if RENDER_FIELD_CASTED(Vector3, SHVec3, InputVec3)
else if (field->FieldType == String::typeid) else if (field->FieldType == String::typeid)
{ {
// Prevent issues where String^ is null due to being empty // Prevent issues where String^ is null due to being empty
@ -198,7 +214,7 @@ namespace SHADE
// Actual Field // Actual Field
std::string val = Convert::ToNative(stringVal); std::string val = Convert::ToNative(stringVal);
if (SHEditorUI::::InputTextField(Convert::ToNative(field->Name), val)) if (SHEditorUI::InputTextField(Convert::ToNative(field->Name), val))
{ {
field->SetValue(object, Convert::ToCLI(val)); field->SetValue(object, Convert::ToCLI(val));
} }

View File

@ -36,7 +36,13 @@ namespace SHADE
/// rendering code. /// rendering code.
/// </summary> /// </summary>
/// <param name="entity">The Entity to render the Scripts of.</param> /// <param name="entity">The Entity to render the Scripts of.</param>
static void RenderScriptsInInspector(Entity entity); 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: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -2,6 +2,9 @@ using SHADE;
public class TestScript : Script public class TestScript : Script
{ {
public double Speed = 1.0;
public Vector3 ATestVector;
public bool ABoolean;
private Transform Transform; private Transform Transform;
private double time = 0.0; private double time = 0.0;
public TestScript(GameObject gameObj) : base(gameObj) {} public TestScript(GameObject gameObj) : base(gameObj) {}
@ -21,7 +24,7 @@ public class TestScript : Script
} }
protected override void update() protected override void update()
{ {
time += 0.16; time += Speed * 0.16;
Transform.GlobalPosition = new Vector3(System.Math.Sin(time), System.Math.Cos(time), 0.0f); Transform.GlobalPosition = new Vector3(System.Math.Sin(time), System.Math.Cos(time), 0.0f);
} }
protected override void onDestroy() protected override void onDestroy()