2026-04-05 04:55:25 +08:00
|
|
|
#include "XCUIDemoPanel.h"
|
|
|
|
|
|
|
|
|
|
#include <imgui.h>
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
|
|
namespace XCEngine {
|
|
|
|
|
namespace NewEditor {
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
constexpr float kCanvasHudHeight = 82.0f;
|
|
|
|
|
constexpr float kCanvasHudPadding = 10.0f;
|
|
|
|
|
constexpr char kPreviewDebugSource[] = "new_editor.panels.xcui_demo";
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
void XCUIDemoPanel::Render() {
|
|
|
|
|
ImGui::SetNextWindowSize(ImVec2(1040.0f, 720.0f), ImGuiCond_Appearing);
|
|
|
|
|
ImGui::SetNextWindowDockID(ImGui::GetID("XCNewEditorDockSpace"), ImGuiCond_Appearing);
|
|
|
|
|
|
|
|
|
|
bool open = true;
|
|
|
|
|
if (!ImGui::Begin(GetName().c_str(), &open)) {
|
|
|
|
|
ImGui::End();
|
|
|
|
|
if (!open) {
|
|
|
|
|
SetVisible(false);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui::Button("Reload Documents")) {
|
|
|
|
|
m_lastReloadSucceeded = m_runtime.ReloadDocuments();
|
|
|
|
|
}
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
ImGui::Checkbox("Canvas HUD", &m_showCanvasHud);
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
ImGui::Checkbox("Debug Rects", &m_showDebugRects);
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
ImGui::TextUnformatted(m_lastReloadSucceeded ? "Reload: OK" : "Reload: Failed");
|
|
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
|
|
const float diagnosticsHeight = 232.0f;
|
|
|
|
|
const ImVec2 hostRegion = ImGui::GetContentRegionAvail();
|
|
|
|
|
const float canvasHeight = (std::max)(140.0f, hostRegion.y - diagnosticsHeight);
|
2026-04-05 12:30:03 +08:00
|
|
|
const float topInset = m_showCanvasHud ? (kCanvasHudHeight + kCanvasHudPadding) : 0.0f;
|
2026-04-05 17:41:31 +08:00
|
|
|
const XCUIDemoPanelFrameComposition& composition = ComposeFrame(
|
|
|
|
|
XCUIDemoPanelFrameComposeOptions{
|
|
|
|
|
canvasHeight,
|
|
|
|
|
topInset,
|
|
|
|
|
m_hostedPreviewEnabled,
|
|
|
|
|
m_showCanvasHud,
|
|
|
|
|
m_showDebugRects,
|
|
|
|
|
0u,
|
|
|
|
|
"XCUIDemoCanvasHost"});
|
|
|
|
|
const ::XCEngine::Editor::XCUIBackend::XCUIDemoFrameStats& stats = composition.frame->stats;
|
2026-04-05 04:55:25 +08:00
|
|
|
|
|
|
|
|
ImGui::Separator();
|
|
|
|
|
ImGui::BeginChild("XCUIDemoDiagnostics", ImVec2(0.0f, 0.0f), false, ImGuiWindowFlags_NoScrollbar);
|
|
|
|
|
ImGui::SeparatorText("Preview");
|
2026-04-05 17:41:31 +08:00
|
|
|
ImGui::Text(
|
|
|
|
|
"Path: %s | state: %s",
|
|
|
|
|
composition.previewPathLabel.c_str(),
|
|
|
|
|
composition.previewStateLabel.c_str());
|
2026-04-05 04:55:25 +08:00
|
|
|
ImGui::Text(
|
|
|
|
|
"Presenter: presented %s | submit->native %s",
|
2026-04-05 17:41:31 +08:00
|
|
|
composition.previewStats.presented ? "yes" : "no",
|
|
|
|
|
composition.previewStats.queuedToNativePass ? "yes" : "no");
|
2026-04-05 04:55:25 +08:00
|
|
|
ImGui::Text(
|
|
|
|
|
"Submitted: %zu lists / %zu cmds | Flushed: %zu lists / %zu cmds",
|
2026-04-05 17:41:31 +08:00
|
|
|
composition.previewStats.submittedDrawListCount,
|
|
|
|
|
composition.previewStats.submittedCommandCount,
|
|
|
|
|
composition.previewStats.flushedDrawListCount,
|
|
|
|
|
composition.previewStats.flushedCommandCount);
|
2026-04-05 04:55:25 +08:00
|
|
|
ImGui::TextWrapped(
|
|
|
|
|
"Source: %s",
|
2026-04-05 17:41:31 +08:00
|
|
|
composition.hasHostedSurfaceDescriptor && !composition.hostedSurfaceDescriptor.debugSource.empty()
|
|
|
|
|
? composition.hostedSurfaceDescriptor.debugSource.c_str()
|
2026-04-05 04:55:25 +08:00
|
|
|
: kPreviewDebugSource);
|
2026-04-05 17:41:31 +08:00
|
|
|
if (composition.nativeHostedPreview) {
|
2026-04-05 04:55:25 +08:00
|
|
|
ImGui::Text(
|
|
|
|
|
"Surface descriptor: %s | image published: %s | queued frame index: %zu",
|
2026-04-05 17:41:31 +08:00
|
|
|
composition.hasHostedSurfaceDescriptor ? "yes" : "no",
|
|
|
|
|
composition.showHostedSurfaceImage ? "yes" : "no",
|
|
|
|
|
composition.hasHostedSurfaceDescriptor ? composition.hostedSurfaceDescriptor.queuedFrameIndex : 0u);
|
|
|
|
|
if (composition.hasHostedSurfaceDescriptor) {
|
2026-04-05 04:55:25 +08:00
|
|
|
ImGui::Text(
|
|
|
|
|
"Surface: %ux%u | logical: %.0f x %.0f | rendered rect: %.0f, %.0f %.0f x %.0f",
|
2026-04-05 17:41:31 +08:00
|
|
|
composition.hostedSurfaceDescriptor.image.surfaceWidth,
|
|
|
|
|
composition.hostedSurfaceDescriptor.image.surfaceHeight,
|
|
|
|
|
composition.hostedSurfaceDescriptor.logicalSize.width,
|
|
|
|
|
composition.hostedSurfaceDescriptor.logicalSize.height,
|
|
|
|
|
composition.hostedSurfaceDescriptor.image.renderedCanvasRect.x,
|
|
|
|
|
composition.hostedSurfaceDescriptor.image.renderedCanvasRect.y,
|
|
|
|
|
composition.hostedSurfaceDescriptor.image.renderedCanvasRect.width,
|
|
|
|
|
composition.hostedSurfaceDescriptor.image.renderedCanvasRect.height);
|
2026-04-05 04:55:25 +08:00
|
|
|
} else {
|
|
|
|
|
ImGui::TextDisabled("No native surface descriptor has been published back yet.");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ImGui::TextDisabled("Legacy path renders directly into the panel draw list. No native surface descriptor exists.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui::SeparatorText("Runtime");
|
|
|
|
|
ImGui::Text("Status: %s", stats.statusMessage.c_str());
|
|
|
|
|
ImGui::Text(
|
|
|
|
|
"Tree gen: %llu | elements: %zu | dirty roots: %zu",
|
|
|
|
|
static_cast<unsigned long long>(stats.treeGeneration),
|
|
|
|
|
stats.elementCount,
|
|
|
|
|
stats.dirtyRootCount);
|
|
|
|
|
ImGui::Text(
|
|
|
|
|
"Draw lists: %zu | draw cmds: %zu | dependencies: %zu",
|
|
|
|
|
stats.drawListCount,
|
|
|
|
|
stats.commandCount,
|
|
|
|
|
stats.dependencyCount);
|
|
|
|
|
ImGui::Text(
|
|
|
|
|
"Hovered: %s | Focused: %s",
|
|
|
|
|
stats.hoveredElementId.empty() ? "none" : stats.hoveredElementId.c_str(),
|
|
|
|
|
stats.focusedElementId.empty() ? "none" : stats.focusedElementId.c_str());
|
|
|
|
|
ImGui::Text(
|
|
|
|
|
"Last command: %s | Accent: %s",
|
|
|
|
|
stats.lastCommandId.empty() ? "none" : stats.lastCommandId.c_str(),
|
|
|
|
|
stats.accentEnabled ? "on" : "off");
|
2026-04-05 17:41:31 +08:00
|
|
|
ImGui::Text(
|
|
|
|
|
"Canvas: %.0f x %.0f",
|
|
|
|
|
composition.input.canvasRect.width,
|
|
|
|
|
composition.input.canvasRect.height);
|
2026-04-05 04:55:25 +08:00
|
|
|
|
|
|
|
|
ImGui::SeparatorText("Input");
|
|
|
|
|
ImGui::Text(
|
|
|
|
|
"Pointer: %.0f, %.0f | inside %s | down %s | pressed %s | released %s",
|
2026-04-05 17:41:31 +08:00
|
|
|
composition.input.pointerPosition.x,
|
|
|
|
|
composition.input.pointerPosition.y,
|
|
|
|
|
composition.input.pointerInside ? "yes" : "no",
|
|
|
|
|
composition.input.pointerDown ? "yes" : "no",
|
|
|
|
|
composition.input.pointerPressed ? "yes" : "no",
|
|
|
|
|
composition.input.pointerReleased ? "yes" : "no");
|
2026-04-05 04:55:25 +08:00
|
|
|
ImGui::Text(
|
|
|
|
|
"Focus %s | capture mouse %s | capture keyboard %s | text input %s | events %zu",
|
2026-04-05 17:41:31 +08:00
|
|
|
composition.input.windowFocused ? "yes" : "no",
|
|
|
|
|
composition.input.wantCaptureMouse ? "yes" : "no",
|
|
|
|
|
composition.input.wantCaptureKeyboard ? "yes" : "no",
|
|
|
|
|
composition.input.wantTextInput ? "yes" : "no",
|
|
|
|
|
composition.input.events.size());
|
2026-04-05 04:55:25 +08:00
|
|
|
ImGui::EndChild();
|
|
|
|
|
|
|
|
|
|
ImGui::End();
|
|
|
|
|
|
|
|
|
|
if (!open) {
|
|
|
|
|
SetVisible(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace NewEditor
|
|
|
|
|
} // namespace XCEngine
|