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_Message.h" 00025 #include "MyGUI_ResourceSkin.h" 00026 #include "MyGUI_WidgetManager.h" 00027 #include "MyGUI_LayerManager.h" 00028 #include "MyGUI_InputManager.h" 00029 #include "MyGUI_ResourceManager.h" 00030 #include "MyGUI_Gui.h" 00031 #include "MyGUI_ControllerManager.h" 00032 #include "MyGUI_StaticImage.h" 00033 #include "MyGUI_LanguageManager.h" 00034 00035 namespace MyGUI 00036 { 00037 00038 const float MESSAGE_ALPHA_MAX = 0.5f; 00039 const float MESSAGE_ALPHA_MIN = 0.0f; 00040 const float MESSAGE_SPEED_COEF = 3.0f; 00041 00042 Message::Message() : 00043 mWidgetText(nullptr), 00044 mInfoOk(MessageBoxStyle::None), 00045 mInfoCancel(MessageBoxStyle::None), 00046 mSmoothShow(false), 00047 mWidgetFade(nullptr), 00048 mIcon(nullptr), 00049 mLeftOffset1(0), 00050 mLeftOffset2(0) 00051 { 00052 } 00053 00054 void Message::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name) 00055 { 00056 Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name); 00057 00058 initialiseWidgetSkin(_info); 00059 } 00060 00061 Message::~Message() 00062 { 00063 shutdownWidgetSkin(); 00064 } 00065 00066 void Message::baseChangeWidgetSkin(ResourceSkin* _info) 00067 { 00068 shutdownWidgetSkin(); 00069 Base::baseChangeWidgetSkin(_info); 00070 initialiseWidgetSkin(_info); 00071 } 00072 00073 void Message::initialiseWidgetSkin(ResourceSkin* _info) 00074 { 00075 // парсим виджет для текста 00076 for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter) 00077 { 00078 if (*(*iter)->_getInternalData<std::string>() == "Text") 00079 { 00080 MYGUI_DEBUG_ASSERT( ! mWidgetText, "widget already assigned"); 00081 mWidgetText = (*iter); 00082 mOffsetText.set(mCoord.width - mWidgetText->getWidth(), mCoord.height - mWidgetText->getHeight()); 00083 mLeftOffset2 = mLeftOffset1 = mWidgetText->getLeft(); 00084 } 00085 else if (*(*iter)->_getInternalData<std::string>() == "Icon") 00086 { 00087 MYGUI_DEBUG_ASSERT( ! mIcon, "widget already assigned"); 00088 mIcon = (*iter)->castType<StaticImage>(); 00089 } 00090 } 00091 //MYGUI_ASSERT(nullptr != mWidgetText, "Child Text not found in skin (MessageBox must have widget for text)"); 00092 00093 if (mIcon != nullptr) 00094 { 00095 mLeftOffset2 = mIcon->getRight() + 3; 00096 } 00097 00098 // парсим свойства 00099 const MapString& properties = _info->getProperties(); 00100 if (!properties.empty()) 00101 { 00102 MapString::const_iterator iter = properties.find("ButtonSkin"); 00103 if (iter != properties.end()) mButtonSkin = iter->second; 00104 iter = properties.find("ButtonType"); 00105 if (iter != properties.end()) mButtonType = iter->second; 00106 iter = properties.find("ButtonSize"); 00107 if (iter != properties.end()) mButtonSize = IntSize::parse(iter->second); 00108 iter = properties.find("ButtonOffset"); 00109 if (iter != properties.end()) mButtonOffset = IntSize::parse(iter->second); 00110 iter = properties.find("DefaultLayer"); 00111 if (iter != properties.end()) mDefaultLayer = iter->second; 00112 iter = properties.find("FadeSkin"); 00113 if (iter != properties.end()) mFadeSkin = iter->second; 00114 iter = properties.find("FadeLayer"); 00115 if (iter != properties.end()) mFadeLayer = iter->second; 00116 } 00117 00118 } 00119 00120 void Message::shutdownWidgetSkin() 00121 { 00122 mWidgetText = nullptr; 00123 mIcon = nullptr; 00124 } 00125 00126 void Message::setMessageText(const UString& _message) 00127 { 00128 if (mWidgetText != nullptr) 00129 mWidgetText->setCaption(_message); 00130 updateSize(); 00131 } 00132 00133 MessageBoxStyle Message::addButtonName(const UString& _name) 00134 { 00135 //FIXME 00136 if (mVectorButton.size() >= MessageBoxStyle::_CountUserButtons) 00137 { 00138 MYGUI_LOG(Warning, "Too many buttons in message box, ignored"); 00139 return MessageBoxStyle::None; 00140 } 00141 // бит, номер кнопки + смещение до Button1 00142 MessageBoxStyle info = MessageBoxStyle(MessageBoxStyle::Enum(MYGUI_FLAG(mVectorButton.size() + MessageBoxStyle::_IndexUserButton1))); 00143 00144 // запоминаем кнопки для отмены и подтверждения 00145 if (mVectorButton.empty()) mInfoOk = info; 00146 mInfoCancel = info; 00147 00148 Widget* button = createWidgetT(mButtonType, mButtonSkin, IntCoord(), Align::Left | Align::Bottom); 00149 button->eventMouseButtonClick = newDelegate(this, &Message::notifyButtonClick); 00150 button->setCaption(_name); 00151 button->_setInternalData(info); 00152 mVectorButton.push_back(button); 00153 00154 updateSize(); 00155 return info; 00156 } 00157 00158 void Message::setMessageIcon(MessageBoxStyle _icon) 00159 { 00160 if (nullptr == mIcon) return; 00161 if (mIcon->getItemResource() != nullptr) 00162 { 00163 mIcon->setItemName( getIconName(_icon.getIconIndex()) ); 00164 } 00165 else 00166 { 00167 mIcon->setImageIndex(_icon.getIconIndex()); 00168 } 00169 00170 updateSize(); 00171 } 00172 00173 void Message::setMessageButton(MessageBoxStyle _info) 00174 { 00175 clearButton(); 00176 00177 std::vector<MessageBoxStyle> buttons = _info.getButtons(); 00178 00179 for (size_t index=0; index<buttons.size(); ++index) 00180 { 00181 // корректируем ее номер 00182 MessageBoxStyle info = buttons[index]; 00183 00184 // если бит есть то ставим кнопку 00185 addButtonName(getButtonName(info)); 00186 00187 // внутри адд сбрасывается 00188 mVectorButton.back()->_setInternalData(info); 00189 00190 // первая кнопка 00191 if (mVectorButton.size() == 1) mInfoOk = info; 00192 // последняя кнопка 00193 mInfoCancel = info; 00194 } 00195 00196 updateSize(); 00197 } 00198 00199 void Message::setMessageStyle(MessageBoxStyle _style) 00200 { 00201 setMessageButton(_style); 00202 setMessageIcon(_style); 00203 } 00204 00205 void Message::notifyButtonClick(MyGUI::Widget* _sender) 00206 { 00207 _destroyMessage(*_sender->_getInternalData<MessageBoxStyle>()); 00208 } 00209 00210 void Message::clearButton() 00211 { 00212 for (VectorWidgetPtr::iterator iter=mVectorButton.begin(); iter!=mVectorButton.end(); ++iter) 00213 { 00214 WidgetManager::getInstance().destroyWidget(*iter); 00215 } 00216 mVectorButton.clear(); 00217 } 00218 00219 void Message::onKeyButtonPressed(KeyCode _key, Char _char) 00220 { 00221 Base::onKeyButtonPressed(_key, _char); 00222 if ((_key == KeyCode::Return) || (_key == KeyCode::NumpadEnter)) _destroyMessage(mInfoOk); 00223 else if (_key == KeyCode::Escape) _destroyMessage(mInfoCancel); 00224 } 00225 00226 void Message::_destroyMessage(MessageBoxStyle _result) 00227 { 00228 eventMessageBoxResult(this, _result); 00229 if (nullptr != mWidgetFade) 00230 { 00231 if (mSmoothShow) 00232 { 00233 ControllerFadeAlpha* controller = createControllerFadeAlpha(MESSAGE_ALPHA_MIN, MESSAGE_SPEED_COEF, false); 00234 controller->eventPostAction = newDelegate(action::actionWidgetDestroy); 00235 ControllerManager::getInstance().addItem(mWidgetFade, controller); 00236 } 00237 else 00238 { 00239 WidgetManager::getInstance().destroyWidget(mWidgetFade); 00240 } 00241 } 00242 if (mSmoothShow) destroySmooth(); 00243 else WidgetManager::getInstance().destroyWidget(this); 00244 } 00245 00246 void Message::setSmoothShow(bool _smooth) 00247 { 00248 mSmoothShow = _smooth; 00249 if (mSmoothShow) 00250 { 00251 setAlpha(ALPHA_MIN); 00252 setVisible(true); 00253 setVisibleSmooth(true); 00254 } 00255 } 00256 00257 void Message::setWindowFade(bool _fade) 00258 { 00259 return; //пока пропустим 00260 00261 if (_fade) 00262 { 00263 if (nullptr == mWidgetFade) 00264 { 00265 Gui& gui = Gui::getInstance(); 00266 mWidgetFade = gui.createWidgetT(Widget::getClassTypeName(), mFadeSkin, IntCoord(0, 0, gui.getViewSize().width, gui.getViewSize().height), Align::Stretch, mFadeLayer); 00267 if (mSmoothShow) 00268 { 00269 mWidgetFade->setVisible(false); 00270 00271 ControllerFadeAlpha* controller = createControllerFadeAlpha(MESSAGE_ALPHA_MAX, MESSAGE_SPEED_COEF, false); 00272 ControllerManager::getInstance().addItem(mWidgetFade, controller); 00273 } 00274 else 00275 { 00276 mWidgetFade->setAlpha(MESSAGE_ALPHA_MAX); 00277 } 00278 } 00279 } 00280 else 00281 { 00282 if (nullptr != mWidgetFade) 00283 { 00284 WidgetManager::getInstance().destroyWidget(mWidgetFade); 00285 mWidgetFade = nullptr; 00286 } 00287 } 00288 } 00289 00290 const char * Message::getIconName(size_t _index) 00291 { 00292 static const size_t CountIcons = 4; 00293 static const char * IconNames[CountIcons + 1] = { "Info", "Quest", "Error", "Warning", "" }; 00294 if (_index >= CountIcons) return IconNames[CountIcons]; 00295 return IconNames[_index]; 00296 } 00297 00298 MyGUI::Message* Message::createMessageBox( 00299 const std::string& _skin, 00300 const UString& _caption, 00301 const UString& _message, 00302 MessageBoxStyle _style, 00303 const std::string& _layer, 00304 bool _modal, 00305 const std::string& _button1, 00306 const std::string& _button2, 00307 const std::string& _button3, 00308 const std::string& _button4) 00309 { 00310 Message* mess = Gui::getInstance().createWidget<Message>(_skin, IntCoord(), Align::Default, _layer); 00311 00312 mess->setCaption(_caption); 00313 mess->setMessageText(_message); 00314 00315 mess->setSmoothShow(true); 00316 if (_modal) mess->setWindowFade(true); 00317 00318 mess->setMessageStyle(_style); 00319 00320 if (!_button1.empty()) 00321 { 00322 mess->addButtonName(_button1); 00323 if (!_button2.empty()) 00324 { 00325 mess->addButtonName(_button2); 00326 if (!_button3.empty()) 00327 { 00328 mess->addButtonName(_button3); 00329 } 00330 } 00331 } 00332 00333 if (_layer.empty()) LayerManager::getInstance().attachToLayerNode(mess->getDefaultLayer(), mess); 00334 if (_modal) InputManager::getInstance().addWidgetModal(mess); 00335 00336 return mess; 00337 } 00338 00339 void Message::updateSize() 00340 { 00341 ISubWidgetText* text = nullptr; 00342 if (mWidgetText != nullptr) 00343 text = mWidgetText->getSubWidgetText(); 00344 IntSize size = text == nullptr ? IntSize() : text->getTextSize(); 00345 // минимум высота иконки 00346 if ((nullptr != mIcon) && (mIcon->getImageIndex() != ITEM_NONE)) 00347 { 00348 if (size.height < mIcon->getHeight()) size.height = mIcon->getHeight(); 00349 size.width += mIcon->getSize().width; 00350 } 00351 size += mOffsetText; 00352 size.width += 3; 00353 00354 int width = ((int)mVectorButton.size() * mButtonSize.width) + (((int)mVectorButton.size()+1) * mButtonOffset.width); 00355 if (size.width < width) size.width = width; 00356 00357 int offset = (size.width - width)/2; 00358 offset += mButtonOffset.width; 00359 00360 const IntSize& view = Gui::getInstance().getViewSize(); 00361 setCoord((view.width-size.width)/2, (view.height-size.height)/2, size.width, size.height); 00362 00363 if (nullptr != mIcon) 00364 { 00365 if (mWidgetText != nullptr) 00366 { 00367 if (mIcon->getImageIndex() != ITEM_NONE) mWidgetText->setCoord(mLeftOffset2, mWidgetText->getTop(), mWidgetText->getWidth(), mWidgetText->getHeight()); 00368 else mWidgetText->setCoord(mLeftOffset1, mWidgetText->getTop(), mWidgetText->getWidth(), mWidgetText->getHeight()); 00369 } 00370 } 00371 00372 for (VectorWidgetPtr::iterator iter=mVectorButton.begin(); iter!=mVectorButton.end(); ++iter) 00373 { 00374 (*iter)->setCoord(offset, mCoord.height - mButtonOffset.height, mButtonSize.width, mButtonSize.height); 00375 offset += mButtonOffset.width + mButtonSize.width; 00376 } 00377 } 00378 00379 ControllerFadeAlpha* Message::createControllerFadeAlpha(float _alpha, float _coef, bool _enable) 00380 { 00381 ControllerItem* item = ControllerManager::getInstance().createItem(ControllerFadeAlpha::getClassTypeName()); 00382 ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>(); 00383 00384 controller->setAlpha(_alpha); 00385 controller->setCoef(_coef); 00386 controller->setEnabled(_enable); 00387 00388 return controller; 00389 } 00390 00391 void Message::setMessageModal(bool _value) 00392 { 00393 if (_value) InputManager::getInstance().addWidgetModal(this); 00394 else InputManager::getInstance().removeWidgetModal(this); 00395 } 00396 00397 UString Message::getButtonName(MessageBoxStyle _style) 00398 { 00399 size_t index = _style.getButtonIndex(); 00400 const char* tag = getButtonTag(index); 00401 UString result = LanguageManager::getInstance().replaceTags(utility::toString("#{", tag, "}")); 00402 if (result == tag) return getButtonName(index); 00403 return result; 00404 } 00405 00406 const char * Message::getButtonName(size_t _index) 00407 { 00408 static const size_t Count = 9; 00409 static const char * Names[Count + 1] = { "Ok", "Yes", "No", "Abort", "Retry", "Ignore", "Cancel", "Try", "Continue", "" }; 00410 if (_index >= Count) return Names[Count]; 00411 return Names[_index]; 00412 } 00413 00414 const char * Message::getButtonTag(size_t _index) 00415 { 00416 static const size_t Count = 9; 00417 static const char * Names[Count + 1] = { "MyGUI_MessageBox_Ok", "MyGUI_MessageBox_Yes", "MyGUI_MessageBox_No", "MyGUI_MessageBox_Abort", "MyGUI_MessageBox_Retry", "MyGUI_MessageBox_Ignore", "MyGUI_MessageBox_Cancel", "MyGUI_MessageBox_Try", "MyGUI_MessageBox_Continue", "" }; 00418 if (_index >= Count) return Names[Count]; 00419 return Names[_index]; 00420 } 00421 00422 void Message::endMessage(MessageBoxStyle _result) 00423 { 00424 _destroyMessage(_result); 00425 } 00426 00427 void Message::endMessage() 00428 { 00429 _destroyMessage(mInfoCancel); 00430 } 00431 00432 void Message::setProperty(const std::string& _key, const std::string& _value) 00433 { 00434 if (_key == "Message_Caption") setCaption(_value); 00435 else if (_key == "Message_Message") setMessageText(_value); 00436 else if (_key == "Message_Modal") setMessageModal(utility::parseValue<bool>(_value)); 00437 else if (_key == "Message_Button") setMessageButton(utility::parseValue<MessageBoxStyle>(_value)); 00438 else if (_key == "Message_AddButton") addButtonName(_value); 00439 else if (_key == "Message_SmoothShow") setSmoothShow(utility::parseValue<bool>(_value)); 00440 else if (_key == "Message_Fade") setWindowFade(utility::parseValue<bool>(_value)); 00441 else 00442 { 00443 Base::setProperty(_key, _value); 00444 return; 00445 } 00446 eventChangeProperty(this, _key, _value); 00447 } 00448 00449 } // namespace MyGUI