FIFE  6e1afdbeda11afe9ac53e6023a4be96ef88f1dc6
eventmanager.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2017 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #include <iostream>
24 
25 // 3rd party library includes
26 
27 // FIFE includes
28 // These includes are split up in two parts, separated by one empty line
29 // First block: files included from the FIFE root src directory
30 // Second block: files included from the same folder
31 #include "util/base/exception.h"
32 #include "util/log/logger.h"
33 #include "util/math/fife_math.h"
35 #include "eventchannel/key/key.h"
41 #include "video/renderbackend.h"
42 
43 #include "eventmanager.h"
44 
45 namespace FIFE {
46  static Logger _log(LM_EVTCHANNEL);
47 
49  m_commandlisteners(),
50  m_keylisteners(),
51  m_textListeners(),
52  m_mouselisteners(),
53  m_sdleventlisteners(),
54  m_keystatemap(),
55  m_keyfilter(0),
56  m_mousefilter(0),
57  m_mousestate(0),
58  m_mostrecentbtn(MouseEvent::EMPTY),
59  m_mouseSensitivity(0.0),
60  m_acceleration(false),
61  m_warp(false),
62  m_enter(false),
63  m_oldX(0),
64  m_oldY(0),
65  m_lastTicks(0),
66  m_oldVelocity(0.0),
67  m_joystickManager(NULL) {
68  }
69 
71  delete m_joystickManager;
72  }
73 
74  template<typename T>
75  void removeListener(std::deque<T>& vec, T& listener) {
76  vec.push_back(listener);
77  }
78 
79  template<typename T>
80  void addListener(std::deque<T>& vec, T& listener) {
81  vec.push_back(listener);
82  }
83 
85  addListener<ICommandListener*>(m_pending_commandlisteners, listener);
86  }
87 
89  addListener<ICommandListener*>(m_pending_commandlisteners_front, listener);
90  }
91 
93  removeListener<ICommandListener*>(m_pending_cldeletions, listener);
94  }
95 
97  addListener<IKeyListener*>(m_pending_keylisteners, listener);
98  }
99 
101  addListener<IKeyListener*>(m_pending_keylisteners_front, listener);
102  }
103 
105  removeListener<IKeyListener*>(m_pending_kldeletions, listener);
106  }
107 
109  addListener<ITextListener*>(m_pendingTextListeners, listener);
110  }
111 
113  addListener<ITextListener*>(m_pendingTextListenersFront, listener);
114  }
115 
117  removeListener<ITextListener*>(m_pendingTlDeletions, listener);
118  }
119 
121  addListener<IMouseListener*>(m_pending_mouselisteners, listener);
122  }
123 
125  addListener<IMouseListener*>(m_pending_mouselisteners_front, listener);
126  }
127 
129  removeListener<IMouseListener*>(m_pending_mldeletions, listener);
130  }
131 
133  addListener<ISdlEventListener*>(m_pending_sdleventlisteners, listener);
134  }
135 
137  addListener<ISdlEventListener*>(m_pending_sdleventlisteners_front, listener);
138  }
139 
141  removeListener<ISdlEventListener*>(m_pending_sdldeletions, listener);
142  }
143 
145  addListener<IDropListener*>(m_pendingDropListeners, listener);
146  }
147 
149  addListener<IDropListener*>(m_pendingDropListenersFront, listener);
150  }
151 
153  removeListener<IDropListener*>(m_pendingDlDeletions, listener);
154  }
155 
157  if (m_joystickManager) {
159  }
160  }
161 
163  if (m_joystickManager) {
165  }
166  }
167 
169  if (m_joystickManager) {
171  }
172  }
173 
175  if(!m_pending_commandlisteners.empty()) {
176  std::deque<ICommandListener*>::iterator i = m_pending_commandlisteners.begin();
177  while (i != m_pending_commandlisteners.end()) {
178  m_commandlisteners.push_back(*i);
179  ++i;
180  }
182  }
183 
184  if(!m_pending_commandlisteners_front.empty()) {
185  std::deque<ICommandListener*>::iterator i = m_pending_commandlisteners_front.begin();
186  while (i != m_pending_commandlisteners_front.end()) {
187  m_commandlisteners.push_front(*i);
188  ++i;
189  }
191  }
192 
193  if (!m_pending_cldeletions.empty()) {
194  std::deque<ICommandListener*>::iterator i = m_pending_cldeletions.begin();
195  while (i != m_pending_cldeletions.end()) {
196  std::deque<ICommandListener*>::iterator j = m_commandlisteners.begin();
197  while (j != m_commandlisteners.end()) {
198  if(*j == *i) {
199  m_commandlisteners.erase(j);
200  break;
201  }
202  ++j;
203  }
204  ++i;
205  }
206  m_pending_cldeletions.clear();
207  }
208 
209  std::deque<ICommandListener*>::iterator i = m_commandlisteners.begin();
210  while (i != m_commandlisteners.end()) {
211  (*i)->onCommand(command);
212  if (command.isConsumed()) {
213  break;
214  }
215  ++i;
216  }
217  }
218 
220  if(!m_pending_keylisteners.empty()) {
221  std::deque<IKeyListener*>::iterator i = m_pending_keylisteners.begin();
222  while (i != m_pending_keylisteners.end()) {
223  m_keylisteners.push_back(*i);
224  ++i;
225  }
226  m_pending_keylisteners.clear();
227  }
228 
229  if(!m_pending_keylisteners_front.empty()) {
230  std::deque<IKeyListener*>::iterator i = m_pending_keylisteners_front.begin();
231  while (i != m_pending_keylisteners_front.end()) {
232  m_keylisteners.push_front(*i);
233  ++i;
234  }
236  }
237 
238  if (!m_pending_kldeletions.empty()) {
239  std::deque<IKeyListener*>::iterator i = m_pending_kldeletions.begin();
240  while (i != m_pending_kldeletions.end()) {
241  std::deque<IKeyListener*>::iterator j = m_keylisteners.begin();
242  while (j != m_keylisteners.end()) {
243  if(*j == *i) {
244  m_keylisteners.erase(j);
245  break;
246  }
247  ++j;
248  }
249  ++i;
250  }
251  m_pending_kldeletions.clear();
252  }
253 
254  std::deque<IKeyListener*>::iterator i = m_keylisteners.begin();
255  while (i != m_keylisteners.end()) {
256  switch (evt.getType()) {
257  case KeyEvent::PRESSED:
258  (*i)->keyPressed(evt);
259  break;
260  case KeyEvent::RELEASED:
261  (*i)->keyReleased(evt);
262  break;
263  default:
264  break;
265  }
266  ++i;
267  }
268  }
269 
271  if(!m_pendingTextListeners.empty()) {
272  std::deque<ITextListener*>::iterator i = m_pendingTextListeners.begin();
273  while (i != m_pendingTextListeners.end()) {
274  m_textListeners.push_back(*i);
275  ++i;
276  }
277  m_pendingTextListeners.clear();
278  }
279 
280  if(!m_pendingTextListenersFront.empty()) {
281  std::deque<ITextListener*>::iterator i = m_pendingTextListenersFront.begin();
282  while (i != m_pendingTextListenersFront.end()) {
283  m_textListeners.push_front(*i);
284  ++i;
285  }
287  }
288 
289  if (!m_pendingTlDeletions.empty()) {
290  std::deque<ITextListener*>::iterator i = m_pendingTlDeletions.begin();
291  while (i != m_pendingTlDeletions.end()) {
292  std::deque<ITextListener*>::iterator j = m_textListeners.begin();
293  while (j != m_textListeners.end()) {
294  if(*j == *i) {
295  m_textListeners.erase(j);
296  break;
297  }
298  ++j;
299  }
300  ++i;
301  }
302  m_pendingTlDeletions.clear();
303  }
304 
305  std::deque<ITextListener*>::iterator i = m_textListeners.begin();
306  while (i != m_textListeners.end()) {
307  switch (evt.getType()) {
308  case TextEvent::INPUT:
309  (*i)->textInput(evt);
310  break;
311  case TextEvent::EDIT:
312  (*i)->textEdit(evt);
313  break;
314  default:
315  break;
316  }
317  ++i;
318  }
319  }
320 
322  if(!m_pending_mouselisteners.empty()) {
323  std::deque<IMouseListener*>::iterator i = m_pending_mouselisteners.begin();
324  while (i != m_pending_mouselisteners.end()) {
325  m_mouselisteners.push_back(*i);
326  ++i;
327  }
328  m_pending_mouselisteners.clear();
329  }
330 
331  if(!m_pending_mouselisteners_front.empty()) {
332  std::deque<IMouseListener*>::iterator i = m_pending_mouselisteners_front.begin();
333  while (i != m_pending_mouselisteners_front.end()) {
334  m_mouselisteners.push_front(*i);
335  ++i;
336  }
338  }
339 
340  if (!m_pending_mldeletions.empty()) {
341  std::deque<IMouseListener*>::iterator i = m_pending_mldeletions.begin();
342  while (i != m_pending_mldeletions.end()) {
343  std::deque<IMouseListener*>::iterator j = m_mouselisteners.begin();
344  while (j != m_mouselisteners.end()) {
345  if(*j == *i) {
346  m_mouselisteners.erase(j);
347  break;
348  }
349  ++j;
350  }
351  ++i;
352  }
353  m_pending_mldeletions.clear();
354  }
355 
356  std::deque<IMouseListener*>::iterator i = m_mouselisteners.begin();
357  while (i != m_mouselisteners.end()) {
358  switch (evt.getType()) {
359  case MouseEvent::MOVED:
360  (*i)->mouseMoved(evt);
361  break;
362  case MouseEvent::PRESSED:
363  (*i)->mousePressed(evt);
364  break;
366  (*i)->mouseReleased(evt);
367  break;
369  (*i)->mouseWheelMovedDown(evt);
370  break;
372  (*i)->mouseWheelMovedUp(evt);
373  break;
375  (*i)->mouseWheelMovedRight(evt);
376  break;
378  (*i)->mouseWheelMovedLeft(evt);
379  break;
380  case MouseEvent::CLICKED:
381  (*i)->mouseClicked(evt);
382  break;
383  case MouseEvent::ENTERED:
384  (*i)->mouseEntered(evt);
385  break;
386  case MouseEvent::EXITED:
387  (*i)->mouseExited(evt);
388  break;
389  case MouseEvent::DRAGGED:
390  (*i)->mouseDragged(evt);
391  break;
392  default:
393  break;
394  }
395  if (evt.isConsumed()) {
396  break;
397  }
398  ++i;
399  }
400  }
401 
402  bool EventManager::dispatchSdlEvent(SDL_Event& evt) {
403  bool ret = false;
404  if (!m_pending_sdleventlisteners.empty()) {
405  std::deque<ISdlEventListener*>::iterator i = m_pending_sdleventlisteners.begin();
406  while(i != m_pending_sdleventlisteners.end()) {
407  m_sdleventlisteners.push_back(*i);
408  ++i;
409  }
411  }
412 
413  if (!m_pending_sdleventlisteners_front.empty()) {
414  std::deque<ISdlEventListener*>::iterator i = m_pending_sdleventlisteners_front.begin();
415  while(i != m_pending_sdleventlisteners_front.end()) {
416  m_sdleventlisteners.push_front(*i);
417  ++i;
418  }
420  }
421 
422  if (!m_pending_sdldeletions.empty()) {
423  std::deque<ISdlEventListener*>::iterator i = m_pending_sdldeletions.begin();
424  while (i != m_pending_sdldeletions.end()) {
425  std::deque<ISdlEventListener*>::iterator j = m_sdleventlisteners.begin();
426  while (j != m_sdleventlisteners.end()) {
427  if(*j == *i) {
428  m_sdleventlisteners.erase(j);
429  break;
430  }
431  ++j;
432  }
433  ++i;
434  }
435  m_pending_sdldeletions.clear();
436  }
437 
438  std::deque<ISdlEventListener*>::iterator i = m_sdleventlisteners.begin();
439  while (i != m_sdleventlisteners.end()) {
440  ret = ret || (*i)->onSdlEvent(evt);
441  ++i;
442  }
443  return ret;
444  }
445 
447  if(!m_pendingDropListeners.empty()) {
448  std::deque<IDropListener*>::iterator i = m_pendingDropListeners.begin();
449  while (i != m_pendingDropListeners.end()) {
450  m_dropListeners.push_back(*i);
451  ++i;
452  }
453  m_pendingDropListeners.clear();
454  }
455 
456  if(!m_pendingDropListenersFront.empty()) {
457  std::deque<IDropListener*>::iterator i = m_pendingDropListenersFront.begin();
458  while (i != m_pendingDropListenersFront.end()) {
459  m_dropListeners.push_front(*i);
460  ++i;
461  }
463  }
464 
465  if (!m_pendingDlDeletions.empty()) {
466  std::deque<IDropListener*>::iterator i = m_pendingDlDeletions.begin();
467  while (i != m_pendingDlDeletions.end()) {
468  std::deque<IDropListener*>::iterator j = m_dropListeners.begin();
469  while (j != m_dropListeners.end()) {
470  if(*j == *i) {
471  m_dropListeners.erase(j);
472  break;
473  }
474  ++j;
475  }
476  ++i;
477  }
478  m_pendingDlDeletions.clear();
479  }
480 
481  std::deque<IDropListener*>::iterator i = m_dropListeners.begin();
482  while (i != m_dropListeners.end()) {
483  (*i)->fileDropped(evt);
484  ++i;
485  }
486  }
487 
488  bool EventManager::combineEvents(SDL_Event& event1, const SDL_Event& event2) {
489  if(event1.type == event2.type) {
490  switch (event1.type) {
491  case SDL_MOUSEMOTION:
492  if(event1.motion.state == event2.motion.state) {
493  event1.motion.x = event2.motion.x;
494  event1.motion.y = event2.motion.y;
495  event1.motion.xrel += event2.motion.xrel;
496  event1.motion.yrel += event2.motion.yrel;
497  return true;
498  }
499  return false;
500  }
501  }
502  return false;
503  }
504 
506  // The double SDL_PollEvent calls don't throw away events,
507  // but try to combine (mouse motion) events.
508  SDL_Event event, next_event;
509  bool has_next_event = (SDL_PollEvent(&event) != 0);
510  while (has_next_event) {
511  has_next_event = (SDL_PollEvent(&next_event) != 0);
512  if (has_next_event && combineEvents(event, next_event)) {
513  continue;
514  }
515  switch (event.type) {
516  case SDL_QUIT: {
517  Command cmd;
518  cmd.setSource(this);
520  dispatchCommand(cmd);
521  }
522  break;
523 
524  case SDL_WINDOWEVENT:
525  processWindowEvent(event);
526  break;
527 
528  case SDL_KEYDOWN:
529  case SDL_KEYUP:
530  processKeyEvent(event);
531  break;
532 
533  //case SDL_TEXTEDITING: // is buggy with SDL 2.0.1
534  case SDL_TEXTINPUT:
535  processTextEvent(event);
536  break;
537 
538  case SDL_MOUSEWHEEL:
539  case SDL_MOUSEBUTTONUP:
540  case SDL_MOUSEMOTION:
541  case SDL_MOUSEBUTTONDOWN:
542  processMouseEvent(event);
543  break;
544 
545  case SDL_DROPFILE:
546  processDropEvent(event);
547  break;
548 
549  case SDL_JOYBUTTONDOWN:
550  case SDL_JOYBUTTONUP:
551  case SDL_JOYAXISMOTION:
552  case SDL_JOYHATMOTION:
553  case SDL_JOYDEVICEADDED:
554  case SDL_JOYDEVICEREMOVED: {
555  if (m_joystickManager) {
557  }
558  break;
559  }
560  case SDL_CONTROLLERBUTTONDOWN:
561  case SDL_CONTROLLERBUTTONUP:
562  case SDL_CONTROLLERAXISMOTION: {
563  if (m_joystickManager) {
565  }
566  break;
567  }
568 
569  }
570  if (has_next_event) {
571  event = next_event;
572  }
573  }
574  }
575 
576  void EventManager::processWindowEvent(SDL_Event event) {
577  if (dispatchSdlEvent(event)) {
578  return;
579  }
580 
582  switch (event.window.event) {
583  case SDL_WINDOWEVENT_CLOSE:
584  ct = CMD_QUIT_GAME;
585  break;
586 
587  case SDL_WINDOWEVENT_ENTER:
589  break;
590 
591  case SDL_WINDOWEVENT_LEAVE:
593  break;
594 
595  case SDL_WINDOWEVENT_FOCUS_GAINED:
597  break;
598 
599  case SDL_WINDOWEVENT_FOCUS_LOST:
601  break;
602 
603  case SDL_WINDOWEVENT_SHOWN:
604  ct = CMD_APP_RESTORED;
605  break;
606 
607  case SDL_WINDOWEVENT_MINIMIZED:
608  case SDL_WINDOWEVENT_HIDDEN:
609  ct = CMD_APP_ICONIFIED;
610  break;
611 
612  default:
613  ct = CMD_UNKNOWN;
614  }
615  if (ct != CMD_UNKNOWN) {
616  Command cmd;
617  cmd.setCommandType(ct);
618  dispatchCommand(cmd);
619  }
620  }
621 
622  void EventManager::processKeyEvent(SDL_Event event) {
623  KeyEvent keyevt;
624  keyevt.setSource(this);
625  fillKeyEvent(event, keyevt);
626  m_keystatemap[keyevt.getKey().getValue()] = (keyevt.getType() == KeyEvent::PRESSED);
627  // if event is not filtered it gets dispatched, even it is a function key
628  if (!m_keyfilter || !m_keyfilter->isFiltered(keyevt)) {
629  if (dispatchSdlEvent(event))
630  return;
631  }
632 
633  dispatchKeyEvent(keyevt);
634  }
635 
636  void EventManager::processTextEvent(SDL_Event event) {
637  if (dispatchSdlEvent(event)) {
638  return;
639  }
640 
641  TextEvent txtevt;
642  txtevt.setSource(this);
643  fillTextEvent(event, txtevt);
644  dispatchTextEvent(txtevt);
645  }
646 
647  void EventManager::processMouseEvent(SDL_Event event) {
648  if (event.type == SDL_MOUSEMOTION && (!Mathf::Equal(m_mouseSensitivity, 0.0) || m_acceleration)) {
649  uint16_t tmp_x = event.motion.x;
650  uint16_t tmp_y = event.motion.y;
651  if (m_enter) {
652  m_oldX = tmp_x;
653  m_oldY = tmp_y;
654  m_oldVelocity = 0.0;
655  m_enter = false;
656  }
657 
658  float modifier;
659  if (m_acceleration) {
660  uint32_t ticks = SDL_GetTicks();
661  float difference = static_cast<float>((ticks - m_lastTicks) + 1);
662  m_lastTicks = ticks;
663  float dx = static_cast<float>(tmp_x - m_oldX);
664  float dy = static_cast<float>(tmp_y - m_oldY);
665  float distance = Mathf::Sqrt(dx * dx + dy * dy);
666  float acceleration = static_cast<float>((distance / difference) / difference);
667  float velocity = (m_oldVelocity + acceleration * difference)/2;
668  if (velocity > m_mouseSensitivity+1) {
669  velocity = m_mouseSensitivity+1;
670  }
671  m_oldVelocity = velocity;
672  modifier = velocity;
673  } else {
674  modifier = m_mouseSensitivity;
675  }
676 
677  int16_t tmp_xrel = static_cast<int16_t>(tmp_x - m_oldX);
678  int16_t tmp_yrel = static_cast<int16_t>(tmp_y - m_oldY);
679  if ((tmp_xrel != 0) || (tmp_yrel != 0)) {
680  Rect screen = RenderBackend::instance()->getArea();
681  int16_t x_fact = static_cast<int16_t>(round(static_cast<float>(tmp_xrel * modifier)));
682  int16_t y_fact = static_cast<int16_t>(round(static_cast<float>(tmp_yrel * modifier)));
683  if ((tmp_x + x_fact) > screen.w) {
684  tmp_x = screen.w;
685  } else if ((tmp_x + x_fact) < screen.x) {
686  tmp_x = screen.x;
687  } else {
688  tmp_x += x_fact;
689  }
690 
691  if (tmp_y + y_fact > screen.h) {
692  tmp_y = screen.h;
693  } else if ((tmp_y + y_fact) < screen.y) {
694  tmp_y = screen.y;
695  } else {
696  tmp_y += y_fact;
697  }
698  m_oldX = tmp_x;
699  m_oldY = tmp_y;
700  event.motion.x = tmp_x;
701  event.motion.y = tmp_y;
702  m_warp = true; //don't trigger an event handler when warping
703  SDL_WarpMouseInWindow(RenderBackend::instance()->getWindow(), tmp_x, tmp_y);
704  m_warp = false;
705  }
706  }
707 
708  MouseEvent mouseevt;
709  mouseevt.setSource(this);
710  fillMouseEvent(event, mouseevt);
711  fillModifiers(mouseevt);
712  if (event.type == SDL_MOUSEBUTTONDOWN) {
713  m_mousestate |= static_cast<int32_t>(mouseevt.getButton());
714  m_mostrecentbtn = mouseevt.getButton();
715  } else if (event.type == SDL_MOUSEBUTTONUP) {
716  m_mousestate &= ~static_cast<int32_t>(mouseevt.getButton());
717  }
718 
719  bool consumed = dispatchSdlEvent(event);
720  if (consumed && m_mousefilter) {
721  consumed = !m_mousefilter->isFiltered(mouseevt);
722  }
723  if (consumed) {
724  return;
725  }
726 
727  dispatchMouseEvent(mouseevt);
728  }
729 
730  void EventManager::processDropEvent(SDL_Event event) {
731  // only dispatched as DropEvent
732  //if (dispatchSdlEvent(event)) {
733  // return;
734  //}
735 
736  char* tmp = event.drop.file;
737  std::string path(tmp);
738  SDL_free(tmp);
739 
740  DropEvent drop;
741  drop.setPath(path);
742  drop.setSource(this);
743  dispatchDropEvent(drop);
744  }
745 
746  void EventManager::fillMouseEvent(const SDL_Event& sdlevt, MouseEvent& mouseevt) {
747  if (m_warp) {
748  return;
749  }
750 
751  mouseevt.setX(sdlevt.button.x);
752  mouseevt.setY(sdlevt.button.y);
753 
754  mouseevt.setButton(MouseEvent::EMPTY);
755  mouseevt.setType(MouseEvent::MOVED);
756  if ((sdlevt.type == SDL_MOUSEBUTTONUP) || (sdlevt.type == SDL_MOUSEBUTTONDOWN)) {
757  switch (sdlevt.button.button) {
758  case SDL_BUTTON_LEFT:
759  mouseevt.setButton(MouseEvent::LEFT);
760  break;
761  case SDL_BUTTON_RIGHT:
762  mouseevt.setButton(MouseEvent::RIGHT);
763  break;
764  case SDL_BUTTON_MIDDLE:
765  mouseevt.setButton(MouseEvent::MIDDLE);
766  break;
767  case SDL_BUTTON_X1:
768  mouseevt.setButton(MouseEvent::X1);
769  break;
770  case SDL_BUTTON_X2:
771  mouseevt.setButton(MouseEvent::X2);
772  break;
773  default:
775  break;
776  }
777 
778  if (sdlevt.button.state == SDL_RELEASED) {
779  mouseevt.setType(MouseEvent::RELEASED);
780  } else {
781  mouseevt.setType(MouseEvent::PRESSED);
782  }
783  }
784  if (sdlevt.type == SDL_MOUSEWHEEL) {
785 #if SDL_VERSION_ATLEAST(2,0,4)
786  if (sdlevt.wheel.y > 0 || (sdlevt.wheel.direction == SDL_MOUSEWHEEL_FLIPPED && sdlevt.wheel.y < 0)) {
788  } else if (sdlevt.wheel.y < 0 || (sdlevt.wheel.direction == SDL_MOUSEWHEEL_FLIPPED && sdlevt.wheel.y > 0)) {
790  }
791  if (sdlevt.wheel.x > 0 || (sdlevt.wheel.direction == SDL_MOUSEWHEEL_FLIPPED && sdlevt.wheel.x < 0)) {
793  } else if (sdlevt.wheel.x < 0 || (sdlevt.wheel.direction == SDL_MOUSEWHEEL_FLIPPED && sdlevt.wheel.x > 0)) {
795  }
796 #else
797  if (sdlevt.wheel.y > 0) {
799  } else if (sdlevt.wheel.y < 0) {
801  }
802  if (sdlevt.wheel.x > 0) {
804  } else if (sdlevt.wheel.x < 0) {
806  }
807 #endif
808  }
809 
810  if ((mouseevt.getType() == MouseEvent::MOVED) && ((m_mousestate & m_mostrecentbtn) != 0)) {
811  mouseevt.setType(MouseEvent::DRAGGED);
812  mouseevt.setButton(m_mostrecentbtn);
813  }
814  }
815 
816  void EventManager::fillKeyEvent(const SDL_Event& sdlevt, KeyEvent& keyevt) {
817  if (sdlevt.type == SDL_KEYDOWN) {
818  keyevt.setType(KeyEvent::PRESSED);
819  } else if (sdlevt.type == SDL_KEYUP) {
820  keyevt.setType(KeyEvent::RELEASED);
821  } else {
822  FL_WARN(_log, LMsg("fillKeyEvent()")
823  << " Invalid key event type of " << sdlevt.type << ". Ignoring event.");
824  return;
825  }
826 
827  SDL_Keysym keysym = sdlevt.key.keysym;
828  keyevt.setShiftPressed((keysym.mod & KMOD_SHIFT) != 0);
829  keyevt.setControlPressed((keysym.mod & KMOD_CTRL) != 0);
830  keyevt.setAltPressed((keysym.mod & KMOD_ALT) != 0);
831  keyevt.setMetaPressed((keysym.mod & KMOD_GUI) != 0); // currently gui/super keys
832  keyevt.setNumericPad((keysym.mod & KMOD_NUM) != 0);
833  keyevt.setKey(Key(static_cast<Key::KeyType>(keysym.sym)));
834  }
835 
836  void EventManager::fillTextEvent(const SDL_Event& sdlevt, TextEvent& txtevt) {
837  if (sdlevt.type == SDL_TEXTINPUT) {
838  txtevt.setType(TextEvent::INPUT);
839  Text t(sdlevt.text.text);
840  txtevt.setText(t);
841  } else if (sdlevt.type == SDL_TEXTEDITING) {
842  txtevt.setType(TextEvent::EDIT);
843  Text t(sdlevt.edit.text, sdlevt.edit.start, sdlevt.edit.length);
844  txtevt.setText(t);
845  } else {
846  FL_WARN(_log, LMsg("fillTextEvent()")
847  << " Invalid text event type of " << sdlevt.type << ". Ignoring event.");
848  }
849  }
850 
859  }
860 
862  return ES_ENGINE;
863  }
864 
866  m_keyfilter = keyFilter;
867  }
868 
870  m_mousefilter = mouseFilter;
871  }
872 
873  void EventManager::setMouseSensitivity(float sensitivity) {
874  if (sensitivity < -0.99) {
875  sensitivity = -0.99;
876  } else if (sensitivity > 10.0) {
877  sensitivity = 10.0;
878  }
879  m_mouseSensitivity = sensitivity;
880  }
881 
883  return m_mouseSensitivity;
884  }
885 
887  m_acceleration = acceleration;
888  }
889 
891  return m_acceleration;
892  }
893 
895  return SDL_HasClipboardText();
896  }
897 
898  std::string EventManager::getClipboardText() const {
899  std::string text;
900  if (SDL_HasClipboardText()) {
901  text = std::string(SDL_GetClipboardText());
902  }
903  return text;
904  }
905 
906  void EventManager::setClipboardText(const std::string& text) {
907  SDL_SetClipboardText(text.c_str());
908  }
909 
910  void EventManager::setJoystickSupport(bool support) {
911  if (support && !m_joystickManager) {
913  } else if (!support && m_joystickManager) {
914  delete m_joystickManager;
915  m_joystickManager = NULL;
916  }
917  }
918 
919  Joystick* EventManager::getJoystick(int32_t instanceId) {
920  if (m_joystickManager) {
921  return m_joystickManager->getJoystick(instanceId);
922  }
923  return NULL;
924  }
925 
927  if (m_joystickManager) {
929  }
930  return 0;
931  }
932 
933  void EventManager::loadGamepadMapping(const std::string& file) {
934  if (m_joystickManager) {
936  }
937  }
938 
939  void EventManager::saveGamepadMapping(const std::string guid, const std::string& file) {
940  if (m_joystickManager) {
941  m_joystickManager->saveMapping(guid, file);
942  }
943  }
944 
945  void EventManager::saveGamepadMappings(const std::string& file) {
946  if (m_joystickManager) {
948  }
949  }
950 
951  std::string EventManager::getGamepadStringMapping(const std::string& guid) {
952  std::string mapping;
953  if (m_joystickManager) {
954  mapping = m_joystickManager->getStringMapping(guid);
955  }
956  return mapping;
957  }
958 
959  void EventManager::setGamepadStringMapping(const std::string& mapping) {
960  if (m_joystickManager) {
962  }
963  }
964 }
#define FL_WARN(logger, msg)
Definition: logger.h:72
void addJoystickListener(IJoystickListener *listener)
Adds a listener to the back of the listener deque Listener will be notified via the corresponding eve...
std::deque< ITextListener * > m_pendingTextListenersFront
Definition: eventmanager.h:244
void removeMouseListener(IMouseListener *listener)
Removes an added listener from the controller.
KeyEventType getType() const
Definition: keyevent.h:65
void setPath(const std::string &path)
Sets the path for the file that is droped.
Definition: dropevent.h:62
float getMouseSensitivity() const
Gets mouse sensitivity.
void setClipboardText(const std::string &text)
Sets clipboard text.
virtual void setControlPressed(bool pressed)
Sets control to pressed.
Definition: inputevent.h:72
void setY(int32_t y)
Definition: mouseevent.h:119
std::deque< ITextListener * > m_textListeners
Definition: eventmanager.h:242
Listener of SDL events.
std::string getClipboardText() const
Returns the clipboard text as UTF-8 string.
void addKeyListenerFront(IKeyListener *listener)
Adds a listener to the front of the listener deque Listener will be notified via the corresponding ev...
void saveGamepadMappings(const std::string &file)
Saves all controller mappings that were used during the season.
void processJoystickEvent(SDL_Event event)
Creates and process joystick events.
Class for mouse events.
Definition: mouseevent.h:42
void saveGamepadMapping(const std::string guid, const std::string &file)
Saves controller mapping for given GUID in the specified file.
Represents a text.
Definition: text.h:40
virtual bool isConsumed() const
Checks whether event is consumed.
Definition: command.h:81
static T Sqrt(T _val)
Definition: fife_math.h:277
T h
Height of the rectangle.
Definition: rect.h:93
uint8_t getJoystickCount() const
Return the number of joysticks / gamecontrollers.
void addTextListenerFront(ITextListener *listener)
Adds a listener to the front of the listener deque Listener will be notified via the corresponding ev...
IKeyFilter * m_keyfilter
Definition: eventmanager.h:263
virtual void setSource(IEventSource *source)
Sets the source of the event.
Definition: textevent.h:75
void setKey(const Key &key)
Definition: keyevent.h:72
Helper class to create log strings out from separate parts Usage: LMsg("some text") << variable << "...
Definition: logger.h:82
Listener of text events.
Definition: itextlistener.h:44
KeyType getValue() const
Gets the value of the key.
Definition: key.h:321
Controller provides a way to receive events from the system Using this interface, clients can subscri...
Definition: ikeyfilter.h:42
Base class for input events (like mouse and keyboard)
Definition: inputevent.h:42
MouseEventType getType() const
Gets the type of the event.
Definition: mouseevent.h:102
T x
The X Coordinate.
Definition: rect.h:84
std::deque< IKeyListener * > m_pending_keylisteners
Definition: eventmanager.h:238
std::deque< IMouseListener * > m_pending_mouselisteners
Definition: eventmanager.h:248
Listener of drop events.
Definition: idroplistener.h:44
std::deque< ISdlEventListener * > m_pending_sdleventlisteners_front
Definition: eventmanager.h:254
bool combineEvents(SDL_Event &event1, const SDL_Event &event2)
virtual void setShiftPressed(bool pressed)
Sets shift to pressed.
Definition: inputevent.h:88
Listener of command events.
virtual void setSource(IEventSource *source)
Sets the source of the event.
Definition: dropevent.h:86
void addJoystickListenerFront(IJoystickListener *listener)
void setMouseFilter(IMouseFilter *mouseFilter)
void removeJoystickListener(IJoystickListener *listener)
virtual void setSource(IEventSource *source)
Sets the source of the event.
Definition: command.h:89
Class for text events.
Definition: textevent.h:45
virtual void setSource(IEventSource *source)
Sets the source of the event.
Definition: mouseevent.h:135
MouseButtonType getButton() const
Gets the button of the mouse event.
Definition: mouseevent.h:95
void addSdlEventListener(ISdlEventListener *listener)
Adds a listener to the back of the listener deque Listener will be notified via the corresponding eve...
static Logger _log(LM_AUDIO)
void dispatchCommand(Command &command)
Use this method to send command to command listeners.
void addDropListener(IDropListener *listener)
Adds a listener to the back of the listener deque Listener will be notified via the corresponding eve...
void addCommandListenerFront(ICommandListener *listener)
Adds a listener to the front of the listener deque Listener will be notified via the corresponding ev...
Listener of mouse events.
void setMouseAccelerationEnabled(bool acceleration)
Sets mouse acceleration if mouse acceleration is enabled, then the mouse sensitivity is used as speed...
virtual void setAltPressed(bool pressed)
Sets alt to pressed.
Definition: inputevent.h:64
void setStringMapping(const std::string &mapping)
Sets controller mapping from string and adds or updates the related controllers.
std::deque< IKeyListener * > m_pending_kldeletions
Definition: eventmanager.h:240
Listener of joystick events.
virtual void setControlPressed(bool pressed)
Sets control to pressed.
Definition: keyevent.h:77
void dispatchDropEvent(DropEvent &evt)
static RenderBackend * instance()
Definition: singleton.h:84
TextEventType getType() const
Definition: textevent.h:64
virtual void setShiftPressed(bool pressed)
Sets shift to pressed.
Definition: keyevent.h:81
void removeDropListener(IDropListener *listener)
Removes an added listener from the controller.
std::deque< IDropListener * > m_dropListeners
Definition: eventmanager.h:257
void addDropListenerFront(IDropListener *listener)
Adds a listener to the front of the listener deque Listener will be notified via the corresponding ev...
virtual void setSource(IEventSource *source)
Sets the source of the event.
Definition: keyevent.h:88
Represents a Joystick and if available the Gamecontroller.
Definition: joystick.h:39
std::deque< IDropListener * > m_pendingDropListenersFront
Definition: eventmanager.h:259
Joystick * getJoystick(int32_t instanceId)
Return the joystick with the given instance id.
CommandType
Types for different commands.
Definition: commandids.h:41
unsigned char uint8_t
Definition: core.h:38
void removeCommandListener(ICommandListener *listener)
Removes an added listener from the controller.
IMouseFilter * m_mousefilter
Definition: eventmanager.h:264
void dispatchMouseEvent(MouseEvent &evt)
void processWindowEvent(SDL_Event event)
const Key & getKey() const
Definition: keyevent.h:71
std::deque< ISdlEventListener * > m_pending_sdleventlisteners
Definition: eventmanager.h:253
static bool Equal(T _val1, T _val2)
Definition: fife_math.h:287
void setText(const Text &text)
Definition: textevent.h:68
virtual void setMetaPressed(bool pressed)
Sets meta to pressed.
Definition: keyevent.h:79
std::string getGamepadStringMapping(const std::string &guid)
Return the controller mapping for given GUID as string.
void addCommandListener(ICommandListener *listener)
Adds a listener to the back of the listener deque Listener will be notified via the corresponding eve...
std::deque< IKeyListener * > m_keylisteners
Definition: eventmanager.h:237
std::deque< ICommandListener * > m_pending_cldeletions
Definition: eventmanager.h:235
void removeListener(std::deque< T > &vec, T &listener)
Class for commands Commands are arbitrary events e.g.
Definition: command.h:44
Joystick Manager manages all events related to Joysticks and Gamecontrollers.
bool isClipboardText() const
Returns if clipboard have text or not.
void processDropEvent(SDL_Event event)
void setGamepadStringMapping(const std::string &mapping)
Sets controller mapping from string and adds or updates the related controllers.
std::map< int32_t, bool > m_keystatemap
Definition: eventmanager.h:262
void fillMouseEvent(const SDL_Event &sdlevt, MouseEvent &mouseevt)
Controller provides a way to receive events from the system Using this interface, clients can subscri...
Definition: imousefilter.h:42
EventSourceType getEventSourceType()
Gets the source type of this event.
void addListener(std::deque< T > &vec, T &listener)
std::deque< IMouseListener * > m_pending_mouselisteners_front
Definition: eventmanager.h:249
Represents a key.
Definition: key.h:41
unsigned short uint16_t
Definition: core.h:39
T y
The Y Coordinate.
Definition: rect.h:87
std::iterator_traits< octet_iterator >::difference_type distance(octet_iterator first, octet_iterator last)
Definition: checked.h:198
void saveMapping(const std::string guid, const std::string &file)
Saves controller mapping for given GUID in the specified file.
void setKeyFilter(IKeyFilter *keyFilter)
std::deque< IMouseListener * > m_mouselisteners
Definition: eventmanager.h:247
void setX(int32_t x)
Definition: mouseevent.h:111
void dispatchTextEvent(TextEvent &evt)
uint8_t getJoystickCount() const
Return the number of joysticks / gamecontrollers.
void processTextEvent(SDL_Event event)
void setNumericPad(bool ispad)
Definition: keyevent.h:69
void setButton(MouseButtonType type)
Definition: mouseevent.h:96
void setType(TextEventType type)
Definition: textevent.h:65
void removeKeyListener(IKeyListener *listener)
Removes an added listener from the controller.
EventManager()
Constructor.
std::deque< ITextListener * > m_pendingTextListeners
Definition: eventmanager.h:243
void processControllerEvent(SDL_Event event)
Creates and process gamecontroller events.
void addJoystickListener(IJoystickListener *listener)
virtual bool isConsumed() const
Checks whether event is consumed.
Definition: mouseevent.h:131
void setCommandType(CommandType type)
Sets the type of this command.
Definition: command.h:64
void fillKeyEvent(const SDL_Event &sdlevt, KeyEvent &keyevt)
Joystick * getJoystick(int32_t instanceId)
Return the joystick with the given instance id.
JoystickManager * m_joystickManager
Definition: eventmanager.h:280
std::deque< IMouseListener * > m_pending_mldeletions
Definition: eventmanager.h:250
void setType(KeyEventType type)
Definition: keyevent.h:66
MouseEvent::MouseButtonType m_mostrecentbtn
Definition: eventmanager.h:266
std::deque< IDropListener * > m_pendingDropListeners
Definition: eventmanager.h:258
std::deque< ITextListener * > m_pendingTlDeletions
Definition: eventmanager.h:245
void loadMapping(const std::string &file)
Loads controller mappings from given file and if possible, it opens the related controllers.
void addJoystickListenerFront(IJoystickListener *listener)
Adds a listener to the front of the listener deque Listener will be notified via the corresponding ev...
void fillTextEvent(const SDL_Event &sdlevt, TextEvent &txtevt)
std::deque< IKeyListener * > m_pending_keylisteners_front
Definition: eventmanager.h:239
void setJoystickSupport(bool support)
Sets the joystick support to enabled or disabled.
Class for drop events.
Definition: dropevent.h:43
bool isMouseAccelerationEnabled() const
Returns if mouse acceleration is enabled or not.
Class for key events.
Definition: keyevent.h:45
void addMouseListener(IMouseListener *listener)
Adds a listener to the back of the listener deque Listener will be notified via the corresponding eve...
std::deque< ISdlEventListener * > m_sdleventlisteners
Definition: eventmanager.h:252
void processKeyEvent(SDL_Event event)
std::string getStringMapping(const std::string &guid)
Return the controller mapping for given GUID as string.
virtual ~EventManager()
Destructor.
void removeJoystickListener(IJoystickListener *listener)
Removes an added listener from the controller.
bool dispatchSdlEvent(SDL_Event &evt)
Listener of key events.
Definition: ikeylistener.h:44
void saveMappings(const std::string &file)
Saves all controller mappings that were used during the season.
EventSourceType
Types for different event sources.
void processMouseEvent(SDL_Event event)
void setType(MouseEventType type)
Definition: mouseevent.h:103
void fillModifiers(InputEvent &evt)
std::deque< IDropListener * > m_pendingDlDeletions
Definition: eventmanager.h:260
void addSdlEventListenerFront(ISdlEventListener *listener)
Adds a listener to the front of the listener deque Listener will be notified via the corresponding ev...
void setMouseSensitivity(float sensitivity)
Sets mouse sensitivity The sensitivity is limited to the range -0.99 - 10.0.
unsigned int uint32_t
Definition: core.h:40
std::deque< ICommandListener * > m_commandlisteners
Definition: eventmanager.h:232
void processEvents()
Process the SDL event queue.
void addTextListener(ITextListener *listener)
Adds a listener to the back of the listener deque Listener will be notified via the corresponding eve...
virtual bool isFiltered(const MouseEvent &event)=0
Check whether a mouseevent should be filtered out.
void addMouseListenerFront(IMouseListener *listener)
Adds a listener to the front of the listener deque Listener will be notified via the corresponding ev...
std::deque< ICommandListener * > m_pending_commandlisteners_front
Definition: eventmanager.h:234
T w
Width of the rectangle.
Definition: rect.h:90
std::deque< ISdlEventListener * > m_pending_sdldeletions
Definition: eventmanager.h:255
virtual void setAltPressed(bool pressed)
Sets alt to pressed.
Definition: keyevent.h:75
virtual bool isFiltered(const KeyEvent &event)=0
Check whether a keyevent should be filtered out.
std::deque< ICommandListener * > m_pending_commandlisteners
Definition: eventmanager.h:233
void loadGamepadMapping(const std::string &file)
Loads controller mappings from given file and if possible, it opens the related controllers.
void addKeyListener(IKeyListener *listener)
Adds a listener to the back of the listener deque Listener will be notified via the corresponding eve...
void dispatchKeyEvent(KeyEvent &evt)
void removeTextListener(ITextListener *listener)
Removes an added listener from the controller.
const Rect & getArea() const
void removeSdlEventListener(ISdlEventListener *listener)
Removes an added listener from the controller.