Refactor new editor boundaries and test ownership
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
#include "Platform/Win32/EditorWindow.h"
|
||||
#include "Platform/Win32/EditorWindowChromeController.h"
|
||||
#include "Platform/Win32/EditorWindowInputController.h"
|
||||
#include "Platform/Win32/EditorWindowInternalState.h"
|
||||
#include "Platform/Win32/EditorWindowRuntimeController.h"
|
||||
|
||||
#include <XCEngine/Input/InputTypes.h>
|
||||
#include <XCEngine/UI/Types.h>
|
||||
#include <XCEditor/Shell/UIEditorShellCapturePolicy.h>
|
||||
|
||||
@@ -33,84 +35,6 @@ bool IsScreenPointOverWindow(HWND hwnd, const POINT& screenPoint) {
|
||||
return screenPoint.x >= windowRect.left && screenPoint.x < windowRect.right &&
|
||||
screenPoint.y >= windowRect.top && screenPoint.y < windowRect.bottom;
|
||||
}
|
||||
|
||||
std::int32_t MapVirtualKeyToUIKeyCode(WPARAM wParam) {
|
||||
using ::XCEngine::Input::KeyCode;
|
||||
|
||||
switch (wParam) {
|
||||
case 'A': return static_cast<std::int32_t>(KeyCode::A);
|
||||
case 'B': return static_cast<std::int32_t>(KeyCode::B);
|
||||
case 'C': return static_cast<std::int32_t>(KeyCode::C);
|
||||
case 'D': return static_cast<std::int32_t>(KeyCode::D);
|
||||
case 'E': return static_cast<std::int32_t>(KeyCode::E);
|
||||
case 'F': return static_cast<std::int32_t>(KeyCode::F);
|
||||
case 'G': return static_cast<std::int32_t>(KeyCode::G);
|
||||
case 'H': return static_cast<std::int32_t>(KeyCode::H);
|
||||
case 'I': return static_cast<std::int32_t>(KeyCode::I);
|
||||
case 'J': return static_cast<std::int32_t>(KeyCode::J);
|
||||
case 'K': return static_cast<std::int32_t>(KeyCode::K);
|
||||
case 'L': return static_cast<std::int32_t>(KeyCode::L);
|
||||
case 'M': return static_cast<std::int32_t>(KeyCode::M);
|
||||
case 'N': return static_cast<std::int32_t>(KeyCode::N);
|
||||
case 'O': return static_cast<std::int32_t>(KeyCode::O);
|
||||
case 'P': return static_cast<std::int32_t>(KeyCode::P);
|
||||
case 'Q': return static_cast<std::int32_t>(KeyCode::Q);
|
||||
case 'R': return static_cast<std::int32_t>(KeyCode::R);
|
||||
case 'S': return static_cast<std::int32_t>(KeyCode::S);
|
||||
case 'T': return static_cast<std::int32_t>(KeyCode::T);
|
||||
case 'U': return static_cast<std::int32_t>(KeyCode::U);
|
||||
case 'V': return static_cast<std::int32_t>(KeyCode::V);
|
||||
case 'W': return static_cast<std::int32_t>(KeyCode::W);
|
||||
case 'X': return static_cast<std::int32_t>(KeyCode::X);
|
||||
case 'Y': return static_cast<std::int32_t>(KeyCode::Y);
|
||||
case 'Z': return static_cast<std::int32_t>(KeyCode::Z);
|
||||
case '0': return static_cast<std::int32_t>(KeyCode::Zero);
|
||||
case '1': return static_cast<std::int32_t>(KeyCode::One);
|
||||
case '2': return static_cast<std::int32_t>(KeyCode::Two);
|
||||
case '3': return static_cast<std::int32_t>(KeyCode::Three);
|
||||
case '4': return static_cast<std::int32_t>(KeyCode::Four);
|
||||
case '5': return static_cast<std::int32_t>(KeyCode::Five);
|
||||
case '6': return static_cast<std::int32_t>(KeyCode::Six);
|
||||
case '7': return static_cast<std::int32_t>(KeyCode::Seven);
|
||||
case '8': return static_cast<std::int32_t>(KeyCode::Eight);
|
||||
case '9': return static_cast<std::int32_t>(KeyCode::Nine);
|
||||
case VK_SPACE: return static_cast<std::int32_t>(KeyCode::Space);
|
||||
case VK_TAB: return static_cast<std::int32_t>(KeyCode::Tab);
|
||||
case VK_RETURN: return static_cast<std::int32_t>(KeyCode::Enter);
|
||||
case VK_ESCAPE: return static_cast<std::int32_t>(KeyCode::Escape);
|
||||
case VK_SHIFT: return static_cast<std::int32_t>(KeyCode::LeftShift);
|
||||
case VK_CONTROL: return static_cast<std::int32_t>(KeyCode::LeftCtrl);
|
||||
case VK_MENU: return static_cast<std::int32_t>(KeyCode::LeftAlt);
|
||||
case VK_UP: return static_cast<std::int32_t>(KeyCode::Up);
|
||||
case VK_DOWN: return static_cast<std::int32_t>(KeyCode::Down);
|
||||
case VK_LEFT: return static_cast<std::int32_t>(KeyCode::Left);
|
||||
case VK_RIGHT: return static_cast<std::int32_t>(KeyCode::Right);
|
||||
case VK_HOME: return static_cast<std::int32_t>(KeyCode::Home);
|
||||
case VK_END: return static_cast<std::int32_t>(KeyCode::End);
|
||||
case VK_PRIOR: return static_cast<std::int32_t>(KeyCode::PageUp);
|
||||
case VK_NEXT: return static_cast<std::int32_t>(KeyCode::PageDown);
|
||||
case VK_DELETE: return static_cast<std::int32_t>(KeyCode::Delete);
|
||||
case VK_BACK: return static_cast<std::int32_t>(KeyCode::Backspace);
|
||||
case VK_F1: return static_cast<std::int32_t>(KeyCode::F1);
|
||||
case VK_F2: return static_cast<std::int32_t>(KeyCode::F2);
|
||||
case VK_F3: return static_cast<std::int32_t>(KeyCode::F3);
|
||||
case VK_F4: return static_cast<std::int32_t>(KeyCode::F4);
|
||||
case VK_F5: return static_cast<std::int32_t>(KeyCode::F5);
|
||||
case VK_F6: return static_cast<std::int32_t>(KeyCode::F6);
|
||||
case VK_F7: return static_cast<std::int32_t>(KeyCode::F7);
|
||||
case VK_F8: return static_cast<std::int32_t>(KeyCode::F8);
|
||||
case VK_F9: return static_cast<std::int32_t>(KeyCode::F9);
|
||||
case VK_F10: return static_cast<std::int32_t>(KeyCode::F10);
|
||||
case VK_F11: return static_cast<std::int32_t>(KeyCode::F11);
|
||||
case VK_F12: return static_cast<std::int32_t>(KeyCode::F12);
|
||||
default: return static_cast<std::int32_t>(KeyCode::None);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsRepeatKeyMessage(LPARAM lParam) {
|
||||
return (static_cast<unsigned long>(lParam) & (1ul << 30)) != 0ul;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool EditorWindow::ApplyCurrentCursor() const {
|
||||
@@ -129,53 +53,34 @@ bool EditorWindow::ApplyCurrentCursor() const {
|
||||
|
||||
|
||||
bool EditorWindow::HasInteractiveCaptureState() const {
|
||||
return m_state->composition.shellRuntime.HasInteractiveCapture() ||
|
||||
m_state->chrome.runtime.IsBorderlessWindowDragRestoreArmed() ||
|
||||
m_state->chrome.runtime.IsBorderlessResizeActive() ||
|
||||
m_state->input.pointerCaptureOwner != EditorWindowPointerCaptureOwner::None;
|
||||
return m_runtime->GetShellRuntime().HasInteractiveCapture() ||
|
||||
m_chromeController->IsBorderlessWindowDragRestoreArmed() ||
|
||||
m_chromeController->IsBorderlessResizeActive() ||
|
||||
m_inputController->HasPointerCaptureOwner();
|
||||
}
|
||||
|
||||
EditorWindowPointerCaptureOwner EditorWindow::GetPointerCaptureOwner() const {
|
||||
return m_state->input.pointerCaptureOwner;
|
||||
return m_inputController->GetPointerCaptureOwner();
|
||||
}
|
||||
|
||||
bool EditorWindow::OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const {
|
||||
return m_state->input.pointerCaptureOwner == owner;
|
||||
return m_inputController->OwnsPointerCapture(owner);
|
||||
}
|
||||
|
||||
void EditorWindow::AcquirePointerCapture(EditorWindowPointerCaptureOwner owner) {
|
||||
if (owner == EditorWindowPointerCaptureOwner::None ||
|
||||
m_state->window.hwnd == nullptr ||
|
||||
!IsWindow(m_state->window.hwnd)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_state->input.pointerCaptureOwner = owner;
|
||||
if (GetCapture() != m_state->window.hwnd) {
|
||||
SetCapture(m_state->window.hwnd);
|
||||
}
|
||||
m_inputController->AcquirePointerCapture(m_state->window.hwnd, owner);
|
||||
}
|
||||
|
||||
void EditorWindow::ReleasePointerCapture(EditorWindowPointerCaptureOwner owner) {
|
||||
if (m_state->input.pointerCaptureOwner != owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_state->input.pointerCaptureOwner = EditorWindowPointerCaptureOwner::None;
|
||||
if (m_state->window.hwnd != nullptr && GetCapture() == m_state->window.hwnd) {
|
||||
ReleaseCapture();
|
||||
}
|
||||
m_inputController->ReleasePointerCapture(m_state->window.hwnd, owner);
|
||||
}
|
||||
|
||||
void EditorWindow::ForceReleasePointerCapture() {
|
||||
m_state->input.pointerCaptureOwner = EditorWindowPointerCaptureOwner::None;
|
||||
if (m_state->window.hwnd != nullptr && GetCapture() == m_state->window.hwnd) {
|
||||
ReleaseCapture();
|
||||
}
|
||||
m_inputController->ForceReleasePointerCapture(m_state->window.hwnd);
|
||||
}
|
||||
|
||||
void EditorWindow::ClearPointerCaptureOwner() {
|
||||
m_state->input.pointerCaptureOwner = EditorWindowPointerCaptureOwner::None;
|
||||
m_inputController->ClearPointerCaptureOwner();
|
||||
}
|
||||
|
||||
void EditorWindow::TryStartImmediateShellPointerCapture(LPARAM lParam) {
|
||||
@@ -189,7 +94,7 @@ void EditorWindow::TryStartImmediateShellPointerCapture(LPARAM lParam) {
|
||||
GET_X_LPARAM(lParam),
|
||||
GET_Y_LPARAM(lParam));
|
||||
if (!ShouldStartImmediateUIEditorShellPointerCapture(
|
||||
m_state->composition.shellRuntime.GetShellFrame(),
|
||||
m_runtime->GetShellFrame(),
|
||||
clientPoint)) {
|
||||
return;
|
||||
}
|
||||
@@ -203,16 +108,11 @@ void EditorWindow::QueuePointerEvent(
|
||||
WPARAM wParam,
|
||||
LPARAM lParam) {
|
||||
UIInputEvent event = {};
|
||||
event.type = type;
|
||||
event.pointerButton = button;
|
||||
event.position = ConvertClientPixelsToDips(
|
||||
GET_X_LPARAM(lParam),
|
||||
GET_Y_LPARAM(lParam));
|
||||
event.modifiers = m_state->input.modifierTracker.ApplyPointerMessage(
|
||||
m_inputController->QueuePointerEvent(
|
||||
type,
|
||||
button,
|
||||
static_cast<std::size_t>(wParam));
|
||||
m_state->input.pendingEvents.push_back(event);
|
||||
ConvertClientPixelsToDips(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)),
|
||||
wParam);
|
||||
}
|
||||
|
||||
void EditorWindow::QueueSyntheticPointerStateSyncEvent(
|
||||
@@ -229,24 +129,20 @@ void EditorWindow::QueueSyntheticPointerStateSyncEvent(
|
||||
return;
|
||||
}
|
||||
|
||||
UIInputEvent event = {};
|
||||
event.type = UIInputEventType::PointerMove;
|
||||
event.position = ConvertClientPixelsToDips(screenPoint.x, screenPoint.y);
|
||||
event.modifiers = modifiers;
|
||||
m_state->input.pendingEvents.push_back(event);
|
||||
m_inputController->QueueSyntheticPointerStateSyncEvent(
|
||||
ConvertClientPixelsToDips(screenPoint.x, screenPoint.y),
|
||||
modifiers);
|
||||
}
|
||||
|
||||
void EditorWindow::QueuePointerLeaveEvent() {
|
||||
UIInputEvent event = {};
|
||||
event.type = UIInputEventType::PointerLeave;
|
||||
::XCEngine::UI::UIPoint position = {};
|
||||
if (m_state->window.hwnd != nullptr) {
|
||||
POINT clientPoint = {};
|
||||
GetCursorPos(&clientPoint);
|
||||
ScreenToClient(m_state->window.hwnd, &clientPoint);
|
||||
event.position = ConvertClientPixelsToDips(clientPoint.x, clientPoint.y);
|
||||
position = ConvertClientPixelsToDips(clientPoint.x, clientPoint.y);
|
||||
}
|
||||
event.modifiers = m_state->input.modifierTracker.GetCurrentModifiers();
|
||||
m_state->input.pendingEvents.push_back(event);
|
||||
m_inputController->QueuePointerLeaveEvent(position);
|
||||
}
|
||||
|
||||
void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam) {
|
||||
@@ -260,50 +156,34 @@ void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARA
|
||||
};
|
||||
ScreenToClient(m_state->window.hwnd, &screenPoint);
|
||||
|
||||
UIInputEvent event = {};
|
||||
event.type = UIInputEventType::PointerWheel;
|
||||
event.position = ConvertClientPixelsToDips(screenPoint.x, screenPoint.y);
|
||||
event.wheelDelta = static_cast<float>(wheelDelta);
|
||||
event.modifiers = m_state->input.modifierTracker.ApplyPointerMessage(
|
||||
UIInputEventType::PointerWheel,
|
||||
UIPointerButton::None,
|
||||
static_cast<std::size_t>(wParam));
|
||||
m_state->input.pendingEvents.push_back(event);
|
||||
m_inputController->QueuePointerWheelEvent(
|
||||
ConvertClientPixelsToDips(screenPoint.x, screenPoint.y),
|
||||
wheelDelta,
|
||||
wParam);
|
||||
}
|
||||
|
||||
void EditorWindow::QueueKeyEvent(UIInputEventType type, WPARAM wParam, LPARAM lParam) {
|
||||
UIInputEvent event = {};
|
||||
event.type = type;
|
||||
event.keyCode = MapVirtualKeyToUIKeyCode(wParam);
|
||||
event.modifiers = m_state->input.modifierTracker.ApplyKeyMessage(type, wParam, lParam);
|
||||
event.repeat = IsRepeatKeyMessage(lParam);
|
||||
m_state->input.pendingEvents.push_back(event);
|
||||
m_inputController->QueueKeyEvent(type, wParam, lParam);
|
||||
}
|
||||
|
||||
void EditorWindow::QueueCharacterEvent(WPARAM wParam, LPARAM) {
|
||||
UIInputEvent event = {};
|
||||
event.type = UIInputEventType::Character;
|
||||
event.character = static_cast<std::uint32_t>(wParam);
|
||||
event.modifiers = m_state->input.modifierTracker.GetCurrentModifiers();
|
||||
m_state->input.pendingEvents.push_back(event);
|
||||
m_inputController->QueueCharacterEvent(wParam);
|
||||
}
|
||||
|
||||
void EditorWindow::QueueWindowFocusEvent(UIInputEventType type) {
|
||||
UIInputEvent event = {};
|
||||
event.type = type;
|
||||
m_state->input.pendingEvents.push_back(event);
|
||||
m_inputController->QueueWindowFocusEvent(type);
|
||||
}
|
||||
|
||||
void EditorWindow::SyncInputModifiersFromSystemState() {
|
||||
m_state->input.modifierTracker.SyncFromSystemState();
|
||||
m_inputController->SyncInputModifiersFromSystemState();
|
||||
}
|
||||
|
||||
void EditorWindow::ResetInputModifiers() {
|
||||
m_state->input.modifierTracker.Reset();
|
||||
m_inputController->ResetInputModifiers();
|
||||
}
|
||||
|
||||
void EditorWindow::RequestManualScreenshot() {
|
||||
m_state->render.autoScreenshot.RequestCapture("manual_f12");
|
||||
m_runtime->RequestManualScreenshot("manual_f12");
|
||||
}
|
||||
|
||||
bool EditorWindow::IsPointerInsideClientArea() const {
|
||||
@@ -328,14 +208,14 @@ bool EditorWindow::IsPointerInsideClientArea() const {
|
||||
|
||||
LPCWSTR EditorWindow::ResolveCurrentCursorResource() const {
|
||||
const Host::BorderlessWindowResizeEdge borderlessResizeEdge =
|
||||
m_state->chrome.runtime.IsBorderlessResizeActive()
|
||||
? m_state->chrome.runtime.GetBorderlessResizeEdge()
|
||||
: m_state->chrome.runtime.GetHoveredBorderlessResizeEdge();
|
||||
m_chromeController->IsBorderlessResizeActive()
|
||||
? m_chromeController->GetBorderlessResizeEdge()
|
||||
: m_chromeController->GetHoveredBorderlessResizeEdge();
|
||||
if (borderlessResizeEdge != Host::BorderlessWindowResizeEdge::None) {
|
||||
return Host::ResolveBorderlessWindowResizeCursor(borderlessResizeEdge);
|
||||
}
|
||||
|
||||
switch (m_state->composition.shellRuntime.GetHostedContentCursorKind()) {
|
||||
switch (m_runtime->GetShellRuntime().GetHostedContentCursorKind()) {
|
||||
case ProjectPanel::CursorKind::ResizeEW:
|
||||
return IDC_SIZEWE;
|
||||
case ProjectPanel::CursorKind::Arrow:
|
||||
@@ -343,7 +223,7 @@ LPCWSTR EditorWindow::ResolveCurrentCursorResource() const {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (m_state->composition.shellRuntime.GetDockCursorKind()) {
|
||||
switch (m_runtime->GetShellRuntime().GetDockCursorKind()) {
|
||||
case Widgets::UIEditorDockHostCursorKind::ResizeEW:
|
||||
return IDC_SIZEWE;
|
||||
case Widgets::UIEditorDockHostCursorKind::ResizeNS:
|
||||
|
||||
Reference in New Issue
Block a user