MyGUI  3.4.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  mMovable(true)
33  {
34  }
35 
37  {
38  Base::initialiseOverride();
39 
40  // FIXME нам нужен фокус клавы
41  setNeedKeyFocus(true);
42 
43  // дефолтные размеры
44  mMinmax.set(
45  (std::numeric_limits<int>::min)(),
46  (std::numeric_limits<int>::min)(),
47  (std::numeric_limits<int>::max)(),
48  (std::numeric_limits<int>::max)());
49 
50  bool main_move = false;
51  if (isUserString("MainMove"))
52  {
53  setUserString("Scale", "1 1 0 0");
54  main_move = true;
55  }
56 
57  if (getClientWidget() != nullptr)
58  {
59  if (main_move)
60  {
61  getClientWidget()->setUserString("Scale", "1 1 0 0");
65  }
66  }
67 
69  assignWidget(mWidgetCaption, "Caption");
70  if (mWidgetCaption != nullptr)
71  {
72  mWidgetCaption->setUserString("Scale", "1 1 0 0");
75  mWidgetCaption->eventMouseDrag += newDelegate(this, &Window::notifyMouseDrag);
76  }
77 
78  VectorWidgetPtr buttons = getSkinWidgetsByName("Button");
79  for (VectorWidgetPtr::iterator iter = buttons.begin(); iter != buttons.end(); ++iter)
80  {
81  (*iter)->eventMouseButtonClick += newDelegate(this, &Window::notifyPressedButtonEvent);
82  }
83 
84  VectorWidgetPtr actions = getSkinWidgetsByName("Action");
85  for (VectorWidgetPtr::iterator iter = actions.begin(); iter != actions.end(); ++iter)
86  {
87  (*iter)->eventMouseButtonPressed += newDelegate(this, &Window::notifyMousePressed);
88  (*iter)->eventMouseButtonReleased += newDelegate(this, &Window::notifyMouseReleased);
89  (*iter)->eventMouseDrag += newDelegate(this, &Window::notifyMouseDrag);
90  (*iter)->eventMouseWheel += newDelegate(this, &Window::notifyMouseWheel);
91  }
92 
93  const size_t countNames = 8;
94  const char* resizers[2][countNames] =
95  {
96  {"ResizeLeftTop", "ResizeTop", "ResizeRightTop", "ResizeRight", "ResizeRightBottom", "ResizeBottom", "ResizeLeftBottom", "ResizeLeft"},
97  {"Left Top", "Top", "Right Top", "Right", "Right Bottom", "Bottom", "Left Bottom", "Left"}
98  };
99 
100  for (size_t index = 0; index < countNames; ++ index)
101  {
102  Widget* widget = nullptr;
103  assignWidget(widget, resizers[0][index]);
104  if (widget != nullptr)
105  {
110  widget->setUserString("Action", resizers[1][index]);
111  }
112  }
113  }
114 
116  {
117  mWidgetCaption = nullptr;
118 
119  Base::shutdownOverride();
120  }
121 
123  {
124  mMouseRootFocus = _focus;
125  updateAlpha();
126 
127  Base::onMouseChangeRootFocus(_focus);
128  }
129 
131  {
132  mKeyRootFocus = _focus;
133  updateAlpha();
134 
135  Base::onKeyChangeRootFocus(_focus);
136  }
137 
138  void Window::onMouseDrag(int _left, int _top, MouseButton _id)
139  {
140  // на тот случай, если двигать окно, можно за любое место виджета
141  notifyMouseDrag(this, _left, _top, _id);
142 
143  Base::onMouseDrag(_left, _top, _id);
144  }
145 
146  void Window::onMouseButtonPressed(int _left, int _top, MouseButton _id)
147  {
148  notifyMousePressed(this, _left, _top, _id);
149 
150  Base::onMouseButtonPressed(_left, _top, _id);
151  }
152 
153  void Window::onMouseButtonReleased(int _left, int _top, MouseButton _id)
154  {
155  notifyMouseReleased(this, _left, _top, _id);
156 
157  Base::onMouseButtonReleased(_left, _top, _id);
158  }
159 
160  void Window::notifyMousePressed(MyGUI::Widget* _sender, int _left, int _top, MouseButton _id)
161  {
162  if (MouseButton::Left == _id)
163  {
164  mPreActionCoord = mCoord;
165  mCurrentActionScale = _getActionScale(_sender);
166  }
167  }
168 
170  {
171  eventWindowButtonPressed(this, _sender->getUserString("Event"));
172  }
173 
174  void Window::notifyMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MouseButton _id)
175  {
176  if (_id != MouseButton::Left)
177  return;
178 
180 
181  IntCoord coord = mCurrentActionScale;
182  coord.left *= (_left - point.left);
183  coord.top *= (_top - point.top);
184  coord.width *= (_left - point.left);
185  coord.height *= (_top - point.top);
186 
187  if (coord.empty())
188  return;
189 
190  if (coord.left == 0 && coord.top == 0)
191  setSize((mPreActionCoord + coord).size());
192  else if (coord.width == 0 && coord.height == 0)
193  setPosition((mPreActionCoord + coord).point());
194  else
195  setCoord(mPreActionCoord + coord);
196 
197  // посылаем событие о изменении позиции и размере
199  }
200 
202  {
203  if (!mIsAutoAlpha)
204  return;
205 
206  float alpha;
207  if (mKeyRootFocus)
208  alpha = WINDOW_ALPHA_ACTIVE;
209  else if (mMouseRootFocus)
210  alpha = WINDOW_ALPHA_FOCUS;
211  else
212  alpha = WINDOW_ALPHA_DEACTIVE;
213 
214  ControllerFadeAlpha* controller = createControllerFadeAlpha(alpha, WINDOW_SPEED_COEF, true);
215  ControllerManager::getInstance().addItem(this, controller);
216  }
217 
218  void Window::setAutoAlpha(bool _auto)
219  {
220  mIsAutoAlpha = _auto;
221  if (!_auto)
223  else
224  {
225  if (mKeyRootFocus)
227  else if (mMouseRootFocus)
229  else
231  }
232  }
233 
234  void Window::setPosition(const IntPoint& _point)
235  {
236  IntPoint point = _point;
237  // прилепляем к краям
238  if (mSnap)
239  {
240  IntCoord coord(point, mCoord.size());
241  getSnappedCoord(coord, Snap::Position);
242  point = coord.point();
243  }
244 
245  Base::setPosition(point);
246  }
247 
248  void Window::setSize(const IntSize& _size)
249  {
250  IntSize size = _size;
251  // прилепляем к краям
252 
253  if (size.width < mMinmax.left)
254  size.width = mMinmax.left;
255  else if (size.width > mMinmax.right)
256  size.width = mMinmax.right;
257  if (size.height < mMinmax.top)
258  size.height = mMinmax.top;
259  else if (size.height > mMinmax.bottom)
260  size.height = mMinmax.bottom;
261  if ((size.width == mCoord.width) && (size.height == mCoord.height))
262  return;
263 
264  if (mSnap)
265  {
266  IntCoord coord(mCoord.point(), size);
267  getSnappedCoord(coord, Snap::Size);
268  size = coord.size();
269  }
270 
271  Base::setSize(size);
272  }
273 
274  void Window::setCoord(const IntCoord& _coord)
275  {
276  IntPoint pos = _coord.point();
277  IntSize size = _coord.size();
278 
279  if (size.width < mMinmax.left)
280  {
281  int offset = mMinmax.left - size.width;
282  size.width = mMinmax.left;
283  if ((pos.left - mCoord.left) > offset)
284  pos.left -= offset;
285  else
286  pos.left = mCoord.left;
287  }
288  else if (size.width > mMinmax.right)
289  {
290  int offset = mMinmax.right - size.width;
291  size.width = mMinmax.right;
292  if ((pos.left - mCoord.left) < offset)
293  pos.left -= offset;
294  else
295  pos.left = mCoord.left;
296  }
297  if (size.height < mMinmax.top)
298  {
299  int offset = mMinmax.top - size.height;
300  size.height = mMinmax.top;
301  if ((pos.top - mCoord.top) > offset)
302  pos.top -= offset;
303  else
304  pos.top = mCoord.top;
305  }
306  else if (size.height > mMinmax.bottom)
307  {
308  int offset = mMinmax.bottom - size.height;
309  size.height = mMinmax.bottom;
310  if ((pos.top - mCoord.top) < offset)
311  pos.top -= offset;
312  else
313  pos.top = mCoord.top;
314  }
315 
316  IntCoord coord(pos, size);
317  if (mSnap)
318  {
319  // prefer size change over position change
320  getSnappedCoord(coord, Snap::Size);
321  }
322 
323  if (coord == mCoord)
324  return;
325 
326  Base::setCoord(coord);
327  }
328 
329  void Window::setCaption(const UString& _caption)
330  {
331  if (mWidgetCaption != nullptr)
332  mWidgetCaption->setCaption(_caption);
333  else
334  Base::setCaption(_caption);
335  }
336 
338  {
339  if (mWidgetCaption != nullptr)
340  return mWidgetCaption->getCaption();
341  return Base::getCaption();
342  }
343 
345  {
346  ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MIN, WINDOW_SPEED_COEF, false);
348  ControllerManager::getInstance().addItem(this, controller);
349  }
350 
351  void Window::animateStop(Widget* _widget, ControllerItem* _controller)
352  {
353  if (mAnimateSmooth)
354  {
356  mAnimateSmooth = false;
357  }
358  }
359 
360  void Window::setVisible(bool _visible)
361  {
362  if (mAnimateSmooth)
363  {
365  setAlpha(getAlphaVisible());
366  setEnabledSilent(true);
367  mAnimateSmooth = false;
368  }
369 
370  Base::setVisible(_visible);
371  }
372 
373  float Window::getAlphaVisible() const
374  {
375  return (mIsAutoAlpha && !mKeyRootFocus) ? WINDOW_ALPHA_DEACTIVE : ALPHA_MAX;
376  }
377 
378  void Window::getSnappedCoord(IntCoord& _coord, Snap snapMode) const
379  {
380  const IntSize view_size = getParentSize();
381  bool nearLeftSide = abs(_coord.left) <= WINDOW_SNAP_DISTANSE;
382  bool nearTopSide = abs(_coord.top) <= WINDOW_SNAP_DISTANSE;
383  bool nearRightSide = abs(_coord.left + _coord.width - view_size.width) <= WINDOW_SNAP_DISTANSE;
384  bool nearBottomSide = abs(_coord.top + _coord.height - view_size.height) <= WINDOW_SNAP_DISTANSE;
385 
386  switch (snapMode)
387  {
388  case Snap::Position:
389  if (nearLeftSide)
390  _coord.left = 0;
391  if (nearTopSide)
392  _coord.top = 0;
393 
394  if (nearRightSide)
395  _coord.left = view_size.width - _coord.width;
396  if (nearBottomSide)
397  _coord.top = view_size.height - _coord.height;
398  break;
399  case Snap::Size:
400  if (nearLeftSide)
401  {
402  _coord.width = _coord.right();
403  _coord.left = 0;
404  }
405  if (nearTopSide)
406  {
407  _coord.height = _coord.bottom();
408  _coord.top = 0;
409  }
410 
411  if (nearRightSide)
412  _coord.width = view_size.width - _coord.left;
413  if (nearBottomSide)
414  _coord.height = view_size.height - _coord.top;
415  break;
416  }
417  }
418 
419  void Window::setVisibleSmooth(bool _visible)
420  {
421  mAnimateSmooth = true;
423 
424  if (_visible)
425  {
426  setEnabledSilent(true);
427  if (!getVisible())
428  {
430  Base::setVisible(true);
431  }
432  ControllerFadeAlpha* controller = createControllerFadeAlpha(getAlphaVisible(), WINDOW_SPEED_COEF, true);
433  controller->eventPostAction += newDelegate(this, &Window::animateStop);
434  ControllerManager::getInstance().addItem(this, controller);
435  }
436  else
437  {
438  setEnabledSilent(false);
439  ControllerFadeAlpha* controller = createControllerFadeAlpha(ALPHA_MIN, WINDOW_SPEED_COEF, false);
441  ControllerManager::getInstance().addItem(this, controller);
442  }
443  }
444 
445  ControllerFadeAlpha* Window::createControllerFadeAlpha(float _alpha, float _coef, bool _enable)
446  {
448  ControllerFadeAlpha* controller = item->castType<ControllerFadeAlpha>();
449 
450  controller->setAlpha(_alpha);
451  controller->setCoef(_coef);
452  controller->setEnabled(_enable);
453 
454  return controller;
455  }
456 
457  void Window::setMinSize(const IntSize& _value)
458  {
459  mMinmax.left = _value.width;
460  mMinmax.top = _value.height;
461  }
462 
464  {
465  return IntSize(mMinmax.left, mMinmax.top);
466  }
467 
468  void Window::setMaxSize(const IntSize& _value)
469  {
470  mMinmax.right = _value.width;
471  mMinmax.bottom = _value.height;
472  }
473 
475  {
476  return IntSize(mMinmax.right, mMinmax.bottom);
477  }
478 
479  void Window::setPropertyOverride(const std::string& _key, const std::string& _value)
480  {
482  if (_key == "AutoAlpha")
483  setAutoAlpha(utility::parseValue<bool>(_value));
484 
486  else if (_key == "Snap")
487  setSnap(utility::parseValue<bool>(_value));
488 
490  else if (_key == "MinSize")
491  setMinSize(utility::parseValue<IntSize>(_value));
492 
494  else if (_key == "MaxSize")
495  setMaxSize(utility::parseValue<IntSize>(_value));
496 
498  else if (_key == "Movable")
499  setMovable(utility::parseValue<bool>(_value));
500 
501  else
502  {
503  Base::setPropertyOverride(_key, _value);
504  return;
505  }
506 
507  eventChangeProperty(this, _key, _value);
508  }
509 
511  {
512  return mCurrentActionScale;
513  }
514 
515  bool Window::getAutoAlpha() const
516  {
517  return mIsAutoAlpha;
518  }
519 
521  {
522  return mWidgetCaption;
523  }
524 
525  void Window::setMinSize(int _width, int _height)
526  {
527  setMinSize(IntSize(_width, _height));
528  }
529 
530  void Window::setMaxSize(int _width, int _height)
531  {
532  setMaxSize(IntSize(_width, _height));
533  }
534 
535  bool Window::getSnap() const
536  {
537  return mSnap;
538  }
539 
540  void Window::setSnap(bool _value)
541  {
542  mSnap = _value;
543  }
544 
545  void Window::notifyMouseReleased(MyGUI::Widget* _sender, int _left, int _top, MouseButton _id)
546  {
547  if (MouseButton::Left == _id)
548  {
549  mCurrentActionScale.clear();
550  }
551  }
552 
553  IntCoord Window::_getActionScale(Widget* _widget) const
554  {
555  if (_widget->isUserString("Scale"))
556  {
557  IntCoord result = IntCoord::parse(_widget->getUserString("Scale"));
558 
559  if (result == IntCoord(1, 1, 0, 0) && !mMovable)
560  result.clear();
561 
562  return result;
563  }
564  else if (_widget->isUserString("Action"))
565  {
566  const std::string& action = _widget->getUserString("Action");
567  if (action == "Move")
568  {
569  if (mMovable)
570  return IntCoord(1, 1, 0, 0);
571  else
572  return IntCoord();
573  }
574 
575  IntCoord coord;
576  Align align = Align::parse(action);
577 
578  if (align.isLeft())
579  {
580  coord.left = 1;
581  coord.width = -1;
582  }
583  else if (align.isRight())
584  {
585  coord.width = 1;
586  }
587 
588  if (align.isTop())
589  {
590  coord.top = 1;
591  coord.height = -1;
592  }
593  else if (align.isBottom())
594  {
595  coord.height = 1;
596  }
597 
598  return coord;
599  }
600 
601  return IntCoord();
602  }
603 
604  void Window::setMovable(bool _value)
605  {
606  mMovable = _value;
607  }
608 
609  bool Window::getMovable() const
610  {
611  return mMovable;
612  }
613 
614  void Window::notifyMouseWheel(MyGUI::Widget* _sender, int _rel)
615  {
616  onMouseWheel(_rel);
617  eventMouseWheel(_sender, _rel);
618  }
619 
620 } // namespace MyGUI
static const std::string & getClassTypeName()
EventPairAddParameter< EventHandle_WidgetPtr, EventHandle_WidgetPtrControllerItemPtr > eventPostAction
ControllerItem * createItem(const std::string &_type)
static ControllerManager & getInstance()
void addItem(Widget *_widget, ControllerItem *_item)
Type * castType(bool _throw=true)
Definition: MyGUI_IObject.h:18
const IntPoint & getLastPressedPosition(MouseButton _id) const
static InputManager & getInstance()
widget description should be here.
Definition: MyGUI_TextBox.h:21
virtual const UString & getCaption() const
virtual void setCaption(const UString &_value)
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
bool isUserString(const std::string &_key) const
const std::string & getUserString(const std::string &_key) const
void setUserString(const std::string &_key, const std::string &_value)
widget description should be here.
Definition: MyGUI_Widget.h:37
VectorWidgetPtr getSkinWidgetsByName(const std::string &_name) const
void setAlpha(float _value)
EventHandle_WidgetStringString eventChangeProperty
Definition: MyGUI_Widget.h:267
void assignWidget(T *&_widget, const std::string &_name)
Definition: MyGUI_Widget.h:335
IntSize getParentSize() const
bool getVisible() const
Widget * getClientWidget()
void setEnabledSilent(bool _value)
EventHandle_WidgetIntIntButton eventMouseButtonReleased
void setNeedKeyFocus(bool _value)
virtual void onMouseWheel(int _rel)
EventHandle_WidgetIntIntButton eventMouseButtonPressed
EventPairAddParameter< EventHandle_WidgetIntInt, EventHandle_WidgetIntIntButton > eventMouseDrag
EventHandle_WidgetInt eventMouseWheel
void onKeyChangeRootFocus(bool _focus) override
void setCoord(const IntCoord &_value) override
void setMovable(bool _value)
void setVisibleSmooth(bool _value)
void setSnap(bool _value)
EventPair< EventHandle_WidgetVoid, EventHandle_WindowPtr > eventWindowChangeCoord
Definition: MyGUI_Window.h:107
void onMouseButtonReleased(int _left, int _top, MouseButton _id) override
IntSize getMaxSize() const
void setMinSize(const IntSize &_value)
void notifyMousePressed(MyGUI::Widget *_sender, int _left, int _top, MouseButton _id)
const UString & getCaption() const override
void animateStop(Widget *_widget, ControllerItem *_controller)
void notifyPressedButtonEvent(MyGUI::Widget *_sender)
void onMouseButtonPressed(int _left, int _top, MouseButton _id) override
const IntCoord & getActionScale() const
void setCaption(const UString &_value) override
void setMaxSize(const IntSize &_value)
void onMouseChangeRootFocus(bool _focus) override
void notifyMouseReleased(MyGUI::Widget *_sender, int _left, int _top, MouseButton _id)
void setPosition(const IntPoint &_value) override
TextBox * getCaptionWidget() const
void notifyMouseDrag(MyGUI::Widget *_sender, int _left, int _top, MouseButton _id)
void setSize(const IntSize &_value) override
void notifyMouseWheel(MyGUI::Widget *_sender, int _rel)
bool getSnap() const
void setVisible(bool _value) override
void onMouseDrag(int _left, int _top, MouseButton _id) override
bool getMovable() const
void shutdownOverride() override
EventPair< EventHandle_WidgetString, EventHandle_WindowPtrCStringRef > eventWindowButtonPressed
Definition: MyGUI_Window.h:101
void destroySmooth()
void initialiseOverride() override
void setPropertyOverride(const std::string &_key, const std::string &_value) override
void setAutoAlpha(bool _value)
IntSize getMinSize() const
bool getAutoAlpha() const
void actionWidgetDestroy(Widget *_widget, ControllerItem *_controller)
void actionWidgetHide(Widget *_widget, ControllerItem *_controller)
const float WINDOW_ALPHA_FOCUS
const float WINDOW_SPEED_COEF
const float WINDOW_ALPHA_ACTIVE
const float ALPHA_MIN
Definition: MyGUI_Macros.h:20
const float WINDOW_ALPHA_DEACTIVE
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
types::TCoord< int > IntCoord
Definition: MyGUI_Types.h:35
std::vector< Widget * > VectorWidgetPtr
const int WINDOW_SNAP_DISTANSE
const float ALPHA_MAX
Definition: MyGUI_Macros.h:19
types::TSize< int > IntSize
Definition: MyGUI_Types.h:29
static Align parse(const std::string &_value)
Definition: MyGUI_Align.h:127
bool empty() const
Definition: MyGUI_TCoord.h:180
TSize< T > size() const
Definition: MyGUI_TCoord.h:190
TPoint< T > point() const
Definition: MyGUI_TCoord.h:185
static TCoord< int > parse(const std::string &_value)
Definition: MyGUI_TCoord.h:207
void set(T const &_left, T const &_top, T const &_right, T const &_bottom)
Definition: MyGUI_TRect.h:121