添加场景的组件动态添加删除功能
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
set(PROJECT_NAME Hazel)
|
||||
project(${PROJECT_NAME})
|
||||
|
||||
add_subdirectory(vendor/SDL)
|
||||
set(SDL3_SHARED ON CACHE BOOL "Build SDL as shared library" FORCE)
|
||||
|
||||
add_subdirectory(vendor/spdlog)
|
||||
add_subdirectory(vendor/GLAD)
|
||||
@ -25,25 +27,17 @@ file(GLOB IMGUI ${IMGUI_INCLUDE_DIR}/*.cpp
|
||||
${IMGUI_INCLUDE_DIR}/backends/imgui_impl_opengl3.cpp
|
||||
${IMGUI_INCLUDE_DIR}/backends/imgui_impl_sdl3.cpp)
|
||||
|
||||
add_library(Hazel SHARED
|
||||
add_library(${PROJECT_NAME} SHARED
|
||||
${SOURCES}
|
||||
${IMGUI}
|
||||
${STB}
|
||||
${ENTT}
|
||||
${IMGUI}
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries" FORCE)
|
||||
add_subdirectory(vendor/SDL)
|
||||
set(SDL3_SHARED ON CACHE BOOL "Build SDL as shared library" FORCE)
|
||||
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src # 暴露头文件给其他项目
|
||||
${STB_INCLUDE_DIR}
|
||||
${STB_INCLUDE_DIR}
|
||||
${IMGUI_INCLUDE_DIR}
|
||||
${ENTT_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
@ -29,6 +29,7 @@ namespace Hazel
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
io.ConfigFlags |= ImGuiBackendFlags_HasMouseCursors;
|
||||
io.ConfigFlags |= ImGuiBackendFlags_HasSetMousePos;
|
||||
|
||||
@ -37,6 +38,17 @@ namespace Hazel
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // IF using Docking Branch
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
|
||||
io.Fonts->AddFontFromFileTTF("assets/fonts/OpenSans/OpenSans-Bold.ttf", 18.0f);
|
||||
io.FontDefault = io.Fonts->AddFontFromFileTTF("assets/fonts/OpenSans/OpenSans-Regular.ttf", 18.0f);
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
SetDarkThemeColors();
|
||||
|
||||
Application& app = Application::Get();
|
||||
auto window = static_cast<SDL_Window*>(app.GetWindow().GetNativeWindow());
|
||||
auto GL_Context = static_cast<SDL_GLContext>(app.GetWindow().GetNativeGLContext());
|
||||
@ -99,4 +111,38 @@ namespace Hazel
|
||||
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiLayer::SetDarkThemeColors()
|
||||
{
|
||||
auto& colors = ImGui::GetStyle().Colors;
|
||||
|
||||
colors[ImGuiCol_WindowBg] = ImVec4{ 0.1f, 0.105f, 0.11f, 1.0f };
|
||||
|
||||
// Headers
|
||||
colors[ImGuiCol_Header] = ImVec4{ 0.2f, 0.205f, 0.21f, 1.0f };
|
||||
colors[ImGuiCol_HeaderHovered] = ImVec4{ 0.3f, 0.305f, 0.31f, 1.0f };
|
||||
colors[ImGuiCol_HeaderActive] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f };
|
||||
|
||||
// Buttons
|
||||
colors[ImGuiCol_Button] = ImVec4{ 0.2f, 0.205f, 0.21f, 1.0f };
|
||||
colors[ImGuiCol_ButtonHovered] = ImVec4{ 0.3f, 0.305f, 0.31f, 1.0f };
|
||||
colors[ImGuiCol_ButtonActive] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f };
|
||||
|
||||
// Frame BG
|
||||
colors[ImGuiCol_FrameBg] = ImVec4{ 0.2f, 0.205f, 0.21f, 1.0f };
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4{ 0.3f, 0.305f, 0.31f, 1.0f };
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f };
|
||||
|
||||
// Tabs
|
||||
colors[ImGuiCol_Tab] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f };
|
||||
colors[ImGuiCol_TabHovered] = ImVec4{ 0.38f, 0.3805f, 0.381f, 1.0f };
|
||||
colors[ImGuiCol_TabActive] = ImVec4{ 0.28f, 0.2805f, 0.281f, 1.0f };
|
||||
colors[ImGuiCol_TabUnfocused] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f };
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImVec4{ 0.2f, 0.205f, 0.21f, 1.0f };
|
||||
|
||||
// Title
|
||||
colors[ImGuiCol_TitleBg] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f };
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f };
|
||||
colors[ImGuiCol_TitleBgCollapsed] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f };
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,10 @@ namespace Hazel {
|
||||
|
||||
void BlockEvents(const bool block) {m_BlockEvent = block;}
|
||||
|
||||
private:
|
||||
private:
|
||||
void SetDarkThemeColors();
|
||||
|
||||
private:
|
||||
bool m_BlockEvent = true;
|
||||
float m_Time = 0.0f;
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
#ifndef COMPONENTS_H
|
||||
#define COMPONENTS_H
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <Hazel/Renderer/Camera.h>
|
||||
#include <Hazel/Renderer/ScenceCamera.h>
|
||||
|
||||
@ -14,16 +15,26 @@ namespace Hazel
|
||||
{
|
||||
struct TransformComponent
|
||||
{
|
||||
glm::mat4 Transform{1.0f};
|
||||
glm::vec3 Translation{0.0f};
|
||||
glm::vec3 Rotation{0.0f};
|
||||
glm::vec3 Scale{1.0f};
|
||||
|
||||
TransformComponent() = default;
|
||||
TransformComponent(const TransformComponent&) = default;
|
||||
|
||||
TransformComponent(const glm::mat4& transform) : Transform(transform)
|
||||
TransformComponent(const glm::vec3& translation) : Translation(translation)
|
||||
{
|
||||
}
|
||||
|
||||
operator glm::mat4&() { return Transform; }
|
||||
operator const glm::mat4&() const { return Transform; }
|
||||
glm::mat4 GetTransform() const
|
||||
{
|
||||
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), Rotation.x, glm::vec3(1.0f, 0.0f, 0.0f))
|
||||
* glm::rotate(glm::mat4(1.0f), Rotation.y, glm::vec3(0.0f, 1.0f, 0.0f))
|
||||
* glm::rotate(glm::mat4(1.0f), Rotation.z, glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
|
||||
return glm::translate(glm::mat4(1.0f), Translation) * rotation * glm::scale(glm::mat4(1.0f), Scale);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct SpriteRendererComponent
|
||||
|
||||
@ -26,10 +26,11 @@ namespace Hazel
|
||||
if (HasComponent<T>())
|
||||
{
|
||||
HZ_CORE_WARN("Entity already has this Component!");
|
||||
return GetComponent<T>();
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return m_Scene->m_Registry.emplace<T>(m_EntityHandle, std::forward<Args>(args)...);
|
||||
T& component = m_Scene->m_Registry.emplace<T>(m_EntityHandle, std::forward<Args>(args)...);
|
||||
m_Scene->OnComponentAdded<T>(*this, component);
|
||||
return component;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -66,7 +67,8 @@ namespace Hazel
|
||||
}
|
||||
|
||||
explicit operator bool() const { return m_EntityHandle != entt::null; }
|
||||
operator uint32_t() const { return static_cast<uint32_t>(m_EntityHandle); }
|
||||
explicit operator uint32_t() const { return static_cast<uint32_t>(m_EntityHandle); }
|
||||
operator entt::entity() const { return m_EntityHandle; }
|
||||
|
||||
bool operator==(const Entity& other) const { return m_EntityHandle == other.m_EntityHandle && m_Scene == other.m_Scene; }
|
||||
bool operator!=(const Entity& other) const { return !(*this==other); }
|
||||
|
||||
@ -29,6 +29,11 @@ namespace Hazel
|
||||
return entity;
|
||||
}
|
||||
|
||||
void Scene::DestoryEntity(const Entity entity)
|
||||
{
|
||||
m_Registry.destroy(entity);
|
||||
}
|
||||
|
||||
void Scene::OnUpdate(TimeStep& ts)
|
||||
{
|
||||
|
||||
@ -51,7 +56,7 @@ namespace Hazel
|
||||
|
||||
// Renderer 2D
|
||||
Camera* mainCamera = nullptr;
|
||||
glm::mat4* cameraTranform = nullptr;
|
||||
glm::mat4 cameraTranform;
|
||||
{
|
||||
for (auto view = m_Registry.view<TransformComponent, CameraComponent>(); const auto entity : view)
|
||||
{
|
||||
@ -60,7 +65,7 @@ namespace Hazel
|
||||
if (camera.Primary)
|
||||
{
|
||||
mainCamera = &camera.Camera;
|
||||
cameraTranform = &transform.Transform;
|
||||
cameraTranform = transform.GetTransform();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -70,14 +75,14 @@ namespace Hazel
|
||||
if (mainCamera != nullptr)
|
||||
{
|
||||
|
||||
Renderer2D::BeginScene(mainCamera->GetProjection(), *cameraTranform);
|
||||
Renderer2D::BeginScene(mainCamera->GetProjection(), cameraTranform);
|
||||
|
||||
auto group = m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
|
||||
for (auto entity : group)
|
||||
{
|
||||
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
|
||||
|
||||
Renderer2D::DrawQuad(transform, sprite.Color);
|
||||
Renderer2D::DrawQuad(transform.GetTransform(), sprite.Color);
|
||||
}
|
||||
|
||||
Renderer2D::EndScene();
|
||||
@ -102,4 +107,43 @@ namespace Hazel
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Scene::OnComponentAdded(Entity entity, T& component)
|
||||
{
|
||||
static_assert(false);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<TransformComponent>(Entity entity, TransformComponent& component)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<CameraComponent>(Entity entity, CameraComponent& component)
|
||||
{
|
||||
component.Camera.SetViewPortSize(m_ViewportWidth, m_ViewportHeight);
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<SpriteRendererComponent>(Entity entity, SpriteRendererComponent& component)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<TagComponent>(Entity entity, TagComponent& component)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void Scene::OnComponentAdded<NativeScriptComponent>(Entity entity, NativeScriptComponent& component)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template HAZEL_API void Scene::OnComponentAdded<TransformComponent>(Entity, TransformComponent&);
|
||||
template HAZEL_API void Scene::OnComponentAdded<CameraComponent>(Entity, CameraComponent&);
|
||||
template HAZEL_API void Scene::OnComponentAdded<TagComponent>(Entity, TagComponent&);
|
||||
template HAZEL_API void Scene::OnComponentAdded<SpriteRendererComponent>(Entity, SpriteRendererComponent&);
|
||||
template HAZEL_API void Scene::OnComponentAdded<NativeScriptComponent>(Entity, NativeScriptComponent&);
|
||||
}
|
||||
|
||||
@ -24,9 +24,18 @@ namespace Hazel
|
||||
|
||||
Entity CreateEntity(const std::string& name = "");
|
||||
|
||||
void DestoryEntity(Entity entity);
|
||||
|
||||
void OnUpdate(TimeStep& ts);
|
||||
void OnViewportResize(uint32_t width, uint32_t height);
|
||||
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
void OnComponentAdded(Entity entity, T& component);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
entt::registry m_Registry;
|
||||
|
||||
|
||||
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