2026-04-05 04:55:25 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
2026-04-05 20:46:24 +08:00
|
|
|
#ifndef NOMINMAX
|
|
|
|
|
#define NOMINMAX
|
|
|
|
|
#endif
|
2026-04-05 12:50:55 +08:00
|
|
|
|
2026-04-10 01:59:15 +08:00
|
|
|
#include <Host/AutoScreenshot.h>
|
2026-04-12 23:21:59 +08:00
|
|
|
#include <Host/D3D12WindowRenderer.h>
|
2026-04-10 01:59:15 +08:00
|
|
|
#include <Host/InputModifierTracker.h>
|
|
|
|
|
#include <Host/NativeRenderer.h>
|
2026-04-06 03:17:53 +08:00
|
|
|
|
2026-04-12 01:29:00 +08:00
|
|
|
#include "Core/ProductEditorContext.h"
|
|
|
|
|
#include "Workspace/ProductEditorWorkspace.h"
|
2026-04-11 20:20:30 +08:00
|
|
|
|
2026-04-10 16:40:11 +08:00
|
|
|
#include <XCEditor/Shell/UIEditorShellInteraction.h>
|
2026-04-05 20:46:24 +08:00
|
|
|
|
|
|
|
|
#include <windows.h>
|
2026-04-05 21:27:00 +08:00
|
|
|
#include <windowsx.h>
|
2026-04-05 04:55:25 +08:00
|
|
|
|
|
|
|
|
#include <cstdint>
|
2026-04-05 20:46:24 +08:00
|
|
|
#include <filesystem>
|
2026-04-05 04:55:25 +08:00
|
|
|
#include <string>
|
2026-04-10 16:40:11 +08:00
|
|
|
#include <string_view>
|
2026-04-05 04:55:25 +08:00
|
|
|
#include <vector>
|
|
|
|
|
|
2026-04-06 20:02:34 +08:00
|
|
|
namespace XCEngine::UI::Editor {
|
2026-04-05 04:55:25 +08:00
|
|
|
|
2026-04-12 01:49:08 +08:00
|
|
|
class Application {
|
2026-04-05 04:55:25 +08:00
|
|
|
public:
|
2026-04-10 16:40:11 +08:00
|
|
|
Application() = default;
|
2026-04-05 12:50:55 +08:00
|
|
|
|
2026-04-05 20:46:24 +08:00
|
|
|
int Run(HINSTANCE hInstance, int nCmdShow);
|
2026-04-05 04:55:25 +08:00
|
|
|
|
2026-04-10 16:40:11 +08:00
|
|
|
private:
|
2026-04-05 20:46:24 +08:00
|
|
|
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
2026-04-05 04:55:25 +08:00
|
|
|
|
2026-04-05 20:46:24 +08:00
|
|
|
bool Initialize(HINSTANCE hInstance, int nCmdShow);
|
|
|
|
|
void Shutdown();
|
|
|
|
|
void RenderFrame();
|
2026-04-13 18:52:30 +08:00
|
|
|
void OnResize();
|
|
|
|
|
void OnEnterSizeMove();
|
|
|
|
|
void OnExitSizeMove();
|
2026-04-11 17:07:37 +08:00
|
|
|
void OnDpiChanged(UINT dpi, const RECT& suggestedRect);
|
2026-04-13 18:52:30 +08:00
|
|
|
void QueueWindowResize(UINT width, UINT height);
|
|
|
|
|
void QueueCurrentClientResize();
|
|
|
|
|
bool ApplyPendingWindowResize();
|
|
|
|
|
void RequestDeferredRenderFrame();
|
|
|
|
|
bool QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const;
|
2026-04-11 22:14:02 +08:00
|
|
|
bool IsPointerInsideClientArea() const;
|
2026-04-11 20:20:30 +08:00
|
|
|
bool ApplyCurrentCursor() const;
|
|
|
|
|
LPCWSTR ResolveCurrentCursorResource() const;
|
2026-04-11 17:07:37 +08:00
|
|
|
float GetDpiScale() const;
|
|
|
|
|
float PixelsToDips(float pixels) const;
|
|
|
|
|
::XCEngine::UI::UIPoint ConvertClientPixelsToDips(LONG x, LONG y) const;
|
2026-04-12 01:29:00 +08:00
|
|
|
std::string BuildCaptureStatusText() const;
|
2026-04-11 17:07:37 +08:00
|
|
|
void LogRuntimeTrace(std::string_view channel, std::string_view message) const;
|
2026-04-10 16:40:11 +08:00
|
|
|
void ApplyHostCaptureRequests(const UIEditorShellInteractionResult& result);
|
2026-04-11 20:20:30 +08:00
|
|
|
void ApplyHostedContentCaptureRequests();
|
2026-04-10 16:40:11 +08:00
|
|
|
bool HasInteractiveCaptureState() const;
|
2026-04-11 17:07:37 +08:00
|
|
|
std::string DescribeInputEvents(
|
|
|
|
|
const std::vector<::XCEngine::UI::UIInputEvent>& events) const;
|
2026-04-10 16:40:11 +08:00
|
|
|
void QueuePointerEvent(
|
|
|
|
|
::XCEngine::UI::UIInputEventType type,
|
|
|
|
|
::XCEngine::UI::UIPointerButton button,
|
|
|
|
|
WPARAM wParam,
|
|
|
|
|
LPARAM lParam);
|
2026-04-05 22:35:24 +08:00
|
|
|
void QueuePointerLeaveEvent();
|
2026-04-05 21:27:00 +08:00
|
|
|
void QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam);
|
2026-04-06 03:17:53 +08:00
|
|
|
void QueueKeyEvent(::XCEngine::UI::UIInputEventType type, WPARAM wParam, LPARAM lParam);
|
|
|
|
|
void QueueCharacterEvent(WPARAM wParam, LPARAM lParam);
|
|
|
|
|
void QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType type);
|
|
|
|
|
static std::filesystem::path ResolveRepoRootPath();
|
2026-04-11 17:07:37 +08:00
|
|
|
static LONG WINAPI HandleUnhandledException(EXCEPTION_POINTERS* exceptionInfo);
|
2026-04-13 18:52:30 +08:00
|
|
|
static bool IsVerboseRuntimeTraceEnabled();
|
2026-04-05 04:55:25 +08:00
|
|
|
|
|
|
|
|
HWND m_hwnd = nullptr;
|
2026-04-05 20:46:24 +08:00
|
|
|
HINSTANCE m_hInstance = nullptr;
|
|
|
|
|
ATOM m_windowClassAtom = 0;
|
2026-04-10 16:40:11 +08:00
|
|
|
::XCEngine::UI::Editor::Host::NativeRenderer m_renderer = {};
|
2026-04-12 23:21:59 +08:00
|
|
|
::XCEngine::UI::Editor::Host::D3D12WindowRenderer m_windowRenderer = {};
|
2026-04-10 16:40:11 +08:00
|
|
|
::XCEngine::UI::Editor::Host::AutoScreenshotController m_autoScreenshot = {};
|
|
|
|
|
::XCEngine::UI::Editor::Host::InputModifierTracker m_inputModifierTracker = {};
|
2026-04-12 01:29:00 +08:00
|
|
|
App::ProductEditorContext m_editorContext = {};
|
|
|
|
|
App::ProductEditorWorkspace m_editorWorkspace = {};
|
2026-04-05 21:27:00 +08:00
|
|
|
std::vector<::XCEngine::UI::UIInputEvent> m_pendingInputEvents = {};
|
2026-04-05 22:35:24 +08:00
|
|
|
bool m_trackingMouseLeave = false;
|
2026-04-11 17:07:37 +08:00
|
|
|
UINT m_windowDpi = 96u;
|
|
|
|
|
float m_dpiScale = 1.0f;
|
2026-04-13 18:52:30 +08:00
|
|
|
bool m_inInteractiveResize = false;
|
|
|
|
|
bool m_renderFrameQueued = false;
|
|
|
|
|
bool m_hasPendingWindowResize = false;
|
|
|
|
|
UINT m_pendingWindowResizeWidth = 0u;
|
|
|
|
|
UINT m_pendingWindowResizeHeight = 0u;
|
2026-04-05 04:55:25 +08:00
|
|
|
};
|
|
|
|
|
|
2026-04-06 20:02:34 +08:00
|
|
|
int RunXCUIEditorApp(HINSTANCE hInstance, int nCmdShow);
|
2026-04-05 20:46:24 +08:00
|
|
|
|
2026-04-06 20:02:34 +08:00
|
|
|
} // namespace XCEngine::UI::Editor
|