update transformComponent style, and change the position of button 'Add Component'

This commit is contained in:
2026-01-01 00:57:23 +08:00
parent faecfe21ab
commit abf0a65bd6
2 changed files with 156 additions and 184 deletions

View File

@ -53,7 +53,7 @@ namespace FPSExample
RaycastHit hitInfo; RaycastHit hitInfo;
if (Input.IsKeyPressed(KeyCode.H) && if (Input.IsKeyPressed(KeyCode.H) &&
Physics.Raycast(m_CameraTransform.Position + (m_CameraTransform.Transform.Forward * 5.0f), Physics.Raycast(m_CameraTransform.Position + (m_CameraTransform.Transform.Forward),
m_CameraTransform.Transform.Forward, 20.0f, out hitInfo)) m_CameraTransform.Transform.Forward, 20.0f, out hitInfo))
{ {
FindEntityByID(hitInfo.EntityID).GetComponent<MeshComponent>().Mesh.GetMaterial(0).Set("u_AlbedoColor", new Vec3(1.0f ,0.0f, 0.0f)); FindEntityByID(hitInfo.EntityID).GetComponent<MeshComponent>().Mesh.GetMaterial(0).Set("u_AlbedoColor", new Vec3(1.0f ,0.0f, 0.0f));

View File

@ -44,7 +44,96 @@ namespace Prism
} }
} }
void SceneHierarchyPanel::SetSelected(Entity entity) static bool DrawVec3Control(const std::string& label, glm::vec3& values, const float resetValue = 0.0f, const float columnWidth = 100.0f)
{
const ImGuiIO& io = ImGui::GetIO();
const auto boldFont = io.Fonts->Fonts[0];
bool isChanged = false;
ImGui::PushID(label.c_str());
ImGui::Columns(2);
ImGui::SetColumnWidth(0, columnWidth);
ImGui::Text(label.c_str());
ImGui::NextColumn();
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, {0.0f, 0.0f});
const float lineHeight = GImGui->Font->LegacySize + GImGui->Style.FramePadding.y * 2.0f;
const ImVec2 buttonSize = {lineHeight + 3.0f, lineHeight};
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{0.8f, 0.1f, 0.15f, 1.0f});
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4{0.9f, 0.2f, 0.2f, 1.0f});
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4{0.8f, 0.1f, 0.15f, 1.0f});
ImGui::PushFont(boldFont);
if (ImGui::Button("X", buttonSize))
{
values.x = resetValue;
isChanged = true;
}
ImGui::PopFont();
ImGui::PopStyleColor(3);
ImGui::SameLine();
if (ImGui::DragFloat("##X", &values.x, 0.1f))
{
isChanged = true;
}
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{0.2f, 0.7f, 0.2f, 1.0f});
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4{0.3f, 0.8f, 0.3f, 1.0f});
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4{0.2f, 0.7f, 0.2f, 1.0f});
ImGui::PushFont(boldFont);
if (ImGui::Button("Y", buttonSize))
{
values.y = resetValue;
isChanged = true;
}
ImGui::PopFont();
ImGui::PopStyleColor(3);
ImGui::SameLine();
if (ImGui::DragFloat("##Y", &values.y, 0.1f))
{
isChanged = true;
}
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4{0.1f, 0.25f, 0.8f, 1.0f});
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4{0.2f, 0.35f, 0.9f, 1.0f});
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4{0.1f, 0.25f, 0.8f, 1.0f});
ImGui::PushFont(boldFont);
if (ImGui::Button("Z", buttonSize))
{
values.z = resetValue;
isChanged = true;
}
ImGui::PopFont();
ImGui::PopStyleColor(3);
ImGui::SameLine();
if (ImGui::DragFloat("##Z", &values.z, 0.1f))
{
isChanged = true;
}
ImGui::PopItemWidth();
ImGui::PopStyleVar();
ImGui::Columns(1);
ImGui::PopID();
return isChanged;
}
void SceneHierarchyPanel::SetSelected(const Entity entity)
{ {
m_SelectionContext = entity; m_SelectionContext = entity;
} }
@ -94,136 +183,6 @@ namespace Prism
{ {
DrawComponents(m_SelectionContext); DrawComponents(m_SelectionContext);
if (ImGui::Button("Add Component"))
ImGui::OpenPopup("AddComponentPanel");
if (ImGui::BeginPopup("AddComponentPanel"))
{
AddComponentPopup<CameraComponent>("Camera");
AddComponentPopup<MeshComponent>("Mesh");
AddComponentPopup<ScriptComponent>("Script");
AddComponentPopup<SpriteRendererComponent>("SpriteRenderer");
AddComponentPopup<RigidBody2DComponent>("RigidBody2D");
AddComponentPopup<BoxCollider2DComponent>("BoxCollider2D");
AddComponentPopup<CircleCollider2DComponent>("CircleCollider2D");
AddComponentPopup<RigidBodyComponent>("RigidBody");
AddComponentPopup<PhysicsMaterialComponent>("PhysicsMaterial");
AddComponentPopup<BoxColliderComponent>("BoxCollider");
AddComponentPopup<SphereColliderComponent>("SphereCollider");
AddComponentPopup<CapsuleColliderComponent>("CapsuleCollider");
AddComponentPopup<MeshColliderComponent>("MeshCollider");
/*
if (!m_SelectionContext.HasComponent<CameraComponent>())
{
if (ImGui::Button("Camera"))
{
m_SelectionContext.AddComponent<CameraComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<MeshComponent>())
{
if (ImGui::Button("Mesh"))
{
m_SelectionContext.AddComponent<MeshComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<ScriptComponent>())
{
if (ImGui::Button("Script"))
{
m_SelectionContext.AddComponent<ScriptComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<SpriteRendererComponent>())
{
if (ImGui::Button("Sprite Renderer"))
{
m_SelectionContext.AddComponent<SpriteRendererComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<RigidBody2DComponent>())
{
if (ImGui::Button("Rigidbody 2D"))
{
m_SelectionContext.AddComponent<RigidBody2DComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<BoxCollider2DComponent>())
{
if (ImGui::Button("Box Collider 2D"))
{
m_SelectionContext.AddComponent<BoxCollider2DComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<CircleCollider2DComponent>())
{
if (ImGui::Button("Circle Collider 2D"))
{
m_SelectionContext.AddComponent<CircleCollider2DComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<RigidBodyComponent>())
{
if (ImGui::Button("Rigidbody"))
{
m_SelectionContext.AddComponent<RigidBodyComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<PhysicsMaterialComponent>())
{
if (ImGui::Button("Physics Material"))
{
m_SelectionContext.AddComponent<PhysicsMaterialComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<BoxColliderComponent>())
{
if (ImGui::Button("Box Collider"))
{
m_SelectionContext.AddComponent<BoxColliderComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<SphereColliderComponent>())
{
if (ImGui::Button("Sphere Collider"))
{
m_SelectionContext.AddComponent<SphereColliderComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<CapsuleColliderComponent>())
{
if (ImGui::Button("Capsule Collider"))
{
m_SelectionContext.AddComponent<CapsuleColliderComponent>();
ImGui::CloseCurrentPopup();
}
}
if (!m_SelectionContext.HasComponent<MeshColliderComponent>())
{
if (ImGui::Button("Mesh Collider"))
{
m_SelectionContext.AddComponent<MeshColliderComponent>();
ImGui::CloseCurrentPopup();
}
}
*/
ImGui::EndPopup();
}
} }
} }
ImGui::End(); ImGui::End();
@ -252,11 +211,12 @@ namespace Prism
void SceneHierarchyPanel::DrawEntityNode(Entity entity) void SceneHierarchyPanel::DrawEntityNode(Entity entity)
{ {
const char* name = "Unnamed Entity"; auto name = "Unnamed Entity";
if (entity.HasComponent<TagComponent>()) if (entity.HasComponent<TagComponent>())
name = entity.GetComponent<TagComponent>().Tag.c_str(); name = entity.GetComponent<TagComponent>().Tag.c_str();
const ImGuiTreeNodeFlags node_flags = (entity == m_SelectionContext ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnArrow; ImGuiTreeNodeFlags node_flags = (entity == m_SelectionContext ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnArrow;
node_flags |= ImGuiTreeNodeFlags_SpanAvailWidth;
const bool opened = ImGui::TreeNodeEx((const void*)(uintptr_t)(uint32_t)entity, node_flags, name); const bool opened = ImGui::TreeNodeEx((const void*)(uintptr_t)(uint32_t)entity, node_flags, name);
if (ImGui::IsItemClicked()) if (ImGui::IsItemClicked())
{ {
@ -275,12 +235,15 @@ namespace Prism
} }
if (opened) if (opened)
{ {
// TODO: children
/*
if (entity.HasComponent<MeshComponent>()) if (entity.HasComponent<MeshComponent>())
{ {
auto mesh = entity.GetComponent<MeshComponent>().Mesh; auto mesh = entity.GetComponent<MeshComponent>().Mesh;
// if (mesh) // if (mesh)
// DrawMeshNode(mesh); // DrawMeshNode(mesh);
} }
*/
ImGui::TreePop(); ImGui::TreePop();
} }
@ -581,22 +544,29 @@ namespace Prism
template<typename T, typename UIFunction> template<typename T, typename UIFunction>
static void DrawComponent(const std::string& name, Entity entity, UIFunction uiFunction) static void DrawComponent(const std::string& name, Entity entity, UIFunction uiFunction)
{ {
const ImGuiTreeNodeFlags treeNodeFlags = ImGuiTreeNodeFlags_DefaultOpen |
ImGuiTreeNodeFlags_Framed |
ImGuiTreeNodeFlags_SpanAvailWidth |
ImGuiTreeNodeFlags_AllowOverlap |
ImGuiTreeNodeFlags_FramePadding;
if (entity.HasComponent<T>()) if (entity.HasComponent<T>())
{ {
bool removeComponent = false;
auto& component = entity.GetComponent<T>(); auto& component = entity.GetComponent<T>();
const bool open = ImGui::TreeNodeEx((void*)((uint32_t)entity | typeid(T).hash_code()), ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_AllowOverlap, name.c_str());
ImGui::SameLine(); const ImVec2 contentRegionAvailable = ImGui::GetContentRegionAvail();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{ 4, 4 });
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0, 0, 0, 0)); const float lineHeight = GImGui->Font->LegacySize + GImGui->Style.FramePadding.y * 2.0f;
if (ImGui::Button("+")) ImGui::Separator();
const bool open = ImGui::TreeNodeEx((void*)typeid(T).hash_code(), treeNodeFlags, name.c_str());
ImGui::PopStyleVar();
ImGui::SameLine(contentRegionAvailable.x - lineHeight * 0.5f);
if (ImGui::Button("+", ImVec2{ lineHeight, lineHeight }))
{ {
ImGui::OpenPopup("ComponentSettings"); ImGui::OpenPopup("ComponentSettings");
} }
ImGui::PopStyleColor(); bool removeComponent = false;
ImGui::PopStyleColor();
if (ImGui::BeginPopup("ComponentSettings")) if (ImGui::BeginPopup("ComponentSettings"))
{ {
@ -609,11 +579,8 @@ namespace Prism
if (open) if (open)
{ {
uiFunction(component); uiFunction(component);
ImGui::NextColumn();
ImGui::Columns(1);
ImGui::TreePop(); ImGui::TreePop();
} }
ImGui::Separator();
if (removeComponent) if (removeComponent)
entity.RemoveComponent<T>(); entity.RemoveComponent<T>();
@ -626,63 +593,71 @@ namespace Prism
auto id = entity.GetComponent<IDComponent>().ID; auto id = entity.GetComponent<IDComponent>().ID;
ImVec2 contentRegionAvailable = ImGui::GetContentRegionAvail();
if (entity.HasComponent<TagComponent>()) if (entity.HasComponent<TagComponent>())
{ {
auto& tag = entity.GetComponent<TagComponent>().Tag; auto& tag = entity.GetComponent<TagComponent>().Tag;
char buffer[256]; char buffer[256] = {};
memset(buffer, 0, 256);
memcpy(buffer, tag.c_str(), tag.length()); memcpy(buffer, tag.c_str(), tag.length());
ImGui::PushItemWidth(contentRegionAvailable.x * 0.5f);
if (ImGui::InputText("##Tag", buffer, 256)) if (ImGui::InputText("##Tag", buffer, 256))
{ {
tag = std::string(buffer); tag = std::string(buffer);
} }
ImGui::PopItemWidth();
} }
// ID // ID
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextDisabled("%llx", (uint64_t)id); ImGui::TextDisabled("%llx", (uint64_t)id);
const ImVec2 textSize = ImGui::CalcTextSize("Add Component");
ImGui::SameLine(contentRegionAvailable.x - (textSize.x + GImGui->Style.FramePadding.y));
if (ImGui::Button("Add Component"))
ImGui::OpenPopup("AddComponentPanel");
ImGui::Separator(); if (ImGui::BeginPopup("AddComponentPanel"))
{
AddComponentPopup<CameraComponent>("Camera");
AddComponentPopup<MeshComponent>("Mesh");
AddComponentPopup<ScriptComponent>("Script");
AddComponentPopup<SpriteRendererComponent>("SpriteRenderer");
AddComponentPopup<RigidBody2DComponent>("RigidBody2D");
AddComponentPopup<BoxCollider2DComponent>("BoxCollider2D");
AddComponentPopup<CircleCollider2DComponent>("CircleCollider2D");
AddComponentPopup<RigidBodyComponent>("RigidBody");
AddComponentPopup<PhysicsMaterialComponent>("PhysicsMaterial");
AddComponentPopup<BoxColliderComponent>("BoxCollider");
AddComponentPopup<SphereColliderComponent>("SphereCollider");
AddComponentPopup<CapsuleColliderComponent>("CapsuleCollider");
AddComponentPopup<MeshColliderComponent>("MeshCollider");
ImGui::EndPopup();
}
if (entity.HasComponent<TransformComponent>()) if (entity.HasComponent<TransformComponent>())
{ {
const ImGuiTreeNodeFlags treeNodeFlags = ImGuiTreeNodeFlags_DefaultOpen |
ImGuiTreeNodeFlags_Framed |
ImGuiTreeNodeFlags_SpanAvailWidth |
ImGuiTreeNodeFlags_AllowOverlap |
ImGuiTreeNodeFlags_FramePadding;
TransformComponent& transform = entity.GetComponent<TransformComponent>(); TransformComponent& transform = entity.GetComponent<TransformComponent>();
if (ImGui::TreeNodeEx((void*)((uint32_t)entity | typeid(TransformComponent).hash_code()), ImGuiTreeNodeFlags_DefaultOpen, "Transform")) if (ImGui::TreeNodeEx((void*)((uint32_t)entity | typeid(TransformComponent).hash_code()), treeNodeFlags, "Transform"))
{ {
ImGui::Columns(2); DrawVec3Control("Translation", transform.Translation);
ImGui::Text("Translation"); DrawVec3Control("Rotation", transform.Rotation);
ImGui::NextColumn(); DrawVec3Control("Scale", transform.Scale, 1.0f);
ImGui::PushItemWidth(-1);
ImGui::DragFloat3("##translation", glm::value_ptr(transform.Translation), 0.25f);
ImGui::PopItemWidth();
ImGui::NextColumn();
ImGui::Text("Rotation");
ImGui::NextColumn();
ImGui::PushItemWidth(-1);
ImGui::DragFloat3("##rotation", glm::value_ptr(transform.Rotation), 0.25f);
ImGui::PopItemWidth();
ImGui::NextColumn();
ImGui::Text("Scale");
ImGui::NextColumn();
ImGui::PushItemWidth(-1);
ImGui::DragFloat3("##scale", glm::value_ptr(transform.Scale), 0.05f);
ImGui::PopItemWidth();
ImGui::NextColumn();
ImGui::Columns(1);
ImGui::TreePop(); ImGui::TreePop();
} }
ImGui::Separator();
} }
DrawComponent<MeshComponent>("Mesh", entity, [](MeshComponent& meshComponent) { DrawComponent<MeshComponent>("Mesh", entity, [](MeshComponent& meshComponent) {
@ -709,7 +684,6 @@ namespace Prism
} }
}); });
DrawComponent<CameraComponent>("Camera", entity, [](CameraComponent& cameraComponent) { DrawComponent<CameraComponent>("Camera", entity, [](CameraComponent& cameraComponent) {
// Projection Type // Projection Type
const char* projTypeStrings[] = { "Perspective", "Orthographic" }; const char* projTypeStrings[] = { "Perspective", "Orthographic" };
@ -771,7 +745,7 @@ namespace Prism
DrawComponent<ScriptComponent>("Script", entity, [=](ScriptComponent& scriptComponent) mutable { DrawComponent<ScriptComponent>("Script", entity, [=](ScriptComponent& scriptComponent) mutable {
BeginPropertyGrid(); BeginPropertyGrid();
std::string oldName = scriptComponent.ModuleName; const std::string oldName = scriptComponent.ModuleName;
if (Property("Module Name", scriptComponent.ModuleName, !ScriptEngine::ModuleExists(scriptComponent.ModuleName))) // TODO: no live edit if (Property("Module Name", scriptComponent.ModuleName, !ScriptEngine::ModuleExists(scriptComponent.ModuleName))) // TODO: no live edit
{ {
// Shutdown old script // Shutdown old script
@ -869,7 +843,6 @@ namespace Prism
#endif #endif
}); });
DrawComponent<RigidBody2DComponent>("Rigidbody 2D", entity, [](RigidBody2DComponent& rb2dComponent) DrawComponent<RigidBody2DComponent>("Rigidbody 2D", entity, [](RigidBody2DComponent& rb2dComponent)
{ {
// Rigidbody2D Type // Rigidbody2D Type
@ -1055,7 +1028,6 @@ namespace Prism
EndPropertyGrid(); EndPropertyGrid();
}); });
DrawComponent<MeshColliderComponent>("Mesh Collider", entity, [](MeshColliderComponent& mcc) DrawComponent<MeshColliderComponent>("Mesh Collider", entity, [](MeshColliderComponent& mcc)
{ {
ImGui::Columns(3); ImGui::Columns(3);