载入中...
搜索中...
未找到
Mouse.cpp
浏览该文件的文档.
1#include "mouse/sdl/Mouse.h"
2#include "window/Window.h"
3#include "window/sdl/Window.h"
4
5#include <SDL2/SDL_mouse.h>
6
7namespace eve::mouse::sdl {
8
9// SDL reports mouse coordinates in the window coordinate system in OS X, but
10// we want them in pixel coordinates (may be different with high-DPI enabled.)
11static void windowToDPICoords(double *x, double *y)
12{
13 auto window = getModInst(window,Window);
14 // if (window)
15 // window->windowToDPICoords(x, y);
16}
17
18// And vice versa for setting mouse coordinates.
19static void DPIToWindowCoords(double *x, double *y)
20{
21 auto window = getModInst(window,Window);
22 // if (window)
23 // window->DPIToWindowCoords(x, y);
24}
25
26
28 : curCursor(nullptr)
29{
30 // SDL may need the video subsystem in order to clean up the cursor when
31 // quitting. Subsystems are reference-counted.
32 SDL_InitSubSystem(SDL_INIT_VIDEO);
33}
34
36{
37 if (curCursor)
38 setCursor();
39
40 for (auto &c : systemCursors)
41 delete c.second;
42
43 SDL_QuitSubSystem(SDL_INIT_VIDEO);
44}
45
47{
48 return new Cursor(data, hotx, hoty);
49}
50
52{
53 Cursor *cursor = nullptr;
54 auto it = systemCursors.find(cursortype);
55
56 if (it != systemCursors.end())
57 cursor = it->second;
58 else
59 {
60 cursor = new Cursor(cursortype);
61 systemCursors[cursortype] = cursor;
62 }
63
64 return cursor;
65}
66
68{
69 curCursor = cursor;
70 SDL_SetCursor((SDL_Cursor *) cursor->getHandle());
71}
72
74{
75 curCursor = nullptr;
76 SDL_SetCursor(SDL_GetDefaultCursor());
77}
78
80{
81 return curCursor;
82}
83
84
86{
87 return SDL_GetDefaultCursor() != nullptr;
88}
89
90double Mouse::getX() const
91{
92 int x;
93 SDL_GetMouseState(&x, nullptr);
94
95 double dx = (double) x;
96 windowToDPICoords(&dx, nullptr);
97
98 return dx;
99}
100
101double Mouse::getY() const
102{
103 int y;
104 SDL_GetMouseState(nullptr, &y);
105
106 double dy = (double) y;
107 windowToDPICoords(nullptr, &dy);
108
109 return dy;
110}
111
112void Mouse::getPosition(double &x, double &y) const
113{
114 int mx, my;
115 SDL_GetMouseState(&mx, &my);
116
117 x = (double) mx;
118 y = (double) my;
119 windowToDPICoords(&x, &y);
120}
121
122void Mouse::setPosition(double x, double y)
123{
124 // Avoid `auto window = getModInst(window, ...)` — local name shadows namespace `window`.
125 auto *winMod = eve::ModuleManager::getInstance<eve::window::Window>("Window");
126
127 SDL_Window *handle = nullptr;
128 if (winMod)
129 handle = (SDL_Window *) winMod->getHandle();
130
131 DPIToWindowCoords(&x, &y);
132 if (handle) {
133 SDL_WarpMouseInWindow(handle, (int) x, (int) y);
134 // SDL_WarpMouse doesn't directly update SDL's internal mouse state on
135 // Linux/Windows; pump so the next getPosition sees the new coords.
136 SDL_PumpEvents();
137 }
138}
139
140void Mouse::setX(double x)
141{
142 setPosition(x, getY());
143}
144
145void Mouse::setY(double y)
146{
147 setPosition(getX(), y);
148}
149
150void Mouse::setVisible(bool visible)
151{
152 SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
153}
154
155bool Mouse::isDown(const std::vector<int> &buttons) const
156{
157 Uint32 buttonstate = SDL_GetMouseState(nullptr, nullptr);
158
159 for (int button : buttons)
160 {
161 if (button <= 0)
162 continue;
163
164 // We use button index 2 to represent the right mouse button, but SDL
165 // uses 2 to represent the middle mouse button.
166 switch (button)
167 {
168 case 2:
169 button = SDL_BUTTON_RIGHT;
170 break;
171 case 3:
172 button = SDL_BUTTON_MIDDLE;
173 break;
174 }
175
176 if (buttonstate & SDL_BUTTON(button))
177 return true;
178 }
179
180 return false;
181}
182
184{
185 return SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE;
186}
187
188void Mouse::setGrabbed(bool grab)
189{
190 auto window = getModInst(window,Window);
191 // if (window)
192 // window->setMouseGrab(grab);
193}
194
196{
197 auto window = getModInst(window,Window);
198 // if (window)
199 // return window->isMouseGrabbed();
200 // else
201 return false;
202}
203
204bool Mouse::setRelativeMode(bool relative)
205{
206 return SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == 0;
207}
208
210{
211 return SDL_GetRelativeMouseMode() != SDL_FALSE;
212}
213
214} // eve::mouse::sdl
int y
Definition Grass.cpp:135
int x
Definition Grass.cpp:135
uint32_t c
#define getModInst(N, T)
Definition Module.h:36
Light2D::Data * data
Represents raw pixel data.
Definition ImageData.h:26
virtual void * getHandle() const =0
Returns a pointer to the implementation-dependent handle of this Cursor.
SDL 鼠标光标实现(自定义图像或系统光标)。
Definition Cursor.h:14
void setVisible(bool visible) override
Definition Mouse.cpp:150
bool isCursorSupported() const override
Definition Mouse.cpp:85
bool isGrabbed() const override
Definition Mouse.cpp:195
double getY() const override
Definition Mouse.cpp:101
eve::mouse::Cursor * newCursor(eve::image::ImageData *data, int hotx, int hoty) override
Definition Mouse.cpp:46
void setPosition(double x, double y) override
Definition Mouse.cpp:122
void setCursor() override
Definition Mouse.cpp:73
eve::mouse::Cursor * getSystemCursor(std::string cursortype) override
Definition Mouse.cpp:51
void setGrabbed(bool grab) override
Definition Mouse.cpp:188
void getPosition(double &x, double &y) const override
Definition Mouse.cpp:112
bool getRelativeMode() const override
Definition Mouse.cpp:209
void setX(double x) override
Definition Mouse.cpp:140
bool isVisible() const override
Definition Mouse.cpp:183
double getX() const override
Definition Mouse.cpp:90
bool setRelativeMode(bool relative) override
Definition Mouse.cpp:204
eve::mouse::Cursor * getCursor() const override
Definition Mouse.cpp:79
void setY(double y) override
Definition Mouse.cpp:145
bool isDown(const std::vector< int > &buttons) const override
Definition Mouse.cpp:155
WidgetDesc window(std::string title, std::vector< WidgetDesc > children, std::string id)
Top-level window widget with a title bar.
Definition Widget.cpp:225