2026-04-05 04:55:25 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
2026-04-05 12:50:55 +08:00
|
|
|
#include <XCEngine/Input/InputTypes.h>
|
|
|
|
|
|
|
|
|
|
#include "XCUIBackend/XCUIEditorCommandRouter.h"
|
2026-04-05 14:05:46 +08:00
|
|
|
#include "XCUIBackend/NativeXCUIPanelCanvasHost.h"
|
2026-04-05 04:55:25 +08:00
|
|
|
#include "XCUIBackend/XCUIHostedPreviewPresenter.h"
|
|
|
|
|
#include "XCUIBackend/XCUIInputBridge.h"
|
|
|
|
|
#include "XCUIBackend/XCUILayoutLabRuntime.h"
|
|
|
|
|
#include "XCUIBackend/XCUIRHIRenderBackend.h"
|
2026-04-05 12:50:55 +08:00
|
|
|
#include "XCUIBackend/XCUIShellChromeState.h"
|
2026-04-05 04:55:25 +08:00
|
|
|
#include "XCUIBackend/XCUIStandaloneTextAtlasProvider.h"
|
2026-04-05 16:11:08 +08:00
|
|
|
#include "XCUIBackend/UITextureRegistration.h"
|
|
|
|
|
#include "Platform/D3D12WindowRenderer.h"
|
|
|
|
|
#include "Rendering/MainWindowNativeBackdropRenderer.h"
|
2026-04-05 04:55:25 +08:00
|
|
|
|
|
|
|
|
#include <chrono>
|
|
|
|
|
#include <cstdint>
|
2026-04-05 12:50:55 +08:00
|
|
|
#include <functional>
|
|
|
|
|
#include <initializer_list>
|
2026-04-05 04:55:25 +08:00
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
2026-04-05 14:36:02 +08:00
|
|
|
#include <string_view>
|
2026-04-05 04:55:25 +08:00
|
|
|
#include <vector>
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
|
|
|
|
|
namespace XCEngine {
|
2026-04-05 16:11:08 +08:00
|
|
|
namespace Editor {
|
|
|
|
|
namespace XCUIBackend {
|
|
|
|
|
|
|
|
|
|
class IWindowUICompositor;
|
|
|
|
|
|
|
|
|
|
} // namespace XCUIBackend
|
|
|
|
|
} // namespace Editor
|
|
|
|
|
|
2026-04-05 04:55:25 +08:00
|
|
|
namespace NewEditor {
|
|
|
|
|
|
2026-04-05 16:11:08 +08:00
|
|
|
class XCUIDemoPanel;
|
|
|
|
|
class XCUILayoutLabPanel;
|
|
|
|
|
|
2026-04-05 04:55:25 +08:00
|
|
|
class Application {
|
|
|
|
|
public:
|
2026-04-05 16:11:08 +08:00
|
|
|
Application();
|
|
|
|
|
~Application();
|
|
|
|
|
|
2026-04-05 13:24:14 +08:00
|
|
|
using ShellChromeState = ::XCEngine::Editor::XCUIBackend::XCUIShellChromeState;
|
2026-04-05 12:50:55 +08:00
|
|
|
using ShellPanelId = ::XCEngine::Editor::XCUIBackend::XCUIShellPanelId;
|
|
|
|
|
using ShellViewToggleId = ::XCEngine::Editor::XCUIBackend::XCUIShellViewToggleId;
|
|
|
|
|
using ShellHostedPreviewMode = ::XCEngine::Editor::XCUIBackend::XCUIShellHostedPreviewMode;
|
|
|
|
|
using ShellPanelChromeState = ::XCEngine::Editor::XCUIBackend::XCUIShellPanelChromeState;
|
|
|
|
|
using ShellViewToggleState = ::XCEngine::Editor::XCUIBackend::XCUIShellViewToggleState;
|
2026-04-05 14:05:46 +08:00
|
|
|
enum class WindowHostMode : std::uint8_t {
|
|
|
|
|
NativeXCUI = 0,
|
2026-04-05 16:53:40 +08:00
|
|
|
CompatibilityHost
|
2026-04-05 14:05:46 +08:00
|
|
|
};
|
2026-04-05 12:50:55 +08:00
|
|
|
|
|
|
|
|
struct ShellCommandIds {
|
|
|
|
|
static constexpr const char* ToggleXCUIDemoPanel =
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIShellChromeCommandIds::ToggleXCUIDemoPanel;
|
|
|
|
|
static constexpr const char* ToggleXCUILayoutLabPanel =
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIShellChromeCommandIds::ToggleXCUILayoutLabPanel;
|
|
|
|
|
static constexpr const char* ToggleNativeBackdrop =
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIShellChromeCommandIds::ToggleNativeBackdrop;
|
|
|
|
|
static constexpr const char* TogglePulseAccent =
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIShellChromeCommandIds::TogglePulseAccent;
|
|
|
|
|
static constexpr const char* ToggleNativeXCUIOverlay =
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIShellChromeCommandIds::ToggleNativeXCUIOverlay;
|
|
|
|
|
static constexpr const char* ToggleHostedPreviewHud =
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIShellChromeCommandIds::ToggleHostedPreviewHud;
|
|
|
|
|
static constexpr const char* ToggleNativeDemoPanelPreview =
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIShellChromeCommandIds::ToggleNativeDemoPanelPreview;
|
|
|
|
|
static constexpr const char* ToggleNativeLayoutLabPreview =
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIShellChromeCommandIds::ToggleNativeLayoutLabPreview;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ShellCommandBindings {
|
|
|
|
|
std::function<bool()> getXCUIDemoPanelVisible = {};
|
|
|
|
|
std::function<void(bool)> setXCUIDemoPanelVisible = {};
|
|
|
|
|
std::function<bool()> getXCUILayoutLabPanelVisible = {};
|
|
|
|
|
std::function<void(bool)> setXCUILayoutLabPanelVisible = {};
|
|
|
|
|
std::function<bool()> getNativeBackdropVisible = {};
|
|
|
|
|
std::function<void(bool)> setNativeBackdropVisible = {};
|
|
|
|
|
std::function<bool()> getPulseAccentEnabled = {};
|
|
|
|
|
std::function<void(bool)> setPulseAccentEnabled = {};
|
|
|
|
|
std::function<bool()> getNativeXCUIOverlayVisible = {};
|
|
|
|
|
std::function<void(bool)> setNativeXCUIOverlayVisible = {};
|
|
|
|
|
std::function<bool()> getHostedPreviewHudVisible = {};
|
|
|
|
|
std::function<void(bool)> setHostedPreviewHudVisible = {};
|
|
|
|
|
std::function<bool()> getNativeDemoPanelPreviewEnabled = {};
|
|
|
|
|
std::function<void(bool)> setNativeDemoPanelPreviewEnabled = {};
|
|
|
|
|
std::function<bool()> getNativeLayoutLabPreviewEnabled = {};
|
|
|
|
|
std::function<void(bool)> setNativeLayoutLabPreviewEnabled = {};
|
|
|
|
|
std::function<void()> onHostedPreviewModeChanged = {};
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-05 14:36:02 +08:00
|
|
|
enum class NativeHostedPreviewSurfaceState : std::uint8_t {
|
|
|
|
|
Disabled = 0,
|
|
|
|
|
AwaitingSubmit,
|
|
|
|
|
Warming,
|
|
|
|
|
Live
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct NativeHostedPreviewConsumption {
|
|
|
|
|
NativeHostedPreviewSurfaceState surfaceState = NativeHostedPreviewSurfaceState::Disabled;
|
|
|
|
|
bool queueRuntimeFrame = false;
|
|
|
|
|
bool appendRuntimeDrawDataToShell = true;
|
|
|
|
|
bool showSurfaceImage = false;
|
|
|
|
|
bool drawRuntimeDebugRects = true;
|
|
|
|
|
std::string_view placeholderTitle = {};
|
|
|
|
|
std::string_view placeholderSubtitle = {};
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-05 12:50:55 +08:00
|
|
|
static ::XCEngine::Editor::XCUIBackend::XCUIEditorCommandInputSnapshot BuildShellShortcutSnapshot(
|
|
|
|
|
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta& frameDelta) {
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIEditorCommandInputSnapshot snapshot = {};
|
|
|
|
|
snapshot.modifiers = frameDelta.state.modifiers;
|
|
|
|
|
snapshot.windowFocused = frameDelta.state.windowFocused;
|
|
|
|
|
snapshot.wantCaptureKeyboard = frameDelta.state.wantCaptureKeyboard;
|
|
|
|
|
snapshot.wantTextInput = frameDelta.state.wantTextInput;
|
|
|
|
|
|
|
|
|
|
snapshot.keys.reserve(
|
|
|
|
|
frameDelta.keyboard.pressedKeys.size() +
|
|
|
|
|
frameDelta.keyboard.repeatedKeys.size());
|
|
|
|
|
|
|
|
|
|
const auto appendKeyState =
|
|
|
|
|
[&snapshot](std::int32_t keyCode, bool repeat) {
|
|
|
|
|
for (auto& existing : snapshot.keys) {
|
|
|
|
|
if (existing.keyCode != keyCode) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
existing.down = true;
|
|
|
|
|
existing.repeat = existing.repeat || repeat;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIEditorCommandKeyState keyState = {};
|
|
|
|
|
keyState.keyCode = keyCode;
|
|
|
|
|
keyState.down = true;
|
|
|
|
|
keyState.repeat = repeat;
|
|
|
|
|
snapshot.keys.push_back(keyState);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (std::int32_t keyCode : frameDelta.keyboard.pressedKeys) {
|
|
|
|
|
appendKeyState(keyCode, false);
|
|
|
|
|
}
|
|
|
|
|
for (std::int32_t keyCode : frameDelta.keyboard.repeatedKeys) {
|
|
|
|
|
appendKeyState(keyCode, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return snapshot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void RegisterShellViewCommands(
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIEditorCommandRouter& router,
|
|
|
|
|
const ShellCommandBindings& bindings) {
|
|
|
|
|
using ::XCEngine::Editor::XCUIBackend::XCUIEditorCommandAccelerator;
|
|
|
|
|
using ::XCEngine::Editor::XCUIBackend::XCUIEditorCommandDefinition;
|
|
|
|
|
using ::XCEngine::Input::KeyCode;
|
|
|
|
|
using ModifierState = ::XCEngine::UI::UIInputModifiers;
|
|
|
|
|
|
|
|
|
|
const auto bindToggleCommand =
|
|
|
|
|
[&router](
|
|
|
|
|
const char* commandId,
|
|
|
|
|
const std::function<bool()>& getter,
|
|
|
|
|
const std::function<void(bool)>& setter,
|
|
|
|
|
std::initializer_list<XCUIEditorCommandAccelerator> accelerators,
|
|
|
|
|
const std::function<void()>& afterToggle = {}) {
|
|
|
|
|
if (!getter || !setter) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XCUIEditorCommandDefinition definition = {};
|
|
|
|
|
definition.commandId = commandId;
|
|
|
|
|
definition.isEnabled = [getter, setter]() {
|
|
|
|
|
return static_cast<bool>(getter) && static_cast<bool>(setter);
|
|
|
|
|
};
|
|
|
|
|
definition.invoke = [getter, setter, afterToggle]() {
|
|
|
|
|
const bool nextValue = !getter();
|
|
|
|
|
setter(nextValue);
|
|
|
|
|
if (afterToggle) {
|
|
|
|
|
afterToggle();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
definition.accelerators.assign(accelerators.begin(), accelerators.end());
|
|
|
|
|
router.RegisterCommand(definition);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const ModifierState ctrlOnly = { false, true, false, false };
|
|
|
|
|
const ModifierState ctrlShift = { true, true, false, false };
|
|
|
|
|
const ModifierState ctrlAlt = { false, true, true, false };
|
|
|
|
|
|
|
|
|
|
bindToggleCommand(
|
|
|
|
|
ShellCommandIds::ToggleXCUIDemoPanel,
|
|
|
|
|
bindings.getXCUIDemoPanelVisible,
|
|
|
|
|
bindings.setXCUIDemoPanelVisible,
|
|
|
|
|
{ XCUIEditorCommandAccelerator{
|
|
|
|
|
static_cast<std::int32_t>(KeyCode::One),
|
|
|
|
|
ctrlOnly,
|
|
|
|
|
true,
|
|
|
|
|
false } });
|
|
|
|
|
bindToggleCommand(
|
|
|
|
|
ShellCommandIds::ToggleXCUILayoutLabPanel,
|
|
|
|
|
bindings.getXCUILayoutLabPanelVisible,
|
|
|
|
|
bindings.setXCUILayoutLabPanelVisible,
|
|
|
|
|
{ XCUIEditorCommandAccelerator{
|
|
|
|
|
static_cast<std::int32_t>(KeyCode::Two),
|
|
|
|
|
ctrlOnly,
|
|
|
|
|
true,
|
|
|
|
|
false } });
|
|
|
|
|
bindToggleCommand(
|
|
|
|
|
ShellCommandIds::ToggleNativeBackdrop,
|
|
|
|
|
bindings.getNativeBackdropVisible,
|
|
|
|
|
bindings.setNativeBackdropVisible,
|
|
|
|
|
{ XCUIEditorCommandAccelerator{
|
|
|
|
|
static_cast<std::int32_t>(KeyCode::B),
|
|
|
|
|
ctrlShift,
|
|
|
|
|
true,
|
|
|
|
|
false } });
|
|
|
|
|
bindToggleCommand(
|
|
|
|
|
ShellCommandIds::TogglePulseAccent,
|
|
|
|
|
bindings.getPulseAccentEnabled,
|
|
|
|
|
bindings.setPulseAccentEnabled,
|
|
|
|
|
{ XCUIEditorCommandAccelerator{
|
|
|
|
|
static_cast<std::int32_t>(KeyCode::P),
|
|
|
|
|
ctrlShift,
|
|
|
|
|
true,
|
|
|
|
|
false } });
|
|
|
|
|
bindToggleCommand(
|
|
|
|
|
ShellCommandIds::ToggleNativeXCUIOverlay,
|
|
|
|
|
bindings.getNativeXCUIOverlayVisible,
|
|
|
|
|
bindings.setNativeXCUIOverlayVisible,
|
|
|
|
|
{ XCUIEditorCommandAccelerator{
|
|
|
|
|
static_cast<std::int32_t>(KeyCode::O),
|
|
|
|
|
ctrlShift,
|
|
|
|
|
true,
|
|
|
|
|
false } });
|
|
|
|
|
bindToggleCommand(
|
|
|
|
|
ShellCommandIds::ToggleHostedPreviewHud,
|
|
|
|
|
bindings.getHostedPreviewHudVisible,
|
|
|
|
|
bindings.setHostedPreviewHudVisible,
|
|
|
|
|
{ XCUIEditorCommandAccelerator{
|
|
|
|
|
static_cast<std::int32_t>(KeyCode::H),
|
|
|
|
|
ctrlShift,
|
|
|
|
|
true,
|
|
|
|
|
false } });
|
|
|
|
|
bindToggleCommand(
|
|
|
|
|
ShellCommandIds::ToggleNativeDemoPanelPreview,
|
|
|
|
|
bindings.getNativeDemoPanelPreviewEnabled,
|
|
|
|
|
bindings.setNativeDemoPanelPreviewEnabled,
|
|
|
|
|
{ XCUIEditorCommandAccelerator{
|
|
|
|
|
static_cast<std::int32_t>(KeyCode::One),
|
|
|
|
|
ctrlAlt,
|
|
|
|
|
true,
|
|
|
|
|
false } },
|
|
|
|
|
bindings.onHostedPreviewModeChanged);
|
|
|
|
|
bindToggleCommand(
|
|
|
|
|
ShellCommandIds::ToggleNativeLayoutLabPreview,
|
|
|
|
|
bindings.getNativeLayoutLabPreviewEnabled,
|
|
|
|
|
bindings.setNativeLayoutLabPreviewEnabled,
|
|
|
|
|
{ XCUIEditorCommandAccelerator{
|
|
|
|
|
static_cast<std::int32_t>(KeyCode::Two),
|
|
|
|
|
ctrlAlt,
|
|
|
|
|
true,
|
|
|
|
|
false } },
|
|
|
|
|
bindings.onHostedPreviewModeChanged);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 14:36:02 +08:00
|
|
|
static void BeginHostedPreviewFrameLifecycle(
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewQueue& previewQueue,
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceRegistry& surfaceRegistry) {
|
|
|
|
|
previewQueue.BeginFrame();
|
|
|
|
|
surfaceRegistry.BeginFrame();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool HasHostedPreviewTextureRegistration(
|
|
|
|
|
const ::XCEngine::Editor::XCUIBackend::UITextureRegistration& registration) {
|
|
|
|
|
return registration.texture.IsValid() ||
|
|
|
|
|
registration.cpuHandle.ptr != 0u ||
|
|
|
|
|
registration.gpuHandle.ptr != 0u;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool HasHostedPreviewPublishedTexture(
|
|
|
|
|
const ::XCEngine::Editor::XCUIBackend::UITextureRegistration& registration) {
|
|
|
|
|
return registration.texture.IsValid();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static NativeHostedPreviewConsumption ResolveNativeHostedPreviewConsumption(
|
|
|
|
|
bool nativeHostedPreview,
|
|
|
|
|
bool hasHostedSurfaceDescriptor,
|
|
|
|
|
bool showHostedSurfaceImage,
|
|
|
|
|
std::string_view pendingTitle = {},
|
|
|
|
|
std::string_view pendingSubtitle = {}) {
|
|
|
|
|
NativeHostedPreviewConsumption consumption = {};
|
|
|
|
|
if (!nativeHostedPreview) {
|
|
|
|
|
return consumption;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
consumption.queueRuntimeFrame = true;
|
|
|
|
|
consumption.appendRuntimeDrawDataToShell = false;
|
|
|
|
|
consumption.showSurfaceImage = showHostedSurfaceImage;
|
|
|
|
|
consumption.drawRuntimeDebugRects = showHostedSurfaceImage;
|
|
|
|
|
consumption.surfaceState = showHostedSurfaceImage
|
|
|
|
|
? NativeHostedPreviewSurfaceState::Live
|
|
|
|
|
: (hasHostedSurfaceDescriptor
|
|
|
|
|
? NativeHostedPreviewSurfaceState::Warming
|
|
|
|
|
: NativeHostedPreviewSurfaceState::AwaitingSubmit);
|
|
|
|
|
if (!showHostedSurfaceImage) {
|
|
|
|
|
consumption.placeholderTitle = pendingTitle;
|
|
|
|
|
consumption.placeholderSubtitle = pendingSubtitle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return consumption;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static std::string ComposeNativeHostedPreviewStatusLine(
|
|
|
|
|
const NativeHostedPreviewConsumption& consumption,
|
|
|
|
|
std::string_view status) {
|
|
|
|
|
switch (consumption.surfaceState) {
|
|
|
|
|
case NativeHostedPreviewSurfaceState::AwaitingSubmit:
|
|
|
|
|
return std::string("Native surface awaiting submit | ") + std::string(status);
|
|
|
|
|
case NativeHostedPreviewSurfaceState::Warming:
|
|
|
|
|
return std::string("Native surface warming | ") + std::string(status);
|
|
|
|
|
case NativeHostedPreviewSurfaceState::Live:
|
|
|
|
|
return std::string("Native surface live | ") + std::string(status);
|
|
|
|
|
case NativeHostedPreviewSurfaceState::Disabled:
|
|
|
|
|
default:
|
|
|
|
|
return std::string(status);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 04:55:25 +08:00
|
|
|
int Run(HINSTANCE instance, int nCmdShow);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
struct HostedPreviewPanelDiagnostics {
|
|
|
|
|
std::string debugName = {};
|
|
|
|
|
std::string debugSource = {};
|
|
|
|
|
bool visible = false;
|
|
|
|
|
bool hostedPreviewEnabled = false;
|
|
|
|
|
bool nativeRequested = false;
|
|
|
|
|
bool nativePresenterBound = false;
|
|
|
|
|
bool descriptorAvailable = false;
|
|
|
|
|
bool surfaceImageAvailable = false;
|
|
|
|
|
bool surfaceAllocated = false;
|
|
|
|
|
bool surfaceReady = false;
|
|
|
|
|
bool presentedThisFrame = false;
|
|
|
|
|
bool queuedToNativePassThisFrame = false;
|
|
|
|
|
std::uint32_t surfaceWidth = 0;
|
|
|
|
|
std::uint32_t surfaceHeight = 0;
|
|
|
|
|
float logicalWidth = 0.0f;
|
|
|
|
|
float logicalHeight = 0.0f;
|
|
|
|
|
std::size_t queuedFrameIndex = 0;
|
|
|
|
|
std::size_t submittedDrawListCount = 0;
|
|
|
|
|
std::size_t submittedCommandCount = 0;
|
|
|
|
|
std::size_t flushedDrawListCount = 0;
|
|
|
|
|
std::size_t flushedCommandCount = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct HostedPreviewOffscreenSurface {
|
|
|
|
|
std::string debugName = {};
|
|
|
|
|
std::uint32_t width = 0;
|
|
|
|
|
std::uint32_t height = 0;
|
|
|
|
|
::XCEngine::RHI::RHITexture* colorTexture = nullptr;
|
|
|
|
|
::XCEngine::RHI::RHIResourceView* colorView = nullptr;
|
2026-04-05 06:43:51 +08:00
|
|
|
::XCEngine::Editor::XCUIBackend::UITextureRegistration textureRegistration = {};
|
2026-04-05 04:55:25 +08:00
|
|
|
::XCEngine::RHI::ResourceStates colorState = ::XCEngine::RHI::ResourceStates::Common;
|
|
|
|
|
|
|
|
|
|
bool IsReady() const {
|
|
|
|
|
return !debugName.empty() &&
|
|
|
|
|
colorTexture != nullptr &&
|
|
|
|
|
colorView != nullptr &&
|
2026-04-05 14:36:02 +08:00
|
|
|
Application::HasHostedPreviewPublishedTexture(textureRegistration) &&
|
2026-04-05 04:55:25 +08:00
|
|
|
width > 0u &&
|
|
|
|
|
height > 0u;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
|
|
|
LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
|
|
|
|
|
|
|
|
bool CreateMainWindow(HINSTANCE instance, int nCmdShow);
|
|
|
|
|
bool InitializeRenderer();
|
2026-04-05 06:15:24 +08:00
|
|
|
void InitializeWindowCompositor();
|
2026-04-05 14:05:46 +08:00
|
|
|
void InitializeNativeShell();
|
2026-04-05 06:15:24 +08:00
|
|
|
void ShutdownWindowCompositor();
|
2026-04-05 04:55:25 +08:00
|
|
|
void ShutdownRenderer();
|
|
|
|
|
void DestroyHostedPreviewSurfaces();
|
2026-04-05 12:50:55 +08:00
|
|
|
void SyncShellChromePanelStateFromPanels();
|
2026-04-05 04:55:25 +08:00
|
|
|
void SyncHostedPreviewSurfaces();
|
|
|
|
|
std::unique_ptr<::XCEngine::Editor::XCUIBackend::IXCUIHostedPreviewPresenter> CreateHostedPreviewPresenter(
|
|
|
|
|
bool nativePreview);
|
|
|
|
|
void ConfigureHostedPreviewPresenters();
|
2026-04-05 12:50:55 +08:00
|
|
|
const ShellPanelChromeState* TryGetShellPanelState(ShellPanelId panelId) const;
|
|
|
|
|
bool IsShellViewToggleEnabled(ShellViewToggleId toggleId) const;
|
|
|
|
|
void SetShellViewToggleEnabled(ShellViewToggleId toggleId, bool enabled);
|
|
|
|
|
bool IsNativeHostedPreviewEnabled(ShellPanelId panelId) const;
|
2026-04-05 04:55:25 +08:00
|
|
|
HostedPreviewPanelDiagnostics BuildHostedPreviewPanelDiagnostics(
|
|
|
|
|
const char* debugName,
|
|
|
|
|
const char* fallbackDebugSource,
|
|
|
|
|
bool visible,
|
|
|
|
|
bool hostedPreviewEnabled,
|
|
|
|
|
bool nativeRequested,
|
|
|
|
|
bool nativePresenterBound,
|
|
|
|
|
const ::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewStats& previewStats) const;
|
|
|
|
|
HostedPreviewOffscreenSurface* FindHostedPreviewSurface(const std::string& debugName);
|
|
|
|
|
const HostedPreviewOffscreenSurface* FindHostedPreviewSurface(const std::string& debugName) const;
|
|
|
|
|
HostedPreviewOffscreenSurface& FindOrAddHostedPreviewSurface(const std::string& debugName);
|
|
|
|
|
bool EnsureHostedPreviewSurface(
|
|
|
|
|
HostedPreviewOffscreenSurface& previewSurface,
|
|
|
|
|
std::uint32_t width,
|
|
|
|
|
std::uint32_t height);
|
|
|
|
|
bool RenderHostedPreviewOffscreenSurface(
|
|
|
|
|
HostedPreviewOffscreenSurface& previewSurface,
|
|
|
|
|
const ::XCEngine::Rendering::RenderContext& renderContext,
|
|
|
|
|
const ::XCEngine::UI::UIDrawData& drawData);
|
2026-04-05 17:12:43 +08:00
|
|
|
void ResetCompatibilityHostPanels();
|
2026-04-05 12:50:55 +08:00
|
|
|
void ConfigureShellCommandRouter();
|
2026-04-05 14:05:46 +08:00
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta DispatchShellShortcuts(
|
|
|
|
|
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot& snapshot);
|
|
|
|
|
bool IsNativeWindowHostEnabled() const;
|
2026-04-05 15:28:42 +08:00
|
|
|
void InitializePanelsForActiveWindowHost();
|
2026-04-05 16:53:40 +08:00
|
|
|
void InitializeCompatibilityHostPanels();
|
|
|
|
|
void RenderCompatibilityHostUiFrame();
|
2026-04-05 14:05:46 +08:00
|
|
|
::XCEngine::UI::UIDrawData BuildNativeShellDrawData(
|
|
|
|
|
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot& shellSnapshot,
|
|
|
|
|
const ::XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameDelta& shellFrameDelta);
|
2026-04-05 16:53:40 +08:00
|
|
|
void FrameCompatibilityHost();
|
2026-04-05 14:05:46 +08:00
|
|
|
void FrameNativeXCUIHost();
|
2026-04-05 04:55:25 +08:00
|
|
|
void RenderShellChrome();
|
|
|
|
|
void RenderHostedPreviewHud();
|
|
|
|
|
void RenderQueuedHostedPreviews(
|
|
|
|
|
const ::XCEngine::Rendering::RenderContext& renderContext,
|
|
|
|
|
const ::XCEngine::Rendering::RenderSurface& surface);
|
|
|
|
|
void Frame();
|
|
|
|
|
|
|
|
|
|
HWND m_hwnd = nullptr;
|
|
|
|
|
::XCEngine::Editor::Platform::D3D12WindowRenderer m_windowRenderer;
|
2026-04-05 06:15:24 +08:00
|
|
|
std::unique_ptr<::XCEngine::Editor::XCUIBackend::IWindowUICompositor> m_windowCompositor;
|
2026-04-05 04:55:25 +08:00
|
|
|
std::unique_ptr<XCUIDemoPanel> m_demoPanel;
|
|
|
|
|
std::unique_ptr<XCUILayoutLabPanel> m_layoutLabPanel;
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIWin32InputSource m_xcuiInputSource;
|
2026-04-05 12:50:55 +08:00
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIInputBridge m_shellInputBridge;
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIEditorCommandRouter m_shellCommandRouter;
|
2026-04-05 04:55:25 +08:00
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewQueue m_hostedPreviewQueue;
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceRegistry m_hostedPreviewSurfaceRegistry;
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIStandaloneTextAtlasProvider m_hostedPreviewTextAtlasProvider;
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::XCUIRHIRenderBackend m_hostedPreviewRenderBackend;
|
2026-04-05 13:24:14 +08:00
|
|
|
ShellChromeState m_shellChromeState = {};
|
2026-04-05 04:55:25 +08:00
|
|
|
std::vector<HostedPreviewOffscreenSurface> m_hostedPreviewSurfaces = {};
|
2026-04-05 14:05:46 +08:00
|
|
|
WindowHostMode m_windowHostMode = WindowHostMode::NativeXCUI;
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::NativeXCUIPanelCanvasHost m_nativeDemoCanvasHost;
|
|
|
|
|
::XCEngine::Editor::XCUIBackend::NativeXCUIPanelCanvasHost m_nativeLayoutCanvasHost;
|
|
|
|
|
ShellPanelId m_nativeActivePanel = ShellPanelId::XCUIDemo;
|
2026-04-05 16:46:47 +08:00
|
|
|
bool m_legacyHostDemoWindowVisible = false;
|
2026-04-05 04:55:25 +08:00
|
|
|
::XCEngine::Editor::XCUIBackend::XCUILayoutLabRuntime m_nativeOverlayRuntime;
|
|
|
|
|
MainWindowNativeBackdropRenderer m_nativeBackdropRenderer;
|
|
|
|
|
bool m_running = false;
|
|
|
|
|
bool m_renderReady = false;
|
|
|
|
|
std::chrono::steady_clock::time_point m_startTime = {};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace NewEditor
|
|
|
|
|
} // namespace XCEngine
|