MyGUI  3.2.0
MyGUI_InputManager.cpp
Go to the documentation of this file.
1 
6 /*
7  This file is part of MyGUI.
8 
9  MyGUI is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  MyGUI is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "MyGUI_Precompiled.h"
23 #include "MyGUI_InputManager.h"
24 #include "MyGUI_Widget.h"
25 #include "MyGUI_WidgetManager.h"
26 #include "MyGUI_Gui.h"
27 #include "MyGUI_WidgetManager.h"
28 #include "MyGUI_Constants.h"
29 
30 namespace MyGUI
31 {
32  const unsigned long INPUT_TIME_DOUBLE_CLICK = 250; //measured in milliseconds
33  const float INPUT_DELAY_FIRST_KEY = 0.4f;
34  const float INPUT_INTERVAL_KEY = 0.05f;
35 
37  template <> const char* Singleton<InputManager>::mClassTypeName("InputManager");
38 
40  mWidgetMouseFocus(nullptr),
41  mWidgetKeyFocus(nullptr),
42  mLayerMouseFocus(nullptr),
43  mIsShiftPressed(false),
44  mIsControlPressed(false),
45  mHoldKey(KeyCode::None),
46  mHoldChar(0),
47  mFirstPressKey(false),
48  mTimerKey(0.0f),
49  mOldAbsZ(0),
50  mIsInitialise(false)
51  {
53  }
54 
56  {
57  MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice");
58  MYGUI_LOG(Info, "* Initialise: " << getClassTypeName());
59 
60  mWidgetMouseFocus = 0;
61  mWidgetKeyFocus = 0;
62  mLayerMouseFocus = 0;
63  for (int i = MouseButton::Button0; i < MouseButton::MAX; ++i)
64  {
65  mMouseCapture[i] = false;
66  }
67  mIsShiftPressed = false;
68  mIsControlPressed = false;
69  mHoldKey = KeyCode::None;
70  mHoldChar = 0;
71  mFirstPressKey = true;
72  mTimerKey = 0.0f;
73  mOldAbsZ = 0;
74 
76  Gui::getInstance().eventFrameStart += newDelegate(this, &InputManager::frameEntered);
77 
78  MYGUI_LOG(Info, getClassTypeName() << " successfully initialized");
79  mIsInitialise = true;
80  }
81 
83  {
84  MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised");
85  MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName());
86 
87  Gui::getInstance().eventFrameStart -= newDelegate(this, &InputManager::frameEntered);
89 
90  MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown");
91  mIsInitialise = false;
92  }
93 
94  bool InputManager::injectMouseMove(int _absx, int _absy, int _absz)
95  {
96  // запоминаем позицию
97  mMousePosition.set(_absx, _absy);
98 
99  // вычисляем прирост по колеса
100  int relz = _absz - mOldAbsZ;
101  mOldAbsZ = _absz;
102 
103  // проверка на скролл
104  if (relz != 0)
105  {
106  bool isFocus = isFocusMouse();
107  if (isFocusMouse())
108  mWidgetMouseFocus->_riseMouseWheel(relz);
109  return isFocus;
110  }
111 
112  if (isCaptureMouse())
113  {
114  if (isFocusMouse())
115  {
116  if (mLayerMouseFocus != nullptr)
117  {
118  IntPoint point = mLayerMouseFocus->getPosition(_absx, _absy);
119  for (int i = MouseButton::Button0; i < MouseButton::MAX; ++i)
120  {
121  if (mMouseCapture[i])
122  mWidgetMouseFocus->_riseMouseDrag(point.left, point.top, MouseButton::Enum(i));
123  }
124  }
125  }
126  else
127  {
129  }
130 
131  return true;
132  }
133 
134  Widget* old_mouse_focus = mWidgetMouseFocus;
135 
136  // ищем активное окно
137  Widget* item = LayerManager::getInstance().getWidgetFromPoint(_absx, _absy);
138 
139  // ничего не изменилось
140  if (mWidgetMouseFocus == item)
141  {
142  bool isFocus = isFocusMouse();
143  if (isFocusMouse())
144  {
145  if (mLayerMouseFocus != nullptr)
146  {
147  IntPoint point = mLayerMouseFocus->getPosition(_absx, _absy);
148  mWidgetMouseFocus->_riseMouseMove(point.left, point.top);
149  }
150  }
151  return isFocus;
152  }
153 
154  if (item)
155  {
156  // поднимаемся до рута
157  Widget* root = item;
158  while (root->getParent()) root = root->getParent();
159 
160  // проверяем на модальность
161  if (!mVectorModalRootWidget.empty())
162  {
163  if (root != mVectorModalRootWidget.back())
164  {
165  item = nullptr;
166  }
167  }
168 
169  if (item != nullptr)
170  {
171  mLayerMouseFocus = root->getLayer();
172  }
173  }
174 
175  //-------------------------------------------------------------------------------------//
176  // новый вид рутового фокуса мыши
177  Widget* save_widget = nullptr;
178 
179  // спускаемся по новому виджету и устанавливаем рутовый фокус
180  Widget* root_focus = item;
181  while (root_focus != nullptr)
182  {
183  if (root_focus->getRootMouseFocus())
184  {
185  save_widget = root_focus;
186  break;
187  }
188 
189  root_focus->_setRootMouseFocus(true);
190  root_focus->_riseMouseChangeRootFocus(true);
191  root_focus = root_focus->getParent();
192  }
193 
194  // спускаемся по старому виджету и сбрасываем фокус
195  root_focus = mWidgetMouseFocus;
196  while (root_focus != nullptr)
197  {
198  if (root_focus == save_widget)
199  break;
200 
201  root_focus->_setRootMouseFocus(false);
202  root_focus->_riseMouseChangeRootFocus(false);
203  root_focus = root_focus->getParent();
204  }
205  //-------------------------------------------------------------------------------------//
206 
207  // смена фокуса, проверяем на доступность виджета
208  if (isFocusMouse() && mWidgetMouseFocus->getEnabled())
209  {
210  mWidgetMouseFocus->_riseMouseLostFocus(item);
211  }
212 
213  if ((item != nullptr) && (item->getEnabled()))
214  {
215  item->_riseMouseMove(_absx, _absy);
216  item->_riseMouseSetFocus(mWidgetMouseFocus);
217  }
218 
219  // запоминаем текущее окно
220  mWidgetMouseFocus = item;
221 
222  if (old_mouse_focus != mWidgetMouseFocus)
223  eventChangeMouseFocus(mWidgetMouseFocus);
224 
225  return isFocusMouse();
226  }
227 
228  bool InputManager::injectMousePress(int _absx, int _absy, MouseButton _id)
229  {
230  Widget* old_key_focus = mWidgetKeyFocus;
231 
232  // если мы щелкнули не на гуй
233  if (!isFocusMouse())
234  {
236 
237  if (old_key_focus != mWidgetKeyFocus)
238  eventChangeKeyFocus(mWidgetKeyFocus);
239 
240  return false;
241  }
242 
243  // если активный элемент заблокирован
244  //FIXME
245  if (!mWidgetMouseFocus->getEnabled())
246  return true;
247 
248  if (MouseButton::None != _id && MouseButton::MAX != _id)
249  {
250  // start capture
251  mMouseCapture[_id.toValue()] = true;
252  // remember last pressed position
253  if (mLayerMouseFocus != nullptr)
254  {
255  IntPoint point = mLayerMouseFocus->getPosition(_absx, _absy);
256  mLastPressed[_id.toValue()] = point;
257  }
258  }
259 
260  // ищем вверх тот виджет который может принимать фокус
261  Widget* item = mWidgetMouseFocus;
262  while ((item != nullptr) && (!item->getNeedKeyFocus()))
263  item = item->getParent();
264 
265  // устанавливаем перед вызовом т.к. возможно внутри ктонить поменяет фокус под себя
266  setKeyFocusWidget(item);
267 
268  if (isFocusMouse())
269  {
270  mWidgetMouseFocus->_riseMouseButtonPressed(_absx, _absy, _id);
271 
272  // после пресса может сброситься
273  if (mWidgetMouseFocus)
274  {
275  // поднимаем виджет, надо подумать что делать если поменялся фокус клавы
276  LayerManager::getInstance().upLayerItem(mWidgetMouseFocus);
277 
278  // поднимаем пикинг Overlapped окон
279  Widget* pick = mWidgetMouseFocus;
280  do
281  {
282  // если оверлаппед, то поднимаем пикинг
284  {
285  if (pick->getParent()) pick->getParent()->_forcePick(pick);
286  }
287 
288  pick = pick->getParent();
289  }
290  while (pick);
291  }
292  }
293 
294  if (old_key_focus != mWidgetKeyFocus)
295  eventChangeKeyFocus(mWidgetKeyFocus);
296 
297  return true;
298  }
299 
300  bool InputManager::injectMouseRelease(int _absx, int _absy, MouseButton _id)
301  {
302  if (isFocusMouse())
303  {
304  // если активный элемент заблокирован
305  if (!mWidgetMouseFocus->getEnabled())
306  return true;
307 
308  if (_id != MouseButton::None && _id != MouseButton::MAX)
309  {
310  if (mMouseCapture[_id.toValue()])
311  {
312  // drop capture
313  mMouseCapture[_id.toValue()] = false;
314  }
315  }
316 
317  mWidgetMouseFocus->_riseMouseButtonReleased(_absx, _absy, _id);
318 
319  // после вызова, виджет может быть сброшен
320  if (nullptr != mWidgetMouseFocus)
321  {
322  if (MouseButton::Left == _id)
323  {
325  {
326  mWidgetMouseFocus->_riseMouseButtonClick();
327  // после вызова, виджет может быть сброшен
328  if (nullptr != mWidgetMouseFocus)
329  mWidgetMouseFocus->_riseMouseButtonDoubleClick();
330  }
331  else
332  {
333  // проверяем над тем ли мы окном сейчас что и были при нажатии
334  Widget* item = LayerManager::getInstance().getWidgetFromPoint(_absx, _absy);
335  if ( item == mWidgetMouseFocus)
336  {
337  mWidgetMouseFocus->_riseMouseButtonClick();
338  }
339  mTimer.reset();
340  }
341  }
342  }
343 
344  // для корректного отображения
345  injectMouseMove(_absx, _absy, mOldAbsZ);
346 
347  return true;
348  }
349 
350  return false;
351  }
352 
354  {
355  // проверка на переключение языков
356  firstEncoding(_key, true);
357 
358  // запоминаем клавишу
359  storeKey(_key, _text);
360 
361  bool wasFocusKey = isFocusKey();
362 
363  //Pass keystrokes to the current active text widget
364  if (isFocusKey())
365  {
366  mWidgetKeyFocus->_riseKeyButtonPressed(_key, _text);
367  }
368 
369  return wasFocusKey;
370  }
371 
373  {
374  // проверка на переключение языков
375  firstEncoding(_key, false);
376 
377  // сбрасываем клавишу
378  resetKey();
379 
380  bool wasFocusKey = isFocusKey();
381 
382  if (isFocusKey())
383  mWidgetKeyFocus->_riseKeyButtonReleased(_key);
384 
385  return wasFocusKey;
386  }
387 
388  void InputManager::firstEncoding(KeyCode _key, bool bIsKeyPressed)
389  {
390  if ((_key == KeyCode::LeftShift) || (_key == KeyCode::RightShift))
391  mIsShiftPressed = bIsKeyPressed;
392  if ((_key == KeyCode::LeftControl) || (_key == KeyCode::RightControl))
393  mIsControlPressed = bIsKeyPressed;
394  }
395 
397  {
398  if (_widget == mWidgetKeyFocus)
399  return;
400 
401  //-------------------------------------------------------------------------------------//
402  // новый вид рутового фокуса
403  Widget* save_widget = nullptr;
404 
405  // спускаемся по новому виджету и устанавливаем рутовый фокус
406  Widget* root_focus = _widget;
407  while (root_focus != nullptr)
408  {
409  if (root_focus->getRootKeyFocus())
410  {
411  save_widget = root_focus;
412  break;
413  }
414 
415  root_focus->_setRootKeyFocus(true);
416  root_focus->_riseKeyChangeRootFocus(true);
417  root_focus = root_focus->getParent();
418  }
419 
420  // спускаемся по старому виджету и сбрасываем фокус
421  root_focus = mWidgetKeyFocus;
422  while (root_focus != nullptr)
423  {
424  if (root_focus == save_widget)
425  break;
426 
427  root_focus->_setRootKeyFocus(false);
428  root_focus->_riseKeyChangeRootFocus(false);
429  root_focus = root_focus->getParent();
430  }
431  //-------------------------------------------------------------------------------------//
432 
433  // сбрасываем старый
434  if (mWidgetKeyFocus)
435  {
436  mWidgetKeyFocus->_riseKeyLostFocus(_widget);
437  }
438 
439  // устанавливаем новый
440  if (_widget && _widget->getNeedKeyFocus())
441  {
442  _widget->_riseKeySetFocus(mWidgetKeyFocus);
443  }
444 
445  mWidgetKeyFocus = _widget;
446  }
447 
449  {
450  Widget* mouseFocus = mWidgetMouseFocus;
451  mWidgetMouseFocus = nullptr;
452 
453  // спускаемся по старому виджету и сбрасываем фокус
454  Widget* root_focus = mouseFocus;
455  while (root_focus != nullptr)
456  {
457  root_focus->_setRootMouseFocus(false);
458  root_focus->_riseMouseChangeRootFocus(false);
459  root_focus = root_focus->getParent();
460  }
461 
462  for (int i = MouseButton::Button0; i < MouseButton::MAX; ++i)
463  {
464  if (mMouseCapture[i])
465  {
466  mMouseCapture[i] = false;
467  mouseFocus->_riseMouseButtonReleased(mLastPressed[i].left, mLastPressed[i].top, MouseButton::Enum(i));
468  }
469  }
470 
471  if (nullptr != mouseFocus)
472  {
473  mouseFocus->_riseMouseLostFocus(nullptr);
474  }
475  }
476 
477  // удаляем данный виджет из всех возможных мест
478  void InputManager::_unlinkWidget(Widget* _widget)
479  {
480  if (nullptr == _widget)
481  return;
482 
483  if (mWidgetMouseFocus == _widget)
485 
486  if (_widget == mWidgetKeyFocus)
487  {
488  mWidgetKeyFocus = nullptr;
489  }
490 
491  // ручками сбрасываем, чтобы не менять фокусы
492  for (VectorWidgetPtr::iterator iter = mVectorModalRootWidget.begin(); iter != mVectorModalRootWidget.end(); ++iter)
493  {
494  if ((*iter == _widget))
495  {
496  mVectorModalRootWidget.erase(iter);
497  break;
498  }
499  }
500  }
501 
503  {
504  if (nullptr == _widget)
505  return;
506  MYGUI_ASSERT(nullptr == _widget->getParent(), "Modal widget must be root");
507 
509  removeWidgetModal(_widget);
510  mVectorModalRootWidget.push_back(_widget);
511 
512  setKeyFocusWidget(_widget);
514  }
515 
517  {
518  resetKeyFocusWidget(_widget);
520 
521  for (VectorWidgetPtr::iterator iter = mVectorModalRootWidget.begin(); iter != mVectorModalRootWidget.end(); ++iter)
522  {
523  if ((*iter == _widget))
524  {
525  mVectorModalRootWidget.erase(iter);
526  break;
527  }
528  }
529  // если еще есть модальные то их фокусируем и поднимаем
530  if (!mVectorModalRootWidget.empty())
531  {
532  setKeyFocusWidget(mVectorModalRootWidget.back());
533  LayerManager::getInstance().upLayerItem(mVectorModalRootWidget.back());
534  }
535  }
536 
537  void InputManager::storeKey(KeyCode _key, Char _text)
538  {
539  mHoldKey = KeyCode::None;
540  mHoldChar = 0;
541 
542  if ( !isFocusKey() ) return;
543  if ( (_key == KeyCode::LeftShift) || (_key == KeyCode::RightShift)
544  || (_key == KeyCode::LeftControl) || (_key == KeyCode::RightControl)
545  || (_key == KeyCode::LeftAlt) || (_key == KeyCode::RightAlt)
546  ) return;
547 
548  mFirstPressKey = true;
549  mHoldKey = _key;
550  mHoldChar = _text;
551  mTimerKey = 0.0f;
552  }
553 
554  void InputManager::resetKey()
555  {
556  mHoldKey = KeyCode::None;
557  mHoldChar = 0;
558  }
559 
560  void InputManager::frameEntered(float _frame)
561  {
562  if ( mHoldKey == KeyCode::None)
563  return;
564 
565  if ( !isFocusKey() )
566  {
567  mHoldKey = KeyCode::None;
568  mHoldChar = 0;
569  return;
570  }
571 
572  mTimerKey += _frame;
573 
574  if (mFirstPressKey)
575  {
576  if (mTimerKey > INPUT_DELAY_FIRST_KEY)
577  {
578  mFirstPressKey = false;
579  mTimerKey = 0.0f;
580  }
581  }
582  else
583  {
584  if (mTimerKey > INPUT_INTERVAL_KEY)
585  {
586  while (mTimerKey > INPUT_INTERVAL_KEY)
587  mTimerKey -= INPUT_INTERVAL_KEY;
588  mWidgetKeyFocus->_riseKeyButtonPressed(mHoldKey, mHoldChar);
589  // focus can be dropped in onKeyButtonPressed
590  if (isFocusKey())
591  mWidgetKeyFocus->_riseKeyButtonReleased(mHoldKey);
592  }
593  }
594 
595  }
596 
598  {
599  if (mWidgetKeyFocus == _widget)
600  setKeyFocusWidget(nullptr);
601  }
602 
604  {
605  if (mLayerMouseFocus != nullptr)
606  return mLayerMouseFocus->getPosition(mMousePosition.left, mMousePosition.top);
607  return mMousePosition;
608  }
609 
611  {
612  return mWidgetMouseFocus != nullptr;
613  }
614 
616  {
617  return mWidgetKeyFocus != nullptr;
618  }
619 
621  {
622  for (int i = MouseButton::Button0; i < MouseButton::MAX; ++i)
623  {
624  if (mMouseCapture[i])
625  return true;
626  }
627  return false;
628  }
629 
631  {
632  setKeyFocusWidget(nullptr);
633  }
634 
636  {
637  return mWidgetMouseFocus;
638  }
639 
641  {
642  return mWidgetKeyFocus;
643  }
644 
646  {
647  if (_id != MouseButton::None && _id != MouseButton::MAX)
648  {
649  return mLastPressed[_id.toValue()];
650  }
652  }
653 
655  {
656  return mMousePosition;
657  }
658 
660  {
661  return !mVectorModalRootWidget.empty();
662  }
663 
665  {
666  return mIsControlPressed;
667  }
668 
670  {
671  return mIsShiftPressed;
672  }
673 
675  {
676  for (int i = MouseButton::Button0; i < MouseButton::MAX; ++i)
677  {
678  mMouseCapture[i] = false;
679  }
680  }
681 
683  {
684  _unlinkWidget(_widget);
685  }
686 
687 } // namespace MyGUI