174 lines
5.2 KiB
C++
174 lines
5.2 KiB
C++
#pragma once
|
|
|
|
#ifndef NOMINMAX
|
|
#define NOMINMAX
|
|
#endif
|
|
|
|
#include <XCEngine/UI/Types.h>
|
|
|
|
#include <windows.h>
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
|
|
namespace XCEngine::UI::Editor::Host {
|
|
|
|
class InputModifierTracker {
|
|
public:
|
|
void Reset() {
|
|
m_leftShift = false;
|
|
m_rightShift = false;
|
|
m_leftControl = false;
|
|
m_rightControl = false;
|
|
m_leftAlt = false;
|
|
m_rightAlt = false;
|
|
m_leftSuper = false;
|
|
m_rightSuper = false;
|
|
}
|
|
|
|
void SyncFromSystemState() {
|
|
m_leftShift = (GetKeyState(VK_LSHIFT) & 0x8000) != 0;
|
|
m_rightShift = (GetKeyState(VK_RSHIFT) & 0x8000) != 0;
|
|
m_leftControl = (GetKeyState(VK_LCONTROL) & 0x8000) != 0;
|
|
m_rightControl = (GetKeyState(VK_RCONTROL) & 0x8000) != 0;
|
|
m_leftAlt = (GetKeyState(VK_LMENU) & 0x8000) != 0;
|
|
m_rightAlt = (GetKeyState(VK_RMENU) & 0x8000) != 0;
|
|
m_leftSuper = (GetKeyState(VK_LWIN) & 0x8000) != 0;
|
|
m_rightSuper = (GetKeyState(VK_RWIN) & 0x8000) != 0;
|
|
}
|
|
|
|
::XCEngine::UI::UIInputModifiers GetCurrentModifiers() const {
|
|
return BuildModifiers();
|
|
}
|
|
|
|
::XCEngine::UI::UIInputModifiers BuildPointerModifiers(std::size_t wParam) const {
|
|
::XCEngine::UI::UIInputModifiers modifiers = BuildModifiers();
|
|
modifiers.shift = modifiers.shift || (wParam & MK_SHIFT) != 0;
|
|
modifiers.control = modifiers.control || (wParam & MK_CONTROL) != 0;
|
|
return modifiers;
|
|
}
|
|
|
|
::XCEngine::UI::UIInputModifiers ApplyKeyMessage(
|
|
::XCEngine::UI::UIInputEventType type,
|
|
WPARAM wParam,
|
|
LPARAM lParam) {
|
|
if (type == ::XCEngine::UI::UIInputEventType::KeyDown) {
|
|
SetModifierState(ResolveModifierKey(wParam, lParam), true);
|
|
} else if (type == ::XCEngine::UI::UIInputEventType::KeyUp) {
|
|
SetModifierState(ResolveModifierKey(wParam, lParam), false);
|
|
}
|
|
|
|
return BuildModifiers();
|
|
}
|
|
|
|
private:
|
|
enum class ModifierKey : std::uint8_t {
|
|
None = 0,
|
|
LeftShift,
|
|
RightShift,
|
|
LeftControl,
|
|
RightControl,
|
|
LeftAlt,
|
|
RightAlt,
|
|
LeftSuper,
|
|
RightSuper
|
|
};
|
|
|
|
static bool IsExtendedKey(LPARAM lParam) {
|
|
return (static_cast<std::uint32_t>(lParam) & 0x01000000u) != 0u;
|
|
}
|
|
|
|
static std::uint32_t ExtractScanCode(LPARAM lParam) {
|
|
return (static_cast<std::uint32_t>(lParam) >> 16u) & 0xffu;
|
|
}
|
|
|
|
static ModifierKey ResolveModifierKey(WPARAM wParam, LPARAM lParam) {
|
|
switch (static_cast<std::uint32_t>(wParam)) {
|
|
case VK_SHIFT: {
|
|
const UINT shiftVirtualKey = MapVirtualKeyW(ExtractScanCode(lParam), MAPVK_VSC_TO_VK_EX);
|
|
return shiftVirtualKey == VK_RSHIFT
|
|
? ModifierKey::RightShift
|
|
: ModifierKey::LeftShift;
|
|
}
|
|
case VK_LSHIFT:
|
|
return ModifierKey::LeftShift;
|
|
case VK_RSHIFT:
|
|
return ModifierKey::RightShift;
|
|
case VK_CONTROL:
|
|
return IsExtendedKey(lParam)
|
|
? ModifierKey::RightControl
|
|
: ModifierKey::LeftControl;
|
|
case VK_LCONTROL:
|
|
return ModifierKey::LeftControl;
|
|
case VK_RCONTROL:
|
|
return ModifierKey::RightControl;
|
|
case VK_MENU:
|
|
return IsExtendedKey(lParam)
|
|
? ModifierKey::RightAlt
|
|
: ModifierKey::LeftAlt;
|
|
case VK_LMENU:
|
|
return ModifierKey::LeftAlt;
|
|
case VK_RMENU:
|
|
return ModifierKey::RightAlt;
|
|
case VK_LWIN:
|
|
return ModifierKey::LeftSuper;
|
|
case VK_RWIN:
|
|
return ModifierKey::RightSuper;
|
|
default:
|
|
return ModifierKey::None;
|
|
}
|
|
}
|
|
|
|
void SetModifierState(ModifierKey key, bool pressed) {
|
|
switch (key) {
|
|
case ModifierKey::LeftShift:
|
|
m_leftShift = pressed;
|
|
break;
|
|
case ModifierKey::RightShift:
|
|
m_rightShift = pressed;
|
|
break;
|
|
case ModifierKey::LeftControl:
|
|
m_leftControl = pressed;
|
|
break;
|
|
case ModifierKey::RightControl:
|
|
m_rightControl = pressed;
|
|
break;
|
|
case ModifierKey::LeftAlt:
|
|
m_leftAlt = pressed;
|
|
break;
|
|
case ModifierKey::RightAlt:
|
|
m_rightAlt = pressed;
|
|
break;
|
|
case ModifierKey::LeftSuper:
|
|
m_leftSuper = pressed;
|
|
break;
|
|
case ModifierKey::RightSuper:
|
|
m_rightSuper = pressed;
|
|
break;
|
|
case ModifierKey::None:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
::XCEngine::UI::UIInputModifiers BuildModifiers() const {
|
|
::XCEngine::UI::UIInputModifiers modifiers = {};
|
|
modifiers.shift = m_leftShift || m_rightShift;
|
|
modifiers.control = m_leftControl || m_rightControl;
|
|
modifiers.alt = m_leftAlt || m_rightAlt;
|
|
modifiers.super = m_leftSuper || m_rightSuper;
|
|
return modifiers;
|
|
}
|
|
|
|
bool m_leftShift = false;
|
|
bool m_rightShift = false;
|
|
bool m_leftControl = false;
|
|
bool m_rightControl = false;
|
|
bool m_leftAlt = false;
|
|
bool m_rightAlt = false;
|
|
bool m_leftSuper = false;
|
|
bool m_rightSuper = false;
|
|
};
|
|
|
|
} // namespace XCEngine::UI::Editor::Host
|