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
16namespace 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
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
610 {
611 return mMovable;
612 }
613
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 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 setPosition(const IntPoint &_value) 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)
TextBox * getCaptionWidget() const
void notifyMouseDrag(MyGUI::Widget *_sender, int _left, int _top, MouseButton _id)
void setCoord(const IntCoord &_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 setSize(const IntSize &_value) override
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
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
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))
static Align parse(const std::string &_value)
Definition: MyGUI_Align.h:127
bool empty() const
Definition: MyGUI_TCoord.h:180
TPoint< T > point() const
Definition: MyGUI_TCoord.h:185
TSize< T > size() const
Definition: MyGUI_TCoord.h:190
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