126 lines
4.0 KiB
C++
126 lines
4.0 KiB
C++
#pragma once
|
|
|
|
#include "Core/IEditorContext.h"
|
|
#include "Viewport/IViewportHostService.h"
|
|
#include "UI/UI.h"
|
|
|
|
#include <imgui.h>
|
|
|
|
#include <string>
|
|
|
|
namespace XCEngine {
|
|
namespace Editor {
|
|
|
|
inline ::XCEngine::UI::UISize ToUISize(const ImVec2& value) {
|
|
return ::XCEngine::UI::UISize(value.x, value.y);
|
|
}
|
|
|
|
inline ImTextureID ToImGuiTextureId(const ::XCEngine::UI::UITextureHandle& texture) {
|
|
return static_cast<ImTextureID>(texture.nativeHandle);
|
|
}
|
|
|
|
struct ViewportPanelContentResult {
|
|
EditorViewportFrame frame;
|
|
ImVec2 availableSize = ImVec2(0.0f, 0.0f);
|
|
ImVec2 itemMin = ImVec2(0.0f, 0.0f);
|
|
ImVec2 itemMax = ImVec2(0.0f, 0.0f);
|
|
bool hasViewportArea = false;
|
|
bool hovered = false;
|
|
bool focused = false;
|
|
bool clickedLeft = false;
|
|
bool clickedRight = false;
|
|
bool clickedMiddle = false;
|
|
};
|
|
|
|
inline void DrawViewportStatusMessage(const std::string& message) {
|
|
if (message.empty()) {
|
|
return;
|
|
}
|
|
|
|
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
|
if (drawList == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const ImVec2 min = ImGui::GetItemRectMin();
|
|
const ImVec2 max = ImGui::GetItemRectMax();
|
|
const ImVec2 textSize = ImGui::CalcTextSize(message.c_str());
|
|
const ImVec2 textPos(
|
|
min.x + ((max.x - min.x) - textSize.x) * 0.5f,
|
|
min.y + ((max.y - min.y) - textSize.y) * 0.5f);
|
|
|
|
drawList->AddText(textPos, ImGui::GetColorU32(ImGuiCol_TextDisabled), message.c_str());
|
|
}
|
|
|
|
inline const char* GetViewportInteractionSurfaceId(EditorViewportKind kind) {
|
|
switch (kind) {
|
|
case EditorViewportKind::Scene:
|
|
return "##SceneViewportInteractionSurface";
|
|
case EditorViewportKind::Game:
|
|
return "##GameViewportInteractionSurface";
|
|
default:
|
|
return "##ViewportInteractionSurface";
|
|
}
|
|
}
|
|
|
|
inline void RenderViewportInteractionSurface(
|
|
ViewportPanelContentResult& result,
|
|
EditorViewportKind kind,
|
|
const ImVec2& interactionSize) {
|
|
ImGui::SetNextItemAllowOverlap();
|
|
ImGui::InvisibleButton(
|
|
GetViewportInteractionSurfaceId(kind),
|
|
interactionSize,
|
|
ImGuiButtonFlags_MouseButtonLeft |
|
|
ImGuiButtonFlags_MouseButtonRight |
|
|
ImGuiButtonFlags_MouseButtonMiddle);
|
|
|
|
result.itemMin = ImGui::GetItemRectMin();
|
|
result.itemMax = ImGui::GetItemRectMax();
|
|
result.hovered = ImGui::IsItemHovered();
|
|
result.clickedLeft = ImGui::IsItemClicked(ImGuiMouseButton_Left);
|
|
result.clickedRight = ImGui::IsItemClicked(ImGuiMouseButton_Right);
|
|
result.clickedMiddle = ImGui::IsItemClicked(ImGuiMouseButton_Middle);
|
|
}
|
|
|
|
inline ViewportPanelContentResult RenderViewportPanelContent(
|
|
IEditorContext& context,
|
|
EditorViewportKind kind) {
|
|
ViewportPanelContentResult result = {};
|
|
UI::CollapsePanelSectionSpacing();
|
|
result.availableSize = ImGui::GetContentRegionAvail();
|
|
result.focused = ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows);
|
|
|
|
IViewportHostService* viewportHostService = context.GetViewportHostService();
|
|
if (result.availableSize.x <= 1.0f || result.availableSize.y <= 1.0f) {
|
|
ImGui::Dummy(ImVec2(0.0f, 0.0f));
|
|
return result;
|
|
}
|
|
|
|
result.hasViewportArea = true;
|
|
|
|
if (viewportHostService == nullptr) {
|
|
RenderViewportInteractionSurface(result, kind, result.availableSize);
|
|
DrawViewportStatusMessage("Viewport host is unavailable");
|
|
return result;
|
|
}
|
|
|
|
result.frame = viewportHostService->RequestViewport(kind, ToUISize(result.availableSize));
|
|
RenderViewportInteractionSurface(result, kind, result.availableSize);
|
|
|
|
if (result.frame.hasTexture) {
|
|
if (ImDrawList* drawList = ImGui::GetWindowDrawList()) {
|
|
drawList->AddImage(ToImGuiTextureId(result.frame.texture), result.itemMin, result.itemMax);
|
|
}
|
|
}
|
|
|
|
DrawViewportStatusMessage(
|
|
result.frame.statusText.empty() && !result.frame.hasTexture
|
|
? "Viewport is initializing"
|
|
: result.frame.statusText);
|
|
return result;
|
|
}
|
|
|
|
} // namespace Editor
|
|
} // namespace XCEngine
|