MyGUI
3.2.0
Main Page
Related Pages
Namespaces
Data Structures
Files
Examples
File List
Globals
MyGUIEngine
src
MyGUI_ScrollBar.cpp
Go to the documentation of this file.
1
6
/*
7
This file is part of MyGUI.
8
9
MyGUI is free software: you can redistribute it and/or modify
10
it under the terms of the GNU Lesser General Public License as published by
11
the Free Software Foundation, either version 3 of the License, or
12
(at your option) any later version.
13
14
MyGUI is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU Lesser General Public License for more details.
18
19
You should have received a copy of the GNU Lesser General Public License
20
along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21
*/
22
#include "
MyGUI_Precompiled.h
"
23
#include "
MyGUI_ScrollBar.h
"
24
#include "
MyGUI_InputManager.h
"
25
#include "
MyGUI_Button.h
"
26
#include "
MyGUI_ResourceSkin.h
"
27
28
namespace
MyGUI
29
{
30
31
// FIXME - move to widget property
32
const
int
SCROLL_MOUSE_WHEEL
= 50;
// колличество пикселей для колеса мыши
33
34
ScrollBar::ScrollBar
() :
35
mWidgetStart(
nullptr
),
36
mWidgetEnd(
nullptr
),
37
mWidgetTrack(
nullptr
),
38
mWidgetFirstPart(
nullptr
),
39
mWidgetSecondPart(
nullptr
),
40
mSkinRangeStart(0),
41
mSkinRangeEnd(0),
42
mScrollRange(0),
43
mScrollPosition(0),
44
mScrollPage(0),
45
mScrollViewPage(0),
46
mMinTrackSize(0),
47
mMoveToClick(false),
48
mVerticalAlignment(true)
49
{
50
}
51
52
void
ScrollBar::initialiseOverride
()
53
{
54
Base::initialiseOverride
();
55
56
// при нуле, будет игнорировать кнопки
57
mScrollPage
= 1;
58
mScrollViewPage
= 1;
59
mMinTrackSize
= 0;
60
mSkinRangeStart
= 0;
61
mSkinRangeEnd
= 0;
62
63
assignWidget
(
mWidgetStart
,
"Start"
);
64
if
(
mWidgetStart
!=
nullptr
)
65
{
66
mWidgetStart
->
eventMouseButtonPressed
+=
newDelegate
(
this
, &
ScrollBar::notifyMousePressed
);
67
mWidgetStart
->
eventMouseWheel
+=
newDelegate
(
this
, &
ScrollBar::notifyMouseWheel
);
68
}
69
70
assignWidget
(
mWidgetEnd
,
"End"
);
71
if
(
mWidgetEnd
!=
nullptr
)
72
{
73
mWidgetEnd
->
eventMouseButtonPressed
+=
newDelegate
(
this
, &
ScrollBar::notifyMousePressed
);
74
mWidgetEnd
->
eventMouseWheel
+=
newDelegate
(
this
, &
ScrollBar::notifyMouseWheel
);
75
}
76
77
assignWidget
(
mWidgetTrack
,
"Track"
);
78
if
(
mWidgetTrack
)
79
{
80
mWidgetTrack
->
eventMouseDrag
+=
newDelegate
(
this
, &
ScrollBar::notifyMouseDrag
);
81
mWidgetTrack
->
eventMouseButtonPressed
+=
newDelegate
(
this
, &
ScrollBar::notifyMousePressed
);
82
mWidgetTrack
->
eventMouseButtonReleased
+=
newDelegate
(
this
, &
ScrollBar::notifyMouseReleased
);
83
mWidgetTrack
->
eventMouseWheel
+=
newDelegate
(
this
, &
ScrollBar::notifyMouseWheel
);
84
mWidgetTrack
->
setVisible
(
false
);
85
}
86
87
assignWidget
(
mWidgetFirstPart
,
"FirstPart"
);
88
if
(
mWidgetFirstPart
!=
nullptr
)
89
{
90
mWidgetFirstPart
->
eventMouseButtonPressed
+=
newDelegate
(
this
, &
ScrollBar::notifyMousePressed
);
91
mWidgetFirstPart
->
eventMouseWheel
+=
newDelegate
(
this
, &
ScrollBar::notifyMouseWheel
);
92
}
93
94
assignWidget
(
mWidgetSecondPart
,
"SecondPart"
);
95
if
(
mWidgetSecondPart
!=
nullptr
)
96
{
97
mWidgetSecondPart
->
eventMouseButtonPressed
+=
newDelegate
(
this
, &
ScrollBar::notifyMousePressed
);
98
mWidgetSecondPart
->
eventMouseWheel
+=
newDelegate
(
this
, &
ScrollBar::notifyMouseWheel
);
99
}
100
101
if
(
isUserString
(
"MinTrackSize"
))
102
mMinTrackSize
= utility::parseValue<int>(
getUserString
(
"MinTrackSize"
));
103
if
(
isUserString
(
"TrackRangeMargins"
))
104
utility::parseComplex<size_t>(
getUserString
(
"TrackRangeMargins"
),
mSkinRangeStart
,
mSkinRangeEnd
);
105
106
if
(
mWidgetTrack
!=
nullptr
)
107
{
108
if
(
mWidgetTrack
->
isUserString
(
"MinTrackSize"
))
109
mMinTrackSize
= utility::parseValue<int>(
mWidgetTrack
->
getUserString
(
"MinTrackSize"
));
110
}
111
}
112
113
void
ScrollBar::shutdownOverride
()
114
{
115
mWidgetStart
=
nullptr
;
116
mWidgetEnd
=
nullptr
;
117
mWidgetTrack
=
nullptr
;
118
mWidgetFirstPart
=
nullptr
;
119
mWidgetSecondPart
=
nullptr
;
120
121
Base::shutdownOverride
();
122
}
123
124
void
ScrollBar::updateTrack
()
125
{
126
if
(
mWidgetTrack
==
nullptr
)
127
return
;
128
129
_forcePick
(
mWidgetTrack
);
130
// размер диапазана в пикселях
131
int
pos =
getLineSize
();
132
133
if
(
mVerticalAlignment
)
134
{
135
// скрываем если диапазан маленький или места мало
136
if
((
mScrollRange
< 2) || (pos <= mWidgetTrack->
getHeight
()))
137
{
138
mWidgetTrack
->
setVisible
(
false
);
139
if
(
nullptr
!=
mWidgetFirstPart
)
140
mWidgetFirstPart
->
setSize
(
mWidgetFirstPart
->
getWidth
(), pos / 2);
141
if
(
nullptr
!=
mWidgetSecondPart
)
142
mWidgetSecondPart
->
setCoord
(
mWidgetSecondPart
->
getLeft
(), pos / 2 + (int)
mSkinRangeStart
,
mWidgetSecondPart
->
getWidth
(), pos - pos / 2);
143
return
;
144
}
145
// если скрыт то покажем
146
if
(!
mWidgetTrack
->
getVisible
())
147
mWidgetTrack
->
setVisible
(
true
);
148
149
// и обновляем позицию
150
pos = (int)(((
size_t
)(pos -
getTrackSize
()) *
mScrollPosition
) / (
mScrollRange
- 1) +
mSkinRangeStart
);
151
152
mWidgetTrack
->
setPosition
(
mWidgetTrack
->
getLeft
(), pos);
153
if
(
nullptr
!=
mWidgetFirstPart
)
154
{
155
int
height = pos -
mWidgetFirstPart
->
getTop
();
156
mWidgetFirstPart
->
setSize
(
mWidgetFirstPart
->
getWidth
(), height);
157
}
158
if
(
nullptr
!=
mWidgetSecondPart
)
159
{
160
int
top = pos +
mWidgetTrack
->
getHeight
();
161
int
height =
mWidgetSecondPart
->
getHeight
() +
mWidgetSecondPart
->
getTop
() - top;
162
mWidgetSecondPart
->
setCoord
(
mWidgetSecondPart
->
getLeft
(), top,
mWidgetSecondPart
->
getWidth
(), height);
163
}
164
}
165
else
166
{
167
// скрываем если диапазан маленький или места мало
168
if
((
mScrollRange
< 2) || (pos <=
mWidgetTrack
->
getWidth
()))
169
{
170
mWidgetTrack
->
setVisible
(
false
);
171
if
(
nullptr
!=
mWidgetFirstPart
)
172
mWidgetFirstPart
->
setSize
(pos / 2,
mWidgetFirstPart
->
getHeight
());
173
if
(
nullptr
!=
mWidgetSecondPart
)
174
mWidgetSecondPart
->
setCoord
(pos / 2 + (
int
)
mSkinRangeStart
,
mWidgetSecondPart
->
getTop
(), pos - pos / 2,
mWidgetSecondPart
->
getHeight
());
175
return
;
176
}
177
// если скрыт то покажем
178
if
(!
mWidgetTrack
->
getVisible
())
179
mWidgetTrack
->
setVisible
(
true
);
180
181
// и обновляем позицию
182
pos = (int)(((
size_t
)(pos -
getTrackSize
()) *
mScrollPosition
) / (
mScrollRange
- 1) +
mSkinRangeStart
);
183
184
mWidgetTrack
->
setPosition
(pos,
mWidgetTrack
->
getTop
());
185
if
(
nullptr
!=
mWidgetFirstPart
)
186
{
187
int
height = pos -
mWidgetFirstPart
->
getLeft
();
188
mWidgetFirstPart
->
setSize
(height,
mWidgetFirstPart
->
getHeight
());
189
}
190
if
(
nullptr
!=
mWidgetSecondPart
)
191
{
192
int
top = pos +
mWidgetTrack
->
getWidth
();
193
int
height =
mWidgetSecondPart
->
getWidth
() +
mWidgetSecondPart
->
getLeft
() - top;
194
mWidgetSecondPart
->
setCoord
(top,
mWidgetSecondPart
->
getTop
(), height,
mWidgetSecondPart
->
getHeight
());
195
}
196
}
197
}
198
199
void
ScrollBar::TrackMove
(
int
_left,
int
_top)
200
{
201
if
(
mWidgetTrack
==
nullptr
)
202
return
;
203
204
const
IntPoint
& point =
InputManager::getInstance
().
getLastPressedPosition
(
MouseButton::Left
);
205
206
if
(
mVerticalAlignment
)
207
{
208
// расчитываем позицию виджета
209
int
start =
mPreActionOffset
.
top
+ (_top - point.
top
);
210
if
(start < (
int
)
mSkinRangeStart
)
211
start = (
int
)
mSkinRangeStart
;
212
else
if
(start > (
getTrackPlaceLength
() - (
int
)
mSkinRangeEnd
-
mWidgetTrack
->
getHeight
()))
213
start = (
getTrackPlaceLength
() - (int)
mSkinRangeEnd
-
mWidgetTrack
->
getHeight
());
214
if
(
mWidgetTrack
->
getTop
() != start)
215
mWidgetTrack
->
setPosition
(
mWidgetTrack
->
getLeft
(), start);
216
217
// расчитываем положение соответствующее позиции
218
// плюс пол позиции
219
int
pos = start - (int)
mSkinRangeStart
+ (
getLineSize
() -
getTrackSize
()) / (((
int
)
mScrollRange
- 1) * 2);
220
// высчитываем ближайшее значение и обновляем
221
pos = pos * (int)(
mScrollRange
- 1) / (
getLineSize
() -
getTrackSize
());
222
223
// проверяем на выходы и изменения
224
if
(pos < 0)
225
pos = 0;
226
else
if
(pos >= (
int
)
mScrollRange
)
227
pos = (
int
)
mScrollRange
- 1;
228
if
(pos == (
int
)
mScrollPosition
)
229
return
;
230
231
mScrollPosition
= pos;
232
}
233
else
234
{
235
// расчитываем позицию виджета
236
int
start =
mPreActionOffset
.
left
+ (_left - point.
left
);
237
if
(start < (
int
)
mSkinRangeStart
)
238
start = (
int
)
mSkinRangeStart
;
239
else
if
(start > (
getTrackPlaceLength
() - (int)
mSkinRangeEnd
-
mWidgetTrack
->
getWidth
()))
240
start = (
getTrackPlaceLength
() - (int)
mSkinRangeEnd
-
mWidgetTrack
->
getWidth
());
241
if
(
mWidgetTrack
->
getLeft
() != start)
242
mWidgetTrack
->
setPosition
(
IntPoint
(start,
mWidgetTrack
->
getTop
()));
243
244
// расчитываем положение соответствующее позиции
245
// плюс пол позиции
246
int
pos = start - (int)
mSkinRangeStart
+ (
getLineSize
() -
getTrackSize
()) / (((
int
)
mScrollRange
- 1) * 2);
247
// высчитываем ближайшее значение и обновляем
248
pos = pos * (int)(
mScrollRange
- 1) / (
getLineSize
() -
getTrackSize
());
249
250
// проверяем на выходы и изменения
251
if
(pos < 0)
252
pos = 0;
253
else
if
(pos >= (
int
)
mScrollRange
)
254
pos = (
int
)
mScrollRange
- 1;
255
if
(pos == (
int
)
mScrollPosition
)
256
return
;
257
258
mScrollPosition
= pos;
259
}
260
261
updateTrack
();
262
263
// отсылаем событие
264
eventScrollChangePosition
(
this
, (
int
)
mScrollPosition
);
265
}
266
267
void
ScrollBar::notifyMousePressed
(
Widget
* _sender,
int
_left,
int
_top,
MouseButton
_id)
268
{
269
// диспечерезируем нажатие своих детей как свое
270
eventMouseButtonPressed
(
this
, _left, _top, _id);
271
272
if
(
MouseButton::Left
!= _id)
273
return
;
274
275
if
(
mMoveToClick
&&
276
_sender !=
mWidgetTrack
&&
277
_sender !=
mWidgetStart
&&
278
_sender !=
mWidgetEnd
)
279
{
280
if
(
mWidgetTrack
!=
nullptr
)
281
{
282
mPreActionOffset
=
InputManager::getInstance
().
getLastPressedPosition
(
MouseButton::Left
);
283
const
IntPoint
& point =
InputManager::getInstance
().
getMousePositionByLayer
() -
mWidgetTrack
->
getParent
()->
getAbsolutePosition
();
284
285
mPreActionOffset
.
left
-=
getTrackSize
() / 2;
286
mPreActionOffset
.
top
-=
getTrackSize
() / 2;
287
288
TrackMove
(point.
left
, point.
top
);
289
}
290
}
291
else
if
(_sender ==
mWidgetStart
)
292
{
293
// минимальное значение
294
if
(
mScrollPosition
== 0)
295
return
;
296
297
// расчитываем следующее положение
298
if
(
mScrollPosition
>
mScrollPage
)
299
mScrollPosition
-=
mScrollPage
;
300
else
301
mScrollPosition
= 0;
302
303
// оповещаем
304
eventScrollChangePosition
(
this
, (
int
)
mScrollPosition
);
305
updateTrack
();
306
}
307
else
if
(_sender ==
mWidgetEnd
)
308
{
309
// максимальное значение
310
if
((
mScrollRange
< 2) || (
mScrollPosition
>= (
mScrollRange
- 1)))
311
return
;
312
313
// расчитываем следующее положение
314
if
((
mScrollPosition
+
mScrollPage
) < (
mScrollRange
- 1))
315
mScrollPosition
+=
mScrollPage
;
316
else
317
mScrollPosition
=
mScrollRange
- 1;
318
319
// оповещаем
320
eventScrollChangePosition
(
this
, (
int
)
mScrollPosition
);
321
updateTrack
();
322
}
323
else
if
(_sender ==
mWidgetFirstPart
)
324
{
325
// минимальное значение
326
if
(
mScrollPosition
== 0)
327
return
;
328
329
// расчитываем следующее положение
330
if
(
mScrollPosition
>
mScrollViewPage
)
331
mScrollPosition
-=
mScrollViewPage
;
332
else
333
mScrollPosition
= 0;
334
335
// оповещаем
336
eventScrollChangePosition
(
this
, (
int
)
mScrollPosition
);
337
updateTrack
();
338
}
339
else
if
(_sender ==
mWidgetSecondPart
)
340
{
341
// максимальное значение
342
if
((
mScrollRange
< 2) || (
mScrollPosition
>= (
mScrollRange
- 1)))
343
return
;
344
345
// расчитываем следующее положение
346
if
((
mScrollPosition
+
mScrollViewPage
) < (
mScrollRange
- 1))
347
mScrollPosition
+=
mScrollViewPage
;
348
else
349
mScrollPosition
=
mScrollRange
- 1;
350
351
// оповещаем
352
eventScrollChangePosition
(
this
, (
int
)
mScrollPosition
);
353
updateTrack
();
354
}
355
else
if
(_sender ==
mWidgetTrack
)
356
{
357
mPreActionOffset
.
left
= _sender->
getLeft
();
358
mPreActionOffset
.
top
= _sender->
getTop
();
359
}
360
}
361
362
void
ScrollBar::notifyMouseReleased
(
Widget
* _sender,
int
_left,
int
_top,
MouseButton
_id)
363
{
364
updateTrack
();
365
}
366
367
void
ScrollBar::notifyMouseDrag
(
Widget
* _sender,
int
_left,
int
_top,
MouseButton
_id)
368
{
369
if
(_id ==
MouseButton::Left
)
370
TrackMove
(_left, _top);
371
}
372
373
void
ScrollBar::setScrollRange
(
size_t
_range)
374
{
375
if
(_range ==
mScrollRange
)
376
return
;
377
378
mScrollRange
= _range;
379
mScrollPosition
= (
mScrollPosition
<
mScrollRange
) ?
mScrollPosition
: 0;
380
updateTrack
();
381
}
382
383
void
ScrollBar::setScrollPosition
(
size_t
_position)
384
{
385
if
(_position ==
mScrollPosition
)
386
return
;
387
388
if
(_position >=
mScrollRange
)
389
_position = 0;
390
391
mScrollPosition
= _position;
392
updateTrack
();
393
}
394
395
void
ScrollBar::setPosition
(
const
IntPoint
& _point)
396
{
397
Base::setPosition
(_point);
398
}
399
400
void
ScrollBar::setSize
(
const
IntSize
& _size)
401
{
402
Base::setSize
(_size);
403
// обновляем трек
404
updateTrack
();
405
}
406
407
void
ScrollBar::setCoord
(
const
IntCoord
& _coord)
408
{
409
Base::setCoord
(_coord);
410
// обновляем трек
411
updateTrack
();
412
}
413
414
void
ScrollBar::setTrackSize
(
int
_size)
415
{
416
if
(
mWidgetTrack
!=
nullptr
)
417
{
418
if
(
mVerticalAlignment
)
419
mWidgetTrack
->
setSize
(
mWidgetTrack
->
getWidth
(), ((int)_size < (
int
)
mMinTrackSize
) ? (
int
)
mMinTrackSize
: (int)_size);
420
else
421
mWidgetTrack
->
setSize
(((
int
)_size < (
int
)
mMinTrackSize
) ? (
int
)mMinTrackSize : (
int
)_size,
mWidgetTrack
->
getHeight
());
422
}
423
424
updateTrack
();
425
}
426
427
int
ScrollBar::getTrackSize
()
const
428
{
429
if
(
mWidgetTrack
!=
nullptr
)
430
{
431
if
(
mVerticalAlignment
)
432
return
mWidgetTrack
->
getHeight
();
433
else
434
return
mWidgetTrack
->
getWidth
();
435
}
436
return
1;
437
}
438
439
int
ScrollBar::getLineSize
()
const
440
{
441
return
getTrackPlaceLength
() - (int)(
mSkinRangeStart
+
mSkinRangeEnd
);
442
}
443
444
void
ScrollBar::onMouseWheel
(
int
_rel)
445
{
446
notifyMouseWheel
(
nullptr
, _rel);
447
448
Base::onMouseWheel
(_rel);
449
}
450
451
void
ScrollBar::notifyMouseWheel
(
Widget
* _sender,
int
_rel)
452
{
453
if
(
mScrollRange
< 2)
454
return
;
455
456
int
offset =
mScrollPosition
;
457
if
(_rel < 0)
458
offset +=
SCROLL_MOUSE_WHEEL
;
459
else
460
offset -=
SCROLL_MOUSE_WHEEL
;
461
462
if
(offset < 0)
463
offset = 0;
464
else
if
(offset > (
int
)(
mScrollRange
- 1))
465
offset =
mScrollRange
- 1;
466
467
if
((
size_t
)offset !=
mScrollPosition
)
468
{
469
mScrollPosition
= offset;
470
// оповещаем
471
eventScrollChangePosition
(
this
, (
int
)
mScrollPosition
);
472
updateTrack
();
473
}
474
}
475
476
void
ScrollBar::setPropertyOverride
(
const
std::string& _key,
const
std::string& _value)
477
{
478
if
(_key ==
"Range"
)
479
setScrollRange
(utility::parseValue<size_t>(_value));
480
else
if
(_key ==
"RangePosition"
)
481
setScrollPosition
(utility::parseValue<size_t>(_value));
482
else
if
(_key ==
"Page"
)
483
setScrollPage
(utility::parseValue<size_t>(_value));
484
else
if
(_key ==
"ViewPage"
)
485
setScrollViewPage
(utility::parseValue<size_t>(_value));
486
else
if
(_key ==
"MoveToClick"
)
487
setMoveToClick
(utility::parseValue<bool>(_value));
488
else
if
(_key ==
"VerticalAlignment"
)
489
setVerticalAlignment
(utility::parseValue<bool>(_value));
490
else
491
{
492
Base::setPropertyOverride
(_key, _value);
493
return
;
494
}
495
eventChangeProperty
(
this
, _key, _value);
496
}
497
498
size_t
ScrollBar::getScrollRange
()
const
499
{
500
return
mScrollRange
;
501
}
502
503
size_t
ScrollBar::getScrollPosition
()
const
504
{
505
return
mScrollPosition
;
506
}
507
508
void
ScrollBar::setScrollPage
(
size_t
_value)
509
{
510
mScrollPage
= _value;
511
}
512
513
size_t
ScrollBar::getScrollPage
()
const
514
{
515
return
mScrollPage
;
516
}
517
518
void
ScrollBar::setScrollViewPage
(
size_t
_value)
519
{
520
mScrollViewPage
= _value;
521
}
522
523
size_t
ScrollBar::getScrollViewPage
()
const
524
{
525
return
mScrollViewPage
;
526
}
527
528
void
ScrollBar::setMinTrackSize
(
int
_value)
529
{
530
mMinTrackSize
= _value;
531
}
532
533
int
ScrollBar::getMinTrackSize
()
const
534
{
535
return
mMinTrackSize
;
536
}
537
538
void
ScrollBar::setMoveToClick
(
bool
_value)
539
{
540
mMoveToClick
= _value;
541
}
542
543
bool
ScrollBar::getMoveToClick
()
const
544
{
545
return
mMoveToClick
;
546
}
547
548
void
ScrollBar::setPosition
(
int
_left,
int
_top)
549
{
550
setPosition
(
IntPoint
(_left, _top));
551
}
552
553
void
ScrollBar::setSize
(
int
_width,
int
_height)
554
{
555
setSize
(
IntSize
(_width, _height));
556
}
557
558
void
ScrollBar::setCoord
(
int
_left,
int
_top,
int
_width,
int
_height)
559
{
560
setCoord
(
IntCoord
(_left, _top, _width, _height));
561
}
562
563
int
ScrollBar::getTrackPlaceLength
()
const
564
{
565
if
(
mWidgetTrack
!=
nullptr
)
566
{
567
if
(
mVerticalAlignment
)
568
return
mWidgetTrack
->
getParent
()->
getHeight
();
569
else
570
return
mWidgetTrack
->
getParent
()->
getWidth
();
571
}
572
return
0;
573
}
574
575
void
ScrollBar::setVerticalAlignment
(
bool
_value)
576
{
577
mVerticalAlignment
= _value;
578
579
updateTrack
();
580
}
581
582
bool
ScrollBar::getVerticalAlignment
()
const
583
{
584
return
mVerticalAlignment
;
585
}
586
587
}
// namespace MyGUI
Generated on Tue Apr 30 2013 18:25:42 for MyGUI by
1.8.1.2