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