1
0
Fork 0
spectre/source/Platform/Win32/Win32Mouse.cpp
2023-08-23 20:05:54 +02:00

137 lines
2.9 KiB
C++

#include <Windows.h>
#include <Spectre/System/Log.h>
#include <Spectre/Input/InputModule.h>
#include "Win32Input.h"
#include "Win32Mouse.h"
namespace sp {
static Vector2f _normalizePos(int x, int y, RECT area)
{
Vector2f out;
out.x = x / ((float) (area.right - area.left));
out.y = y / ((float) (area.bottom - area.top));
return out;
}
static RECT GetClientArea(HWND hwnd) {
RECT rect;
GetClientRect(hwnd, &rect);
return rect;
}
void Win32Mouse::init()
{
}
Vector2f Win32Mouse::getPosition() const
{
return m_position;
}
Vector2f Win32Mouse::getAbsPosition() const
{
return m_abs_position;
}
bool Win32Mouse::isButtonDown(Mouse::Button button) const
{
int btn;
switch(button) {
case Mouse::Left : btn = GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON; break;
case Mouse::Right : btn = GetSystemMetrics(SM_SWAPBUTTON) ? VK_LBUTTON : VK_RBUTTON; break;
case Mouse::Middle : btn = VK_MBUTTON; break;
case Mouse::XButton1 : btn = VK_XBUTTON1; break;
case Mouse::XButton2 : btn = VK_XBUTTON2; break;
default: btn = 0;
}
return ::GetAsyncKeyState(btn) & 0x8000;
}
void Win32Mouse::update(InputModule *input)
{
HWND handle;
POINT p;
// Update absolute position
GetCursorPos(&p);
m_abs_position = Vector2f(p.x, p.y);
// Update relative position
// Get the active window.
handle = ::GetActiveWindow();
if (handle) {
// Translate position to the active window.
ScreenToClient(handle, &p);
m_position = Vector2f(p.x, p.y);
}
}
bool Win32Mouse::handleMessage(MSG msg, Event& event)
{
switch(msg.message) {
case WM_LBUTTONUP :
case WM_LBUTTONDOWN :
case WM_RBUTTONUP :
case WM_RBUTTONDOWN :
case WM_MBUTTONUP :
case WM_MBUTTONDOWN :
case WM_XBUTTONUP :
case WM_XBUTTONDOWN :
event.type = Event::MouseButton;
break;
}
switch(msg.message) {
case WM_LBUTTONUP :
case WM_LBUTTONDOWN :
event.mouseButton.button = Mouse::Button::Left;
event.mouseButton.pressed = msg.message == WM_LBUTTONDOWN;
return true;
case WM_RBUTTONUP :
case WM_RBUTTONDOWN :
event.mouseButton.button = Mouse::Button::Right;
event.mouseButton.pressed = msg.message == WM_RBUTTONDOWN;
return true;
case WM_MBUTTONUP :
case WM_MBUTTONDOWN :
event.mouseButton.button = Mouse::Button::Right;
event.mouseButton.pressed = msg.message == WM_MBUTTONDOWN;
return true;
case WM_XBUTTONUP :
case WM_XBUTTONDOWN :
event.mouseButton.button = GET_XBUTTON_WPARAM(msg.wParam) == XBUTTON1
? Mouse::Button::XButton1 : Mouse::Button::XButton2;
event.mouseButton.pressed = msg.message == WM_XBUTTONDOWN;
return true;
case WM_MOUSEMOVE :
RECT area = GetClientArea(msg.hwnd);
int x = LOWORD(msg.lParam);
int y = HIWORD(msg.lParam);
// Do not forward the message if mouse is outside client area.
if ( (x < area.left) || (x > area.right)
|| (y < area.top) || (y > area.bottom) ) {
return false;
}
event.type = Event::MouseMove;
event.mouseMove.x = x;
event.mouseMove.y = y;
return true;
}
return false;
}
} // namespace sp