214 lines
7.6 KiB
C++
214 lines
7.6 KiB
C++
#pragma once
|
|
#include "../Devices/Screen.h"
|
|
#include "../IPC/Event.h"
|
|
#include <algorithm>
|
|
#include <libg/PixelBitmap.h>
|
|
#include <libg/Point.h>
|
|
|
|
#ifdef TARGET_DESKTOP
|
|
#define CURSOR_OFFSET (2)
|
|
#elif TARGET_MOBILE
|
|
#define CURSOR_OFFSET (6)
|
|
#endif
|
|
|
|
namespace WinServer {
|
|
|
|
class CursorManager {
|
|
public:
|
|
enum class Params {
|
|
X,
|
|
Y,
|
|
LeftButton,
|
|
RightButton,
|
|
OffsetX,
|
|
OffsetY,
|
|
Wheel,
|
|
|
|
// Only for getters of conditions changes.
|
|
Coords,
|
|
Buttons,
|
|
};
|
|
|
|
inline static CursorManager& the()
|
|
{
|
|
extern CursorManager* s_WinServer_CursorManager_the;
|
|
return *s_WinServer_CursorManager_the;
|
|
}
|
|
|
|
CursorManager();
|
|
~CursorManager() = default;
|
|
|
|
inline const LG::PixelBitmap& current_cursor() const { return std_cursor(); }
|
|
inline const LG::PixelBitmap& std_cursor() const { return m_std_cursor; }
|
|
inline LG::Point<int> draw_position() { return { m_mouse_x - CURSOR_OFFSET, m_mouse_y - CURSOR_OFFSET }; }
|
|
|
|
inline int x() const
|
|
{
|
|
return m_mouse_x;
|
|
}
|
|
inline int y() const { return m_mouse_y; }
|
|
|
|
template <Params param>
|
|
constexpr int get();
|
|
|
|
template <Params param>
|
|
constexpr bool pressed() const;
|
|
|
|
template <Params param>
|
|
constexpr bool is_changed();
|
|
inline void clear_changed(uint32_t val = 0) { m_mask_changed_objects = val; }
|
|
|
|
template <Params param, typename Value>
|
|
inline constexpr void set(Value val)
|
|
{
|
|
if constexpr (param == CursorManager::Params::X) {
|
|
val = std::max(std::min(val, (int)m_screen.width() - 1), 0);
|
|
m_mouse_offset_x = val - m_mouse_x;
|
|
m_mouse_x = val;
|
|
set_changed<CursorManager::Params::X>();
|
|
} else if constexpr (param == CursorManager::Params::Y) {
|
|
val = std::max(std::min(val, (int)m_screen.height() - 1), 0);
|
|
m_mouse_offset_y = val - m_mouse_y;
|
|
m_mouse_y = val;
|
|
set_changed<CursorManager::Params::Y>();
|
|
} else if constexpr (param == CursorManager::Params::OffsetX) {
|
|
if (val != 0) {
|
|
set<CursorManager::Params::X>(m_mouse_x + val);
|
|
} else {
|
|
m_mouse_offset_x = 0;
|
|
}
|
|
} else if constexpr (param == CursorManager::Params::OffsetY) {
|
|
if (val != 0) {
|
|
set<CursorManager::Params::Y>(m_mouse_y + val);
|
|
} else {
|
|
m_mouse_offset_y = 0;
|
|
}
|
|
} else if constexpr (param == CursorManager::Params::LeftButton) {
|
|
if (m_mouse_left_button_pressed != val) {
|
|
set_changed<CursorManager::Params::LeftButton>();
|
|
}
|
|
m_mouse_left_button_pressed = val;
|
|
} else if constexpr (param == CursorManager::Params::RightButton) {
|
|
if (m_mouse_right_button_pressed != val) {
|
|
set_changed<CursorManager::Params::RightButton>();
|
|
}
|
|
m_mouse_right_button_pressed = val;
|
|
} else if constexpr (param == CursorManager::Params::Wheel) {
|
|
if (val != 0) {
|
|
set_changed<CursorManager::Params::Wheel>();
|
|
}
|
|
m_wheel = val;
|
|
} else {
|
|
[]<bool flag = false>() { static_assert(flag, "Could not call set() with such param!"); }
|
|
();
|
|
}
|
|
}
|
|
|
|
template <Params param>
|
|
inline constexpr void set_changed()
|
|
{
|
|
if constexpr (param == CursorManager::Params::X) {
|
|
m_mask_changed_objects |= CursorManager::ChangedValues::MouseCoords;
|
|
} else if constexpr (param == CursorManager::Params::Y) {
|
|
m_mask_changed_objects |= CursorManager::ChangedValues::MouseCoords;
|
|
} else if constexpr (param == CursorManager::Params::LeftButton) {
|
|
m_mask_changed_objects |= CursorManager::ChangedValues::LeftButton;
|
|
} else if constexpr (param == CursorManager::Params::RightButton) {
|
|
m_mask_changed_objects |= CursorManager::ChangedValues::RightButton;
|
|
} else if constexpr (param == CursorManager::Params::Wheel) {
|
|
m_mask_changed_objects |= CursorManager::ChangedValues::Wheel;
|
|
} else {
|
|
[]<bool flag = false>() { static_assert(flag, "Could not set_changed() for the param!"); }
|
|
();
|
|
}
|
|
}
|
|
|
|
void update_position(MouseEvent* mouse_event)
|
|
{
|
|
clear_changed();
|
|
set<Params::OffsetX>(mouse_event->packet().x_offset);
|
|
set<Params::OffsetY>(-mouse_event->packet().y_offset);
|
|
set<Params::LeftButton>((mouse_event->packet().button_states & 1));
|
|
set<Params::RightButton>((mouse_event->packet().button_states & 2) >> 1);
|
|
set<Params::Wheel>(mouse_event->packet().wheel_data);
|
|
}
|
|
|
|
private:
|
|
enum ChangedValues {
|
|
MouseCoords = 0x1,
|
|
LeftButton = 0x2,
|
|
RightButton = 0x4,
|
|
Wheel = 0x8,
|
|
};
|
|
|
|
int m_mouse_x { 0 };
|
|
int m_mouse_y { 0 };
|
|
int m_mouse_offset_x { 0 };
|
|
int m_mouse_offset_y { 0 };
|
|
int m_wheel { 0 };
|
|
bool m_mouse_left_button_pressed { false };
|
|
bool m_mouse_right_button_pressed { false };
|
|
uint32_t m_mask_changed_objects { 0 };
|
|
bool m_mouse_changed_button_status { false };
|
|
|
|
Screen& m_screen;
|
|
LG::PixelBitmap m_std_cursor;
|
|
};
|
|
|
|
template <CursorManager::Params param>
|
|
inline constexpr int CursorManager::get()
|
|
{
|
|
if constexpr (param == CursorManager::Params::X) {
|
|
return m_mouse_x;
|
|
} else if constexpr (param == CursorManager::Params::Y) {
|
|
return m_mouse_y;
|
|
} else if constexpr (param == CursorManager::Params::OffsetX) {
|
|
return m_mouse_offset_x;
|
|
} else if constexpr (param == CursorManager::Params::OffsetY) {
|
|
return m_mouse_offset_y;
|
|
} else if constexpr (param == CursorManager::Params::Wheel) {
|
|
return m_wheel;
|
|
} else {
|
|
[]<bool flag = false>() { static_assert(flag, "Could call get() only for coords-like params!"); }
|
|
();
|
|
}
|
|
}
|
|
|
|
template <CursorManager::Params param>
|
|
inline constexpr bool CursorManager::pressed() const
|
|
{
|
|
if constexpr (param == CursorManager::Params::LeftButton) {
|
|
return m_mouse_left_button_pressed;
|
|
} else if constexpr (param == CursorManager::Params::RightButton) {
|
|
return m_mouse_right_button_pressed;
|
|
} else {
|
|
[]<bool flag = false>() { static_assert(flag, "Could call pressed() only for buttons!"); }
|
|
();
|
|
}
|
|
}
|
|
|
|
template <CursorManager::Params param>
|
|
inline constexpr bool CursorManager::is_changed()
|
|
{
|
|
if constexpr (param == CursorManager::Params::X) {
|
|
return (m_mask_changed_objects & CursorManager::ChangedValues::MouseCoords);
|
|
} else if constexpr (param == CursorManager::Params::Y) {
|
|
return (m_mask_changed_objects & CursorManager::ChangedValues::MouseCoords);
|
|
} else if constexpr (param == CursorManager::Params::LeftButton) {
|
|
return (m_mask_changed_objects & CursorManager::ChangedValues::LeftButton);
|
|
} else if constexpr (param == CursorManager::Params::RightButton) {
|
|
return (m_mask_changed_objects & CursorManager::ChangedValues::RightButton);
|
|
} else if constexpr (param == CursorManager::Params::Coords) {
|
|
return (m_mask_changed_objects & CursorManager::ChangedValues::MouseCoords);
|
|
} else if constexpr (param == CursorManager::Params::Buttons) {
|
|
return (m_mask_changed_objects & CursorManager::ChangedValues::LeftButton) | (m_mask_changed_objects & CursorManager::ChangedValues::RightButton);
|
|
} else if constexpr (param == CursorManager::Params::Wheel) {
|
|
return (m_mask_changed_objects & CursorManager::ChangedValues::Wheel);
|
|
} else {
|
|
[]<bool flag = false>() { static_assert(flag, "Could not call is_changed() for the param!"); }
|
|
();
|
|
}
|
|
}
|
|
|
|
} // namespace WinServer
|