aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CGUIScrollBar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CGUIScrollBar.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CGUIScrollBar.cpp569
1 files changed, 569 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CGUIScrollBar.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CGUIScrollBar.cpp
new file mode 100644
index 0000000..b65699e
--- /dev/null
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CGUIScrollBar.cpp
@@ -0,0 +1,569 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CGUIScrollBar.h"
6#ifdef _IRR_COMPILE_WITH_GUI_
7
8#include "IGUISkin.h"
9#include "IGUIEnvironment.h"
10#include "IVideoDriver.h"
11#include "CGUIButton.h"
12#include "IGUIFont.h"
13#include "IGUIFontBitmap.h"
14#include "os.h"
15
16namespace irr
17{
18namespace gui
19{
20
21
22//! constructor
23CGUIScrollBar::CGUIScrollBar(bool horizontal, IGUIEnvironment* environment,
24 IGUIElement* parent, s32 id,
25 core::rect<s32> rectangle, bool noclip)
26 : IGUIScrollBar(environment, parent, id, rectangle), UpButton(0),
27 DownButton(0), Dragging(false), Horizontal(horizontal),
28 DraggedBySlider(false), TrayClick(false), Pos(0), DrawPos(0),
29 DrawHeight(0), Min(0), Max(100), SmallStep(10), LargeStep(50), DesiredPos(0),
30 LastChange(0)
31{
32 #ifdef _DEBUG
33 setDebugName("CGUIScrollBar");
34 #endif
35
36 refreshControls();
37
38 setNotClipped(noclip);
39
40 // this element can be tabbed to
41 setTabStop(true);
42 setTabOrder(-1);
43
44 setPos(0);
45}
46
47
48//! destructor
49CGUIScrollBar::~CGUIScrollBar()
50{
51 if (UpButton)
52 UpButton->drop();
53
54 if (DownButton)
55 DownButton->drop();
56}
57
58
59//! called if an event happened.
60bool CGUIScrollBar::OnEvent(const SEvent& event)
61{
62 if (isEnabled())
63 {
64
65 switch(event.EventType)
66 {
67 case EET_KEY_INPUT_EVENT:
68 if (event.KeyInput.PressedDown)
69 {
70 const s32 oldPos = Pos;
71 bool absorb = true;
72 switch (event.KeyInput.Key)
73 {
74 case KEY_LEFT:
75 case KEY_UP:
76 setPos(Pos-SmallStep);
77 break;
78 case KEY_RIGHT:
79 case KEY_DOWN:
80 setPos(Pos+SmallStep);
81 break;
82 case KEY_HOME:
83 setPos(Min);
84 break;
85 case KEY_PRIOR:
86 setPos(Pos-LargeStep);
87 break;
88 case KEY_END:
89 setPos(Max);
90 break;
91 case KEY_NEXT:
92 setPos(Pos+LargeStep);
93 break;
94 default:
95 absorb = false;
96 }
97
98 if (Pos != oldPos)
99 {
100 SEvent newEvent;
101 newEvent.EventType = EET_GUI_EVENT;
102 newEvent.GUIEvent.Caller = this;
103 newEvent.GUIEvent.Element = 0;
104 newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
105 Parent->OnEvent(newEvent);
106 }
107 if (absorb)
108 return true;
109 }
110 break;
111 case EET_GUI_EVENT:
112 if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
113 {
114 if (event.GUIEvent.Caller == UpButton)
115 setPos(Pos-SmallStep);
116 else
117 if (event.GUIEvent.Caller == DownButton)
118 setPos(Pos+SmallStep);
119
120 SEvent newEvent;
121 newEvent.EventType = EET_GUI_EVENT;
122 newEvent.GUIEvent.Caller = this;
123 newEvent.GUIEvent.Element = 0;
124 newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
125 Parent->OnEvent(newEvent);
126
127 return true;
128 }
129 else
130 if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
131 {
132 if (event.GUIEvent.Caller == this)
133 Dragging = false;
134 }
135 break;
136 case EET_MOUSE_INPUT_EVENT:
137 {
138 const core::position2di p(event.MouseInput.X, event.MouseInput.Y);
139 bool isInside = isPointInside ( p );
140 switch(event.MouseInput.Event)
141 {
142 case EMIE_MOUSE_WHEEL:
143 if (Environment->hasFocus(this))
144 {
145 // thanks to a bug report by REAPER
146 // thanks to tommi by tommi for another bugfix
147 // everybody needs a little thanking. hallo niko!;-)
148 setPos( getPos() +
149 ( (event.MouseInput.Wheel < 0 ? -1 : 1) * SmallStep * (Horizontal ? 1 : -1 ) )
150 );
151
152 SEvent newEvent;
153 newEvent.EventType = EET_GUI_EVENT;
154 newEvent.GUIEvent.Caller = this;
155 newEvent.GUIEvent.Element = 0;
156 newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
157 Parent->OnEvent(newEvent);
158 return true;
159 }
160 break;
161 case EMIE_LMOUSE_PRESSED_DOWN:
162 {
163 if (isInside)
164 {
165 Dragging = true;
166 DraggedBySlider = SliderRect.isPointInside(p);
167 TrayClick = !DraggedBySlider;
168 DesiredPos = getPosFromMousePos(p);
169 Environment->setFocus ( this );
170 return true;
171 }
172 break;
173 }
174 case EMIE_LMOUSE_LEFT_UP:
175 case EMIE_MOUSE_MOVED:
176 {
177 if ( !event.MouseInput.isLeftPressed () )
178 Dragging = false;
179
180 if ( !Dragging )
181 {
182 if ( event.MouseInput.Event == EMIE_MOUSE_MOVED )
183 break;
184 return isInside;
185 }
186
187 if ( event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP )
188 Dragging = false;
189
190 const s32 newPos = getPosFromMousePos(p);
191 const s32 oldPos = Pos;
192
193 if (!DraggedBySlider)
194 {
195 if ( isInside )
196 {
197 DraggedBySlider = SliderRect.isPointInside(p);
198 TrayClick = !DraggedBySlider;
199 }
200
201 if (DraggedBySlider)
202 {
203 setPos(newPos);
204 }
205 else
206 {
207 TrayClick = false;
208 if (event.MouseInput.Event == EMIE_MOUSE_MOVED)
209 return isInside;
210 }
211 }
212
213 if (DraggedBySlider)
214 {
215 setPos(newPos);
216 }
217 else
218 {
219 DesiredPos = newPos;
220 }
221
222 if (Pos != oldPos && Parent)
223 {
224 SEvent newEvent;
225 newEvent.EventType = EET_GUI_EVENT;
226 newEvent.GUIEvent.Caller = this;
227 newEvent.GUIEvent.Element = 0;
228 newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
229 Parent->OnEvent(newEvent);
230 }
231 return isInside;
232 } break;
233
234 default:
235 break;
236 }
237 } break;
238 default:
239 break;
240 }
241 }
242
243 return IGUIElement::OnEvent(event);
244}
245
246void CGUIScrollBar::OnPostRender(u32 timeMs)
247{
248 if (Dragging && !DraggedBySlider && TrayClick && timeMs > LastChange + 200)
249 {
250 LastChange = timeMs;
251
252 const s32 oldPos = Pos;
253
254 if (DesiredPos >= Pos + LargeStep)
255 setPos(Pos + LargeStep);
256 else
257 if (DesiredPos <= Pos - LargeStep)
258 setPos(Pos - LargeStep);
259 else
260 if (DesiredPos >= Pos - LargeStep && DesiredPos <= Pos + LargeStep)
261 setPos(DesiredPos);
262
263 if (Pos != oldPos && Parent)
264 {
265 SEvent newEvent;
266 newEvent.EventType = EET_GUI_EVENT;
267 newEvent.GUIEvent.Caller = this;
268 newEvent.GUIEvent.Element = 0;
269 newEvent.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED;
270 Parent->OnEvent(newEvent);
271 }
272 }
273
274}
275
276//! draws the element and its children
277void CGUIScrollBar::draw()
278{
279 if (!IsVisible)
280 return;
281
282 IGUISkin* skin = Environment->getSkin();
283 if (!skin)
284 return;
285
286
287 video::SColor iconColor = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL);
288 if ( iconColor != CurrentIconColor )
289 {
290 refreshControls();
291 }
292
293
294 SliderRect = AbsoluteRect;
295
296 // draws the background
297 skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR), SliderRect, &AbsoluteClippingRect);
298
299 if ( core::isnotzero ( range() ) )
300 {
301 // recalculate slider rectangle
302 if (Horizontal)
303 {
304 SliderRect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + DrawPos + RelativeRect.getHeight() - DrawHeight/2;
305 SliderRect.LowerRightCorner.X = SliderRect.UpperLeftCorner.X + DrawHeight;
306 }
307 else
308 {
309 SliderRect.UpperLeftCorner.Y = AbsoluteRect.UpperLeftCorner.Y + DrawPos + RelativeRect.getWidth() - DrawHeight/2;
310 SliderRect.LowerRightCorner.Y = SliderRect.UpperLeftCorner.Y + DrawHeight;
311 }
312
313 skin->draw3DButtonPaneStandard(this, SliderRect, &AbsoluteClippingRect);
314 }
315
316 // draw buttons
317 IGUIElement::draw();
318}
319
320
321void CGUIScrollBar::updateAbsolutePosition()
322{
323 IGUIElement::updateAbsolutePosition();
324 // todo: properly resize
325 refreshControls();
326 setPos ( Pos );
327}
328
329//!
330s32 CGUIScrollBar::getPosFromMousePos(const core::position2di &pos) const
331{
332 f32 w, p;
333 if (Horizontal)
334 {
335 w = RelativeRect.getWidth() - f32(RelativeRect.getHeight())*3.0f;
336 p = pos.X - AbsoluteRect.UpperLeftCorner.X - RelativeRect.getHeight()*1.5f;
337 }
338 else
339 {
340 w = RelativeRect.getHeight() - f32(RelativeRect.getWidth())*3.0f;
341 p = pos.Y - AbsoluteRect.UpperLeftCorner.Y - RelativeRect.getWidth()*1.5f;
342 }
343 return (s32) ( p/w * range() ) + Min;
344}
345
346
347//! sets the position of the scrollbar
348void CGUIScrollBar::setPos(s32 pos)
349{
350 Pos = core::s32_clamp ( pos, Min, Max );
351
352 if (Horizontal)
353 {
354 f32 f = (RelativeRect.getWidth() - ((f32)RelativeRect.getHeight()*3.0f)) / range();
355 DrawPos = (s32)( ( ( Pos - Min ) * f) + ((f32)RelativeRect.getHeight() * 0.5f));
356 DrawHeight = RelativeRect.getHeight();
357 }
358 else
359 {
360 f32 f = (RelativeRect.getHeight() - ((f32)RelativeRect.getWidth()*3.0f)) / range();
361
362 DrawPos = (s32)( ( ( Pos - Min ) * f) + ((f32)RelativeRect.getWidth() * 0.5f));
363 DrawHeight = RelativeRect.getWidth();
364 }
365
366}
367
368
369//! gets the small step value
370s32 CGUIScrollBar::getSmallStep() const
371{
372 return SmallStep;
373}
374
375
376//! sets the small step value
377void CGUIScrollBar::setSmallStep(s32 step)
378{
379 if (step > 0)
380 SmallStep = step;
381 else
382 SmallStep = 10;
383}
384
385
386//! gets the small step value
387s32 CGUIScrollBar::getLargeStep() const
388{
389 return LargeStep;
390}
391
392
393//! sets the small step value
394void CGUIScrollBar::setLargeStep(s32 step)
395{
396 if (step > 0)
397 LargeStep = step;
398 else
399 LargeStep = 50;
400}
401
402
403//! gets the maximum value of the scrollbar.
404s32 CGUIScrollBar::getMax() const
405{
406 return Max;
407}
408
409
410//! sets the maximum value of the scrollbar.
411void CGUIScrollBar::setMax(s32 max)
412{
413 Max = max;
414 if ( Min > Max )
415 Min = Max;
416
417 bool enable = core::isnotzero ( range() );
418 UpButton->setEnabled(enable);
419 DownButton->setEnabled(enable);
420 setPos(Pos);
421}
422
423//! gets the minimum value of the scrollbar.
424s32 CGUIScrollBar::getMin() const
425{
426 return Min;
427}
428
429
430//! sets the minimum value of the scrollbar.
431void CGUIScrollBar::setMin(s32 min)
432{
433 Min = min;
434 if ( Max < Min )
435 Max = Min;
436
437
438 bool enable = core::isnotzero ( range() );
439 UpButton->setEnabled(enable);
440 DownButton->setEnabled(enable);
441 setPos(Pos);
442}
443
444
445//! gets the current position of the scrollbar
446s32 CGUIScrollBar::getPos() const
447{
448 return Pos;
449}
450
451
452//! refreshes the position and text on child buttons
453void CGUIScrollBar::refreshControls()
454{
455 CurrentIconColor = video::SColor(255,255,255,255);
456
457 IGUISkin* skin = Environment->getSkin();
458 IGUISpriteBank* sprites = 0;
459
460 if (skin)
461 {
462 sprites = skin->getSpriteBank();
463 CurrentIconColor = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL);
464 }
465
466 if (Horizontal)
467 {
468 s32 h = RelativeRect.getHeight();
469 if (!UpButton)
470 {
471 UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, h, h), NoClip);
472 UpButton->setSubElement(true);
473 UpButton->setTabStop(false);
474 }
475 if (sprites)
476 {
477 UpButton->setSpriteBank(sprites);
478 UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_LEFT), CurrentIconColor);
479 UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_LEFT), CurrentIconColor);
480 }
481 UpButton->setRelativePosition(core::rect<s32>(0,0, h, h));
482 UpButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
483 if (!DownButton)
484 {
485 DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h), NoClip);
486 DownButton->setSubElement(true);
487 DownButton->setTabStop(false);
488 }
489 if (sprites)
490 {
491 DownButton->setSpriteBank(sprites);
492 DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_RIGHT), CurrentIconColor);
493 DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_RIGHT), CurrentIconColor);
494 }
495 DownButton->setRelativePosition(core::rect<s32>(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h));
496 DownButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
497 }
498 else
499 {
500 s32 w = RelativeRect.getWidth();
501 if (!UpButton)
502 {
503 UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, w, w), NoClip);
504 UpButton->setSubElement(true);
505 UpButton->setTabStop(false);
506 }
507 if (sprites)
508 {
509 UpButton->setSpriteBank(sprites);
510 UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_UP), CurrentIconColor);
511 UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_UP), CurrentIconColor);
512 }
513 UpButton->setRelativePosition(core::rect<s32>(0,0, w, w));
514 UpButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
515 if (!DownButton)
516 {
517 DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight()), NoClip);
518 DownButton->setSubElement(true);
519 DownButton->setTabStop(false);
520 }
521 if (sprites)
522 {
523 DownButton->setSpriteBank(sprites);
524 DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), CurrentIconColor);
525 DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), CurrentIconColor);
526 }
527 DownButton->setRelativePosition(core::rect<s32>(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight()));
528 DownButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT);
529 }
530}
531
532
533//! Writes attributes of the element.
534void CGUIScrollBar::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
535{
536 IGUIScrollBar::serializeAttributes(out,options);
537
538 out->addBool("Horizontal", Horizontal);
539 out->addInt ("Value", Pos);
540 out->addInt ("Min", Min);
541 out->addInt ("Max", Max);
542 out->addInt ("SmallStep", SmallStep);
543 out->addInt ("LargeStep", LargeStep);
544 // CurrentIconColor - not serialized as continuiously updated
545}
546
547
548//! Reads attributes of the element
549void CGUIScrollBar::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
550{
551 IGUIScrollBar::deserializeAttributes(in,options);
552
553 Horizontal = in->getAttributeAsBool("Horizontal");
554 setMin(in->getAttributeAsInt("Min"));
555 setMax(in->getAttributeAsInt("Max"));
556 setPos(in->getAttributeAsInt("Value"));
557 setSmallStep(in->getAttributeAsInt("SmallStep"));
558 setLargeStep(in->getAttributeAsInt("LargeStep"));
559 // CurrentIconColor - not serialized as continuiously updated
560
561 refreshControls();
562}
563
564
565} // end namespace gui
566} // end namespace irr
567
568#endif // _IRR_COMPILE_WITH_GUI_
569