MyGUI
3.0.3
|
00001 00007 /* 00008 This file is part of MyGUI. 00009 00010 MyGUI is free software: you can redistribute it and/or modify 00011 it under the terms of the GNU Lesser General Public License as published by 00012 the Free Software Foundation, either version 3 of the License, or 00013 (at your option) any later version. 00014 00015 MyGUI is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public License 00021 along with MyGUI. If not, see <http://www.gnu.org/licenses/>. 00022 */ 00023 #include "MyGUI_Precompiled.h" 00024 #include "MyGUI_InputManager.h" 00025 #include "MyGUI_Widget.h" 00026 #include "MyGUI_WidgetManager.h" 00027 #include "MyGUI_Gui.h" 00028 #include "MyGUI_WidgetManager.h" 00029 00030 namespace MyGUI 00031 { 00032 const unsigned long INPUT_TIME_DOUBLE_CLICK = 250; //measured in milliseconds 00033 const float INPUT_DELAY_FIRST_KEY = 0.4f; 00034 const float INPUT_INTERVAL_KEY = 0.05f; 00035 00036 MYGUI_INSTANCE_IMPLEMENT( InputManager ) 00037 00038 void InputManager::initialise() 00039 { 00040 MYGUI_ASSERT(!mIsInitialise, INSTANCE_TYPE_NAME << " initialised twice"); 00041 MYGUI_LOG(Info, "* Initialise: " << INSTANCE_TYPE_NAME); 00042 00043 mWidgetMouseFocus = 0; 00044 mWidgetKeyFocus = 0; 00045 mLayerMouseFocus = 0; 00046 mIsWidgetMouseCapture = false; 00047 mIsShiftPressed = false; 00048 mIsControlPressed = false; 00049 mHoldKey = KeyCode::None; 00050 mHoldChar = 0; 00051 mFirstPressKey = true; 00052 mTimerKey = 0.0f; 00053 mOldAbsZ = 0; 00054 00055 WidgetManager::getInstance().registerUnlinker(this); 00056 Gui::getInstance().eventFrameStart += newDelegate(this, &InputManager::frameEntered); 00057 00058 MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully initialized"); 00059 mIsInitialise = true; 00060 } 00061 00062 void InputManager::shutdown() 00063 { 00064 if (!mIsInitialise) return; 00065 MYGUI_LOG(Info, "* Shutdown: " << INSTANCE_TYPE_NAME); 00066 00067 Gui::getInstance().eventFrameStart -= newDelegate(this, &InputManager::frameEntered); 00068 WidgetManager::getInstance().unregisterUnlinker(this); 00069 00070 MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully shutdown"); 00071 mIsInitialise = false; 00072 } 00073 00074 bool InputManager::injectMouseMove(int _absx, int _absy, int _absz) 00075 { 00076 // запоминаем позицию 00077 mMousePosition.set(_absx, _absy); 00078 00079 // вычисляем прирост по колеса 00080 int relz = _absz - mOldAbsZ; 00081 mOldAbsZ = _absz; 00082 00083 // проверка на скролл 00084 if (relz != 0) 00085 { 00086 bool isFocus = isFocusMouse(); 00087 if (mWidgetMouseFocus != nullptr) mWidgetMouseFocus->onMouseWheel(relz); 00088 return isFocus; 00089 } 00090 00091 if (mIsWidgetMouseCapture) 00092 { 00093 if (mWidgetMouseFocus != nullptr) 00094 { 00095 if (mLayerMouseFocus != nullptr) 00096 { 00097 IntPoint point = mLayerMouseFocus->getPosition(_absx, _absy); 00098 mWidgetMouseFocus->onMouseDrag(point.left, point.top); 00099 } 00100 } 00101 else 00102 mIsWidgetMouseCapture = false; 00103 return true; 00104 } 00105 00106 Widget* old_mouse_focus = mWidgetMouseFocus; 00107 00108 // ищем активное окно 00109 Widget* item = LayerManager::getInstance().getWidgetFromPoint(_absx, _absy); 00110 00111 // ничего не изменилось 00112 if (mWidgetMouseFocus == item) 00113 { 00114 bool isFocus = isFocusMouse(); 00115 if (mWidgetMouseFocus != nullptr) 00116 { 00117 if (mLayerMouseFocus != nullptr) 00118 { 00119 IntPoint point = mLayerMouseFocus->getPosition(_absx, _absy); 00120 mWidgetMouseFocus->onMouseMove(_absx, _absy); 00121 } 00122 } 00123 return isFocus; 00124 } 00125 00126 if (item) 00127 { 00128 // поднимаемся до рута 00129 Widget* root = item; 00130 while (root->getParent()) root = root->getParent(); 00131 00132 // проверяем на модальность 00133 if (!mVectorModalRootWidget.empty()) 00134 { 00135 if (root != mVectorModalRootWidget.back()) 00136 { 00137 item = nullptr; 00138 } 00139 } 00140 00141 if (item != nullptr) 00142 { 00143 mLayerMouseFocus = root->getLayer(); 00144 } 00145 } 00146 00147 // в методе может пропасть наш виджет 00148 WidgetManager::getInstance().addWidgetToUnlink(item); 00149 00150 00151 //-------------------------------------------------------------------------------------// 00152 // новый вид рутового фокуса мыши 00153 Widget* save_widget = nullptr; 00154 00155 // спускаемся по новому виджету и устанавливаем рутовый фокус 00156 Widget* root_focus = item; 00157 while (root_focus != nullptr) 00158 { 00159 if (root_focus->mRootMouseActive) 00160 { 00161 save_widget = root_focus; 00162 break; 00163 } 00164 root_focus->mRootMouseActive = true; 00165 00166 // в методе может пропасть наш виджет 00167 WidgetManager::getInstance().addWidgetToUnlink(root_focus); 00168 root_focus->onMouseChangeRootFocus(true); 00169 WidgetManager::getInstance().removeWidgetFromUnlink(root_focus); 00170 00171 if (root_focus) 00172 root_focus = root_focus->getParent(); 00173 } 00174 00175 // спускаемся по старому виджету и сбрасываем фокус 00176 root_focus = mWidgetMouseFocus; 00177 while (root_focus != nullptr) 00178 { 00179 if (root_focus == save_widget) 00180 { 00181 break; 00182 } 00183 root_focus->mRootMouseActive = false; 00184 00185 // в методе может пропасть наш виджет 00186 WidgetManager::getInstance().addWidgetToUnlink(root_focus); 00187 root_focus->onMouseChangeRootFocus(false); 00188 WidgetManager::getInstance().removeWidgetFromUnlink(root_focus); 00189 00190 if (root_focus) 00191 root_focus = root_focus->getParent(); 00192 } 00193 //-------------------------------------------------------------------------------------// 00194 00195 // смена фокуса, проверяем на доступность виджета 00196 if ((mWidgetMouseFocus != nullptr) && (mWidgetMouseFocus->isEnabled())) 00197 { 00198 mWidgetMouseFocus->onMouseLostFocus(item); 00199 } 00200 00201 WidgetManager::getInstance().removeWidgetFromUnlink(item); 00202 00203 00204 if ((item != nullptr) && (item->isEnabled())) 00205 { 00206 item->onMouseMove(_absx, _absy); 00207 item->onMouseSetFocus(mWidgetMouseFocus); 00208 } 00209 00210 // запоминаем текущее окно 00211 mWidgetMouseFocus = item; 00212 00213 if (old_mouse_focus != mWidgetMouseFocus) 00214 eventChangeMouseFocus(mWidgetMouseFocus); 00215 00216 return isFocusMouse(); 00217 } 00218 00219 bool InputManager::injectMousePress(int _absx, int _absy, MouseButton _id) 00220 { 00221 Widget* old_key_focus = mWidgetKeyFocus; 00222 00223 // если мы щелкнули не на гуй 00224 if (!isFocusMouse()) 00225 { 00226 resetKeyFocusWidget(); 00227 00228 if (old_key_focus != mWidgetKeyFocus) 00229 eventChangeKeyFocus(mWidgetKeyFocus); 00230 00231 return false; 00232 } 00233 00234 // если активный элемент заблокирован 00235 //FIXME 00236 if (!mWidgetMouseFocus->isEnabled()) 00237 return true; 00238 00239 // захватываем только по левой клавише и только если виджету надо 00240 if (MouseButton::Left == _id) 00241 { 00242 // захват окна 00243 mIsWidgetMouseCapture = true; 00244 // запоминаем место нажатия 00245 if (mLayerMouseFocus != nullptr) 00246 { 00247 IntPoint point = mLayerMouseFocus->getPosition(_absx, _absy); 00248 mLastLeftPressed = point; 00249 } 00250 } 00251 00252 // ищем вверх тот виджет который может принимать фокус 00253 Widget* item = mWidgetMouseFocus; 00254 while ((item != nullptr) && (!item->isNeedKeyFocus())) 00255 item = item->getParent(); 00256 00257 // устанавливаем перед вызовом т.к. возможно внутри ктонить поменяет фокус под себя 00258 setKeyFocusWidget(item); 00259 00260 if (mWidgetMouseFocus != nullptr) 00261 { 00262 mWidgetMouseFocus->onMouseButtonPressed(_absx, _absy, _id); 00263 00264 // после пресса может сброситься 00265 if (mWidgetMouseFocus) 00266 { 00267 // поднимаем виджет, надо подумать что делать если поменялся фокус клавы 00268 LayerManager::getInstance().upLayerItem(mWidgetMouseFocus); 00269 00270 // поднимаем пикинг Overlapped окон 00271 Widget* pick = mWidgetMouseFocus; 00272 do 00273 { 00274 // если оверлаппед, то поднимаем пикинг 00275 if (pick->getWidgetStyle() == WidgetStyle::Overlapped) 00276 { 00277 if (pick->getParent()) pick->getParent()->_forcePeek(pick); 00278 } 00279 00280 pick = pick->getParent(); 00281 } 00282 while (pick); 00283 } 00284 } 00285 00286 if (old_key_focus != mWidgetKeyFocus) 00287 eventChangeKeyFocus(mWidgetKeyFocus); 00288 00289 return true; 00290 } 00291 00292 bool InputManager::injectMouseRelease(int _absx, int _absy, MouseButton _id) 00293 { 00294 if (isFocusMouse()) 00295 { 00296 // если активный элемент заблокирован 00297 if (!mWidgetMouseFocus->isEnabled()) 00298 return true; 00299 00300 mWidgetMouseFocus->onMouseButtonReleased(_absx, _absy, _id); 00301 00302 if (mIsWidgetMouseCapture) 00303 { 00304 // сбрасываем захват 00305 mIsWidgetMouseCapture = false; 00306 00307 // после вызова, виджет может быть сброшен 00308 if (nullptr != mWidgetMouseFocus) 00309 { 00310 if ((MouseButton::Left == _id) && mTimer.getMilliseconds() < INPUT_TIME_DOUBLE_CLICK) 00311 { 00312 mWidgetMouseFocus->onMouseButtonClick(); 00313 // после вызова, виджет может быть сброшен 00314 if (nullptr != mWidgetMouseFocus) mWidgetMouseFocus->onMouseButtonDoubleClick(); 00315 } 00316 else 00317 { 00318 // проверяем над тем ли мы окном сейчас что и были при нажатии 00319 Widget* item = LayerManager::getInstance().getWidgetFromPoint(_absx, _absy); 00320 if ( item == mWidgetMouseFocus) 00321 { 00322 mWidgetMouseFocus->onMouseButtonClick(); 00323 } 00324 mTimer.reset(); 00325 } 00326 } 00327 } 00328 00329 // для корректного отображения 00330 injectMouseMove(_absx, _absy, mOldAbsZ); 00331 00332 return true; 00333 } 00334 00335 return false; 00336 } 00337 00338 bool InputManager::injectKeyPress(KeyCode _key, Char _text) 00339 { 00340 // проверка на переключение языков 00341 firstEncoding(_key, true); 00342 00343 // запоминаем клавишу 00344 storeKey(_key, _text); 00345 00346 bool wasFocusKey = isFocusKey(); 00347 00348 //Pass keystrokes to the current active text widget 00349 if (isFocusKey()) 00350 { 00351 mWidgetKeyFocus->onKeyButtonPressed(_key, _text); 00352 } 00353 00354 return wasFocusKey; 00355 } 00356 00357 bool InputManager::injectKeyRelease(KeyCode _key) 00358 { 00359 // проверка на переключение языков 00360 firstEncoding(_key, false); 00361 00362 // сбрасываем клавишу 00363 resetKey(); 00364 00365 bool wasFocusKey = isFocusKey(); 00366 00367 if (isFocusKey()) mWidgetKeyFocus->onKeyButtonReleased(_key); 00368 00369 return wasFocusKey; 00370 } 00371 00372 void InputManager::firstEncoding(KeyCode _key, bool bIsKeyPressed) 00373 { 00374 if ((_key == KeyCode::LeftShift) || (_key == KeyCode::RightShift)) 00375 mIsShiftPressed = bIsKeyPressed; 00376 if ((_key == KeyCode::LeftControl) || (_key == KeyCode::RightControl)) 00377 mIsControlPressed = bIsKeyPressed; 00378 } 00379 00380 void InputManager::setKeyFocusWidget(Widget* _widget) 00381 { 00382 if (_widget == mWidgetKeyFocus) 00383 return; 00384 00385 //-------------------------------------------------------------------------------------// 00386 // новый вид рутового фокуса 00387 Widget* save_widget = nullptr; 00388 00389 // спускаемся по новому виджету и устанавливаем рутовый фокус 00390 Widget* root_focus = _widget; 00391 while (root_focus != nullptr) 00392 { 00393 if (root_focus->mRootKeyActive) 00394 { 00395 save_widget = root_focus; 00396 break; 00397 } 00398 root_focus->mRootKeyActive = true; 00399 00400 // в методе может пропасть наш виджет 00401 WidgetManager::getInstance().addWidgetToUnlink(root_focus); 00402 root_focus->onKeyChangeRootFocus(true); 00403 WidgetManager::getInstance().removeWidgetFromUnlink(root_focus); 00404 00405 if (root_focus) 00406 root_focus = root_focus->getParent(); 00407 } 00408 00409 // спускаемся по старому виджету и сбрасываем фокус 00410 root_focus = mWidgetKeyFocus; 00411 while (root_focus != nullptr) 00412 { 00413 if (root_focus == save_widget) 00414 { 00415 break; 00416 } 00417 root_focus->mRootKeyActive = false; 00418 00419 // в методе может пропасть наш виджет 00420 WidgetManager::getInstance().addWidgetToUnlink(root_focus); 00421 root_focus->onKeyChangeRootFocus(false); 00422 WidgetManager::getInstance().removeWidgetFromUnlink(root_focus); 00423 00424 if (root_focus) 00425 root_focus = root_focus->getParent(); 00426 } 00427 //-------------------------------------------------------------------------------------// 00428 00429 // сбрасываем старый 00430 if (mWidgetKeyFocus) 00431 { 00432 mWidgetKeyFocus->onKeyLostFocus(_widget); 00433 } 00434 00435 // устанавливаем новый 00436 if (_widget && _widget->isNeedKeyFocus()) 00437 { 00438 _widget->onKeySetFocus(mWidgetKeyFocus); 00439 } 00440 00441 mWidgetKeyFocus = _widget; 00442 } 00443 00444 void InputManager::resetMouseFocusWidget() 00445 { 00446 // спускаемся по старому виджету и сбрасываем фокус 00447 Widget* root_focus = mWidgetMouseFocus; 00448 while (root_focus != nullptr) 00449 { 00450 root_focus->mRootMouseActive = false; 00451 00452 // в методе может пропасть наш виджет 00453 WidgetManager::getInstance().addWidgetToUnlink(root_focus); 00454 root_focus->onMouseChangeRootFocus(false); 00455 WidgetManager::getInstance().removeWidgetFromUnlink(root_focus); 00456 00457 if (root_focus) 00458 root_focus = root_focus->getParent(); 00459 } 00460 00461 mIsWidgetMouseCapture = false; 00462 if (nullptr != mWidgetMouseFocus) 00463 { 00464 mWidgetMouseFocus->onMouseLostFocus(nullptr); 00465 mWidgetMouseFocus = nullptr; 00466 } 00467 00468 } 00469 00470 // удаляем данный виджет из всех возможных мест 00471 void InputManager::_unlinkWidget(Widget* _widget) 00472 { 00473 if (nullptr == _widget) return; 00474 if (_widget == mWidgetMouseFocus) 00475 { 00476 mIsWidgetMouseCapture = false; 00477 mWidgetMouseFocus = nullptr; 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 00496 void InputManager::addWidgetModal(Widget* _widget) 00497 { 00498 if (nullptr == _widget) 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 if ( mHoldKey == KeyCode::None) 00556 return; 00557 00558 if ( !isFocusKey() ) 00559 { 00560 mHoldKey = KeyCode::None; 00561 mHoldChar = 0; 00562 return; 00563 } 00564 00565 mTimerKey += _frame; 00566 00567 if (mFirstPressKey) 00568 { 00569 if (mTimerKey > INPUT_DELAY_FIRST_KEY) 00570 { 00571 mFirstPressKey = false; 00572 mTimerKey = 0.0f; 00573 } 00574 } 00575 else 00576 { 00577 if (mTimerKey > INPUT_INTERVAL_KEY) 00578 { 00579 while (mTimerKey > INPUT_INTERVAL_KEY) mTimerKey -= INPUT_INTERVAL_KEY; 00580 mWidgetKeyFocus->onKeyButtonPressed(mHoldKey, mHoldChar); 00581 // focus can be dropped in onKeyButtonPressed 00582 if ( isFocusKey() ) mWidgetKeyFocus->onKeyButtonReleased(mHoldKey); 00583 } 00584 } 00585 00586 } 00587 00588 void InputManager::resetKeyFocusWidget(Widget* _widget) 00589 { 00590 if (mWidgetKeyFocus == _widget) 00591 setKeyFocusWidget(nullptr); 00592 } 00593 00594 IntPoint InputManager::getMousePositionByLayer() 00595 { 00596 if (mLayerMouseFocus != nullptr) 00597 return mLayerMouseFocus->getPosition(mMousePosition.left, mMousePosition.top); 00598 return mMousePosition; 00599 } 00600 00601 } // namespace MyGUI