Files
XCEngine/new_editor/app/Platform/Win32/EditorWindow.h

211 lines
8.1 KiB
C++

#pragma once
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "State/EditorContext.h"
#include "Platform/Win32/EditorWindowState.h"
#include <XCEngine/UI/DrawData.h>
#include <windows.h>
#include <filesystem>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor::App {
struct EditorWindowPendingTabDragStart {
std::string nodeId = {};
std::string panelId = {};
POINT screenPoint = {};
};
struct EditorWindowPendingDetachRequest {
std::string nodeId = {};
std::string panelId = {};
POINT screenPoint = {};
};
class EditorWindow {
public:
EditorWindow(
std::string windowId,
std::wstring title,
bool primary,
UIEditorWorkspaceController workspaceController);
EditorWindow(const EditorWindow&) = delete;
EditorWindow& operator=(const EditorWindow&) = delete;
EditorWindow(EditorWindow&&) = delete;
EditorWindow& operator=(EditorWindow&&) = delete;
std::string_view GetWindowId() const;
HWND GetHwnd() const;
bool HasHwnd() const;
bool IsPrimary() const;
bool IsRenderReady() const;
bool IsTrackingMouseLeave() const;
bool HasHoveredBorderlessResizeEdge() const;
const std::wstring& GetTitle() const;
const UIEditorWorkspaceController& GetWorkspaceController() const;
UIEditorWorkspaceController& GetWorkspaceController();
const EditorShellRuntime& GetShellRuntime() const;
EditorShellRuntime& GetShellRuntime();
const UIEditorShellInteractionFrame& GetShellFrame() const;
const UIEditorShellInteractionState& GetShellInteractionState() const;
::XCEngine::UI::UIPoint ConvertScreenPixelsToClientDips(const POINT& screenPoint) const;
void InvalidateHostWindow() const;
void AttachHwnd(HWND hwnd);
void MarkDestroyed();
void SetTrackingMouseLeave(bool trackingMouseLeave);
void SetTitle(std::wstring title);
void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController);
bool Initialize(
const std::filesystem::path& repoRoot,
EditorContext& editorContext,
const std::filesystem::path& captureRoot,
bool autoCaptureOnStartup);
void Shutdown();
void ResetInteractionState();
std::optional<EditorWindowPendingTabDragStart> ConsumePendingTabDragStart();
std::optional<EditorWindowPendingDetachRequest> ConsumeDetachRequest();
void RenderFrame(
EditorContext& editorContext,
bool globalTabDragActive);
void OnPaintMessage(
EditorContext& editorContext,
bool globalTabDragActive);
void OnResize(UINT width, UINT height);
void OnEnterSizeMove();
void OnExitSizeMove();
void OnDpiChanged(UINT dpi, const RECT& suggestedRect);
bool IsBorderlessWindowEnabled() const;
bool IsBorderlessWindowMaximized() const;
bool HandleBorderlessWindowSystemCommand(
EditorContext& editorContext,
bool globalTabDragActive,
WPARAM wParam);
bool HandleBorderlessWindowGetMinMaxInfo(LPARAM lParam) const;
LRESULT HandleBorderlessWindowNcCalcSize(WPARAM wParam, LPARAM lParam) const;
bool ApplyCurrentCursor() const;
bool UpdateBorderlessWindowResizeHover(LPARAM lParam);
bool HandleBorderlessWindowResizeButtonDown(LPARAM lParam);
bool HandleBorderlessWindowResizeButtonUp();
bool HandleBorderlessWindowResizePointerMove(
EditorContext& editorContext,
bool globalTabDragActive);
void ClearBorderlessWindowResizeState();
void ForceClearBorderlessWindowResizeState();
Host::BorderlessWindowChromeHitTarget HitTestBorderlessWindowChrome(LPARAM lParam) const;
bool UpdateBorderlessWindowChromeHover(LPARAM lParam);
bool HandleBorderlessWindowChromeButtonDown(LPARAM lParam);
bool HandleBorderlessWindowChromeButtonUp(
EditorContext& editorContext,
bool globalTabDragActive,
LPARAM lParam);
bool HandleBorderlessWindowChromeDoubleClick(
EditorContext& editorContext,
bool globalTabDragActive,
LPARAM lParam);
bool HandleBorderlessWindowChromeDragRestorePointerMove(
EditorContext& editorContext,
bool globalTabDragActive);
void ClearBorderlessWindowChromeDragRestoreState();
void ClearBorderlessWindowChromeState();
bool HasInteractiveCaptureState() const;
void QueuePointerEvent(
::XCEngine::UI::UIInputEventType type,
::XCEngine::UI::UIPointerButton button,
WPARAM wParam,
LPARAM lParam);
void QueuePointerLeaveEvent();
void QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam);
void QueueKeyEvent(::XCEngine::UI::UIInputEventType type, WPARAM wParam, LPARAM lParam);
void QueueCharacterEvent(WPARAM wParam, LPARAM lParam);
void QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType type);
void SyncInputModifiersFromSystemState();
void ResetInputModifiers();
void RequestManualScreenshot();
private:
bool ApplyWindowResize(UINT width, UINT height);
bool QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const;
bool ResolveRenderClientPixelSize(UINT& outWidth, UINT& outHeight) const;
::XCEngine::UI::UIRect ResolveWorkspaceBounds(
float clientWidthDips,
float clientHeightDips) const;
void RenderRuntimeFrame(
EditorContext& editorContext,
bool globalTabDragActive,
const ::XCEngine::UI::UIRect& workspaceBounds,
::XCEngine::UI::UIDrawList& drawList);
void RenderInvalidFrame(
EditorContext& editorContext,
::XCEngine::UI::UIDrawList& drawList) const;
void LogFrameInteractionTrace(
EditorContext& editorContext,
const std::vector<::XCEngine::UI::UIInputEvent>& frameEvents,
const UIEditorShellInteractionFrame& shellFrame) const;
void QueueShellTransferRequests(
bool globalTabDragActive,
const UIEditorDockHostInteractionState& dockHostInteractionState,
const UIEditorShellInteractionFrame& shellFrame);
bool IsPointerInsideClientArea() const;
LPCWSTR ResolveCurrentCursorResource() const;
float GetDpiScale() const;
float PixelsToDips(float pixels) const;
::XCEngine::UI::UIPoint ConvertClientPixelsToDips(LONG x, LONG y) const;
std::string BuildCaptureStatusText() const;
void ApplyHostCaptureRequests(const UIEditorShellInteractionResult& result);
void ApplyHostedContentCaptureRequests();
std::string DescribeInputEvents(
const std::vector<::XCEngine::UI::UIInputEvent>& events) const;
Host::BorderlessWindowResizeEdge HitTestBorderlessWindowResizeEdge(LPARAM lParam) const;
void ApplyBorderlessWindowResizeCursorHoverPriority();
Host::BorderlessWindowChromeLayout ResolveBorderlessWindowChromeLayout(
float clientWidthDips) const;
bool QueryCurrentWindowRect(RECT& outRect) const;
bool QueryBorderlessWindowWorkAreaRect(RECT& outRect) const;
bool ApplyPredictedWindowRectTransition(
EditorContext& editorContext,
bool globalTabDragActive,
const RECT& targetRect);
bool ShouldUseDetachedTitleBarTabStrip() const;
void ToggleBorderlessWindowMaximizeRestore(
EditorContext& editorContext,
bool globalTabDragActive);
void AppendBorderlessWindowChrome(
::XCEngine::UI::UIDrawList& drawList,
float clientWidthDips) const;
void ExecuteBorderlessWindowChromeAction(
EditorContext& editorContext,
bool globalTabDragActive,
Host::BorderlessWindowChromeHitTarget target);
void QueuePendingTabDragStart(std::string_view nodeId, std::string_view panelId);
void QueuePendingDetachRequest(std::string_view nodeId, std::string_view panelId);
void UpdateCachedTitleText();
static bool IsVerboseRuntimeTraceEnabled();
EditorWindowWindowState m_window = {};
EditorWindowRenderState m_render = {};
EditorWindowInputState m_input = {};
EditorWindowCompositionState m_composition = {};
EditorWindowChromeRuntimeState m_chrome = {};
EditorWindowPanelTransferState m_pendingDetachRequest = {};
EditorWindowPanelTransferState m_pendingTabDragStart = {};
};
} // namespace XCEngine::UI::Editor::App