#include "Platform/Win32/EditorWindow.h" #include "Platform/Win32/EditorWindowInputSupport.h" #include #include namespace XCEngine::UI::Editor::App { using namespace EditorWindowSupport; using ::XCEngine::UI::UIInputEvent; using ::XCEngine::UI::UIInputEventType; using ::XCEngine::UI::UIPointerButton; bool EditorWindow::ApplyCurrentCursor() const { if (!HasInteractiveCaptureState() && !IsPointerInsideClientArea()) { return false; } const HCURSOR cursor = LoadCursorW(nullptr, ResolveCurrentCursorResource()); if (cursor == nullptr) { return false; } SetCursor(cursor); return true; } bool EditorWindow::HasInteractiveCaptureState() const { return m_composition.shellRuntime.HasInteractiveCapture() || m_chrome.runtime.IsBorderlessWindowDragRestoreArmed(); } void EditorWindow::QueuePointerEvent( UIInputEventType type, UIPointerButton button, 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_input.modifierTracker.BuildPointerModifiers(static_cast(wParam)); m_input.pendingEvents.push_back(event); } void EditorWindow::QueuePointerLeaveEvent() { UIInputEvent event = {}; event.type = UIInputEventType::PointerLeave; if (m_window.hwnd != nullptr) { POINT clientPoint = {}; GetCursorPos(&clientPoint); ScreenToClient(m_window.hwnd, &clientPoint); event.position = ConvertClientPixelsToDips(clientPoint.x, clientPoint.y); } m_input.pendingEvents.push_back(event); } void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam) { if (m_window.hwnd == nullptr) { return; } POINT screenPoint = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; ScreenToClient(m_window.hwnd, &screenPoint); UIInputEvent event = {}; event.type = UIInputEventType::PointerWheel; event.position = ConvertClientPixelsToDips(screenPoint.x, screenPoint.y); event.wheelDelta = static_cast(wheelDelta); event.modifiers = m_input.modifierTracker.BuildPointerModifiers(static_cast(wParam)); m_input.pendingEvents.push_back(event); } void EditorWindow::QueueKeyEvent(UIInputEventType type, WPARAM wParam, LPARAM lParam) { UIInputEvent event = {}; event.type = type; event.keyCode = MapVirtualKeyToUIKeyCode(wParam); event.modifiers = m_input.modifierTracker.ApplyKeyMessage(type, wParam, lParam); event.repeat = IsRepeatKeyMessage(lParam); m_input.pendingEvents.push_back(event); } void EditorWindow::QueueCharacterEvent(WPARAM wParam, LPARAM) { UIInputEvent event = {}; event.type = UIInputEventType::Character; event.character = static_cast(wParam); event.modifiers = m_input.modifierTracker.GetCurrentModifiers(); m_input.pendingEvents.push_back(event); } void EditorWindow::QueueWindowFocusEvent(UIInputEventType type) { UIInputEvent event = {}; event.type = type; m_input.pendingEvents.push_back(event); } void EditorWindow::SyncInputModifiersFromSystemState() { m_input.modifierTracker.SyncFromSystemState(); } void EditorWindow::ResetInputModifiers() { m_input.modifierTracker.Reset(); } void EditorWindow::RequestManualScreenshot() { m_render.autoScreenshot.RequestCapture("manual_f12"); } bool EditorWindow::IsPointerInsideClientArea() const { if (m_window.hwnd == nullptr || !IsWindow(m_window.hwnd)) { return false; } POINT screenPoint = {}; if (!GetCursorPos(&screenPoint)) { return false; } const LPARAM pointParam = MAKELPARAM( static_cast(screenPoint.x), static_cast(screenPoint.y)); return SendMessageW(m_window.hwnd, WM_NCHITTEST, 0, pointParam) == HTCLIENT; } LPCWSTR EditorWindow::ResolveCurrentCursorResource() const { const Host::BorderlessWindowResizeEdge borderlessResizeEdge = m_chrome.runtime.IsBorderlessResizeActive() ? m_chrome.runtime.GetBorderlessResizeEdge() : m_chrome.runtime.GetHoveredBorderlessResizeEdge(); if (borderlessResizeEdge != Host::BorderlessWindowResizeEdge::None) { return Host::ResolveBorderlessWindowResizeCursor(borderlessResizeEdge); } switch (m_composition.shellRuntime.GetHostedContentCursorKind()) { case ProjectPanel::CursorKind::ResizeEW: return IDC_SIZEWE; case ProjectPanel::CursorKind::Arrow: default: break; } switch (m_composition.shellRuntime.GetDockCursorKind()) { case Widgets::UIEditorDockHostCursorKind::ResizeEW: return IDC_SIZEWE; case Widgets::UIEditorDockHostCursorKind::ResizeNS: return IDC_SIZENS; case Widgets::UIEditorDockHostCursorKind::Arrow: default: return IDC_ARROW; } } } // namespace XCEngine::UI::Editor::App