MyGUI 3.4.1
MyGUI_ScrollBar.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_ScrollBar.h"
10#include "MyGUI_Button.h"
11#include "MyGUI_ResourceSkin.h"
14
15namespace MyGUI
16{
17
19 mWidgetStart(nullptr),
20 mWidgetEnd(nullptr),
21 mWidgetTrack(nullptr),
22 mWidgetFirstPart(nullptr),
23 mWidgetSecondPart(nullptr),
24 mSkinRangeStart(0),
25 mSkinRangeEnd(0),
26 mScrollRange(0),
27 mScrollPosition(0),
28 mScrollPage(0),
29 mScrollViewPage(0),
30 mScrollWheelPage(0),
31 mEnableRepeat(true),
32 mRepeatTriggerTime(0.f),
33 mRepeatStepTime(0.f),
34 mMinTrackSize(0),
35 mMoveToClick(false),
36 mVerticalAlignment(true)
37 {
38 }
39
41 {
42 Base::initialiseOverride();
43
44 // при нуле, будет игнорировать кнопки
45 mScrollPage = 1;
48 mMinTrackSize = 0;
50 mSkinRangeEnd = 0;
51
52 mRepeatTriggerTime = 0.5f;
53 mRepeatStepTime = 0.1f;
54
56 assignWidget(mWidgetStart, "Start");
57 if (mWidgetStart != nullptr)
58 {
62 }
63
66 if (mWidgetEnd != nullptr)
67 {
71 }
72
74 assignWidget(mWidgetTrack, "Track");
75 if (mWidgetTrack)
76 {
82 }
83
85 assignWidget(mWidgetFirstPart, "FirstPart");
86 if (mWidgetFirstPart != nullptr)
87 {
91 }
92
94 assignWidget(mWidgetSecondPart, "SecondPart");
95 if (mWidgetSecondPart != nullptr)
96 {
100 }
101
102 if (isUserString("MinTrackSize"))
103 mMinTrackSize = utility::parseValue<int>(getUserString("MinTrackSize"));
104
105 if (isUserString("TrackRangeMargins"))
106 utility::parseComplex<size_t>(getUserString("TrackRangeMargins"), mSkinRangeStart, mSkinRangeEnd);
107
108 if (mWidgetTrack != nullptr)
109 {
110 if (mWidgetTrack->isUserString("MinTrackSize"))
111 mMinTrackSize = utility::parseValue<int>(mWidgetTrack->getUserString("MinTrackSize"));
112 }
113 }
114
116 {
117 mWidgetStart = nullptr;
118 mWidgetEnd = nullptr;
119 mWidgetTrack = nullptr;
120 mWidgetFirstPart = nullptr;
121 mWidgetSecondPart = nullptr;
122
123 Base::shutdownOverride();
124 }
125
127 {
128 if (mWidgetTrack == nullptr)
129 return;
130
132 // размер диапазана в пикселях
133 int pos = getLineSize();
134
136 {
137 // скрываем если диапазан маленький или места мало
138 if ((mScrollRange < 2) || (pos <= mWidgetTrack->getHeight()))
139 {
140 mWidgetTrack->setVisible(false);
141 if (nullptr != mWidgetFirstPart)
143 if (nullptr != mWidgetSecondPart)
145 return;
146 }
147 // если скрыт то покажем
148 if (!mWidgetTrack->getVisible())
150
151 // и обновляем позицию
152 pos = (int)(((size_t)(pos - getTrackSize()) * mScrollPosition) / (mScrollRange - 1) + mSkinRangeStart);
153
155 if (nullptr != mWidgetFirstPart)
156 {
157 int height = pos - mWidgetFirstPart->getTop();
159 }
160 if (nullptr != mWidgetSecondPart)
161 {
162 int top = pos + mWidgetTrack->getHeight();
163 int height = getTrackPlaceLength() - top;
165 }
166 }
167 else
168 {
169 // скрываем если диапазан маленький или места мало
170 if ((mScrollRange < 2) || (pos <= mWidgetTrack->getWidth()))
171 {
172 mWidgetTrack->setVisible(false);
173 if (nullptr != mWidgetFirstPart)
175 if (nullptr != mWidgetSecondPart)
177 return;
178 }
179 // если скрыт то покажем
180 if (!mWidgetTrack->getVisible())
182
183 // и обновляем позицию
184 pos = (int)(((size_t)(pos - getTrackSize()) * mScrollPosition) / (mScrollRange - 1) + mSkinRangeStart);
185
187 if (nullptr != mWidgetFirstPart)
188 {
189 int height = pos - mWidgetFirstPart->getLeft();
191 }
192 if (nullptr != mWidgetSecondPart)
193 {
194 int left = pos + mWidgetTrack->getWidth();
195 int width = getTrackPlaceLength() - left;
197 }
198 }
199 }
200
201 void ScrollBar::TrackMove(int _left, int _top)
202 {
203 if (mWidgetTrack == nullptr)
204 return;
205
207
209 {
210 // расчитываем позицию виджета
211 int start = mPreActionOffset.top + (_top - point.top);
212 if (start < (int)mSkinRangeStart)
213 start = (int)mSkinRangeStart;
214 else if (start > (getTrackPlaceLength() - (int)mSkinRangeEnd - mWidgetTrack->getHeight()))
216 if (mWidgetTrack->getTop() != start)
218
219 // расчитываем положение соответствующее позиции
220 // плюс пол позиции
221 int pos = start - (int)mSkinRangeStart + (getLineSize() - getTrackSize()) / (((int)mScrollRange - 1) * 2);
222 // высчитываем ближайшее значение и обновляем
223 pos = pos * (int)(mScrollRange - 1) / (getLineSize() - getTrackSize());
224
225 // проверяем на выходы и изменения
226 if (pos < 0)
227 pos = 0;
228 else if (pos >= (int)mScrollRange)
229 pos = (int)mScrollRange - 1;
230 if (pos == (int)mScrollPosition)
231 return;
232
233 mScrollPosition = pos;
234 }
235 else
236 {
237 // расчитываем позицию виджета
238 int start = mPreActionOffset.left + (_left - point.left);
239 if (start < (int)mSkinRangeStart)
240 start = (int)mSkinRangeStart;
241 else if (start > (getTrackPlaceLength() - (int)mSkinRangeEnd - mWidgetTrack->getWidth()))
243 if (mWidgetTrack->getLeft() != start)
245
246 // расчитываем положение соответствующее позиции
247 // плюс пол позиции
248 int pos = start - (int)mSkinRangeStart + (getLineSize() - getTrackSize()) / (((int)mScrollRange - 1) * 2);
249 // высчитываем ближайшее значение и обновляем
250 pos = pos * (int)(mScrollRange - 1) / (getLineSize() - getTrackSize());
251
252 // проверяем на выходы и изменения
253 if (pos < 0)
254 pos = 0;
255 else if (pos >= (int)mScrollRange)
256 pos = (int)mScrollRange - 1;
257 if (pos == (int)mScrollPosition)
258 return;
259
260 mScrollPosition = pos;
261 }
262
263 updateTrack();
264
265 // отсылаем событие
267 }
268
269 void ScrollBar::notifyMousePressed(Widget* _sender, int _left, int _top, MouseButton _id)
270 {
271 // диспечерезируем нажатие своих детей как свое
272 eventMouseButtonPressed(this, _left, _top, _id);
273
274 if (MouseButton::Left != _id)
275 return;
276
277 if (mEnableRepeat && _sender != mWidgetTrack
278 && ((_sender != mWidgetFirstPart && _sender != mWidgetSecondPart) || !mMoveToClick))
279 {
282 controller->eventRepeatClick += newDelegate(this, &ScrollBar::repeatClick);
284 ControllerManager::getInstance().addItem(_sender, controller);
285 }
286
287 if (mMoveToClick &&
288 _sender != mWidgetTrack &&
289 _sender != mWidgetStart &&
290 _sender != mWidgetEnd)
291 {
292 if (mWidgetTrack != nullptr)
293 {
296
299
300 TrackMove(point.left, point.top);
301 }
302 }
303 else if (_sender == mWidgetStart)
304 {
305 widgetStartPressed();
306 }
307 else if (_sender == mWidgetEnd)
308 {
309 widgetEndPressed();
310 }
311 else if (_sender == mWidgetFirstPart)
312 {
313 widgetFirstPartPressed();
314 }
315 else if (_sender == mWidgetSecondPart)
316 {
317 widgetSecondPartPressed();
318 }
319 else if (_sender == mWidgetTrack)
320 {
321 mPreActionOffset.left = _sender->getLeft();
322 mPreActionOffset.top = _sender->getTop();
323 }
324 }
325
326 void ScrollBar::notifyMouseReleased(Widget* _sender, int _left, int _top, MouseButton _id)
327 {
328 updateTrack();
330 }
331
332 void ScrollBar::notifyMouseDrag(Widget* _sender, int _left, int _top, MouseButton _id)
333 {
334 if (mScrollRange < 2)
335 return;
336 if (_id == MouseButton::Left)
337 TrackMove(_left, _top);
338 }
339
340 void ScrollBar::setScrollRange(size_t _range)
341 {
342 if (_range == mScrollRange)
343 return;
344
345 mScrollRange = _range;
347 updateTrack();
348 }
349
350 void ScrollBar::setScrollPosition(size_t _position)
351 {
352 if (_position == mScrollPosition)
353 return;
354
355 if (_position >= mScrollRange)
356 _position = 0;
357
358 mScrollPosition = _position;
359 updateTrack();
360 }
361
363 {
364 Base::setPosition(_point);
365 }
366
367 void ScrollBar::setSize(const IntSize& _size)
368 {
369 Base::setSize(_size);
370 // обновляем трек
371 updateTrack();
372 }
373
374 void ScrollBar::setCoord(const IntCoord& _coord)
375 {
376 Base::setCoord(_coord);
377 // обновляем трек
378 updateTrack();
379 }
380
382 {
383 if (mWidgetTrack != nullptr)
384 {
386 mWidgetTrack->setSize(mWidgetTrack->getWidth(), ((int)_size < (int)mMinTrackSize) ? (int)mMinTrackSize : (int)_size);
387 else
388 mWidgetTrack->setSize(((int)_size < (int)mMinTrackSize) ? (int)mMinTrackSize : (int)_size, mWidgetTrack->getHeight());
389 }
390 updateTrack();
391 }
392
394 {
395 mRepeatTriggerTime = time;
396 }
397
399 {
400 mRepeatStepTime = time;
401 }
402
403 float ScrollBar::getRepeatTriggerTime(float time) const
404 {
405 return mRepeatTriggerTime;
406 }
407
408 float ScrollBar::getRepeatStepTime(float time) const
409 {
410 return mRepeatStepTime;
411 }
412
414 {
415 mEnableRepeat = enabled;
416 }
417
419 {
420 return mEnableRepeat;
421 }
422
424 {
425 if (mWidgetTrack != nullptr)
426 {
428 return mWidgetTrack->getHeight();
429 else
430 return mWidgetTrack->getWidth();
431 }
432 return 1;
433 }
434
436 {
438 }
439
441 {
442 notifyMouseWheel(nullptr, _rel);
443
444 Base::onMouseWheel(_rel);
445 }
446
447 void ScrollBar::notifyMouseWheel(Widget* _sender, int _rel)
448 {
449 if (mScrollRange < 2)
450 return;
451
452 int offset = mScrollPosition;
453 if (_rel < 0)
454 offset += mScrollWheelPage;
455 else
456 offset -= mScrollWheelPage;
457
458 if (offset < 0)
459 offset = 0;
460 else if (offset > (int)(mScrollRange - 1))
461 offset = mScrollRange - 1;
462
463 if ((size_t)offset != mScrollPosition)
464 {
465 mScrollPosition = offset;
466 // оповещаем
468 updateTrack();
469 }
470 }
471
472 void ScrollBar::repeatClick(Widget *_widget, ControllerItem *_controller)
473 {
474 if (_widget == mWidgetStart)
475 widgetStartPressed();
476 else if (_widget == mWidgetEnd)
477 widgetEndPressed();
478 else if (_widget == mWidgetFirstPart)
479 widgetFirstPartPressed();
480 else if (_widget == mWidgetSecondPart)
481 widgetSecondPartPressed();
482 }
483
484 void ScrollBar::widgetStartPressed()
485 {
486 // минимальное значение
487 if (mScrollPosition == 0)
488 return;
489
490 // расчитываем следующее положение
493 else
494 mScrollPosition = 0;
495
496 // оповещаем
498 updateTrack();
499 }
500
501 void ScrollBar::widgetEndPressed()
502 {
503 // максимальное значение
504 if ((mScrollRange < 2) || (mScrollPosition >= (mScrollRange - 1)))
505 return;
506
507 // расчитываем следующее положение
510 else
512
513 // оповещаем
515 updateTrack();
516 }
517
518 void ScrollBar::widgetFirstPartPressed()
519 {
520 // минимальное значение
521 if (mScrollPosition == 0)
522 return;
523
524 // расчитываем следующее положение
527 else
528 mScrollPosition = 0;
529
530 // оповещаем
532 updateTrack();
533 }
534
535 void ScrollBar::widgetSecondPartPressed()
536 {
537 // максимальное значение
538 if ((mScrollRange < 2) || (mScrollPosition >= (mScrollRange - 1)))
539 return;
540
541 // расчитываем следующее положение
544 else
546
547 // оповещаем
549 updateTrack();
550 }
551
552 void ScrollBar::setPropertyOverride(const std::string& _key, const std::string& _value)
553 {
555 if (_key == "Range")
556 setScrollRange(utility::parseValue<size_t>(_value));
557
559 else if (_key == "RangePosition")
560 setScrollPosition(utility::parseValue<size_t>(_value));
561
563 else if (_key == "Page")
564 setScrollPage(utility::parseValue<size_t>(_value));
565
567 else if (_key == "ViewPage")
568 setScrollViewPage(utility::parseValue<size_t>(_value));
569
571 else if (_key == "WheelPage")
572 setScrollWheelPage(utility::parseValue<size_t>(_value));
573
575 else if (_key == "MoveToClick")
576 setMoveToClick(utility::parseValue<bool>(_value));
577
579 else if (_key == "VerticalAlignment")
580 setVerticalAlignment(utility::parseValue<bool>(_value));
581
583 else if (_key == "Repeat")
584 setRepeatEnabled(utility::parseValue<bool>(_value));
585
587 else if (_key == "RepeatTriggerTime")
588 setRepeatTriggerTime(utility::parseValue<float>(_value));
589
591 else if (_key == "RepeatStepTime")
592 setRepeatStepTime(utility::parseValue<float>(_value));
593
594 else
595 {
596 Base::setPropertyOverride(_key, _value);
597 return;
598 }
599
600 eventChangeProperty(this, _key, _value);
601 }
602
604 {
605 return mScrollRange;
606 }
607
609 {
610 return mScrollPosition;
611 }
612
613 void ScrollBar::setScrollPage(size_t _value)
614 {
615 mScrollPage = _value;
616 }
617
619 {
620 return mScrollPage;
621 }
622
624 {
625 mScrollViewPage = _value;
626 }
627
629 {
630 return mScrollViewPage;
631 }
632
634 {
635 mScrollWheelPage = _value;
636 }
638 {
639 return mScrollWheelPage;
640 }
641
643 {
644 mMinTrackSize = _value;
645 }
646
648 {
649 return mMinTrackSize;
650 }
651
653 {
654 mMoveToClick = _value;
655 }
656
658 {
659 return mMoveToClick;
660 }
661
663 {
664 if (mWidgetTrack != nullptr)
665 {
667 return mWidgetTrack->getParent()->getHeight();
668 else
669 return mWidgetTrack->getParent()->getWidth();
670 }
671 return 0;
672 }
673
675 {
676 mVerticalAlignment = _value;
677
678 updateTrack();
679 }
680
682 {
683 return mVerticalAlignment;
684 }
685
686} // namespace MyGUI
ControllerItem * createItem(const std::string &_type)
static ControllerManager & getInstance()
void addItem(Widget *_widget, ControllerItem *_item)
EventHandle_RepeatClick eventRepeatClick
static const std::string & getClassTypeName()
void setRepeat(float init, float step)
const IntPoint & getAbsolutePosition() const
Type * castType(bool _throw=true)
Definition: MyGUI_IObject.h:18
const IntPoint & getLastPressedPosition(MouseButton _id) const
static InputManager & getInstance()
IntPoint getMousePositionByLayer() const
int getMinTrackSize() const
void setVerticalAlignment(bool _value)
void setRepeatEnabled(bool enabled)
EventHandle_ScrollBarPtrSizeT eventScrollChangePosition
void setMoveToClick(bool _value)
void shutdownOverride() override
void setScrollRange(size_t _value)
int getLineSize() const
void setScrollWheelPage(size_t _value)
void initialiseOverride() override
void setTrackSize(int _value)
void setMinTrackSize(int _value)
size_t getScrollPage() const
void setPropertyOverride(const std::string &_key, const std::string &_value) override
void notifyMousePressed(Widget *_sender, int _left, int _top, MouseButton _id)
void setRepeatTriggerTime(float time)
void setRepeatStepTime(float time)
Widget * mWidgetFirstPart
void setSize(const IntSize &_value) override
bool getVerticalAlignment() const
bool getRepeatEnabled() const
size_t getScrollPosition() const
void TrackMove(int _left, int _top)
void notifyMouseReleased(Widget *_sender, int _left, int _top, MouseButton _id)
Widget * mWidgetSecondPart
size_t getScrollViewPage() const
void setPosition(const IntPoint &_value) override
void setCoord(const IntCoord &_value) override
void setScrollPosition(size_t _value)
size_t getScrollRange() const
int getTrackPlaceLength() const
void setScrollViewPage(size_t _value)
bool getMoveToClick() const
void notifyMouseDrag(Widget *_sender, int _left, int _top, MouseButton _id)
int getTrackSize() const
void onMouseWheel(int _rel) override
float getRepeatTriggerTime(float time) const
void setScrollPage(size_t _value)
IntPoint mPreActionOffset
size_t getScrollWheelPage() const
void notifyMouseWheel(Widget *_sender, int _rel)
float getRepeatStepTime(float time) const
bool isUserString(const std::string &_key) const
const std::string & getUserString(const std::string &_key) const
widget description should be here.
Definition: MyGUI_Widget.h:37
Widget * getParent() const
void setCoord(const IntCoord &_value) override
EventHandle_WidgetStringString eventChangeProperty
Definition: MyGUI_Widget.h:267
void assignWidget(T *&_widget, const std::string &_name)
Definition: MyGUI_Widget.h:335
virtual void setVisible(bool _value)
void setPosition(const IntPoint &_value) override
bool getVisible() const
void setSize(const IntSize &_value) override
void _forcePick(Widget *_widget)
EventHandle_WidgetIntIntButton eventMouseButtonReleased
EventHandle_WidgetIntIntButton eventMouseButtonPressed
EventPairAddParameter< EventHandle_WidgetIntInt, EventHandle_WidgetIntIntButton > eventMouseDrag
EventHandle_WidgetInt eventMouseWheel
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))