Files
XCEngine/new_editor/src/XCUIBackend/XCUIInputBridge.h

153 lines
4.3 KiB
C++

#pragma once
#include <XCEngine/Input/InputTypes.h>
#include <XCEngine/UI/Types.h>
#include <imgui.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <vector>
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
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<bool, PointerButtonCount> 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<XCUIInputBridgeKeyState> keys = {};
std::vector<std::uint32_t> 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<bool, XCUIInputBridgeFrameSnapshot::PointerButtonCount> pressed = {};
std::array<bool, XCUIInputBridgeFrameSnapshot::PointerButtonCount> released = {};
bool moved = false;
bool entered = false;
bool left = false;
};
struct XCUIInputBridgeKeyboardDelta {
std::vector<std::int32_t> pressedKeys = {};
std::vector<std::int32_t> releasedKeys = {};
std::vector<std::int32_t> repeatedKeys = {};
std::vector<std::uint32_t> characters = {};
};
struct XCUIInputBridgeFrameDelta {
XCUIInputBridgeFrameSnapshot state = {};
XCUIInputBridgePointerDelta pointer = {};
XCUIInputBridgeKeyboardDelta keyboard = {};
std::vector<UI::UIInputEvent> 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<bool, XCUIInputBridgeFrameSnapshot::PointerButtonCount> m_pointerButtonsDown = {};
UI::UIPoint m_wheelDelta = {};
UI::UIInputModifiers m_modifiers = {};
std::vector<XCUIInputBridgeKeyState> m_keyStates = {};
std::vector<std::uint32_t> m_characters = {};
};
} // namespace XCUIBackend
} // namespace Editor
} // namespace XCEngine