MyGUI  3.2.1
MyGUI_Window.cpp
Go to the documentation of this file.
1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #include "MyGUI_Precompiled.h"
8 #include "MyGUI_Window.h"
9 #include "MyGUI_Macros.h"
10 #include "MyGUI_Gui.h"
12 #include "MyGUI_InputManager.h"
13 #include "MyGUI_WidgetManager.h"
14 #include "MyGUI_ResourceSkin.h"
15 
16 namespace MyGUI
17 {
19  const float WINDOW_ALPHA_FOCUS = 0.7f;
20  const float WINDOW_ALPHA_DEACTIVE = 0.3f;
21  const float WINDOW_SPEED_COEF = 3.0f;
22 
23  const int WINDOW_SNAP_DISTANSE = 10;
24 
26  mWidgetCaption(nullptr),
27  mMouseRootFocus(false),
28  mKeyRootFocus(false),
29  mIsAutoAlpha(false),
30  mSnap(false),
31  mAnimateSmooth(false),
32  mClient(nullptr),
33  mMovable(true)
34  {
35  }
36 
38  {
39  Base::initialiseOverride();
40 
41  // FIXME нам нужен фокус клавы
42  setNeedKeyFocus(true);
43 
44  // дефолтные размеры
45  mMinmax.set(
46  (std::numeric_limits<int>::min)(),
47  (std::numeric_limits<int>::min)(),
48  (std::numeric_limits<int>::max)(),
49  (std::numeric_limits<int>::max)());
50 
51  bool main_move = false;
52  if (isUserString("MainMove"))
53  {
54  setUserString("Scale", "1 1 0 0");
55  main_move = true;
56  }
57 
59  assignWidget(mClient, "Client");
60  if (mClient != nullptr)
61  {
62  if (main_move)
63  {
64  mClient->setUserString("Scale", "1 1 0 0");
68  }
69  setWidgetClient(mClient);
70  }
71 
73  assignWidget(mWidgetCaption, "Caption");
74  if (mWidgetCaption != nullptr)
75  {
76  mWidgetCaption->setUserString("Scale", "1 1 0 0");
79  mWidgetCaption->eventMouseDrag += newDelegate(this, &Window::notifyMouseDrag);
80  }
81 
82  VectorWidgetPtr buttons = getSkinWidgetsByName("Button");
83  for (VectorWidgetPtr::iterator iter = buttons.begin(); iter != buttons.end(); ++iter)
84  {
85  (*iter)->eventMouseButtonClick += newDelegate(this, &Window::notifyPressedButtonEvent);
86  }
87 
88  VectorWidgetPtr actions = getSkinWidgetsByName("Action");
89  for (VectorWidgetPtr::iterator iter = actions.begin(); iter != actions.end(); ++iter)
90  {
91  (*iter)->eventMouseButtonPressed += newDelegate(this, &Window::notifyMousePressed);
92  (*iter)->eventMouseButtonReleased += newDelegate(this, &Window::notifyMouseReleased);
93  (*iter)->eventMouseDrag += newDelegate(this, &Window::notifyMouseDrag);
94  (*iter)->eventMouseWheel += newDelegate(this, &Window::notifyMouseWheel);
95  }
96 
97  const size_t countNames = 8;
98  const char* resizers[2][countNames] =
99  {
100  {"ResizeLeftTop", "ResizeTop", "ResizeRightTop", "ResizeRight", "ResizeRightBottom", "ResizeBottom", "ResizeLeftBottom", "ResizeLeft"},
101  {"Left Top", "Top", "Right Top", "Right", "Right Bottom", "Bottom", "Left Bottom", "Left"}
102  };
103 
104  for (size_t index = 0; index < countNames; ++ index)
105  {
106  Widget* widget = nullptr;
107  assignWidget(widget, resizers[0][index]);
108  if (widget != nullptr)
109  {
114  widget->setUserString("Action", resizers[1][index]);
115  }
116  }
117  }
118 
120  {
121  mClient = nullptr;
122  mWidgetCaption = nullptr;
123 
124  Base::shutdownOverride();
125  }
126 
128  {
129  mMouseRootFocus = _focus;
130  updateAlpha();
131 
132  Base::onMouseChangeRootFocus(_focus);
133  }
134 
136  {
137  mKeyRootFocus = _focus;
138  updateAlpha();
139 
140  Base::onKeyChangeRootFocus(_focus);
141  }
142 
143  void Window::onMouseDrag(int _left, int _top, MouseButton _id)
144  {
145  // на тот случай, если двигать окно, можно за любое место виджета
146  notifyMouseDrag(this, _left, _top, _id);
147 
148  Base::onMouseDrag(_left, _top, _id);
149  }
150 
151  void Window::onMouseButtonPressed(int _left, int _top, MouseButton _id)
152  {
153  notifyMousePressed(this, _left, _top, _id);
154 
155  Base::onMouseButtonPressed(_left, _top, _id);
156  }
157 
158  void Window::onMouseButtonReleased(int _left, int _top, MouseButton _id)
159  {
160  notifyMouseReleased(this, _left, _top, _id);
161 
162  Base::onMouseButtonReleased(_left, _top, _id);
163  }
164 
165  void Window::notifyMousePressed(MyGUI::Widget* _sender, int _left, int _top, MouseButton _id)
166  {
167  if (MouseButton::Left == _id)
168  {
169  mPreActionCoord = mCoord;
170  mCurrentActionScale = _getActionScale(_sender);
171  }
172  }
173 
175  {
176  eventWindowButtonPressed(this, _sender->getUserString("Event"));
177  }
178 
179  void Window::notifyMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MouseButton _id)
180  {
181  if (_id != MouseButton::Left)
182  return;
183 
185 
186  IntCoord coord = mCurrentActionScale;
187  coord.left *= (_left - point.left);
188  coord.top *= (_top - point.top);
189  coord.width *= (_left - point.left);
190  coord.height *= (_top - point.top);
191 
192  if (coord.empty())
193  return;
194 
195  if (coord.left == 0 && coord.top == 0)
196  setSize((mPreActionCoord + coord).size());
197  else if (coord.width == 0 && coord.height == 0)
198  setPosition((mPreActionCoord + coord).point());
199  else
200  setCoord(mPreActionCoord + coord);
201 
202  // посылаем событие о изменении позиции и размере
204  }
205 
207  {
208  if (!mIsAutoAlpha)
209  return;
210 
211  float alpha;
212  if (mKeyRootFocus)
213  alpha = WINDOW_ALPHA_ACTIVE;
214  else if (mMouseRootFocus)
215  alpha = WINDOW_ALPHA_FOCUS;
216  else
217  alpha = WINDOW_ALPHA_DEACTIVE;
218 
219  ControllerFadeAlpha* controller = createControllerFadeAlpha(alpha, WINDOW_SPEED_COEF, true);
220  ControllerManager::getInstance().addItem(this, controller);
221  }
222 
223  void Window::setAutoAlpha(bool _auto)
224  {
225  mIsAutoAlpha = _auto;
226  if (!_auto)
228  else
229  {
230  if (mKeyRootFocus)
232  else if (mMouseRootFocus)
234  else
236  }
237  }
238 
239  void Window::setPosition(const IntPoint& _point)
240  {
241  IntPoint point = _point;
242  // прилепляем к краям
243  if (mSnap)
244  {
245  IntCoord coord(point, mCoord.size());
246  getSnappedCoord(coord);
247  point = coord.point();
248  }
249 
250  Base::setPosition(point);
251  }
252 
253  void Window::setSize(const IntSize& _size)
254  {
255  IntSize size = _size;
256  // прилепляем к краям
257 
258  if (size.width < mMinmax.left)
259  size.width = mMinmax.left;
260  else if (size.width > mMinmax.right)
261  size.width = mMinmax.right;
262  if (size.height < mMinmax.top)
263  size.height = mMinmax.top;
264  else if (size.height > mMinmax.bottom)
265  size.height = mMinmax.bottom;
266  if ((size.width == mCoord.width) && (size.height == mCoord.height))
267  return;
268 
269  if (mSnap)
270  {
271  IntCoord coord(mCoord.point(), size);
272  getSnappedCoord(coord);
273  size = coord.size();
274  }
275 
276  Base::setSize(size);
277  }
278 
279  void Window::setCoord(const IntCoord& _coord)
280  {
281  IntPoint pos = _coord.point();
282  IntSize size = _coord.size();
283 
284  if (size.width < mMinmax.left)
285  {
286  int offset = mMinmax.left - size.width;
287  size.width = mMinmax.left;
288  if ((pos.left - mCoord.left) > offset)
289  pos.left -= offset;
290  else
291  pos.left = mCoord.left;
292  }
293  else if (size.width > mMinmax.right)
294  {
295  int offset = mMinmax.right - size.width;
296  size.width = mMinmax.right;
297  if ((pos.left - mCoord.left) < offset)
298  pos.left -= offset;
299  else
300  pos.left = mCoord.left;
301  }
302  if (size.height < mMinmax.top)
303  {
304  int offset = mMinmax.top - size.height;
305  size.height = mMinmax.top;
306  if ((pos.top - mCoord.top) > offset)
307  pos.top -= offset;
308  else
309  pos.top = mCoord.top;
310  }
311  else if (size.height > mMinmax.bottom)
312  {
313  int offset = mMinmax.bottom - size.height;
314  size.height = mMinmax.bottom;
315  if ((pos.top - mCoord.top) < offset)
316  pos.top -= offset;
317  else
318  pos.top = mCoord.top;
319  }
320 
321  // прилепляем к краям
322  if (mSnap)
323  {
324  IntCoord coord(pos, size);
325  getSnappedCoord(coord);
326  size = coord.size();
327  }
328 
329  IntCoord coord(pos, size);
330  if (coord == mCoord)
331  return;
332 
333  Base::setCoord(coord);
334  }
335 
336  void Window::setCaption(const UString& _caption)
337  {
338  if (mWidgetCaption != nullptr)
339  mWidgetCaption->setCaption(_caption);
340  else
341  Base::setCaption(_caption);
342  }
343 
345  {
346  if (mWidgetCaption != nullptr)
347  return mWidgetCaption->getCaption();
348  return Base::getCaption();
349  }
350 
352  {
353  ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MIN, WINDOW_SPEED_COEF, false);
355  ControllerManager::getInstance().addItem(this, controller);
356  }
357 
358  void Window::animateStop(Widget* _widget, ControllerItem* _controller)
359  {
360  if (mAnimateSmooth)
361  {
363  mAnimateSmooth = false;
364  }
365  }
366 
367  void Window::setVisible(bool _visible)
368  {
369  if (mAnimateSmooth)
370  {
372  setAlpha(getAlphaVisible());
373  setEnabledSilent(true);
374  mAnimateSmooth = false;
375  }
376 
377  Base::setVisible(_visible);
378  }
379 
380  float Window::getAlphaVisible() const
381  {
382  return (mIsAutoAlpha && !mKeyRootFocus) ? WINDOW_ALPHA_DEACTIVE : ALPHA_MAX;
383  }
384 
385  void Window::getSnappedCoord(IntCoord& _coord)
386  {
387  if (abs(_coord.left) <= WINDOW_SNAP_DISTANSE) _coord.left = 0;
388  if (abs(_coord.top) <= WINDOW_SNAP_DISTANSE) _coord.top = 0;
389 
390  const IntSize view_size = getParentSize();
391 
392  if ( abs(_coord.left + _coord.width - view_size.width) < WINDOW_SNAP_DISTANSE)
393  _coord.left = view_size.width - _coord.width;
394  if ( abs(_coord.top + _coord.height - view_size.height) < WINDOW_SNAP_DISTANSE)
395  _coord.top = view_size.height - _coord.height;
396  }
397 
398  void Window::setVisibleSmooth(bool _visible)
399  {
400  mAnimateSmooth = true;
402 
403  if (_visible)
404  {
405  setEnabledSilent(true);
406  if (!getVisible())
407  {
409  Base::setVisible(true);
410  }
411  ControllerFadeAlpha* controller = createControllerFadeAlpha(getAlphaVisible(), WINDOW_SPEED_COEF, true);
412  controller->eventPostAction += newDelegate(this, &Window::animateStop);
413  ControllerManager::getInstance().addItem(this, controller);
414  }
415  else
416  {
417  setEnabledSilent(false);
418  ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MIN, WINDOW_SPEED_COEF, false);
420  ControllerManager::getInstance().addItem(this, controller);
421  }
422  }
423 
424  ControllerFadeAlpha* Window::createControllerFadeAlpha(float _alpha, float _coef, bool _enable)
425  {
427  ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>();
428 
429  controller->setAlpha(_alpha);
430  controller->setCoef(_coef);
431  controller->setEnabled(_enable);
432 
433  return controller;
434  }
435 
436  void Window::setMinSize(const IntSize& _value)
437  {
438  mMinmax.left = _value.width;
439  mMinmax.top = _value.height;
440  }
441 
443  {
444  return IntSize(mMinmax.left, mMinmax.top);
445  }
446 
447  void Window::setMaxSize(const IntSize& _value)
448  {
449  mMinmax.right = _value.width;
450  mMinmax.bottom = _value.height;
451  }
452 
454  {
455  return IntSize(mMinmax.right, mMinmax.bottom);
456  }
457 
458  void Window::setPropertyOverride(const std::string& _key, const std::string& _value)
459  {
461  if (_key == "AutoAlpha")
462  setAutoAlpha(utility::parseValue<bool>(_value));
463 
465  else if (_key == "Snap")
466  setSnap(utility::parseValue<bool>(_value));
467 
469  else if (_key == "MinSize")
470  setMinSize(utility::parseValue<IntSize>(_value));
471 
473  else if (_key == "MaxSize")
474  setMaxSize(utility::parseValue<IntSize>(_value));
475 
477  else if (_key == "Movable")
478  setMovable(utility::parseValue<bool>(_value));
479 
480  else
481  {
482  Base::setPropertyOverride(_key, _value);
483  return;
484  }
485 
486  eventChangeProperty(this, _key, _value);
487  }
488 
490  {
491  return mCurrentActionScale;
492  }
493 
494  bool Window::getAutoAlpha() const
495  {
496  return mIsAutoAlpha;
497  }
498 
500  {
501  return mWidgetCaption;
502  }
503 
504  void Window::setMinSize(int _width, int _height)
505  {
506  setMinSize(IntSize(_width, _height));
507  }
508 
509  void Window::setMaxSize(int _width, int _height)
510  {
511  setMaxSize(IntSize(_width, _height));
512  }
513 
514  void Window::setPosition(int _left, int _top)
515  {
516  setPosition(IntPoint(_left, _top));
517  }
518 
519  void Window::setSize(int _width, int _height)
520  {
521  setSize(IntSize(_width, _height));
522  }
523 
524  void Window::setCoord(int _left, int _top, int _width, int _height)
525  {
526  setCoord(IntCoord(_left, _top, _width, _height));
527  }
528 
529  bool Window::getSnap() const
530  {
531  return mSnap;
532  }
533 
534  void Window::setSnap(bool _value)
535  {
536  mSnap = _value;
537  }
538 
539  void Window::notifyMouseReleased(MyGUI::Widget* _sender, int _left, int _top, MouseButton _id)
540  {
541  if (MouseButton::Left == _id)
542  {
543  mCurrentActionScale.clear();
544  }
545  }
546 
547  IntCoord Window::_getActionScale(Widget* _widget)
548  {
549  if (_widget->isUserString("Scale"))
550  {
551  IntCoord result = IntCoord::parse(_widget->getUserString("Scale"));
552 
553  if (result == IntCoord(1, 1, 0, 0) && !mMovable)
554  result.clear();
555 
556  return result;
557  }
558  else if (_widget->isUserString("Action"))
559  {
560  const std::string& action = _widget->getUserString("Action");
561  if (action == "Move")
562  {
563  if (mMovable)
564  return IntCoord(1, 1, 0, 0);
565  else
566  return IntCoord();
567  }
568 
569  IntCoord coord;
570  Align align = Align::parse(action);
571 
572  if (align.isLeft())
573  {
574  coord.left = 1;
575  coord.width = -1;
576  }
577  else if (align.isRight())
578  {
579  coord.width = 1;
580  }
581 
582  if (align.isTop())
583  {
584  coord.top = 1;
585  coord.height = -1;
586  }
587  else if (align.isBottom())
588  {
589  coord.height = 1;
590  }
591 
592  return coord;
593  }
594 
595  return IntCoord();
596  }
597 
598  void Window::setMovable(bool _value)
599  {
600  mMovable = _value;
601  }
602 
603  bool Window::getMovable() const
604  {
605  return mMovable;
606  }
607 
608  void Window::notifyMouseWheel(MyGUI::Widget* _sender, int _rel)
609  {
610  onMouseWheel(_rel);
611  eventMouseWheel(_sender, _rel);
612  }
613 
614 } // namespace MyGUI