530 lines
17 KiB
C++
530 lines
17 KiB
C++
//
|
|
// Created by sfd on 25-5-25.
|
|
//
|
|
|
|
#include "EditorLayer.h"
|
|
|
|
#include <imgui.h>
|
|
#include <ImGuizmo.h>
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
#include <Hazel/Core/Input.h>
|
|
#include <Hazel/Math/Math.h>
|
|
#include <Hazel/Scene/SceneSerializer.h>
|
|
#include <Hazel/Utils/PlatformUtils.h>
|
|
|
|
#include "glm/gtx/matrix_decompose.hpp"
|
|
|
|
namespace Hazel
|
|
{
|
|
|
|
extern const std::filesystem::path g_AssetPath;
|
|
|
|
EditorLayer::EditorLayer()
|
|
: Layer("HazelEditor"), m_CameraController((float)Application::Get().GetWindow().GetWidth() / (float)Application::Get().GetWindow().GetHeight())
|
|
{
|
|
|
|
}
|
|
|
|
void EditorLayer::OnAttach()
|
|
{
|
|
FrameBufferSpecification spec;
|
|
spec.Width = Application::Get().GetWindow().GetWidth();
|
|
spec.Height = Application::Get().GetWindow().GetHeight();
|
|
spec.Attachments = { FrameBufferTextureFormat::RGBA8, FrameBufferTextureFormat::RED_INTEGER,FrameBufferTextureFormat::DEPTH };
|
|
m_FrameBuffer = FrameBuffer::Create(spec);
|
|
|
|
m_ViewPortSize = { spec.Width, spec.Height };
|
|
|
|
m_LogoTexture = Texture2D::Create("assets/textures/iceLogo.png");
|
|
m_CheckerBoardTexture = Texture2D::Create("assets/textures/Checkerboard.png");
|
|
|
|
m_PlayIcon = Texture2D::Create("Resources/Icons/PlayButton.png");
|
|
m_StopIcon = Texture2D::Create("Resources/Icons/PauseButton.png");
|
|
|
|
m_ActiveScene = CreateRef<Scene>();
|
|
|
|
m_EditorCamera = EditorCamera(45.0f, 1.667f, 0.1f, 1000.0f);
|
|
|
|
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
|
}
|
|
|
|
void EditorLayer::OnDetech()
|
|
{
|
|
}
|
|
|
|
void EditorLayer::OnUpdate(TimeStep& ts)
|
|
{
|
|
// reset Renderer Draw Stats
|
|
Renderer2D::ResetStats();
|
|
|
|
if (const auto& spec = m_FrameBuffer->GetSpecification();
|
|
spec.Width != m_ViewPortSize.x || spec.Height != m_ViewPortSize.y)
|
|
{
|
|
m_FrameBuffer->Resize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
|
|
m_CameraController.OnResize(m_ViewPortSize.x, m_ViewPortSize.y);
|
|
|
|
m_EditorCamera.SetViewPortSize(m_ViewPortSize.x, m_ViewPortSize.y);
|
|
m_ActiveScene->OnViewportResize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
|
|
|
|
}
|
|
|
|
// update camera
|
|
|
|
// update Renderer
|
|
m_FrameBuffer->Bind();
|
|
RendererCommand::SetClearColor(m_BackgroundColor);
|
|
RendererCommand::Clear();
|
|
|
|
m_FrameBuffer->ClearAttachment(1, -1);
|
|
|
|
switch (m_SceneState)
|
|
{
|
|
case SceneState::Play:
|
|
m_ActiveScene->OnUpdateRuntime(ts);
|
|
break;
|
|
case SceneState::Edit:
|
|
if (m_ViewportFocused)
|
|
m_CameraController.OnUpdate(ts);
|
|
|
|
m_EditorCamera.OnUpdate(ts);
|
|
m_ActiveScene->OnUpdateEditor(ts, m_EditorCamera);
|
|
break;
|
|
}
|
|
|
|
// Renderer2D::BeginScene(m_CameraController.GetCamera());
|
|
|
|
auto [mx, my] = ImGui::GetMousePos();
|
|
mx -= m_ViewPortBounds[0].x;
|
|
my -= m_ViewPortBounds[0].y;
|
|
const glm::vec2 viewPortSize = m_ViewPortBounds[1] - m_ViewPortBounds[0];
|
|
my = viewPortSize.y - my;
|
|
|
|
int mouseX = (int)mx;
|
|
int mouseY = (int)my;
|
|
|
|
if (mouseX >= 0 && mouseY >= 0 && mouseX < m_ViewPortSize.x && mouseY < m_ViewPortSize.y)
|
|
{
|
|
int pixelData = m_FrameBuffer->ReadPixel(1, mouseX, mouseY);
|
|
m_HoveredEntity = pixelData == -1 ? Entity{} : Entity{ (entt::entity)pixelData, m_ActiveScene.get()};
|
|
}
|
|
|
|
// Renderer2D::DrawQuad({0, 0.5f}, {1.0f, 1.0f}, {0.2f, 0.3f, 0.8f, 1.0f});
|
|
// Renderer2D::DrawQuad({0, -0.5f}, {1.0f, 1.0f}, {0.8f, 0.2f, 0.2f, 1.0f});
|
|
// Renderer2D::DrawQuad({-1, 0}, {1, 1}, m_LogoTexture);
|
|
// Renderer2D::DrawQuad({1, 0}, {1, 1}, m_CheckerBoardTexture);
|
|
|
|
// Renderer2D::EndScene();
|
|
m_FrameBuffer->UnBind();
|
|
}
|
|
|
|
void EditorLayer::OnImGuiRender()
|
|
{
|
|
static bool showDockspace = true;
|
|
if (showDockspace)
|
|
{
|
|
static bool dockspaceOpen = true;
|
|
static bool opt_fullscreen = true;
|
|
static bool opt_padding = false;
|
|
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
|
|
|
|
// We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into,
|
|
// because it would be confusing to have two docking targets within each others.
|
|
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
|
if (opt_fullscreen)
|
|
{
|
|
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
|
ImGui::SetNextWindowPos(viewport->WorkPos);
|
|
ImGui::SetNextWindowSize(viewport->WorkSize);
|
|
ImGui::SetNextWindowViewport(viewport->ID);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
|
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
|
|
ImGuiWindowFlags_NoMove;
|
|
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
|
}
|
|
else
|
|
{
|
|
dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
|
|
}
|
|
|
|
// When using ImGuiDockNodeFlags_PassthruCentralNode, DockSpace() will render our background
|
|
// and handle the pass-thru hole, so we ask Begin() to not render a background.
|
|
if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
|
|
window_flags |= ImGuiWindowFlags_NoBackground;
|
|
|
|
// Important: note that we proceed even if Begin() returns false (aka window is collapsed).
|
|
// This is because we want to keep our DockSpace() active. If a DockSpace() is inactive,
|
|
// all active windows docked into it will lose their parent and become undocked.
|
|
// We cannot preserve the docking relationship between an active window and an inactive docking, otherwise
|
|
// any change of dockspace/settings would lead to windows being stuck in limbo and never being visible.
|
|
if (!opt_padding)
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
|
ImGui::Begin("DockSpace Demo", &dockspaceOpen, window_flags);
|
|
if (!opt_padding)
|
|
ImGui::PopStyleVar();
|
|
|
|
if (opt_fullscreen)
|
|
ImGui::PopStyleVar(2);
|
|
|
|
// 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");
|
|
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
|
}
|
|
|
|
if (ImGui::BeginMenuBar())
|
|
{
|
|
if (ImGui::BeginMenu("Options"))
|
|
{
|
|
// Disabling fullscreen would allow the window to be moved to the front of other windows,
|
|
// which we can't undo at the moment without finer window depth/z control.
|
|
// ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen);
|
|
// ImGui::MenuItem("Padding", NULL, &opt_padding);
|
|
// ImGui::Separator();
|
|
if (ImGui::MenuItem("New", "Ctrl+N"))
|
|
NewScene();
|
|
if (ImGui::MenuItem("Open...", "Ctrl+O"))
|
|
OpenScene();
|
|
if (ImGui::MenuItem("Save As...", "Ctrl+Shift+S"))
|
|
SaveScene();
|
|
|
|
ImGui::Separator();
|
|
if (ImGui::MenuItem("Exit")) { Hazel::Application::Get().Close(); }
|
|
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
ImGui::EndMenuBar();
|
|
}
|
|
|
|
// Scene Hierachy Panel
|
|
m_SceneHierachyPanel.OnImGuiRender();
|
|
m_ContentBroswerPanel.OnImGuiRender();
|
|
|
|
// Render Status
|
|
{
|
|
ImGui::Begin("Render Status");
|
|
|
|
auto stats = Renderer2D::GetStats();
|
|
ImGui::Text("Renderer BatchInfo: ");
|
|
ImGui::Text("Draw Calls: %d", stats.DrawCalls);
|
|
ImGui::Text("Quads: %d", stats.QuadCount);
|
|
ImGui::Text("Vertices: %d", stats.GetTotalVertexCount());
|
|
ImGui::Text("Indices: %d", stats.GetTotalIndexCount());
|
|
|
|
ImGui::Separator();
|
|
|
|
ImGui::Text("viewPortSize: (%.2f, %.2f)", m_ViewPortSize.x, m_ViewPortSize.y);
|
|
|
|
ImGui::Separator();
|
|
|
|
std::string name = "none";
|
|
if (m_HoveredEntity)
|
|
name = m_HoveredEntity.GetComponent<TagComponent>().Tag;
|
|
|
|
ImGui::Text("Hovered Entity: %s", name.c_str());
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
// ViewPort
|
|
{
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {0.0f, 0.0f});
|
|
ImGui::Begin("Viewport");
|
|
auto viewportOffet = ImGui::GetCursorPos();
|
|
m_ViewportFocused = ImGui::IsWindowFocused();
|
|
m_ViewportHovered = ImGui::IsWindowHovered();
|
|
|
|
|
|
ImVec2 viewPortPanelSize = ImGui::GetContentRegionAvail();
|
|
if (m_ViewPortSize != *reinterpret_cast<glm::vec2*>(&viewPortPanelSize))
|
|
{
|
|
m_ViewPortSize = {viewPortPanelSize.x, viewPortPanelSize.y};
|
|
}
|
|
// ImGui::Text("Viewport: (%.2f, %.2f)", viewPortPanelSize.x, viewPortPanelSize.y);
|
|
ImGui::Image(m_FrameBuffer->GetColorAttachmentID(), {m_ViewPortSize.x, m_ViewPortSize.y}, {0, 1},
|
|
{1, 0});
|
|
|
|
if (ImGui::BeginDragDropTarget())
|
|
{
|
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("CONTENT_BROSWER_ITEM"))
|
|
{
|
|
const wchar_t* path = (const wchar_t*)payload->Data;
|
|
OpenScene(std::filesystem::path(g_AssetPath) / path);
|
|
}
|
|
ImGui::EndDragDropTarget();
|
|
}
|
|
|
|
auto windowsSize = ImGui::GetWindowSize();
|
|
ImVec2 minBound = ImGui::GetWindowPos();
|
|
|
|
|
|
minBound.x += viewportOffet.x;
|
|
minBound.y += viewportOffet.y + m_ViewPortSize.y - windowsSize.y;
|
|
|
|
ImVec2 maxBound = {minBound.x + windowsSize.x, minBound.y + windowsSize.y};
|
|
m_ViewPortBounds[0] = {minBound.x, minBound.y};
|
|
m_ViewPortBounds[1] = {maxBound.x, maxBound.y};
|
|
|
|
// ImGuizmo
|
|
Entity selectedEntity = m_SceneHierachyPanel.GetSelectedEntity();
|
|
if (selectedEntity)
|
|
{
|
|
ImGuizmo::SetOrthographic(false);
|
|
ImGuizmo::SetDrawlist();
|
|
|
|
const float windowWidth = ImGui::GetWindowWidth();
|
|
const float windowHeight = ImGui::GetWindowHeight();
|
|
|
|
ImVec2 windowPos = ImGui::GetWindowPos();
|
|
windowPos.y += m_ViewPortSize.y - windowsSize.y;
|
|
|
|
ImGuizmo::SetRect(windowPos.x, windowPos.y, windowWidth, windowHeight);
|
|
|
|
if (m_GizmoType != -1)
|
|
{
|
|
|
|
glm::mat4 cameraProjection;
|
|
glm::mat4 cameraView;
|
|
|
|
if (m_SceneState == SceneState::Play)
|
|
{
|
|
auto cameraEntity = m_ActiveScene->GetPrimaryCameraEntity();
|
|
const auto& camera = cameraEntity.GetComponent<CameraComponent>().Camera;
|
|
|
|
cameraProjection = camera.GetProjection();
|
|
cameraView = glm::inverse(cameraEntity.GetComponent<TransformComponent>().GetTransform());
|
|
}else if (m_SceneState == SceneState::Edit)
|
|
{
|
|
cameraProjection = m_EditorCamera.GetProjection();
|
|
cameraView = m_EditorCamera.GetViewMatrix();
|
|
}
|
|
|
|
auto& tc = selectedEntity.GetComponent<TransformComponent>();
|
|
|
|
glm::mat4 transform = tc.GetTransform();
|
|
bool snap = SDL_GetModState() & SDL_KMOD_CTRL;
|
|
float snapValue = 0.5f;
|
|
if (m_GizmoType == ImGuizmo::OPERATION::TRANSLATE)
|
|
snapValue = 0.25f;
|
|
else if (m_GizmoType == ImGuizmo::OPERATION::ROTATE)
|
|
snapValue = 15.0f;
|
|
else if (m_GizmoType == ImGuizmo::OPERATION::SCALE)
|
|
snapValue = 0.25f;
|
|
|
|
float snapValues[3] = {snapValue, snapValue, snapValue};
|
|
if (ImGuizmo::Manipulate(glm::value_ptr(cameraView), glm::value_ptr(cameraProjection),
|
|
static_cast<ImGuizmo::OPERATION>(m_GizmoType), ImGuizmo::WORLD,
|
|
glm::value_ptr(transform), nullptr, snap ? snapValues : nullptr) && !Input::IsKeyPressed(SDL_SCANCODE_LALT))
|
|
{
|
|
if (ImGuizmo::IsUsing())
|
|
{
|
|
glm::vec3 translation, rotation, scale;
|
|
|
|
Hazel::Math::DecomposeTransform(transform, translation, rotation, scale);
|
|
|
|
glm::vec3 deltaRotation = rotation - tc.Rotation;
|
|
|
|
tc.Translation = translation;
|
|
tc.Rotation += deltaRotation;
|
|
tc.Scale = scale;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
ImGui::End();
|
|
ImGui::PopStyleVar();
|
|
}
|
|
|
|
UI_ToolBar();
|
|
|
|
ImGui::End();
|
|
}
|
|
}
|
|
|
|
void EditorLayer::SaveScene() const
|
|
{
|
|
std::string filepath = FileDiaglogs::SaveFile("Hazel Scene (*.scene,*.yaml)\0*.scene;*.yaml\0*\0*.*\0\0");
|
|
if (!filepath.empty())
|
|
{
|
|
SceneSerializer serializer(m_ActiveScene);
|
|
serializer.Serialize(filepath);
|
|
}
|
|
}
|
|
|
|
void EditorLayer::OpenScene()
|
|
{
|
|
std::string filepath = FileDiaglogs::OpenFile("Scene(*.scene, *.yaml)\0*.scene;*.yaml\0All files\0*.*\0\0");
|
|
if (!filepath.empty())
|
|
OpenScene(filepath);
|
|
}
|
|
|
|
void EditorLayer::OpenScene(const std::filesystem::path& scenePath)
|
|
{
|
|
if (m_SceneState != SceneState::Edit)
|
|
OnSceneStop();
|
|
|
|
Ref<Scene> newScene = CreateRef<Scene>();
|
|
SceneSerializer serializer(newScene);
|
|
if (serializer.Deserialize(scenePath.string()))
|
|
{
|
|
m_EditorScene = newScene;
|
|
m_EditorScene->OnViewportResize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
|
|
|
|
m_ActiveScene = m_EditorScene;
|
|
|
|
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
|
}
|
|
|
|
/*
|
|
m_ActiveScene = CreateRef<Scene>();
|
|
m_ActiveScene->OnViewportResize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
|
|
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
|
|
|
SceneSerializer serializer(m_ActiveScene);
|
|
serializer.Deserialize(scenePath.string());
|
|
*/
|
|
|
|
}
|
|
|
|
void EditorLayer::NewScene()
|
|
{
|
|
m_ActiveScene = CreateRef<Scene>();
|
|
m_ActiveScene->OnViewportResize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
|
|
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
|
}
|
|
|
|
void EditorLayer::OnDuplicateEntity()
|
|
{
|
|
if (m_SceneState != SceneState::Edit)
|
|
return;
|
|
Entity selectedEntity = m_SceneHierachyPanel.GetSelectedEntity();
|
|
if (selectedEntity)
|
|
m_EditorScene->DuplicateEntity(selectedEntity);
|
|
}
|
|
|
|
void EditorLayer::OnScenePlay()
|
|
{
|
|
m_SceneState = SceneState::Play;
|
|
|
|
m_ActiveScene = Scene::Copy(m_EditorScene);
|
|
m_ActiveScene->OnRuntimeStart();
|
|
|
|
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
|
}
|
|
|
|
void EditorLayer::OnSceneStop()
|
|
{
|
|
m_SceneState = SceneState::Edit;
|
|
m_ActiveScene->OnRuntimeStop();
|
|
m_ActiveScene = m_EditorScene;
|
|
|
|
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
|
}
|
|
|
|
void EditorLayer::ChangeOptMode(unsigned int mode)
|
|
{
|
|
if (m_ViewportHovered)
|
|
m_GizmoType = mode;
|
|
}
|
|
|
|
void EditorLayer::OnEvent(SDL_Event& e)
|
|
{
|
|
if (m_ViewportFocused)
|
|
{
|
|
m_CameraController.OnEvent(e);
|
|
m_EditorCamera.OnEvent(e);
|
|
}
|
|
if (e.button.clicks && m_ViewportHovered && !ImGuizmo::IsOver() && Input::IsMouseButtonPressed(SDL_BUTTON_LEFT) && !Input::IsKeyPressed(SDL_SCANCODE_LALT))
|
|
m_SceneHierachyPanel.SetSelectedEntity(m_HoveredEntity);
|
|
|
|
#define SHORTCUT_EXIT (SDL_KMOD_CTRL | SDLK_W)
|
|
#define SHORTCUT_NEW (SDL_KMOD_CTRL | SDLK_N)
|
|
#define SHORTCUT_OPEN (SDL_KMOD_CTRL | SDLK_O)
|
|
#define SHORTCUT_SAVE_ALL (SDL_KMOD_CTRL | SDL_KMOD_SHIFT | SDLK_S)
|
|
#define SHORTCUT_CTRL_D (SDL_KMOD_CTRL | SDLK_D)
|
|
|
|
const auto mod = SDL_GetModState();
|
|
const auto ctrl = (mod & SDL_KMOD_CTRL) ? SDL_KMOD_CTRL : 0;
|
|
const auto shift = (mod & SDL_KMOD_SHIFT) ? SDL_KMOD_SHIFT : 0;
|
|
if (e.key.down && e.key.repeat == 0)
|
|
switch (ctrl | shift | e.key.key)
|
|
{
|
|
case SHORTCUT_EXIT:
|
|
Application::Get().Close();
|
|
break;
|
|
case SHORTCUT_NEW:
|
|
NewScene();
|
|
break;
|
|
case SHORTCUT_OPEN:
|
|
OpenScene();
|
|
break;
|
|
case SHORTCUT_SAVE_ALL:
|
|
SaveScene();
|
|
break;
|
|
case SHORTCUT_CTRL_D:
|
|
OnDuplicateEntity();
|
|
break;
|
|
|
|
// GIZMO
|
|
case SDLK_Q:
|
|
ChangeOptMode(-1);
|
|
break;
|
|
case SDLK_W:
|
|
ChangeOptMode(ImGuizmo::OPERATION::TRANSLATE);
|
|
break;
|
|
case SDLK_E:
|
|
ChangeOptMode(ImGuizmo::OPERATION::SCALE);
|
|
break;
|
|
case SDLK_R:
|
|
ChangeOptMode(ImGuizmo::OPERATION::ROTATE);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void EditorLayer::UI_ToolBar()
|
|
{
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 2));
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0, 0));
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
|
auto& colors = ImGui::GetStyle().Colors;
|
|
auto& buttonHovered = colors[ImGuiCol_ButtonHovered];
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(buttonHovered.x, buttonHovered.y, buttonHovered.z, 0.5f));
|
|
auto& buttonActive = colors[ImGuiCol_ButtonActive];
|
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(buttonActive.x, buttonActive.y, buttonActive.z, 0.5f));
|
|
|
|
|
|
ImGui::Begin("##ToolBar", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
|
// ImGui::Begin("##ToolBar", nullptr);
|
|
|
|
float size = ImGui::GetWindowHeight() - 10.0f;
|
|
Ref<Texture2D> icon = m_SceneState == SceneState::Edit ? m_PlayIcon : m_StopIcon;
|
|
ImGui::SetCursorPosX(ImGui::GetWindowContentRegionMax().x * 0.5f - size * 0.5f);
|
|
ImGui::SetCursorPosX(ImGui::GetWindowContentRegionMax().x * 0.5f - (size * 0.5f));
|
|
if (ImGui::ImageButton("toolbar", icon->GetRendererID(), ImVec2{size, size}, ImVec2{0, 0}, ImVec2{1, 1}))
|
|
{
|
|
if (m_SceneState == SceneState::Edit)
|
|
OnScenePlay();
|
|
else if (m_SceneState == SceneState::Play)
|
|
OnSceneStop();
|
|
|
|
}
|
|
|
|
|
|
ImGui::PopStyleVar(2);
|
|
ImGui::PopStyleColor(3);
|
|
ImGui::End();
|
|
}
|
|
|
|
}
|