MyGUI  3.0.1
MyGUI_Window.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_Window.h"
25 #include "MyGUI_Macros.h"
26 #include "MyGUI_Gui.h"
28 #include "MyGUI_InputManager.h"
29 #include "MyGUI_WidgetManager.h"
30 #include "MyGUI_ResourceSkin.h"
31 
32 namespace MyGUI
33 {
34 
36  const float WINDOW_ALPHA_FOCUS = 0.7f;
37  const float WINDOW_ALPHA_DEACTIVE = 0.3f;
38  const float WINDOW_SPEED_COEF = 3.0f;
39 
40  const int WINDOW_SNAP_DISTANSE = 10;
41 
43  mWidgetCaption(nullptr),
44  mMouseRootFocus(false),
45  mKeyRootFocus(false),
46  mIsAutoAlpha(false),
47  mSnap(false),
48  mAnimateSmooth(false)
49  {
50  }
51 
52  void Window::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
53  {
54  Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
55 
56  initialiseWidgetSkin(_info);
57  }
58 
60  {
61  shutdownWidgetSkin();
62  }
63 
65  {
66  shutdownWidgetSkin();
68  initialiseWidgetSkin(_info);
69  }
70 
71  void Window::initialiseWidgetSkin(ResourceSkin* _info)
72  {
73  // нам нужен фокус клавы
74  mNeedKeyFocus = true;
75 
76  // дефолтные размеры
77  mMinmax.set(0, 0, 3000, 3000);
78 
79  bool main_move = false;
80  // парсим свойства
81  const MapString& properties = _info->getProperties();
82  if (!properties.empty())
83  {
84  MapString::const_iterator iter = properties.find("Snap");
85  if (iter != properties.end()) mSnap = utility::parseBool(iter->second);
86  iter = properties.find("MainMove");
87  if (iter != properties.end())
88  {
89  setUserString("Scale", "1 1 0 0");
90  main_move = true;
91  }
92  }
93 
94  for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter)
95  {
96  if (*(*iter)->_getInternalData<std::string>() == "Client")
97  {
98  MYGUI_DEBUG_ASSERT( ! mWidgetClient, "widget already assigned");
99  mWidgetClient = (*iter);
100  if (main_move)
101  {
102  (*iter)->setUserString("Scale", "1 1 0 0");
103  (*iter)->eventMouseButtonPressed = newDelegate(this, &Window::notifyMousePressed);
104  (*iter)->eventMouseDrag = newDelegate(this, &Window::notifyMouseDrag);
105  }
106  }
107  else if (*(*iter)->_getInternalData<std::string>() == "Caption")
108  {
109  MYGUI_DEBUG_ASSERT( ! mWidgetCaption, "widget already assigned");
110  mWidgetCaption = (*iter);
112  mWidgetCaption->eventMouseDrag = newDelegate(this, &Window::notifyMouseDrag);
113  }
114  else if (*(*iter)->_getInternalData<std::string>() == "Button")
115  {
116  (*iter)->eventMouseButtonClick = newDelegate(this, &Window::notifyPressedButtonEvent);
117  }
118  else if (*(*iter)->_getInternalData<std::string>() == "Action")
119  {
120  (*iter)->eventMouseButtonPressed = newDelegate(this, &Window::notifyMousePressed);
121  (*iter)->eventMouseDrag = newDelegate(this, &Window::notifyMouseDrag);
122  }
123  }
124 
125  }
126 
127  void Window::shutdownWidgetSkin()
128  {
129  mWidgetClient = nullptr;
130  mWidgetCaption = nullptr;
131  }
132 
133  // переопределяем для присвоению клиенту
134  Widget* Window::baseCreateWidget(WidgetStyle _style, const std::string& _type, const std::string& _skin, const IntCoord& _coord, Align _align, const std::string& _layer, const std::string& _name)
135  {
136  MYGUI_ASSERT(mWidgetClient != this, "mWidgetClient can not be this widget");
137  if (mWidgetClient != nullptr) return mWidgetClient->createWidgetT(_style, _type, _skin, _coord, _align, _layer, _name);
138  return Base::baseCreateWidget(_style, _type, _skin, _coord, _align, _layer, _name);
139  }
140 
142  {
143  mMouseRootFocus = _focus;
144  updateAlpha();
145 
147  }
148 
150  {
151  mKeyRootFocus = _focus;
152  updateAlpha();
153 
155  }
156 
157  void Window::onMouseDrag(int _left, int _top)
158  {
159  // на тот случай, если двигать окно, можно за любое место виджета
160  notifyMouseDrag(this, _left, _top);
161 
162  Base::onMouseDrag(_left, _top);
163  }
164 
165  void Window::onMouseButtonPressed(int _left, int _top, MouseButton _id)
166  {
167  notifyMousePressed(this, _left, _top, _id);
168 
169  Base::onMouseButtonPressed(_left, _top, _id);
170  }
171 
172  void Window::notifyMousePressed(MyGUI::Widget* _sender, int _left, int _top, MouseButton _id)
173  {
174  if (MouseButton::Left == _id)
175  {
176  mPreActionCoord = mCoord;
177  mCurrentActionScale = IntCoord::parse(_sender->getUserString("Scale"));
178  }
179  }
180 
182  {
183  eventWindowButtonPressed(this, _sender->getUserString("Event"));
184  }
185 
186  void Window::notifyMouseDrag(MyGUI::Widget* _sender, int _left, int _top)
187  {
189 
190  IntCoord coord = mCurrentActionScale;
191  coord.left *= (_left - point.left);
192  coord.top *= (_top - point.top);
193  coord.width *= (_left - point.left);
194  coord.height *= (_top - point.top);
195 
196  if (coord.left == 0 && coord.top == 0)
197  setSize((mPreActionCoord + coord).size());
198  else if (coord.width == 0 && coord.height == 0)
199  setPosition((mPreActionCoord + coord).point());
200  else
201  setCoord(mPreActionCoord + coord);
202 
203  // посылаем событие о изменении позиции и размере
205  }
206 
208  {
209  if (!mIsAutoAlpha) return;
210 
211  float alpha;
212  if (mKeyRootFocus) alpha = WINDOW_ALPHA_ACTIVE;
213  else if (mMouseRootFocus) alpha = WINDOW_ALPHA_FOCUS;
214  else alpha = WINDOW_ALPHA_DEACTIVE;
215 
216  ControllerFadeAlpha * controller = createControllerFadeAlpha(alpha, WINDOW_SPEED_COEF, true);
217  ControllerManager::getInstance().addItem(this, controller);
218  }
219 
220  void Window::setAutoAlpha(bool _auto)
221  {
222  mIsAutoAlpha = _auto;
223  if (!_auto) setAlpha(ALPHA_MAX);
224  else
225  {
226  if (mKeyRootFocus) setAlpha(WINDOW_ALPHA_ACTIVE);
227  else if (mMouseRootFocus) setAlpha(WINDOW_ALPHA_FOCUS);
229  }
230  }
231 
232  void Window::setPosition(const IntPoint& _point)
233  {
234  IntPoint point = _point;
235  // прилепляем к краям
236  if (mSnap)
237  {
238  IntCoord coord(point, mCoord.size());
239  getSnappedCoord(coord);
240  point = coord.point();
241  }
242 
243  Base::setPosition(point);
244  }
245 
246  void Window::setSize(const IntSize& _size)
247  {
248  IntSize size = _size;
249  // прилепляем к краям
250 
251  if (size.width < mMinmax.left) size.width = mMinmax.left;
252  else if (size.width > mMinmax.right) size.width = mMinmax.right;
253  if (size.height < mMinmax.top) size.height = mMinmax.top;
254  else if (size.height > mMinmax.bottom) size.height = mMinmax.bottom;
255  if ((size.width == mCoord.width) && (size.height == mCoord.height) ) return;
256 
257  if (mSnap)
258  {
259  IntCoord coord(mCoord.point(), size);
260  getSnappedCoord(coord);
261  size = coord.size();
262  }
263 
264  Base::setSize(size);
265  }
266 
267  void Window::setCoord(const IntCoord& _coord)
268  {
269  IntPoint pos = _coord.point();
270  IntSize size = _coord.size();
271 
272  if (size.width < mMinmax.left)
273  {
274  int offset = mMinmax.left - size.width;
275  size.width = mMinmax.left;
276  if ((pos.left - mCoord.left) > offset) pos.left -= offset;
277  else pos.left = mCoord.left;
278  }
279  else if (size.width > mMinmax.right)
280  {
281  int offset = mMinmax.right - size.width;
282  size.width = mMinmax.right;
283  if ((pos.left - mCoord.left) < offset) pos.left -= offset;
284  else pos.left = mCoord.left;
285  }
286  if (size.height < mMinmax.top)
287  {
288  int offset = mMinmax.top - size.height;
289  size.height = mMinmax.top;
290  if ((pos.top - mCoord.top) > offset) pos.top -= offset;
291  else pos.top = mCoord.top;
292  }
293  else if (size.height > mMinmax.bottom)
294  {
295  int offset = mMinmax.bottom - size.height;
296  size.height = mMinmax.bottom;
297  if ((pos.top - mCoord.top) < offset) pos.top -= offset;
298  else pos.top = mCoord.top;
299  }
300 
301  // прилепляем к краям
302  if (mSnap)
303  {
304  IntCoord coord(pos, size);
305  getSnappedCoord(coord);
306  size = coord.size();
307  }
308 
309  IntCoord coord(pos, size);
310  if (coord == mCoord) return;
311 
312  Base::setCoord(coord);
313  }
314 
315  void Window::setCaption(const UString& _caption)
316  {
317  if (mWidgetCaption != nullptr) mWidgetCaption->setCaption(_caption);
318  else Base::setCaption(_caption);
319  }
320 
322  {
323  if (mWidgetCaption != nullptr) return mWidgetCaption->getCaption();
324  return Base::getCaption();
325  }
326 
328  {
329  ControllerFadeAlpha * controller = createControllerFadeAlpha(ALPHA_MIN, WINDOW_SPEED_COEF, false);
331  ControllerManager::getInstance().addItem(this, controller);
332  }
333 
335  {
336  if (mAnimateSmooth)
337  {
339  mAnimateSmooth = false;
340  }
341  }
342 
343  void Window::setVisible(bool _visible)
344  {
345 
346  if (mAnimateSmooth)
347  {
349  setAlpha(getAlphaVisible());
350  setEnabledSilent(true);
351  mAnimateSmooth = false;
352  }
353 
354  Base::setVisible(_visible);
355  }
356 
357  float Window::getAlphaVisible()
358  {
359  return (mIsAutoAlpha && !mKeyRootFocus) ? WINDOW_ALPHA_DEACTIVE : ALPHA_MAX;
360  }
361 
362  void Window::getSnappedCoord(IntCoord& _coord)
363  {
364  if (abs(_coord.left) <= WINDOW_SNAP_DISTANSE) _coord.left = 0;
365  if (abs(_coord.top) <= WINDOW_SNAP_DISTANSE) _coord.top = 0;
366 
367  IntSize view_size;
368  if (getCroppedParent() == nullptr)
369  view_size = this->getLayer()->getSize();
370  else
371  view_size = ((Widget*)getCroppedParent())->getSize();
372 
373  if ( abs(_coord.left + _coord.width - view_size.width) < WINDOW_SNAP_DISTANSE) _coord.left = view_size.width - _coord.width;
374  if ( abs(_coord.top + _coord.height - view_size.height) < WINDOW_SNAP_DISTANSE) _coord.top = view_size.height - _coord.height;
375  }
376 
377  void Window::setVisibleSmooth(bool _visible)
378  {
379  mAnimateSmooth = true;
381 
382  if (_visible)
383  {
384  setEnabledSilent(true);
385  if ( ! isVisible() )
386  {
388  Base::setVisible(true);
389  }
390  ControllerFadeAlpha * controller = createControllerFadeAlpha(getAlphaVisible(), WINDOW_SPEED_COEF, true);
391  controller->eventPostAction = newDelegate(this, &Window::animateStop);
392  ControllerManager::getInstance().addItem(this, controller);
393  }
394  else
395  {
396  setEnabledSilent(false);
397  ControllerFadeAlpha * controller = createControllerFadeAlpha(ALPHA_MIN, WINDOW_SPEED_COEF, false);
399  ControllerManager::getInstance().addItem(this, controller);
400  }
401  }
402 
403  ControllerFadeAlpha* Window::createControllerFadeAlpha(float _alpha, float _coef, bool _enable)
404  {
406  ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>();
407 
408  controller->setAlpha(_alpha);
409  controller->setCoef(_coef);
410  controller->setEnabled(_enable);
411 
412  return controller;
413  }
414 
415  void Window::setMinSize(const IntSize& _value)
416  {
417  mMinmax.left = _value.width;
418  mMinmax.top = _value.height;
419  }
420 
422  {
423  return IntSize(mMinmax.left, mMinmax.top);
424  }
425 
426  void Window::setMaxSize(const IntSize& _value)
427  {
428  mMinmax.right = _value.width;
429  mMinmax.bottom = _value.height;
430  }
431 
433  {
434  return IntSize(mMinmax.right, mMinmax.bottom);
435  }
436 
437  void Window::setProperty(const std::string& _key, const std::string& _value)
438  {
439  if (_key == "Window_AutoAlpha") setAutoAlpha(utility::parseValue<bool>(_value));
440  else if (_key == "Window_Snap") setSnap(utility::parseValue<bool>(_value));
441  else if (_key == "Window_MinSize") setMinSize(utility::parseValue<IntSize>(_value));
442  else if (_key == "Window_MaxSize") setMaxSize(utility::parseValue<IntSize>(_value));
443 
444 #ifndef MYGUI_DONT_USE_OBSOLETE
445  else if (_key == "Window_MinMax")
446  {
447  IntRect rect = IntRect::parse(_value);
448  setMinSize(rect.left, rect.top);
449  setMaxSize(rect.right, rect.bottom);
450  MYGUI_LOG(Warning, "Window_MinMax is obsolete, use Window_MinSize or Window_MaxSize");
451  }
452 #endif // MYGUI_DONT_USE_OBSOLETE
453 
454  else
455  {
456  Base::setProperty(_key, _value);
457  return;
458  }
459  eventChangeProperty(this, _key, _value);
460  }
461 
462 } // namespace MyGUI