Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
InputHandler.cpp
Go to the documentation of this file.
1
2
5
7
8namespace Divide {
9namespace Input {
10
12 : _app(app),
13 _eventListener(eventListener)
14{
15 //Note: We only pass input events to a single listeners. Listeners should forward events where needed instead of doing a loop
16 //over all, because where and how we pass input events is very context sensitive: does the ProjectManager consume the input or does it pass
17 //it along to the scene? Does the editor consume the input or does it pass if along to the gizmo? Should both editor and gizmo consume an input? etc
18}
19
20namespace {
21 Uint32 GetEventWindowID(const SDL_Event event) noexcept {
22 switch (event.type) {
23 case SDL_KEYDOWN :
24 case SDL_KEYUP :
25 return event.key.windowID;
26
27 case SDL_MOUSEBUTTONDOWN :
28 case SDL_MOUSEBUTTONUP :
29 return event.button.windowID;
30
31 case SDL_MOUSEMOTION :
32 return event.motion.windowID;
33
34 case SDL_MOUSEWHEEL :
35 return event.wheel.windowID;
36
37 case SDL_WINDOWEVENT :
38 return event.window.windowID;
39
40 case SDL_TEXTINPUT :
41 return event.text.windowID;
42 default: break;
43 }
44
45 return 0;
46 }
47};
48
49bool InputHandler::onSDLEvent(SDL_Event event) {
50 // Find the window that sent the event
51 DisplayWindow* eventWindow = _app.windowManager().getWindowByID(GetEventWindowID(event));
52 if (eventWindow == nullptr) {
53 return false;
54 }
55
56 switch (event.type) {
57 case SDL_TEXTEDITING:
58 case SDL_TEXTINPUT: {
59 const TextEvent arg{eventWindow, 0, event.text.text};
61 return true;
62 }
63
64 case SDL_KEYUP:
65 case SDL_KEYDOWN: {
66 KeyEvent arg(eventWindow, 0);
67 arg._key = KeyCodeFromSDLKey(event.key.keysym.sym);
68 arg._pressed = event.type == SDL_KEYDOWN;
69 arg._isRepeat = event.key.repeat;
70 arg.scancode = event.key.keysym.scancode;
71 arg.sym = event.key.keysym.sym;
72
73 if ((event.key.keysym.mod & KMOD_LSHIFT) != 0) {
75 }
76 if ((event.key.keysym.mod & KMOD_RSHIFT) != 0) {
78 }
79 if ((event.key.keysym.mod & KMOD_LCTRL) != 0) {
81 }
82 if ((event.key.keysym.mod & KMOD_RCTRL) != 0) {
84 }
85 if ((event.key.keysym.mod & KMOD_LALT) != 0) {
87 }
88 if ((event.key.keysym.mod & KMOD_RALT) != 0) {
90 }
91 if ((event.key.keysym.mod & KMOD_LGUI) != 0) {
93 }
94 if ((event.key.keysym.mod & KMOD_RGUI) != 0) {
96 }
97 if ((event.key.keysym.mod & KMOD_NUM) != 0) {
99 }
100 if ((event.key.keysym.mod & KMOD_CAPS) != 0) {
102 }
103 if ((event.key.keysym.mod & KMOD_MODE) != 0) {
105 }
106 if (arg._pressed) {
108 } else {
110 }
111 return true;
112 }
113 case SDL_MOUSEBUTTONDOWN:
114 case SDL_MOUSEBUTTONUP:
115 {
116 MouseButtonEvent arg(eventWindow, to_U8(event.button.which));
117 arg.pressed(event.type == SDL_MOUSEBUTTONDOWN);
118 switch (event.button.button) {
119 case SDL_BUTTON_LEFT:
120 arg.button(MouseButton::MB_Left);
121 break;
122 case SDL_BUTTON_RIGHT:
123 arg.button(MouseButton::MB_Right);
124 break;
125 case SDL_BUTTON_MIDDLE:
126 arg.button(MouseButton::MB_Middle);
127 break;
128 case SDL_BUTTON_X1:
129 arg.button(MouseButton::MB_Button3);
130 break;
131 case SDL_BUTTON_X2:
132 arg.button(MouseButton::MB_Button4);
133 break;
134 case 6:
135 arg.button(MouseButton::MB_Button5);
136 break;
137 case 7:
138 arg.button(MouseButton::MB_Button6);
139 break;
140 case 8:
141 arg.button(MouseButton::MB_Button7);
142 break;
143 default: break;
144 }
145
146 arg.numCliks(to_U8(event.button.clicks));
148 state.X.abs = event.button.x;
149 state.Y.abs = event.button.y;
150
151 if (arg.pressed())
152 {
154 }
155 else
156 {
158 }
159 return true;
160 }
161 case SDL_MOUSEWHEEL:
162 case SDL_MOUSEMOTION:
163 {
164 MouseMoveEvent arg(eventWindow, to_U8(event.motion.which), event.type == SDL_MOUSEWHEEL);
165 auto& state = Attorney::MouseEventInputHandler::state( arg );
166 state.X.abs = event.motion.x;
167 state.X.rel = event.motion.xrel;
168 state.Y.abs = event.motion.y;
169 state.Y.rel = event.motion.yrel;
170 state.HWheel = event.wheel.x;
171 state.VWheel = event.wheel.y;
172
174 return true;
175 }
176 case SDL_CONTROLLERAXISMOTION:
177 case SDL_JOYAXISMOTION:
178 {
179 JoystickData jData = {};
180 jData._gamePad = event.type == SDL_CONTROLLERAXISMOTION;
181 jData._dataSigned = jData._gamePad ? event.caxis.value : event.jaxis.value;
182
183 JoystickElement element = {};
185 element._data = jData;
186 element._elementIndex = (jData._gamePad ? event.caxis.axis : event.jaxis.axis);
187
188 JoystickEvent arg(eventWindow, to_U8(jData._gamePad ? event.caxis.which : event.jaxis.which));
189 arg._element = element;
190
192 return true;
193 };
194 case SDL_JOYBALLMOTION:
195 {
196 JoystickData jData = {};
197 jData._smallDataSigned[0] = event.jball.xrel;
198 jData._smallDataSigned[1] = event.jball.yrel;
199
200 JoystickElement element = {};
202 element._data = jData;
203 element._elementIndex = (event.jball.ball);
204
205 JoystickEvent arg(eventWindow, to_U8(event.jball.which));
206 arg._element = element;
207
209 return true;
210 };
211 case SDL_JOYHATMOTION:
212 {
213 // POV
214 U32 PovMask = 0;
215 switch (event.jhat.value) {
216 case SDL_HAT_CENTERED:
218 break;
219 case SDL_HAT_UP:
221 break;
222 case SDL_HAT_RIGHT:
224 break;
225 case SDL_HAT_DOWN:
227 break;
228 case SDL_HAT_LEFT:
230 break;
231 case SDL_HAT_RIGHTUP:
234 break;
235 case SDL_HAT_RIGHTDOWN:
238 break;
239 case SDL_HAT_LEFTUP:
242 break;
243 case SDL_HAT_LEFTDOWN:
246 break;
247 default: break;
248 };
249
250 JoystickData jData = {};
251 jData._data = PovMask;
252
253 JoystickElement element = {};
255 element._data = jData;
256 element._elementIndex = (event.jhat.hat);
257
258 JoystickEvent arg(eventWindow, to_U8(event.jhat.which));
259 arg._element = element;
260
262 return true;
263 };
264 case SDL_CONTROLLERBUTTONDOWN:
265 case SDL_CONTROLLERBUTTONUP:
266 case SDL_JOYBUTTONDOWN:
267 case SDL_JOYBUTTONUP:
268 {
269 JoystickData jData = {};
270 jData._gamePad = event.type == SDL_CONTROLLERBUTTONDOWN || event.type == SDL_CONTROLLERBUTTONUP;
271
272 const Uint8 state = jData._gamePad ? event.cbutton.state : event.jbutton.state;
273 jData._data = state == SDL_PRESSED ? to_U32(InputState::PRESSED) : to_U32(InputState::RELEASED);
274
275 JoystickElement element = {};
277 element._data = jData;
278 element._elementIndex = jData._gamePad ? event.cbutton.button : event.jbutton.button;
279
280 JoystickEvent arg(eventWindow, to_U8(jData._gamePad ? event.cbutton.which : event.jbutton.which));
281 arg._element = element;
282
283 if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_CONTROLLERBUTTONDOWN) {
285 } else {
287 }
288 return true;
289 };
290 case SDL_CONTROLLERDEVICEADDED:
291 case SDL_CONTROLLERDEVICEREMOVED:
292 case SDL_JOYDEVICEADDED:
293 case SDL_JOYDEVICEREMOVED:
294 {
295 JoystickData jData = {};
296 jData._gamePad = event.type == SDL_CONTROLLERDEVICEADDED || event.type == SDL_CONTROLLERDEVICEREMOVED;
297 jData._data = (jData._gamePad ? event.type == SDL_CONTROLLERDEVICEADDED : event.type == SDL_JOYDEVICEADDED) ? 1 : 0;
298
299 JoystickElement element = {};
301 element._data = jData;
302
303 JoystickEvent arg(eventWindow, to_U8(jData._gamePad ? event.cdevice.which : event.jdevice.which));
304 arg._element = element;
305
307 return true;
308 };
309
310
311 case SDL_CONTROLLERDEVICEREMAPPED:
312 {
313 JoystickElement element = {};
315
316 JoystickEvent arg(eventWindow, to_U8(event.jdevice.which));
317 arg._element = element;
318
320 return true;
321 };
322 default: break;
323 }
324
325 return false;
326}
327}; // namespace Input
328}; // namespace Divide
Class that provides an interface between our framework and the OS (start/stop, display support,...
Definition: Application.h:97
WindowManager & windowManager() noexcept
Definition: Application.inl:77
static MouseState & state(MouseEvent &evt) noexcept
virtual bool joystickPovMoved(const JoystickEvent &arg)=0
virtual bool mouseButtonPressed(const MouseButtonEvent &arg)=0
virtual bool mouseMoved(const MouseMoveEvent &arg)=0
Mouse: return true if input was consumed.
virtual bool onKeyUp(const KeyEvent &arg)=0
virtual bool joystickAxisMoved(const JoystickEvent &arg)=0
virtual bool joystickAddRemove(const JoystickEvent &arg)=0
virtual bool mouseButtonReleased(const MouseButtonEvent &arg)=0
virtual bool joystickButtonReleased(const JoystickEvent &arg)=0
virtual bool onKeyDown(const KeyEvent &arg)=0
Keyboard: return true if input was consumed.
virtual bool joystickRemap(const JoystickEvent &arg)=0
virtual bool joystickButtonPressed(const JoystickEvent &arg)=0
Joystick or Gamepad: return true if input was consumed.
virtual bool joystickBallMoved(const JoystickEvent &arg)=0
virtual bool onTextEvent(const TextEvent &arg)=0
InputHandler(InputAggregatorInterface &eventListener, Application &app) noexcept
bool onSDLEvent(SDL_Event event) override
InputAggregatorInterface & _eventListener
Definition: InputHandler.h:55
DisplayWindow * getWindowByID(U32 ID) noexcept
Uint32 GetEventWindowID(const SDL_Event event) noexcept
KeyCode KeyCodeFromSDLKey(SDL_Keycode code) noexcept
Definition: Input.cpp:136
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
constexpr U32 to_U32(const T value)
constexpr U8 to_U8(const T value)
uint32_t U32
constexpr auto to_base(const Type value) -> Type
JoystickElementType _type
Definition: Input.h:85