MyGUI
3.2.1
|
00001 /* 00002 * This source file is part of MyGUI. For the latest info, see http://mygui.info/ 00003 * Distributed under the MIT License 00004 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT) 00005 */ 00006 00007 #include "MyGUI_Precompiled.h" 00008 #include "MyGUI_InputManager.h" 00009 #include "MyGUI_Widget.h" 00010 #include "MyGUI_WidgetManager.h" 00011 #include "MyGUI_Gui.h" 00012 #include "MyGUI_WidgetManager.h" 00013 #include "MyGUI_Constants.h" 00014 00015 namespace MyGUI 00016 { 00017 00018 // In seconds 00019 const float INPUT_TIME_DOUBLE_CLICK = 0.25f; 00020 const float INPUT_DELAY_FIRST_KEY = 0.4f; 00021 const float INPUT_INTERVAL_KEY = 0.05f; 00022 00023 template <> InputManager* Singleton<InputManager>::msInstance = nullptr; 00024 template <> const char* Singleton<InputManager>::mClassTypeName = "InputManager"; 00025 00026 InputManager::InputManager() : 00027 mWidgetMouseFocus(nullptr), 00028 mWidgetKeyFocus(nullptr), 00029 mLayerMouseFocus(nullptr), 00030 mTimerDoubleClick(INPUT_TIME_DOUBLE_CLICK), 00031 mIsShiftPressed(false), 00032 mIsControlPressed(false), 00033 mHoldKey(KeyCode::None), 00034 mHoldChar(0), 00035 mFirstPressKey(false), 00036 mTimerKey(0.0f), 00037 mOldAbsZ(0), 00038 mIsInitialise(false) 00039 { 00040 resetMouseCaptureWidget(); 00041 } 00042 00043 void InputManager::initialise() 00044 { 00045 MYGUI_ASSERT(!mIsInitialise, getClassTypeName() << " initialised twice"); 00046 MYGUI_LOG(Info, "* Initialise: " << getClassTypeName()); 00047 00048 mWidgetMouseFocus = 0; 00049 mWidgetKeyFocus = 0; 00050 mLayerMouseFocus = 0; 00051 for (int i = MouseButton::Button0; i < MouseButton::MAX; ++i) 00052 { 00053 mMouseCapture[i] = false; 00054 } 00055 mIsShiftPressed = false; 00056 mIsControlPressed = false; 00057 mHoldKey = KeyCode::None; 00058 mHoldChar = 0; 00059 mFirstPressKey = true; 00060 mTimerKey = 0.0f; 00061 mOldAbsZ = 0; 00062 00063 WidgetManager::getInstance().registerUnlinker(this); 00064 Gui::getInstance().eventFrameStart += newDelegate(this, &InputManager::frameEntered); 00065 00066 MYGUI_LOG(Info, getClassTypeName() << " successfully initialized"); 00067 mIsInitialise = true; 00068 } 00069 00070 void InputManager::shutdown() 00071 { 00072 MYGUI_ASSERT(mIsInitialise, getClassTypeName() << " is not initialised"); 00073 MYGUI_LOG(Info, "* Shutdown: " << getClassTypeName()); 00074 00075 Gui::getInstance().eventFrameStart -= newDelegate(this, &InputManager::frameEntered); 00076 WidgetManager::getInstance().unregisterUnlinker(this); 00077 00078 MYGUI_LOG(Info, getClassTypeName() << " successfully shutdown"); 00079 mIsInitialise = false; 00080 } 00081 00082 bool InputManager::injectMouseMove(int _absx, int _absy, int _absz) 00083 { 00084 // запоминаем позицию 00085 mMousePosition.set(_absx, _absy); 00086 00087 // вычисляем прирост по колеса 00088 int relz = _absz - mOldAbsZ; 00089 mOldAbsZ = _absz; 00090 00091 // проверка на скролл 00092 if (relz != 0) 00093 { 00094 bool isFocus = isFocusMouse(); 00095 if (isFocusMouse()) 00096 mWidgetMouseFocus->_riseMouseWheel(relz); 00097 return isFocus; 00098 } 00099 00100 if (isCaptureMouse()) 00101 { 00102 if (isFocusMouse()) 00103 { 00104 if (mLayerMouseFocus != nullptr) 00105 { 00106 IntPoint point = mLayerMouseFocus->getPosition(_absx, _absy); 00107 for (int i = MouseButton::Button0; i < MouseButton::MAX; ++i) 00108 { 00109 if (mMouseCapture[i]) 00110 mWidgetMouseFocus->_riseMouseDrag(point.left, point.top, MouseButton::Enum(i)); 00111 } 00112 } 00113 } 00114 else 00115 { 00116 resetMouseCaptureWidget(); 00117 } 00118 00119 return true; 00120 } 00121 00122 Widget* old_mouse_focus = mWidgetMouseFocus; 00123 00124 // ищем активное окно 00125 Widget* item = LayerManager::getInstance().getWidgetFromPoint(_absx, _absy); 00126 00127 // ничего не изменилось 00128 if (mWidgetMouseFocus == item) 00129 { 00130 bool isFocus = isFocusMouse(); 00131 if (isFocusMouse()) 00132 { 00133 if (mLayerMouseFocus != nullptr) 00134 { 00135 IntPoint point = mLayerMouseFocus->getPosition(_absx, _absy); 00136 mWidgetMouseFocus->_riseMouseMove(point.left, point.top); 00137 } 00138 } 00139 return isFocus; 00140 } 00141 00142 if (item) 00143 { 00144 // поднимаемся до рута 00145 Widget* root = item; 00146 while (root->getParent()) root = root->getParent(); 00147 00148 // проверяем на модальность 00149 if (!mVectorModalRootWidget.empty()) 00150 { 00151 if (root != mVectorModalRootWidget.back()) 00152 { 00153 item = nullptr; 00154 } 00155 } 00156 00157 if (item != nullptr) 00158 { 00159 mLayerMouseFocus = root->getLayer(); 00160 } 00161 } 00162 00163 //-------------------------------------------------------------------------------------// 00164 // новый вид рутового фокуса мыши 00165 Widget* save_widget = nullptr; 00166 00167 // спускаемся по новому виджету и устанавливаем рутовый фокус 00168 Widget* root_focus = item; 00169 while (root_focus != nullptr) 00170 { 00171 if (root_focus->getRootMouseFocus()) 00172 { 00173 save_widget = root_focus; 00174 break; 00175 } 00176 00177 root_focus->_setRootMouseFocus(true); 00178 root_focus->_riseMouseChangeRootFocus(true); 00179 root_focus = root_focus->getParent(); 00180 } 00181 00182 // спускаемся по старому виджету и сбрасываем фокус 00183 root_focus = mWidgetMouseFocus; 00184 while (root_focus != nullptr) 00185 { 00186 if (root_focus == save_widget) 00187 break; 00188 00189 root_focus->_setRootMouseFocus(false); 00190 root_focus->_riseMouseChangeRootFocus(false); 00191 root_focus = root_focus->getParent(); 00192 } 00193 //-------------------------------------------------------------------------------------// 00194 00195 // смена фокуса, проверяем на доступность виджета 00196 if (isFocusMouse() && mWidgetMouseFocus->getInheritedEnabled()) 00197 { 00198 mWidgetMouseFocus->_riseMouseLostFocus(item); 00199 } 00200 00201 if ((item != nullptr) && (item->getInheritedEnabled())) 00202 { 00203 item->_riseMouseMove(_absx, _absy); 00204 item->_riseMouseSetFocus(mWidgetMouseFocus); 00205 } 00206 00207 // запоминаем текущее окно 00208 mWidgetMouseFocus = item; 00209 00210 if (old_mouse_focus != mWidgetMouseFocus) 00211 { 00212 // Reset double click timer, double clicks should only work when clicking on the *same* item twice 00213 mTimerDoubleClick = INPUT_TIME_DOUBLE_CLICK; 00214 eventChangeMouseFocus(mWidgetMouseFocus); 00215 } 00216 00217 return isFocusMouse(); 00218 } 00219 00220 bool InputManager::injectMousePress(int _absx, int _absy, MouseButton _id) 00221 { 00222 injectMouseMove(_absx, _absy, mOldAbsZ); 00223 00224 Widget* old_key_focus = mWidgetKeyFocus; 00225 00226 // если мы щелкнули не на гуй 00227 if (!isFocusMouse()) 00228 { 00229 resetKeyFocusWidget(); 00230 00231 return false; 00232 } 00233 00234 // если активный элемент заблокирован 00235 //FIXME 00236 if (!mWidgetMouseFocus->getInheritedEnabled()) 00237 return true; 00238 00239 if (MouseButton::None != _id && MouseButton::MAX != _id) 00240 { 00241 // start capture 00242 mMouseCapture[_id.getValue()] = true; 00243 // remember last pressed position 00244 if (mLayerMouseFocus != nullptr) 00245 { 00246 IntPoint point = mLayerMouseFocus->getPosition(_absx, _absy); 00247 mLastPressed[_id.getValue()] = point; 00248 } 00249 } 00250 00251 // ищем вверх тот виджет который может принимать фокус 00252 Widget* item = mWidgetMouseFocus; 00253 while ((item != nullptr) && (!item->getNeedKeyFocus())) 00254 item = item->getParent(); 00255 00256 // устанавливаем перед вызовом т.к. возможно внутри ктонить поменяет фокус под себя 00257 setKeyFocusWidget(item); 00258 00259 if (isFocusMouse()) 00260 { 00261 mWidgetMouseFocus->_riseMouseButtonPressed(_absx, _absy, _id); 00262 00263 // после пресса может сброситься 00264 if (mWidgetMouseFocus) 00265 { 00266 // поднимаем виджет, надо подумать что делать если поменялся фокус клавы 00267 LayerManager::getInstance().upLayerItem(mWidgetMouseFocus); 00268 00269 // поднимаем пикинг Overlapped окон 00270 Widget* pick = mWidgetMouseFocus; 00271 do 00272 { 00273 // если оверлаппед, то поднимаем пикинг 00274 if (pick->getWidgetStyle() == WidgetStyle::Overlapped) 00275 { 00276 if (pick->getParent()) pick->getParent()->_forcePick(pick); 00277 } 00278 00279 pick = pick->getParent(); 00280 } 00281 while (pick); 00282 } 00283 } 00284 00285 return true; 00286 } 00287 00288 bool InputManager::injectMouseRelease(int _absx, int _absy, MouseButton _id) 00289 { 00290 if (isFocusMouse()) 00291 { 00292 // если активный элемент заблокирован 00293 if (!mWidgetMouseFocus->getInheritedEnabled()) 00294 return true; 00295 00296 if (_id != MouseButton::None && _id != MouseButton::MAX) 00297 { 00298 if (mMouseCapture[_id.getValue()]) 00299 { 00300 // drop capture 00301 mMouseCapture[_id.getValue()] = false; 00302 } 00303 } 00304 00305 mWidgetMouseFocus->_riseMouseButtonReleased(_absx, _absy, _id); 00306 00307 // после вызова, виджет может быть сброшен 00308 if (nullptr != mWidgetMouseFocus) 00309 { 00310 if (MouseButton::Left == _id) 00311 { 00312 if (mTimerDoubleClick < INPUT_TIME_DOUBLE_CLICK) 00313 { 00314 mWidgetMouseFocus->_riseMouseButtonClick(); 00315 // после вызова, виджет может быть сброшен 00316 if (nullptr != mWidgetMouseFocus) 00317 mWidgetMouseFocus->_riseMouseButtonDoubleClick(); 00318 } 00319 else 00320 { 00321 // проверяем над тем ли мы окном сейчас что и были при нажатии 00322 Widget* item = LayerManager::getInstance().getWidgetFromPoint(_absx, _absy); 00323 if ( item == mWidgetMouseFocus) 00324 { 00325 mWidgetMouseFocus->_riseMouseButtonClick(); 00326 } 00327 mTimerDoubleClick = 0; 00328 } 00329 } 00330 } 00331 00332 // для корректного отображения 00333 injectMouseMove(_absx, _absy, mOldAbsZ); 00334 00335 return true; 00336 } 00337 00338 return false; 00339 } 00340 00341 bool InputManager::injectKeyPress(KeyCode _key, Char _text) 00342 { 00343 // проверка на переключение языков 00344 firstEncoding(_key, true); 00345 00346 // запоминаем клавишу 00347 storeKey(_key, _text); 00348 00349 bool wasFocusKey = isFocusKey(); 00350 00351 //Pass keystrokes to the current active text widget 00352 if (isFocusKey()) 00353 { 00354 mWidgetKeyFocus->_riseKeyButtonPressed(_key, _text); 00355 } 00356 00357 return wasFocusKey; 00358 } 00359 00360 bool InputManager::injectKeyRelease(KeyCode _key) 00361 { 00362 // проверка на переключение языков 00363 firstEncoding(_key, false); 00364 00365 // сбрасываем клавишу 00366 resetKey(); 00367 00368 bool wasFocusKey = isFocusKey(); 00369 00370 if (isFocusKey()) 00371 mWidgetKeyFocus->_riseKeyButtonReleased(_key); 00372 00373 return wasFocusKey; 00374 } 00375 00376 void InputManager::firstEncoding(KeyCode _key, bool bIsKeyPressed) 00377 { 00378 if ((_key == KeyCode::LeftShift) || (_key == KeyCode::RightShift)) 00379 mIsShiftPressed = bIsKeyPressed; 00380 if ((_key == KeyCode::LeftControl) || (_key == KeyCode::RightControl)) 00381 mIsControlPressed = bIsKeyPressed; 00382 } 00383 00384 void InputManager::setKeyFocusWidget(Widget* _widget) 00385 { 00386 if (_widget == mWidgetKeyFocus) 00387 return; 00388 00389 //-------------------------------------------------------------------------------------// 00390 // новый вид рутового фокуса 00391 Widget* save_widget = nullptr; 00392 00393 // спускаемся по новому виджету и устанавливаем рутовый фокус 00394 Widget* root_focus = _widget; 00395 while (root_focus != nullptr) 00396 { 00397 if (root_focus->getRootKeyFocus()) 00398 { 00399 save_widget = root_focus; 00400 break; 00401 } 00402 00403 root_focus->_setRootKeyFocus(true); 00404 root_focus->_riseKeyChangeRootFocus(true); 00405 root_focus = root_focus->getParent(); 00406 } 00407 00408 // спускаемся по старому виджету и сбрасываем фокус 00409 root_focus = mWidgetKeyFocus; 00410 while (root_focus != nullptr) 00411 { 00412 if (root_focus == save_widget) 00413 break; 00414 00415 root_focus->_setRootKeyFocus(false); 00416 root_focus->_riseKeyChangeRootFocus(false); 00417 root_focus = root_focus->getParent(); 00418 } 00419 //-------------------------------------------------------------------------------------// 00420 00421 // сбрасываем старый 00422 if (mWidgetKeyFocus) 00423 { 00424 mWidgetKeyFocus->_riseKeyLostFocus(_widget); 00425 } 00426 00427 // устанавливаем новый 00428 if (_widget && _widget->getNeedKeyFocus()) 00429 { 00430 _widget->_riseKeySetFocus(mWidgetKeyFocus); 00431 } 00432 00433 mWidgetKeyFocus = _widget; 00434 00435 eventChangeKeyFocus(mWidgetKeyFocus); 00436 } 00437 00438 void InputManager::_resetMouseFocusWidget() 00439 { 00440 Widget* mouseFocus = mWidgetMouseFocus; 00441 mWidgetMouseFocus = nullptr; 00442 00443 // спускаемся по старому виджету и сбрасываем фокус 00444 Widget* root_focus = mouseFocus; 00445 while (root_focus != nullptr) 00446 { 00447 root_focus->_setRootMouseFocus(false); 00448 root_focus->_riseMouseChangeRootFocus(false); 00449 root_focus = root_focus->getParent(); 00450 } 00451 00452 for (int i = MouseButton::Button0; i < MouseButton::MAX; ++i) 00453 { 00454 if (mMouseCapture[i]) 00455 { 00456 mMouseCapture[i] = false; 00457 mouseFocus->_riseMouseButtonReleased(mLastPressed[i].left, mLastPressed[i].top, MouseButton::Enum(i)); 00458 } 00459 } 00460 00461 if (nullptr != mouseFocus) 00462 { 00463 mouseFocus->_riseMouseLostFocus(nullptr); 00464 } 00465 00466 if (mouseFocus != mWidgetMouseFocus) 00467 eventChangeMouseFocus(mWidgetMouseFocus); 00468 } 00469 00470 // удаляем данный виджет из всех возможных мест 00471 void InputManager::_unlinkWidget(Widget* _widget) 00472 { 00473 if (nullptr == _widget) 00474 return; 00475 00476 if (mWidgetMouseFocus == _widget) 00477 _resetMouseFocusWidget(); 00478 00479 if (_widget == mWidgetKeyFocus) 00480 { 00481 mWidgetKeyFocus = nullptr; 00482 } 00483 00484 // ручками сбрасываем, чтобы не менять фокусы 00485 for (VectorWidgetPtr::iterator iter = mVectorModalRootWidget.begin(); iter != mVectorModalRootWidget.end(); ++iter) 00486 { 00487 if (*iter == _widget) 00488 { 00489 mVectorModalRootWidget.erase(iter); 00490 break; 00491 } 00492 } 00493 } 00494 00495 void InputManager::addWidgetModal(Widget* _widget) 00496 { 00497 if (nullptr == _widget) 00498 return; 00499 MYGUI_ASSERT(nullptr == _widget->getParent(), "Modal widget must be root"); 00500 00501 _resetMouseFocusWidget(); 00502 removeWidgetModal(_widget); 00503 mVectorModalRootWidget.push_back(_widget); 00504 00505 setKeyFocusWidget(_widget); 00506 LayerManager::getInstance().upLayerItem(_widget); 00507 } 00508 00509 void InputManager::removeWidgetModal(Widget* _widget) 00510 { 00511 resetKeyFocusWidget(_widget); 00512 _resetMouseFocusWidget(); 00513 00514 for (VectorWidgetPtr::iterator iter = mVectorModalRootWidget.begin(); iter != mVectorModalRootWidget.end(); ++iter) 00515 { 00516 if (*iter == _widget) 00517 { 00518 mVectorModalRootWidget.erase(iter); 00519 break; 00520 } 00521 } 00522 // если еще есть модальные то их фокусируем и поднимаем 00523 if (!mVectorModalRootWidget.empty()) 00524 { 00525 setKeyFocusWidget(mVectorModalRootWidget.back()); 00526 LayerManager::getInstance().upLayerItem(mVectorModalRootWidget.back()); 00527 } 00528 } 00529 00530 void InputManager::storeKey(KeyCode _key, Char _text) 00531 { 00532 mHoldKey = KeyCode::None; 00533 mHoldChar = 0; 00534 00535 if ( !isFocusKey() ) return; 00536 if ( (_key == KeyCode::LeftShift) || (_key == KeyCode::RightShift) 00537 || (_key == KeyCode::LeftControl) || (_key == KeyCode::RightControl) 00538 || (_key == KeyCode::LeftAlt) || (_key == KeyCode::RightAlt) 00539 ) return; 00540 00541 mFirstPressKey = true; 00542 mHoldKey = _key; 00543 mHoldChar = _text; 00544 mTimerKey = 0.0f; 00545 } 00546 00547 void InputManager::resetKey() 00548 { 00549 mHoldKey = KeyCode::None; 00550 mHoldChar = 0; 00551 } 00552 00553 void InputManager::frameEntered(float _frame) 00554 { 00555 mTimerDoubleClick += _frame; 00556 00557 if ( mHoldKey == KeyCode::None) 00558 return; 00559 00560 if ( !isFocusKey() ) 00561 { 00562 mHoldKey = KeyCode::None; 00563 mHoldChar = 0; 00564 return; 00565 } 00566 00567 mTimerKey += _frame; 00568 00569 if (mFirstPressKey) 00570 { 00571 if (mTimerKey > INPUT_DELAY_FIRST_KEY) 00572 { 00573 mFirstPressKey = false; 00574 mTimerKey = 0.0f; 00575 } 00576 } 00577 else 00578 { 00579 if (mTimerKey > INPUT_INTERVAL_KEY) 00580 { 00581 while (mTimerKey > INPUT_INTERVAL_KEY) 00582 mTimerKey -= INPUT_INTERVAL_KEY; 00583 mWidgetKeyFocus->_riseKeyButtonPressed(mHoldKey, mHoldChar); 00584 // focus can be dropped in onKeyButtonPressed 00585 if (isFocusKey()) 00586 mWidgetKeyFocus->_riseKeyButtonReleased(mHoldKey); 00587 } 00588 } 00589 00590 } 00591 00592 void InputManager::resetKeyFocusWidget(Widget* _widget) 00593 { 00594 if (mWidgetKeyFocus == _widget) 00595 setKeyFocusWidget(nullptr); 00596 } 00597 00598 IntPoint InputManager::getMousePositionByLayer() 00599 { 00600 if (mLayerMouseFocus != nullptr) 00601 return mLayerMouseFocus->getPosition(mMousePosition.left, mMousePosition.top); 00602 return mMousePosition; 00603 } 00604 00605 bool InputManager::isFocusMouse() const 00606 { 00607 return mWidgetMouseFocus != nullptr; 00608 } 00609 00610 bool InputManager::isFocusKey() const 00611 { 00612 return mWidgetKeyFocus != nullptr; 00613 } 00614 00615 bool InputManager::isCaptureMouse() const 00616 { 00617 for (int i = MouseButton::Button0; i < MouseButton::MAX; ++i) 00618 { 00619 if (mMouseCapture[i]) 00620 return true; 00621 } 00622 return false; 00623 } 00624 00625 void InputManager::resetKeyFocusWidget() 00626 { 00627 setKeyFocusWidget(nullptr); 00628 } 00629 00630 Widget* InputManager::getMouseFocusWidget() const 00631 { 00632 return mWidgetMouseFocus; 00633 } 00634 00635 Widget* InputManager::getKeyFocusWidget() const 00636 { 00637 return mWidgetKeyFocus; 00638 } 00639 00640 const IntPoint& InputManager::getLastPressedPosition(MouseButton _id) const 00641 { 00642 if (_id != MouseButton::None && _id != MouseButton::MAX) 00643 { 00644 return mLastPressed[_id.getValue()]; 00645 } 00646 return Constants::getZeroIntPoint(); 00647 } 00648 00649 const IntPoint& InputManager::getMousePosition() const 00650 { 00651 return mMousePosition; 00652 } 00653 00654 bool InputManager::isModalAny() const 00655 { 00656 return !mVectorModalRootWidget.empty(); 00657 } 00658 00659 bool InputManager::isControlPressed() const 00660 { 00661 return mIsControlPressed; 00662 } 00663 00664 bool InputManager::isShiftPressed() const 00665 { 00666 return mIsShiftPressed; 00667 } 00668 00669 void InputManager::resetMouseCaptureWidget() 00670 { 00671 for (int i = MouseButton::Button0; i < MouseButton::MAX; ++i) 00672 { 00673 mMouseCapture[i] = false; 00674 } 00675 } 00676 00677 void InputManager::unlinkWidget(Widget* _widget) 00678 { 00679 _unlinkWidget(_widget); 00680 } 00681 00682 } // namespace MyGUI