2024-12-25 23:35:38 +00:00
|
|
|
#include "InspectorWindow.h"
|
2024-12-26 00:53:17 +00:00
|
|
|
#include <cstdio> // for debugging or printing if needed
|
|
|
|
#include <cstring> // for strcpy, if needed
|
|
|
|
|
|
|
|
#include <glm/gtc/type_ptr.hpp> // Required for glm::value_ptr
|
|
|
|
|
|
|
|
#include <vector>
|
2024-12-26 00:29:24 +00:00
|
|
|
|
2024-12-26 03:06:17 +00:00
|
|
|
extern std::vector<GameObject> g_GameObjects;
|
2024-12-27 01:34:34 +00:00
|
|
|
extern GameObject *g_SelectedObject; // Pointer to the currently selected object
|
2024-12-26 00:53:17 +00:00
|
|
|
|
|
|
|
void InspectorWindow::Show()
|
2024-12-25 23:35:38 +00:00
|
|
|
{
|
2024-12-25 23:42:58 +00:00
|
|
|
// Increase window/item spacing for a cleaner look
|
2024-12-25 23:35:38 +00:00
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(12, 12));
|
2024-12-26 00:53:17 +00:00
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6, 4));
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10, 10));
|
2024-12-25 23:35:38 +00:00
|
|
|
|
|
|
|
if (ImGui::Begin("Inspector"))
|
|
|
|
{
|
2024-12-25 23:42:58 +00:00
|
|
|
// Title label (white text)
|
2024-12-27 01:34:34 +00:00
|
|
|
if (g_SelectedObject)
|
2024-12-25 23:42:58 +00:00
|
|
|
{
|
2024-12-27 06:09:43 +00:00
|
|
|
|
|
|
|
if (g_SelectedObject == nullptr)
|
|
|
|
{
|
|
|
|
ImGui::Text("No object selected.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Display object name and component count
|
|
|
|
ImGui::Text("Editing Object: %s", g_SelectedObject->name.c_str());
|
2024-12-27 01:34:34 +00:00
|
|
|
ImGui::Text("Components: %d", g_SelectedObject->GetComponentCount());
|
2024-12-26 00:53:17 +00:00
|
|
|
|
2024-12-27 06:09:43 +00:00
|
|
|
ImGui::Spacing();
|
|
|
|
ImGui::Separator();
|
|
|
|
ImGui::Spacing();
|
|
|
|
|
|
|
|
// Begin two-column layout for labels and inputs
|
|
|
|
ImGui::Columns(2, "InspectorColumns", true); // 2 columns, ID "InspectorColumns", border=true
|
|
|
|
ImGui::SetColumnWidth(0, 100.0f); // Optional: Set fixed width for the first column
|
|
|
|
|
|
|
|
// Label in the first column
|
|
|
|
ImGui::Text("Tag:");
|
|
|
|
ImGui::NextColumn(); // Move to the second column
|
|
|
|
|
|
|
|
// Define buffer size
|
|
|
|
const size_t BUFFER_SIZE = 256;
|
|
|
|
|
|
|
|
// Allocate buffer and copy the current string
|
|
|
|
char buffer[BUFFER_SIZE];
|
|
|
|
std::strncpy(buffer, g_SelectedObject->name.c_str(), BUFFER_SIZE - 1);
|
|
|
|
buffer[BUFFER_SIZE - 1] = '\0'; // Ensure null-termination
|
|
|
|
|
|
|
|
// Unique identifier for the InputText to prevent ImGui state conflicts
|
|
|
|
const char *inputLabel = "##TagInput";
|
|
|
|
|
|
|
|
// Render InputText widget
|
|
|
|
if (ImGui::InputText(inputLabel, buffer, BUFFER_SIZE))
|
|
|
|
{
|
|
|
|
// Update the GameObject's name if modified
|
|
|
|
g_SelectedObject->name = buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::NextColumn(); // Move back to the first column (if adding more fields)
|
|
|
|
|
|
|
|
// End columns
|
|
|
|
ImGui::Columns(1);
|
|
|
|
|
|
|
|
ImGui::Spacing();
|
2024-12-27 01:34:34 +00:00
|
|
|
ImGui::Separator();
|
2024-12-25 23:42:58 +00:00
|
|
|
ImGui::Spacing();
|
2024-12-25 23:35:38 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
// ===========================
|
|
|
|
// 1) TRANSFORM
|
|
|
|
// ===========================
|
2024-12-27 05:31:12 +00:00
|
|
|
|
|
|
|
std::shared_ptr<TransformComponent> transform = g_SelectedObject->GetComponent<TransformComponent>();
|
|
|
|
std::shared_ptr<MeshComponent> mesh = g_SelectedObject->GetComponent<MeshComponent>();
|
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
// Color the Transform header
|
|
|
|
|
2024-12-27 05:31:12 +00:00
|
|
|
if (transform && g_SelectedObject) //! Funny: I did not put a null check here and it broke everything.
|
2024-12-25 23:42:58 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
|
2024-12-27 05:31:12 +00:00
|
|
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
bool transformOpen = ImGui::CollapsingHeader("Transform##Main", ImGuiTreeNodeFlags_DefaultOpen);
|
|
|
|
ImGui::PopStyleColor();
|
2024-12-27 01:34:34 +00:00
|
|
|
// Transform* transform = &g_SelectedObject->transform;
|
|
|
|
// printf("%p\n", &transform);
|
2024-12-27 05:31:12 +00:00
|
|
|
if (transformOpen)
|
2024-12-25 23:35:38 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
|
|
|
|
if (ImGui::IsItemHovered())
|
2024-12-26 00:53:17 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
ImGui::BeginTooltip();
|
|
|
|
ImGui::TextUnformatted("Controls the object's Position, Rotation, and Scale.");
|
|
|
|
ImGui::EndTooltip();
|
2024-12-26 00:53:17 +00:00
|
|
|
}
|
2024-12-25 23:42:58 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
// -----------------------------------
|
|
|
|
// Position
|
|
|
|
// -----------------------------------
|
|
|
|
ImGui::TextUnformatted("Position");
|
|
|
|
ImGui::Spacing();
|
2024-12-25 23:42:58 +00:00
|
|
|
|
2024-12-25 23:35:38 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
// We'll assign colors for X, Y, Z buttons
|
|
|
|
// (normal, hovered, active)
|
|
|
|
static const ImVec4 colX = ImVec4(1.0f, 0.4f, 0.4f, 1.0f);
|
|
|
|
static const ImVec4 colXHover = ImVec4(1.0f, 0.6f, 0.6f, 1.0f);
|
|
|
|
static const ImVec4 colXActive = ImVec4(1.0f, 0.2f, 0.2f, 1.0f);
|
|
|
|
|
|
|
|
static const ImVec4 colY = ImVec4(0.4f, 1.0f, 0.4f, 1.0f);
|
|
|
|
static const ImVec4 colYHover = ImVec4(0.6f, 1.0f, 0.6f, 1.0f);
|
|
|
|
static const ImVec4 colYActive = ImVec4(0.2f, 1.0f, 0.2f, 1.0f);
|
|
|
|
|
|
|
|
static const ImVec4 colZ = ImVec4(0.4f, 0.4f, 1.0f, 1.0f);
|
|
|
|
static const ImVec4 colZHover = ImVec4(0.6f, 0.6f, 1.0f, 1.0f);
|
|
|
|
static const ImVec4 colZActive = ImVec4(0.2f, 0.2f, 1.0f, 1.0f);
|
|
|
|
|
|
|
|
const char *axisNames[3] = {"X", "Y", "Z"};
|
|
|
|
// We'll reference transform.position here
|
|
|
|
float *pos = glm::value_ptr(transform->position);
|
|
|
|
|
|
|
|
ImGui::PushID("PositionRow");
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
// Determine color set
|
|
|
|
ImVec4 col, colH, colA;
|
|
|
|
if (i == 0)
|
|
|
|
{
|
|
|
|
col = colX;
|
|
|
|
colH = colXHover;
|
|
|
|
colA = colXActive;
|
|
|
|
}
|
|
|
|
else if (i == 1)
|
|
|
|
{
|
|
|
|
col = colY;
|
|
|
|
colH = colYHover;
|
|
|
|
colA = colYActive;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
col = colZ;
|
|
|
|
colH = colZHover;
|
|
|
|
colA = colZActive;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Push color style for button
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, col);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, colH);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, colA);
|
|
|
|
|
|
|
|
// Small button with the axis name
|
|
|
|
if (ImGui::Button(axisNames[i], ImVec2(20, 0)))
|
|
|
|
{
|
|
|
|
// No action on click, but we have a box with color
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::PopStyleColor(3);
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::SetNextItemWidth(60.0f);
|
|
|
|
ImGui::DragFloat((std::string("##Pos") + axisNames[i]).c_str(), &pos[i], 0.1f);
|
|
|
|
|
|
|
|
if (i < 2)
|
|
|
|
ImGui::SameLine(0, 15);
|
|
|
|
}
|
|
|
|
ImGui::PopID();
|
2024-12-25 23:35:38 +00:00
|
|
|
}
|
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
ImGui::Spacing();
|
|
|
|
ImGui::Separator();
|
2024-12-25 23:35:38 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
// -----------------------------------
|
|
|
|
// Rotation
|
|
|
|
// -----------------------------------
|
|
|
|
ImGui::TextUnformatted("Rotation");
|
|
|
|
ImGui::Spacing();
|
2024-12-25 23:35:38 +00:00
|
|
|
|
2024-12-26 00:53:17 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
// Same approach, but referencing transform.rotation
|
|
|
|
const char *axisNames[3] = {"X", "Y", "Z"};
|
|
|
|
float *rot = glm::value_ptr(transform->rotation);
|
|
|
|
|
|
|
|
// We can reuse the same color sets
|
|
|
|
ImGui::PushID("RotationRow");
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
// Decide color sets for X, Y, Z
|
|
|
|
ImVec4 col, colH, colA;
|
|
|
|
if (i == 0)
|
|
|
|
{
|
|
|
|
col = ImVec4(1.0f, 0.4f, 0.4f, 1.0f);
|
|
|
|
colH = ImVec4(1.0f, 0.6f, 0.6f, 1.0f);
|
|
|
|
colA = ImVec4(1.0f, 0.2f, 0.2f, 1.0f);
|
|
|
|
}
|
|
|
|
else if (i == 1)
|
|
|
|
{
|
|
|
|
col = ImVec4(0.4f, 1.0f, 0.4f, 1.0f);
|
|
|
|
colH = ImVec4(0.6f, 1.0f, 0.6f, 1.0f);
|
|
|
|
colA = ImVec4(0.2f, 1.0f, 0.2f, 1.0f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
col = ImVec4(0.4f, 0.4f, 1.0f, 1.0f);
|
|
|
|
colH = ImVec4(0.6f, 0.6f, 1.0f, 1.0f);
|
|
|
|
colA = ImVec4(0.2f, 0.2f, 1.0f, 1.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, col);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, colH);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, colA);
|
|
|
|
|
|
|
|
if (ImGui::Button(axisNames[i], ImVec2(20, 0)))
|
|
|
|
{
|
|
|
|
// No action
|
|
|
|
}
|
|
|
|
ImGui::PopStyleColor(3);
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::SetNextItemWidth(60.0f);
|
|
|
|
ImGui::DragFloat((std::string("##Rot") + axisNames[i]).c_str(), &rot[i], 0.1f);
|
|
|
|
|
|
|
|
if (i < 2)
|
|
|
|
ImGui::SameLine(0, 15);
|
|
|
|
}
|
|
|
|
ImGui::PopID();
|
2024-12-25 23:42:58 +00:00
|
|
|
}
|
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
ImGui::Spacing();
|
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
// -----------------------------------
|
|
|
|
// Scale
|
|
|
|
// -----------------------------------
|
|
|
|
ImGui::TextUnformatted("Scale");
|
|
|
|
ImGui::Spacing();
|
2024-12-25 23:42:58 +00:00
|
|
|
|
2024-12-25 23:35:38 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
const char *axisNames[3] = {"X", "Y", "Z"};
|
|
|
|
float *scl = glm::value_ptr(transform->scale);
|
|
|
|
|
|
|
|
ImGui::PushID("ScaleRow");
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
// same color approach
|
|
|
|
ImVec4 col, colH, colA;
|
|
|
|
if (i == 0)
|
|
|
|
{
|
|
|
|
col = ImVec4(1.0f, 0.4f, 0.4f, 1.0f);
|
|
|
|
colH = ImVec4(1.0f, 0.6f, 0.6f, 1.0f);
|
|
|
|
colA = ImVec4(1.0f, 0.2f, 0.2f, 1.0f);
|
|
|
|
}
|
|
|
|
else if (i == 1)
|
|
|
|
{
|
|
|
|
col = ImVec4(0.4f, 1.0f, 0.4f, 1.0f);
|
|
|
|
colH = ImVec4(0.6f, 1.0f, 0.6f, 1.0f);
|
|
|
|
colA = ImVec4(0.2f, 1.0f, 0.2f, 1.0f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
col = ImVec4(0.4f, 0.4f, 1.0f, 1.0f);
|
|
|
|
colH = ImVec4(0.6f, 0.6f, 1.0f, 1.0f);
|
|
|
|
colA = ImVec4(0.2f, 0.2f, 1.0f, 1.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, col);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, colH);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, colA);
|
|
|
|
|
|
|
|
if (ImGui::Button(axisNames[i], ImVec2(20, 0)))
|
|
|
|
{
|
|
|
|
// No action
|
|
|
|
}
|
|
|
|
ImGui::PopStyleColor(3);
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::SetNextItemWidth(60.0f);
|
|
|
|
ImGui::DragFloat((std::string("##Scl") + axisNames[i]).c_str(), &scl[i], 0.1f);
|
|
|
|
|
|
|
|
if (i < 2)
|
|
|
|
ImGui::SameLine(0, 15);
|
|
|
|
}
|
|
|
|
ImGui::PopID();
|
2024-12-25 23:35:38 +00:00
|
|
|
}
|
2024-12-25 23:42:58 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
ImGui::Spacing();
|
|
|
|
ImGui::Separator();
|
|
|
|
}
|
2024-12-25 23:42:58 +00:00
|
|
|
}
|
2024-12-25 23:35:38 +00:00
|
|
|
|
2024-12-27 05:31:12 +00:00
|
|
|
if (mesh && g_SelectedObject) //! Funny: I did not put a null check here and it broke everything.
|
2024-12-25 23:42:58 +00:00
|
|
|
{
|
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
// Transform* transform = &g_SelectedObject->transform;
|
2024-12-27 05:31:12 +00:00
|
|
|
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
bool meshOpen = ImGui::CollapsingHeader("Mesh##Main", ImGuiTreeNodeFlags_DefaultOpen);
|
|
|
|
ImGui::PopStyleColor();
|
2024-12-27 01:34:34 +00:00
|
|
|
// printf("%p\n", &transform);
|
2024-12-27 05:31:12 +00:00
|
|
|
if (meshOpen)
|
2024-12-25 23:42:58 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
|
|
|
|
int vao = static_cast<int>(mesh->vao);
|
2024-12-27 05:31:12 +00:00
|
|
|
if (ImGui::InputInt("vao", &vao, 1, 0))
|
2024-12-26 00:53:17 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
mesh->vao = static_cast<GLuint>(vao);
|
2024-12-25 23:42:58 +00:00
|
|
|
}
|
2024-12-27 01:34:34 +00:00
|
|
|
|
|
|
|
int indexCount = static_cast<int>(mesh->indexCount);
|
2024-12-27 05:31:12 +00:00
|
|
|
if (ImGui::InputInt("indexCount", &indexCount, 1, 0))
|
2024-12-26 00:53:17 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
mesh->indexCount = static_cast<GLuint>(indexCount);
|
2024-12-25 23:42:58 +00:00
|
|
|
}
|
2024-12-25 23:35:38 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
int textureID = static_cast<int>(mesh->textureID);
|
2024-12-27 05:31:12 +00:00
|
|
|
if (ImGui::InputInt("textureID", &textureID, 1, 0))
|
2024-12-25 23:35:38 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
mesh->textureID = static_cast<GLuint>(textureID);
|
2024-12-25 23:35:38 +00:00
|
|
|
}
|
2024-12-25 23:42:58 +00:00
|
|
|
}
|
2024-12-25 23:35:38 +00:00
|
|
|
}
|
|
|
|
ImGui::Spacing();
|
2024-12-27 01:34:34 +00:00
|
|
|
|
|
|
|
// ===========================
|
|
|
|
// 2) SCRIPT
|
|
|
|
// ===========================
|
|
|
|
// We keep script text in white
|
|
|
|
// if (ImGui::CollapsingHeader("Script##Main", ImGuiTreeNodeFlags_DefaultOpen))
|
|
|
|
//{
|
|
|
|
// if (ImGui::IsItemHovered())
|
|
|
|
// {
|
|
|
|
// ImGui::BeginTooltip();
|
|
|
|
// ImGui::TextUnformatted("Attach a script or logic component here.");
|
|
|
|
// ImGui::EndTooltip();
|
|
|
|
// }
|
|
|
|
|
|
|
|
// ImGui::TextUnformatted("Script Name:");
|
|
|
|
// ImGui::SameLine();
|
|
|
|
|
|
|
|
// {
|
|
|
|
// char buffer[128];
|
|
|
|
// std::snprintf(buffer, sizeof(buffer), "%s", script.scriptName.c_str());
|
|
|
|
// ImGui::SetNextItemWidth(-1);
|
|
|
|
// if (ImGui::InputText("##ScriptName", buffer, sizeof(buffer)))
|
|
|
|
// {
|
|
|
|
// script.scriptName = buffer;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// ImGui::Spacing();
|
|
|
|
|
|
|
|
// ImGui::TextUnformatted("Script Enabled:");
|
|
|
|
// ImGui::SameLine();
|
|
|
|
// ImGui::Checkbox("##ScriptEnabled", &script.enabled);
|
|
|
|
|
|
|
|
// ImGui::Spacing();
|
|
|
|
// ImGui::Separator();
|
|
|
|
//}
|
2024-12-25 23:35:38 +00:00
|
|
|
}
|
2024-12-27 01:34:34 +00:00
|
|
|
ImGui::End();
|
2024-12-25 23:35:38 +00:00
|
|
|
|
2024-12-27 06:09:43 +00:00
|
|
|
} //
|
2024-12-25 23:35:38 +00:00
|
|
|
|
|
|
|
// Restore style
|
|
|
|
ImGui::PopStyleVar(3);
|
|
|
|
}
|