MyGUI  3.0.1
MyGUI_Message.cpp
Go to the documentation of this file.
1 
7 /*
8  This file is part of MyGUI.
9 
10  MyGUI is free software: you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  MyGUI is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
22 */
23 #include "MyGUI_Precompiled.h"
24 #include "MyGUI_Message.h"
25 #include "MyGUI_ResourceSkin.h"
26 #include "MyGUI_WidgetManager.h"
27 #include "MyGUI_LayerManager.h"
28 #include "MyGUI_InputManager.h"
29 #include "MyGUI_ResourceManager.h"
30 #include "MyGUI_Gui.h"
32 #include "MyGUI_StaticImage.h"
33 #include "MyGUI_LanguageManager.h"
34 
35 namespace MyGUI
36 {
37 
38  const float MESSAGE_ALPHA_MAX = 0.5f;
39  const float MESSAGE_ALPHA_MIN = 0.0f;
40  const float MESSAGE_SPEED_COEF = 3.0f;
41 
43  mWidgetText(nullptr),
44  mInfoOk(MessageBoxStyle::None),
45  mInfoCancel(MessageBoxStyle::None),
46  mSmoothShow(false),
47  mWidgetFade(nullptr),
48  mIcon(nullptr),
49  mLeftOffset1(0),
50  mLeftOffset2(0)
51  {
52  }
53 
54  void Message::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
55  {
56  Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
57 
58  initialiseWidgetSkin(_info);
59  }
60 
62  {
63  shutdownWidgetSkin();
64  }
65 
67  {
68  shutdownWidgetSkin();
70  initialiseWidgetSkin(_info);
71  }
72 
73  void Message::initialiseWidgetSkin(ResourceSkin* _info)
74  {
75  // парсим виджет для текста
76  for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter)
77  {
78  if (*(*iter)->_getInternalData<std::string>() == "Text")
79  {
80  MYGUI_DEBUG_ASSERT( ! mWidgetText, "widget already assigned");
81  mWidgetText = (*iter);
82  mOffsetText.set(mCoord.width - mWidgetText->getWidth(), mCoord.height - mWidgetText->getHeight());
83  mLeftOffset2 = mLeftOffset1 = mWidgetText->getLeft();
84  }
85  else if (*(*iter)->_getInternalData<std::string>() == "Icon")
86  {
87  MYGUI_DEBUG_ASSERT( ! mIcon, "widget already assigned");
88  mIcon = (*iter)->castType<StaticImage>();
89  }
90  }
91  //MYGUI_ASSERT(nullptr != mWidgetText, "Child Text not found in skin (MessageBox must have widget for text)");
92 
93  if (mIcon != nullptr)
94  {
95  mLeftOffset2 = mIcon->getRight() + 3;
96  }
97 
98  // парсим свойства
99  const MapString& properties = _info->getProperties();
100  if (!properties.empty())
101  {
102  MapString::const_iterator iter = properties.find("ButtonSkin");
103  if (iter != properties.end()) mButtonSkin = iter->second;
104  iter = properties.find("ButtonType");
105  if (iter != properties.end()) mButtonType = iter->second;
106  iter = properties.find("ButtonSize");
107  if (iter != properties.end()) mButtonSize = IntSize::parse(iter->second);
108  iter = properties.find("ButtonOffset");
109  if (iter != properties.end()) mButtonOffset = IntSize::parse(iter->second);
110  iter = properties.find("DefaultLayer");
111  if (iter != properties.end()) mDefaultLayer = iter->second;
112  iter = properties.find("FadeSkin");
113  if (iter != properties.end()) mFadeSkin = iter->second;
114  iter = properties.find("FadeLayer");
115  if (iter != properties.end()) mFadeLayer = iter->second;
116  }
117 
118  }
119 
120  void Message::shutdownWidgetSkin()
121  {
122  mWidgetText = nullptr;
123  mIcon = nullptr;
124  }
125 
126  void Message::setMessageText(const UString& _message)
127  {
128  if (mWidgetText != nullptr)
129  mWidgetText->setCaption(_message);
130  updateSize();
131  }
132 
134  {
135  //FIXME
136  if (mVectorButton.size() >= MessageBoxStyle::_CountUserButtons)
137  {
138  MYGUI_LOG(Warning, "Too many buttons in message box, ignored");
139  return MessageBoxStyle::None;
140  }
141  // бит, номер кнопки + смещение до Button1
143 
144  // запоминаем кнопки для отмены и подтверждения
145  if (mVectorButton.empty()) mInfoOk = info;
146  mInfoCancel = info;
147 
148  Widget* button = createWidgetT(mButtonType, mButtonSkin, IntCoord(), Align::Left | Align::Bottom);
150  button->setCaption(_name);
151  button->_setInternalData(info);
152  mVectorButton.push_back(button);
153 
154  updateSize();
155  return info;
156  }
157 
159  {
160  if (nullptr == mIcon) return;
161  if (mIcon->getItemResource() != nullptr)
162  {
163  mIcon->setItemName( getIconName(_icon.getIconIndex()) );
164  }
165  else
166  {
167  mIcon->setImageIndex(_icon.getIconIndex());
168  }
169 
170  updateSize();
171  }
172 
174  {
175  clearButton();
176 
177  std::vector<MessageBoxStyle> buttons = _info.getButtons();
178 
179  for (size_t index=0; index<buttons.size(); ++index)
180  {
181  // корректируем ее номер
182  MessageBoxStyle info = buttons[index];
183 
184  // если бит есть то ставим кнопку
186 
187  // внутри адд сбрасывается
188  mVectorButton.back()->_setInternalData(info);
189 
190  // первая кнопка
191  if (mVectorButton.size() == 1) mInfoOk = info;
192  // последняя кнопка
193  mInfoCancel = info;
194  }
195 
196  updateSize();
197  }
198 
200  {
201  setMessageButton(_style);
202  setMessageIcon(_style);
203  }
204 
206  {
208  }
209 
211  {
212  for (VectorWidgetPtr::iterator iter=mVectorButton.begin(); iter!=mVectorButton.end(); ++iter)
213  {
215  }
216  mVectorButton.clear();
217  }
218 
220  {
221  Base::onKeyButtonPressed(_key, _char);
222  if ((_key == KeyCode::Return) || (_key == KeyCode::NumpadEnter)) _destroyMessage(mInfoOk);
223  else if (_key == KeyCode::Escape) _destroyMessage(mInfoCancel);
224  }
225 
227  {
228  eventMessageBoxResult(this, _result);
229  if (nullptr != mWidgetFade)
230  {
231  if (mSmoothShow)
232  {
233  ControllerFadeAlpha* controller = createControllerFadeAlpha(MESSAGE_ALPHA_MIN, MESSAGE_SPEED_COEF, false);
235  ControllerManager::getInstance().addItem(mWidgetFade, controller);
236  }
237  else
238  {
240  }
241  }
242  if (mSmoothShow) destroySmooth();
244  }
245 
246  void Message::setSmoothShow(bool _smooth)
247  {
248  mSmoothShow = _smooth;
249  if (mSmoothShow)
250  {
252  setVisible(true);
253  setVisibleSmooth(true);
254  }
255  }
256 
257  void Message::setWindowFade(bool _fade)
258  {
259  return; //пока пропустим
260 
261  if (_fade)
262  {
263  if (nullptr == mWidgetFade)
264  {
265  Gui& gui = Gui::getInstance();
266  mWidgetFade = gui.createWidgetT(Widget::getClassTypeName(), mFadeSkin, IntCoord(0, 0, gui.getViewSize().width, gui.getViewSize().height), Align::Stretch, mFadeLayer);
267  if (mSmoothShow)
268  {
269  mWidgetFade->setVisible(false);
270 
271  ControllerFadeAlpha* controller = createControllerFadeAlpha(MESSAGE_ALPHA_MAX, MESSAGE_SPEED_COEF, false);
272  ControllerManager::getInstance().addItem(mWidgetFade, controller);
273  }
274  else
275  {
276  mWidgetFade->setAlpha(MESSAGE_ALPHA_MAX);
277  }
278  }
279  }
280  else
281  {
282  if (nullptr != mWidgetFade)
283  {
285  mWidgetFade = nullptr;
286  }
287  }
288  }
289 
290  const char * Message::getIconName(size_t _index)
291  {
292  static const size_t CountIcons = 4;
293  static const char * IconNames[CountIcons + 1] = { "Info", "Quest", "Error", "Warning", "" };
294  if (_index >= CountIcons) return IconNames[CountIcons];
295  return IconNames[_index];
296  }
297 
299  const std::string& _skin,
300  const UString& _caption,
301  const UString& _message,
302  MessageBoxStyle _style,
303  const std::string& _layer,
304  bool _modal,
305  const std::string& _button1,
306  const std::string& _button2,
307  const std::string& _button3,
308  const std::string& _button4)
309  {
310  Message* mess = Gui::getInstance().createWidget<Message>(_skin, IntCoord(), Align::Default, _layer);
311 
312  mess->setCaption(_caption);
313  mess->setMessageText(_message);
314 
315  mess->setSmoothShow(true);
316  if (_modal) mess->setWindowFade(true);
317 
318  mess->setMessageStyle(_style);
319 
320  if (!_button1.empty())
321  {
322  mess->addButtonName(_button1);
323  if (!_button2.empty())
324  {
325  mess->addButtonName(_button2);
326  if (!_button3.empty())
327  {
328  mess->addButtonName(_button3);
329  }
330  }
331  }
332 
333  if (_layer.empty()) LayerManager::getInstance().attachToLayerNode(mess->getDefaultLayer(), mess);
334  if (_modal) InputManager::getInstance().addWidgetModal(mess);
335 
336  return mess;
337  }
338 
340  {
341  ISubWidgetText* text = nullptr;
342  if (mWidgetText != nullptr)
343  text = mWidgetText->getSubWidgetText();
344  IntSize size = text == nullptr ? IntSize() : text->getTextSize();
345  // минимум высота иконки
346  if ((nullptr != mIcon) && (mIcon->getImageIndex() != ITEM_NONE))
347  {
348  if (size.height < mIcon->getHeight()) size.height = mIcon->getHeight();
349  size.width += mIcon->getSize().width;
350  }
351  size += mOffsetText;
352  size.width += 3;
353 
354  int width = ((int)mVectorButton.size() * mButtonSize.width) + (((int)mVectorButton.size()+1) * mButtonOffset.width);
355  if (size.width < width) size.width = width;
356 
357  int offset = (size.width - width)/2;
358  offset += mButtonOffset.width;
359 
360  const IntSize& view = Gui::getInstance().getViewSize();
361  setCoord((view.width-size.width)/2, (view.height-size.height)/2, size.width, size.height);
362 
363  if (nullptr != mIcon)
364  {
365  if (mWidgetText != nullptr)
366  {
367  if (mIcon->getImageIndex() != ITEM_NONE) mWidgetText->setCoord(mLeftOffset2, mWidgetText->getTop(), mWidgetText->getWidth(), mWidgetText->getHeight());
368  else mWidgetText->setCoord(mLeftOffset1, mWidgetText->getTop(), mWidgetText->getWidth(), mWidgetText->getHeight());
369  }
370  }
371 
372  for (VectorWidgetPtr::iterator iter=mVectorButton.begin(); iter!=mVectorButton.end(); ++iter)
373  {
374  (*iter)->setCoord(offset, mCoord.height - mButtonOffset.height, mButtonSize.width, mButtonSize.height);
375  offset += mButtonOffset.width + mButtonSize.width;
376  }
377  }
378 
379  ControllerFadeAlpha* Message::createControllerFadeAlpha(float _alpha, float _coef, bool _enable)
380  {
382  ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>();
383 
384  controller->setAlpha(_alpha);
385  controller->setCoef(_coef);
386  controller->setEnabled(_enable);
387 
388  return controller;
389  }
390 
391  void Message::setMessageModal(bool _value)
392  {
393  if (_value) InputManager::getInstance().addWidgetModal(this);
395  }
396 
398  {
399  size_t index = _style.getButtonIndex();
400  const char* tag = getButtonTag(index);
402  if (result == tag) return getButtonName(index);
403  return result;
404  }
405 
406  const char * Message::getButtonName(size_t _index)
407  {
408  static const size_t Count = 9;
409  static const char * Names[Count + 1] = { "Ok", "Yes", "No", "Abort", "Retry", "Ignore", "Cancel", "Try", "Continue", "" };
410  if (_index >= Count) return Names[Count];
411  return Names[_index];
412  }
413 
414  const char * Message::getButtonTag(size_t _index)
415  {
416  static const size_t Count = 9;
417  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", "" };
418  if (_index >= Count) return Names[Count];
419  return Names[_index];
420  }
421 
423  {
424  _destroyMessage(_result);
425  }
426 
428  {
429  _destroyMessage(mInfoCancel);
430  }
431 
432  void Message::setProperty(const std::string& _key, const std::string& _value)
433  {
434  if (_key == "Message_Caption") setCaption(_value);
435  else if (_key == "Message_Message") setMessageText(_value);
436  else if (_key == "Message_Modal") setMessageModal(utility::parseValue<bool>(_value));
437  else if (_key == "Message_Button") setMessageButton(utility::parseValue<MessageBoxStyle>(_value));
438  else if (_key == "Message_AddButton") addButtonName(_value);
439  else if (_key == "Message_SmoothShow") setSmoothShow(utility::parseValue<bool>(_value));
440  else if (_key == "Message_Fade") setWindowFade(utility::parseValue<bool>(_value));
441  else
442  {
443  Base::setProperty(_key, _value);
444  return;
445  }
446  eventChangeProperty(this, _key, _value);
447  }
448 
449 } // namespace MyGUI