Files
XCEngine/editor/src/panels/SceneViewPanel.cpp

144 lines
5.3 KiB
C++
Raw Normal View History

2026-03-26 22:31:22 +08:00
#include "Actions/ActionRouting.h"
#include "Core/IEditorContext.h"
#include "Core/ISelectionManager.h"
#include "SceneViewPanel.h"
#include "Viewport/SceneViewportOverlayRenderer.h"
2026-03-28 17:04:14 +08:00
#include "ViewportPanelContent.h"
2026-03-26 21:18:33 +08:00
#include "UI/UI.h"
2026-03-28 17:50:54 +08:00
#include <imgui.h>
namespace XCEngine {
namespace Editor {
SceneViewPanel::SceneViewPanel() : Panel("Scene") {}
void SceneViewPanel::Render() {
UI::PanelWindowScope panel(m_name.c_str());
2026-03-26 22:31:22 +08:00
if (!panel.IsOpen()) {
return;
}
const ViewportPanelContentResult content = RenderViewportPanelContent(*m_context, EditorViewportKind::Scene);
if (IViewportHostService* viewportHostService = m_context->GetViewportHostService()) {
const ImGuiIO& io = ImGui::GetIO();
const bool selectClick =
content.hovered &&
content.frame.hasTexture &&
ImGui::IsMouseClicked(ImGuiMouseButton_Left) &&
!m_lookDragging &&
!m_panDragging;
const bool beginLookDrag =
content.hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Right);
const bool beginPanDrag =
content.hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Middle);
if (selectClick || beginLookDrag || beginPanDrag) {
ImGui::SetWindowFocus();
}
if (selectClick) {
const ImVec2 localMousePosition(
io.MousePos.x - content.itemMin.x,
io.MousePos.y - content.itemMin.y);
const uint64_t selectedEntity = viewportHostService->PickSceneViewEntity(
*m_context,
content.availableSize,
localMousePosition);
if (selectedEntity != 0) {
m_context->GetSelectionManager().SetSelectedEntity(selectedEntity);
} else {
m_context->GetSelectionManager().ClearSelection();
}
}
if (beginLookDrag) {
m_lookDragging = true;
m_lastLookDragDelta = ImVec2(0.0f, 0.0f);
}
if (beginPanDrag) {
m_panDragging = true;
m_lastPanDragDelta = ImVec2(0.0f, 0.0f);
}
if (m_lookDragging && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) {
m_lookDragging = false;
m_lastLookDragDelta = ImVec2(0.0f, 0.0f);
}
if (m_panDragging && !ImGui::IsMouseDown(ImGuiMouseButton_Middle)) {
m_panDragging = false;
m_lastPanDragDelta = ImVec2(0.0f, 0.0f);
}
if (m_lookDragging || m_panDragging) {
ImGui::SetNextFrameWantCaptureMouse(true);
}
if (m_lookDragging) {
ImGui::SetNextFrameWantCaptureKeyboard(true);
}
SceneViewportInput input = {};
input.viewportSize = content.availableSize;
2026-03-28 18:28:11 +08:00
input.deltaTime = io.DeltaTime;
input.hovered = content.hovered;
input.focused = content.focused || m_lookDragging || m_panDragging;
input.mouseWheel = (content.hovered && !m_lookDragging) ? io.MouseWheel : 0.0f;
input.flySpeedDelta = (content.hovered && m_lookDragging) ? io.MouseWheel : 0.0f;
input.looking = m_lookDragging;
input.orbiting = false;
input.panning = m_panDragging;
2026-03-28 18:28:11 +08:00
input.fastMove = io.KeyShift;
input.focusSelectionRequested =
input.focused && !io.WantTextInput && ImGui::IsKeyPressed(ImGuiKey_F, false);
if (m_lookDragging && !io.WantTextInput) {
2026-03-28 18:28:11 +08:00
input.moveForward =
(ImGui::IsKeyDown(ImGuiKey_W) ? 1.0f : 0.0f) -
(ImGui::IsKeyDown(ImGuiKey_S) ? 1.0f : 0.0f);
input.moveRight =
(ImGui::IsKeyDown(ImGuiKey_D) ? 1.0f : 0.0f) -
(ImGui::IsKeyDown(ImGuiKey_A) ? 1.0f : 0.0f);
input.moveUp =
(ImGui::IsKeyDown(ImGuiKey_E) ? 1.0f : 0.0f) -
(ImGui::IsKeyDown(ImGuiKey_Q) ? 1.0f : 0.0f);
}
if (m_lookDragging || m_panDragging) {
if (m_lookDragging) {
const ImVec2 lookDragDelta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right, 0.0f);
input.mouseDelta.x += lookDragDelta.x - m_lastLookDragDelta.x;
input.mouseDelta.y += lookDragDelta.y - m_lastLookDragDelta.y;
m_lastLookDragDelta = lookDragDelta;
} else {
m_lastLookDragDelta = ImVec2(0.0f, 0.0f);
}
if (m_panDragging) {
const ImVec2 panDragDelta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Middle, 0.0f);
input.mouseDelta.x += panDragDelta.x - m_lastPanDragDelta.x;
input.mouseDelta.y += panDragDelta.y - m_lastPanDragDelta.y;
m_lastPanDragDelta = panDragDelta;
} else {
m_lastPanDragDelta = ImVec2(0.0f, 0.0f);
}
}
viewportHostService->UpdateSceneViewInput(*m_context, input);
2026-03-28 17:50:54 +08:00
if (content.hasViewportArea && content.frame.hasTexture) {
const SceneViewportOverlayData overlay = viewportHostService->GetSceneViewOverlayData();
DrawSceneViewportOverlay(
2026-03-28 17:50:54 +08:00
ImGui::GetWindowDrawList(),
overlay,
content.itemMin,
content.itemMax,
content.availableSize);
}
}
2026-03-26 22:31:22 +08:00
Actions::ObserveInactiveActionRoute(*m_context);
}
}
}