添加场景的组件动态添加删除功能
This commit is contained in:
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-Bold.ttf
Normal file
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-Bold.ttf
Normal file
Binary file not shown.
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-BoldItalic.ttf
Normal file
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-ExtraBold.ttf
Normal file
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-ExtraBold.ttf
Normal file
Binary file not shown.
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-ExtraBoldItalic.ttf
Normal file
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-ExtraBoldItalic.ttf
Normal file
Binary file not shown.
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-Italic.ttf
Normal file
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-Italic.ttf
Normal file
Binary file not shown.
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-Light.ttf
Normal file
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-Light.ttf
Normal file
Binary file not shown.
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-LightItalic.ttf
Normal file
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-LightItalic.ttf
Normal file
Binary file not shown.
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-Regular.ttf
Normal file
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-Regular.ttf
Normal file
Binary file not shown.
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-Semibold.ttf
Normal file
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-Semibold.ttf
Normal file
Binary file not shown.
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-SemiboldItalic.ttf
Normal file
BIN
Sandbox/assets/fonts/OpenSans/OpenSans-SemiboldItalic.ttf
Normal file
Binary file not shown.
@ -57,16 +57,16 @@ namespace Hazel
|
||||
public:
|
||||
void OnUpdate(const TimeStep ts)
|
||||
{
|
||||
auto& transform = GetComponent<TransformComponent>().Transform;
|
||||
auto& translation = GetComponent<TransformComponent>().Translation;
|
||||
static const auto state = SDL_GetKeyboardState(nullptr);
|
||||
if (state[SDL_SCANCODE_A])
|
||||
transform[3][0] -= ts * speed;
|
||||
translation.x -= ts * speed;
|
||||
if (state[SDL_SCANCODE_D])
|
||||
transform[3][0] += ts * speed;
|
||||
translation.x += ts * speed;
|
||||
if (state[SDL_SCANCODE_W])
|
||||
transform[3][1] += ts * speed;
|
||||
translation.y += ts * speed;
|
||||
if (state[SDL_SCANCODE_S])
|
||||
transform[3][1] -= ts * speed;
|
||||
translation.y -= ts * speed;
|
||||
}
|
||||
private:
|
||||
float speed = 2.0f;
|
||||
@ -175,6 +175,8 @@ namespace Hazel
|
||||
|
||||
// Submit the DockSpace
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.WindowMinSize.x = 350.0f;
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||
{
|
||||
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
//
|
||||
|
||||
#include "SceneHierachyPanel.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <Hazel/Scene/Components.h>
|
||||
|
||||
@ -34,6 +34,13 @@ namespace Hazel
|
||||
m_SelectionContext = { };
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupContextWindow(0, ImGuiPopupFlags_MouseButtonRight | ImGuiPopupFlags_NoOpenOverItems))
|
||||
{
|
||||
if (ImGui::MenuItem("Create Empty Entity"))
|
||||
m_Context->CreateEntity("Empty Entity");
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
ImGui::Begin("Properties");
|
||||
@ -48,18 +55,172 @@ namespace Hazel
|
||||
void SceneHierachyPanel::DrawEntityNode(Entity entity)
|
||||
{
|
||||
auto& tag = entity.GetComponent<TagComponent>().Tag;
|
||||
bool entityDeleted = false;
|
||||
|
||||
ImGuiTreeNodeFlags flags = ((m_SelectionContext == entity) ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnArrow;
|
||||
flags |= ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||
const bool isopened = ImGui::TreeNodeEx((void*)(uint64_t)(uint32_t)entity, flags, tag.c_str());
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
m_SelectionContext = entity;
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
if (ImGui::MenuItem("Delete Entity"))
|
||||
entityDeleted = true;
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (isopened)
|
||||
{
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (entityDeleted)
|
||||
{
|
||||
m_Context->DestoryEntity(entity);
|
||||
if (m_SelectionContext == entity)
|
||||
{
|
||||
m_SelectionContext = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool DrawVec3Control(const std::string& label, glm::vec3& values, float resetValue = 0.0f, float columnWidth = 100.0f)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
auto boldFont = io.Fonts->Fonts[0];
|
||||
bool isChanged = false;
|
||||
ImGui::PushID(label.c_str());
|
||||
const ImGuiContext* context = ImGui::GetCurrentContext();
|
||||
|
||||
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});
|
||||
|
||||
float lineHeight = context->Font->FontSize + context->Style.FramePadding.y * 2.0f;
|
||||
// float lineHeight = GImGui->Font->FontSize + GImGui->Style.FramePadding.y * 2.0f;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
template<typename T, typename UIfunction>
|
||||
void DrawComponent(const std::string& name, Entity entity, UIfunction uiFunction)
|
||||
{
|
||||
constexpr ImGuiTreeNodeFlags treeNodeFlags = ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_FramePadding;;
|
||||
|
||||
if (entity.HasComponent<T>())
|
||||
{
|
||||
auto& component = entity.GetComponent<T>();
|
||||
|
||||
ImVec2 contextReginAvail = ImGui::GetContentRegionAvail();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {4.0f, 4.0f});
|
||||
auto context = ImGui::GetCurrentContext();
|
||||
float lineHeight = context->Font->FontSize + context->Style.FramePadding.y * 2.0f;
|
||||
|
||||
ImGui::Separator();
|
||||
bool open = ImGui::TreeNodeEx((void*)(uint64_t)typeid(T).hash_code(), treeNodeFlags, name.c_str());
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::SameLine(contextReginAvail.x - lineHeight * 0.5f);
|
||||
if (ImGui::Button("+", ImVec2(lineHeight, lineHeight)))
|
||||
{
|
||||
ImGui::OpenPopup("ComponentSettings");
|
||||
}
|
||||
|
||||
|
||||
bool removeComponent = false;
|
||||
if (ImGui::BeginPopup("ComponentSettings"))
|
||||
{
|
||||
if (ImGui::MenuItem("Remove Component"))
|
||||
removeComponent = true;
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (open)
|
||||
{
|
||||
uiFunction(component);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (removeComponent)
|
||||
entity.RemoveComponent<SpriteRendererComponent>();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneHierachyPanel::DrawComponents(Entity entity)
|
||||
@ -77,25 +238,44 @@ namespace Hazel
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.HasComponent<TransformComponent>())
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(-1);
|
||||
if (ImGui::Button("Add"))
|
||||
ImGui::OpenPopup("Add");
|
||||
if (ImGui::BeginPopup("Add"))
|
||||
{
|
||||
if (ImGui::TreeNodeEx((void*)(uint64_t)typeid(TransformComponent).hash_code(), ImGuiTreeNodeFlags_DefaultOpen, "Transform"))
|
||||
if (ImGui::MenuItem("Camera"))
|
||||
{
|
||||
auto& transform = entity.GetComponent<TransformComponent>().Transform;
|
||||
ImGui::DragFloat3("Position", glm::value_ptr(transform[3]), 0.01f);
|
||||
ImGui::TreePop();
|
||||
m_SelectionContext.AddComponent<CameraComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.HasComponent<CameraComponent>())
|
||||
{
|
||||
if (ImGui::TreeNodeEx((void*)(uint64_t)typeid(CameraComponent).hash_code(), ImGuiTreeNodeFlags_DefaultOpen, "Transform"))
|
||||
if (ImGui::MenuItem("Sprite"))
|
||||
{
|
||||
auto& cameraComponent = entity.GetComponent<CameraComponent>();
|
||||
auto& camera = cameraComponent.Camera;
|
||||
m_SelectionContext.AddComponent<SpriteRendererComponent>();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("isPrimary", &cameraComponent.Primary);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
DrawComponent<TransformComponent>("Transform", entity, [](auto& component)
|
||||
{
|
||||
DrawVec3Control("Translation", component.Translation);
|
||||
glm::vec3 rotation = glm::degrees(component.Rotation);
|
||||
if (DrawVec3Control("Rotation", rotation))
|
||||
{
|
||||
component.Rotation = glm::radians(rotation);
|
||||
}
|
||||
DrawVec3Control("Scale", component.Scale, 1.0f);
|
||||
|
||||
});
|
||||
|
||||
DrawComponent<CameraComponent>("Camera", entity, [](auto& component)
|
||||
{
|
||||
auto& camera = component.Camera;
|
||||
|
||||
ImGui::Checkbox("isPrimary", &component.Primary);
|
||||
static const char* projectionTypeStrings[] = { "Perspective", "Orthographic" };
|
||||
|
||||
const char* currentProjectionTypeString = projectionTypeStrings[(int)camera.GetProjectionType()];
|
||||
@ -146,23 +326,13 @@ namespace Hazel
|
||||
if (ImGui::DragFloat("Far", &far))
|
||||
camera.SetOrthographicFarClip(far);
|
||||
|
||||
ImGui::Checkbox("Fixed Aspect Ratio", &cameraComponent.FixedAspectRatio);
|
||||
ImGui::Checkbox("Fixed Aspect Ratio", &component.FixedAspectRatio);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.HasComponent<SpriteRendererComponent>())
|
||||
DrawComponent<SpriteRendererComponent>("Sprite Renderer", entity, [](auto& component)
|
||||
{
|
||||
if (ImGui::TreeNodeEx((void*)(uint64_t)typeid(SpriteRendererComponent).hash_code(), ImGuiTreeNodeFlags_DefaultOpen, "Sprite Renderer"))
|
||||
{
|
||||
auto& spriteRendererComponent = entity.GetComponent<SpriteRendererComponent>();
|
||||
ImGui::ColorEdit4("Color", glm::value_ptr(spriteRendererComponent.Color));
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
ImGui::ColorEdit4("Color", glm::value_ptr(component.Color));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ namespace Hazel
|
||||
{
|
||||
public:
|
||||
HazelEditor()
|
||||
: Application("Hazel Editor", 1280, 720)
|
||||
: Application("Hazel Editor", 1600, 900)
|
||||
{
|
||||
PushLayer(new EditorLayer());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user