#pragma once #include #include #include #include #include #include #include #ifndef NOMINMAX #define NOMINMAX #endif #include namespace XCEngine { namespace Editor { namespace XCUIBackend { struct XCUIInputBridgeKeyState { std::int32_t keyCode = 0; bool down = false; bool repeat = false; }; struct XCUIInputBridgeFrameSnapshot { static constexpr std::size_t PointerButtonCount = 5u; UI::UIPoint pointerPosition = {}; bool pointerInside = false; std::array pointerButtonsDown = {}; UI::UIPoint wheelDelta = {}; UI::UIInputModifiers modifiers = {}; bool windowFocused = false; bool wantCaptureMouse = false; bool wantCaptureKeyboard = false; bool wantTextInput = false; std::uint64_t timestampNanoseconds = 0; std::vector keys = {}; std::vector characters = {}; const XCUIInputBridgeKeyState* FindKeyState(std::int32_t keyCode) const; bool IsKeyDown(std::int32_t keyCode) const; }; struct XCUIInputBridgeCaptureOptions { UI::UIPoint pointerOffset = {}; bool hasPointerInsideOverride = false; bool pointerInsideOverride = false; bool windowFocused = true; std::uint64_t timestampNanoseconds = 0; }; struct XCUIInputBridgePointerDelta { UI::UIPoint delta = {}; UI::UIPoint wheelDelta = {}; std::array pressed = {}; std::array released = {}; bool moved = false; bool entered = false; bool left = false; }; struct XCUIInputBridgeKeyboardDelta { std::vector pressedKeys = {}; std::vector releasedKeys = {}; std::vector repeatedKeys = {}; std::vector characters = {}; }; struct XCUIInputBridgeFrameDelta { XCUIInputBridgeFrameSnapshot state = {}; XCUIInputBridgePointerDelta pointer = {}; XCUIInputBridgeKeyboardDelta keyboard = {}; std::vector events = {}; bool focusGained = false; bool focusLost = false; bool HasEvents() const; bool HasPointerActivity() const; bool HasKeyboardActivity() const; bool HasEventType(UI::UIInputEventType type) const; }; class XCUIInputBridge { public: void Reset(); void Prime(const XCUIInputBridgeFrameSnapshot& snapshot); bool HasBaseline() const { return m_hasBaseline; } const XCUIInputBridgeFrameSnapshot& GetBaseline() const { return m_baseline; } XCUIInputBridgeFrameDelta Translate(const XCUIInputBridgeFrameSnapshot& current); static XCUIInputBridgeFrameDelta Translate( const XCUIInputBridgeFrameSnapshot& previous, const XCUIInputBridgeFrameSnapshot& current); private: bool m_hasBaseline = false; XCUIInputBridgeFrameSnapshot m_baseline = {}; }; class XCUIWin32InputSource { public: void Reset(); void HandleWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); void ClearFrameTransients(); XCUIInputBridgeFrameSnapshot CaptureSnapshot( const XCUIInputBridgeCaptureOptions& options = XCUIInputBridgeCaptureOptions()) const; const UI::UIPoint& GetPointerPosition() const { return m_pointerPosition; } bool IsPointerInsideWindow() const { return m_pointerInside; } bool IsWindowFocused() const { return m_windowFocused; } private: void UpdateModifierState(); void UpdatePointerInside(HWND hwnd, float x, float y, bool assumeInsideIfUnknown); void SetPointerButtonDown(std::size_t index, bool down); void SetKeyDown(std::int32_t keyCode, bool down, bool repeat); UI::UIPoint m_pointerPosition = {}; bool m_pointerInside = false; bool m_windowFocused = false; bool m_trackingMouseLeave = false; std::array m_pointerButtonsDown = {}; UI::UIPoint m_wheelDelta = {}; UI::UIInputModifiers m_modifiers = {}; std::vector m_keyStates = {}; std::vector m_characters = {}; }; } // namespace XCUIBackend } // namespace Editor } // namespace XCEngine