comparison ext/guichan-0.8.1/src/widgets/scrollarea.cpp @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
1 /* _______ __ __ __ ______ __ __ _______ __ __
2 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
3 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
4 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
5 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
6 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
7 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
8 *
9 * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
10 *
11 *
12 * Per Larsson a.k.a finalman
13 * Olof Naessén a.k.a jansem/yakslem
14 *
15 * Visit: http://guichan.sourceforge.net
16 *
17 * License: (BSD)
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
26 * distribution.
27 * 3. Neither the name of Guichan nor the names of its contributors may
28 * be used to endorse or promote products derived from this software
29 * without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
37 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
38 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 /*
45 * For comments regarding functions please see the header file.
46 */
47
48 #include "guichan/widgets/scrollarea.hpp"
49
50 #include "guichan/exception.hpp"
51 #include "guichan/graphics.hpp"
52
53 namespace gcn
54 {
55 ScrollArea::ScrollArea()
56 {
57 mVScroll = 0;
58 mHScroll = 0;
59 mHPolicy = SHOW_AUTO;
60 mVPolicy = SHOW_AUTO;
61 mScrollbarWidth = 12;
62 mUpButtonPressed = false;
63 mDownButtonPressed = false;
64 mLeftButtonPressed = false;
65 mRightButtonPressed = false;
66 mUpButtonScrollAmount = 10;
67 mDownButtonScrollAmount = 10;
68 mLeftButtonScrollAmount = 10;
69 mRightButtonScrollAmount = 10;
70 mIsVerticalMarkerDragged = false;
71 mIsHorizontalMarkerDragged =false;
72 mOpaque = true;
73
74 addMouseListener(this);
75 }
76
77 ScrollArea::ScrollArea(Widget *content)
78 {
79 mVScroll = 0;
80 mHScroll = 0;
81 mHPolicy = SHOW_AUTO;
82 mVPolicy = SHOW_AUTO;
83 mScrollbarWidth = 12;
84 mUpButtonPressed = false;
85 mDownButtonPressed = false;
86 mLeftButtonPressed = false;
87 mRightButtonPressed = false;
88 mUpButtonScrollAmount = 10;
89 mDownButtonScrollAmount = 10;
90 mLeftButtonScrollAmount = 10;
91 mRightButtonScrollAmount = 10;
92 mIsVerticalMarkerDragged = false;
93 mIsHorizontalMarkerDragged =false;
94 mOpaque = true;
95
96 setContent(content);
97 addMouseListener(this);
98 }
99
100 ScrollArea::ScrollArea(Widget *content,
101 ScrollPolicy hPolicy,
102 ScrollPolicy vPolicy)
103 {
104 mVScroll = 0;
105 mHScroll = 0;
106 mHPolicy = hPolicy;
107 mVPolicy = vPolicy;
108 mScrollbarWidth = 12;
109 mUpButtonPressed = false;
110 mDownButtonPressed = false;
111 mLeftButtonPressed = false;
112 mRightButtonPressed = false;
113 mUpButtonScrollAmount = 10;
114 mDownButtonScrollAmount = 10;
115 mLeftButtonScrollAmount = 10;
116 mRightButtonScrollAmount = 10;
117 mIsVerticalMarkerDragged = false;
118 mIsHorizontalMarkerDragged =false;
119 mOpaque = true;
120
121 setContent(content);
122 addMouseListener(this);
123 }
124
125 ScrollArea::~ScrollArea()
126 {
127 setContent(NULL);
128 }
129
130 void ScrollArea::setContent(Widget* widget)
131 {
132 if (widget != NULL)
133 {
134 clear();
135 add(widget);
136 widget->setPosition(0,0);
137 }
138 else
139 {
140 clear();
141 }
142
143 checkPolicies();
144 }
145
146 Widget* ScrollArea::getContent()
147 {
148 if (mWidgets.size() > 0)
149 {
150 return *mWidgets.begin();
151 }
152
153 return NULL;
154 }
155
156 void ScrollArea::setHorizontalScrollPolicy(ScrollPolicy hPolicy)
157 {
158 mHPolicy = hPolicy;
159 checkPolicies();
160 }
161
162 ScrollArea::ScrollPolicy ScrollArea::getHorizontalScrollPolicy() const
163 {
164 return mHPolicy;
165 }
166
167 void ScrollArea::setVerticalScrollPolicy(ScrollPolicy vPolicy)
168 {
169 mVPolicy = vPolicy;
170 checkPolicies();
171 }
172
173 ScrollArea::ScrollPolicy ScrollArea::getVerticalScrollPolicy() const
174 {
175 return mVPolicy;
176 }
177
178 void ScrollArea::setScrollPolicy(ScrollPolicy hPolicy, ScrollPolicy vPolicy)
179 {
180 mHPolicy = hPolicy;
181 mVPolicy = vPolicy;
182 checkPolicies();
183 }
184
185 void ScrollArea::setVerticalScrollAmount(int vScroll)
186 {
187 int max = getVerticalMaxScroll();
188
189 mVScroll = vScroll;
190
191 if (vScroll > max)
192 {
193 mVScroll = max;
194 }
195
196 if (vScroll < 0)
197 {
198 mVScroll = 0;
199 }
200 }
201
202 int ScrollArea::getVerticalScrollAmount() const
203 {
204 return mVScroll;
205 }
206
207 void ScrollArea::setHorizontalScrollAmount(int hScroll)
208 {
209 int max = getHorizontalMaxScroll();
210
211 mHScroll = hScroll;
212
213 if (hScroll > max)
214 {
215 mHScroll = max;
216 }
217 else if (hScroll < 0)
218 {
219 mHScroll = 0;
220 }
221 }
222
223 int ScrollArea::getHorizontalScrollAmount() const
224 {
225 return mHScroll;
226 }
227
228 void ScrollArea::setScrollAmount(int hScroll, int vScroll)
229 {
230 setHorizontalScrollAmount(hScroll);
231 setVerticalScrollAmount(vScroll);
232 }
233
234 int ScrollArea::getHorizontalMaxScroll()
235 {
236 checkPolicies();
237
238 if (getContent() == NULL)
239 {
240 return 0;
241 }
242
243 int value = getContent()->getWidth() - getChildrenArea().width +
244 2 * getContent()->getFrameSize();
245
246 if (value < 0)
247 {
248 return 0;
249 }
250
251 return value;
252 }
253
254 int ScrollArea::getVerticalMaxScroll()
255 {
256 checkPolicies();
257
258 if (getContent() == NULL)
259 {
260 return 0;
261 }
262
263 int value;
264
265 value = getContent()->getHeight() - getChildrenArea().height +
266 2 * getContent()->getFrameSize();
267
268 if (value < 0)
269 {
270 return 0;
271 }
272
273 return value;
274 }
275
276 void ScrollArea::setScrollbarWidth(int width)
277 {
278 if (width > 0)
279 {
280 mScrollbarWidth = width;
281 }
282 else
283 {
284 throw GCN_EXCEPTION("Width should be greater then 0.");
285 }
286 }
287
288 int ScrollArea::getScrollbarWidth() const
289 {
290 return mScrollbarWidth;
291 }
292
293 void ScrollArea::mousePressed(MouseEvent& mouseEvent)
294 {
295 int x = mouseEvent.getX();
296 int y = mouseEvent.getY();
297
298 if (getUpButtonDimension().isPointInRect(x, y))
299 {
300 setVerticalScrollAmount(getVerticalScrollAmount()
301 - mUpButtonScrollAmount);
302 mUpButtonPressed = true;
303 }
304 else if (getDownButtonDimension().isPointInRect(x, y))
305 {
306 setVerticalScrollAmount(getVerticalScrollAmount()
307 + mDownButtonScrollAmount);
308 mDownButtonPressed = true;
309 }
310 else if (getLeftButtonDimension().isPointInRect(x, y))
311 {
312 setHorizontalScrollAmount(getHorizontalScrollAmount()
313 - mLeftButtonScrollAmount);
314 mLeftButtonPressed = true;
315 }
316 else if (getRightButtonDimension().isPointInRect(x, y))
317 {
318 setHorizontalScrollAmount(getHorizontalScrollAmount()
319 + mRightButtonScrollAmount);
320 mRightButtonPressed = true;
321 }
322 else if (getVerticalMarkerDimension().isPointInRect(x, y))
323 {
324 mIsHorizontalMarkerDragged = false;
325 mIsVerticalMarkerDragged = true;
326
327 mVerticalMarkerDragOffset = y - getVerticalMarkerDimension().y;
328 }
329 else if (getVerticalBarDimension().isPointInRect(x,y))
330 {
331 if (y < getVerticalMarkerDimension().y)
332 {
333 setVerticalScrollAmount(getVerticalScrollAmount()
334 - (int)(getChildrenArea().height * 0.95));
335 }
336 else
337 {
338 setVerticalScrollAmount(getVerticalScrollAmount()
339 + (int)(getChildrenArea().height * 0.95));
340 }
341 }
342 else if (getHorizontalMarkerDimension().isPointInRect(x, y))
343 {
344 mIsHorizontalMarkerDragged = true;
345 mIsVerticalMarkerDragged = false;
346
347 mHorizontalMarkerDragOffset = x - getHorizontalMarkerDimension().x;
348 }
349 else if (getHorizontalBarDimension().isPointInRect(x,y))
350 {
351 if (x < getHorizontalMarkerDimension().x)
352 {
353 setHorizontalScrollAmount(getHorizontalScrollAmount()
354 - (int)(getChildrenArea().width * 0.95));
355 }
356 else
357 {
358 setHorizontalScrollAmount(getHorizontalScrollAmount()
359 + (int)(getChildrenArea().width * 0.95));
360 }
361 }
362 }
363
364 void ScrollArea::mouseReleased(MouseEvent& mouseEvent)
365 {
366 mUpButtonPressed = false;
367 mDownButtonPressed = false;
368 mLeftButtonPressed = false;
369 mRightButtonPressed = false;
370 mIsHorizontalMarkerDragged = false;
371 mIsVerticalMarkerDragged = false;
372
373 mouseEvent.consume();
374 }
375
376 void ScrollArea::mouseDragged(MouseEvent& mouseEvent)
377 {
378 if (mIsVerticalMarkerDragged)
379 {
380 int pos = mouseEvent.getY() - getVerticalBarDimension().y - mVerticalMarkerDragOffset;
381 int length = getVerticalMarkerDimension().height;
382
383 Rectangle barDim = getVerticalBarDimension();
384
385 if ((barDim.height - length) > 0)
386 {
387 setVerticalScrollAmount((getVerticalMaxScroll() * pos)
388 / (barDim.height - length));
389 }
390 else
391 {
392 setVerticalScrollAmount(0);
393 }
394 }
395
396 if (mIsHorizontalMarkerDragged)
397 {
398 int pos = mouseEvent.getX() - getHorizontalBarDimension().x - mHorizontalMarkerDragOffset;
399 int length = getHorizontalMarkerDimension().width;
400
401 Rectangle barDim = getHorizontalBarDimension();
402
403 if ((barDim.width - length) > 0)
404 {
405 setHorizontalScrollAmount((getHorizontalMaxScroll() * pos)
406 / (barDim.width - length));
407 }
408 else
409 {
410 setHorizontalScrollAmount(0);
411 }
412 }
413
414 mouseEvent.consume();
415 }
416
417 void ScrollArea::draw(Graphics *graphics)
418 {
419 drawBackground(graphics);
420
421 if (mVBarVisible)
422 {
423 drawUpButton(graphics);
424 drawDownButton(graphics);
425 drawVBar(graphics);
426 drawVMarker(graphics);
427 }
428
429 if (mHBarVisible)
430 {
431 drawLeftButton(graphics);
432 drawRightButton(graphics);
433 drawHBar(graphics);
434 drawHMarker(graphics);
435 }
436
437 if (mHBarVisible && mVBarVisible)
438 {
439 graphics->setColor(getBaseColor());
440 graphics->fillRectangle(Rectangle(getWidth() - mScrollbarWidth,
441 getHeight() - mScrollbarWidth,
442 mScrollbarWidth,
443 mScrollbarWidth));
444 }
445
446 drawChildren(graphics);
447 }
448
449 void ScrollArea::drawHBar(Graphics* graphics)
450 {
451 Rectangle dim = getHorizontalBarDimension();
452
453 graphics->pushClipArea(dim);
454
455 int alpha = getBaseColor().a;
456 Color trackColor = getBaseColor() - 0x101010;
457 trackColor.a = alpha;
458 Color shadowColor = getBaseColor() - 0x303030;
459 shadowColor.a = alpha;
460
461 graphics->setColor(trackColor);
462 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
463
464 graphics->setColor(shadowColor);
465 graphics->drawLine(0, 0, dim.width, 0);
466
467 graphics->popClipArea();
468 }
469
470 void ScrollArea::drawVBar(Graphics* graphics)
471 {
472 Rectangle dim = getVerticalBarDimension();
473
474 graphics->pushClipArea(dim);
475
476 int alpha = getBaseColor().a;
477 Color trackColor = getBaseColor() - 0x101010;
478 trackColor.a = alpha;
479 Color shadowColor = getBaseColor() - 0x303030;
480 shadowColor.a = alpha;
481
482 graphics->setColor(trackColor);
483 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
484
485 graphics->setColor(shadowColor);
486 graphics->drawLine(0, 0, 0, dim.height);
487
488 graphics->popClipArea();
489 }
490
491 void ScrollArea::drawBackground(Graphics *graphics)
492 {
493 if (isOpaque())
494 {
495 graphics->setColor(getBackgroundColor());
496 graphics->fillRectangle(getChildrenArea());
497 }
498 }
499
500 void ScrollArea::drawUpButton(Graphics* graphics)
501 {
502 Rectangle dim = getUpButtonDimension();
503 graphics->pushClipArea(dim);
504
505 Color highlightColor;
506 Color shadowColor;
507 Color faceColor;
508 int offset;
509 int alpha = getBaseColor().a;
510
511 if (mUpButtonPressed)
512 {
513 faceColor = getBaseColor() - 0x303030;
514 faceColor.a = alpha;
515 highlightColor = faceColor - 0x303030;
516 highlightColor.a = alpha;
517 shadowColor = getBaseColor();
518 shadowColor.a = alpha;
519
520 offset = 1;
521 }
522 else
523 {
524 faceColor = getBaseColor();
525 faceColor.a = alpha;
526 highlightColor = faceColor + 0x303030;
527 highlightColor.a = alpha;
528 shadowColor = faceColor - 0x303030;
529 shadowColor.a = alpha;
530
531 offset = 0;
532 }
533
534 graphics->setColor(faceColor);
535 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
536
537 graphics->setColor(highlightColor);
538 graphics->drawLine(0, 0, dim.width - 1, 0);
539 graphics->drawLine(0, 1, 0, dim.height - 1);
540
541 graphics->setColor(shadowColor);
542 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
543 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
544
545 graphics->setColor(getForegroundColor());
546
547 int i;
548 int w = dim.height / 2;
549 int h = w / 2 + 2;
550 for (i = 0; i < w / 2; ++i)
551 {
552 graphics->drawLine(w - i + offset,
553 i + h + offset,
554 w + i + offset,
555 i + h + offset);
556 }
557
558 graphics->popClipArea();
559 }
560
561 void ScrollArea::drawDownButton(Graphics* graphics)
562 {
563 Rectangle dim = getDownButtonDimension();
564 graphics->pushClipArea(dim);
565
566 Color highlightColor;
567 Color shadowColor;
568 Color faceColor;
569 int offset;
570 int alpha = getBaseColor().a;
571
572 if (mDownButtonPressed)
573 {
574 faceColor = getBaseColor() - 0x303030;
575 faceColor.a = alpha;
576 highlightColor = faceColor - 0x303030;
577 highlightColor.a = alpha;
578 shadowColor = getBaseColor();
579 shadowColor.a = alpha;
580
581 offset = 1;
582 }
583 else
584 {
585 faceColor = getBaseColor();
586 faceColor.a = alpha;
587 highlightColor = faceColor + 0x303030;
588 highlightColor.a = alpha;
589 shadowColor = faceColor - 0x303030;
590 shadowColor.a = alpha;
591
592 offset = 0;
593 }
594
595 graphics->setColor(faceColor);
596 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
597
598 graphics->setColor(highlightColor);
599 graphics->drawLine(0, 0, dim.width - 1, 0);
600 graphics->drawLine(0, 1, 0, dim.height - 1);
601
602 graphics->setColor(shadowColor);
603 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
604 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
605
606 graphics->setColor(getForegroundColor());
607
608 int i;
609 int w = dim.height / 2;
610 int h = w + 1;
611 for (i = 0; i < w / 2; ++i)
612 {
613 graphics->drawLine(w - i + offset,
614 -i + h + offset,
615 w + i + offset,
616 -i + h + offset);
617 }
618
619 graphics->popClipArea();
620 }
621
622 void ScrollArea::drawLeftButton(Graphics* graphics)
623 {
624 Rectangle dim = getLeftButtonDimension();
625 graphics->pushClipArea(dim);
626
627 Color highlightColor;
628 Color shadowColor;
629 Color faceColor;
630 int offset;
631 int alpha = getBaseColor().a;
632
633 if (mLeftButtonPressed)
634 {
635 faceColor = getBaseColor() - 0x303030;
636 faceColor.a = alpha;
637 highlightColor = faceColor - 0x303030;
638 highlightColor.a = alpha;
639 shadowColor = getBaseColor();
640 shadowColor.a = alpha;
641
642 offset = 1;
643 }
644 else
645 {
646 faceColor = getBaseColor();
647 faceColor.a = alpha;
648 highlightColor = faceColor + 0x303030;
649 highlightColor.a = alpha;
650 shadowColor = faceColor - 0x303030;
651 shadowColor.a = alpha;
652
653 offset = 0;
654 }
655
656 graphics->setColor(faceColor);
657 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
658
659 graphics->setColor(highlightColor);
660 graphics->drawLine(0, 0, dim.width - 1, 0);
661 graphics->drawLine(0, 1, 0, dim.height - 1);
662
663 graphics->setColor(shadowColor);
664 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
665 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
666
667 graphics->setColor(getForegroundColor());
668
669 int i;
670 int w = dim.width / 2;
671 int h = w - 2;
672 for (i = 0; i < w / 2; ++i)
673 {
674 graphics->drawLine(i + h + offset,
675 w - i + offset,
676 i + h + offset,
677 w + i + offset);
678 }
679
680 graphics->popClipArea();
681 }
682
683 void ScrollArea::drawRightButton(Graphics* graphics)
684 {
685 Rectangle dim = getRightButtonDimension();
686 graphics->pushClipArea(dim);
687
688 Color highlightColor;
689 Color shadowColor;
690 Color faceColor;
691 int offset;
692 int alpha = getBaseColor().a;
693
694 if (mRightButtonPressed)
695 {
696 faceColor = getBaseColor() - 0x303030;
697 faceColor.a = alpha;
698 highlightColor = faceColor - 0x303030;
699 highlightColor.a = alpha;
700 shadowColor = getBaseColor();
701 shadowColor.a = alpha;
702
703 offset = 1;
704 }
705 else
706 {
707 faceColor = getBaseColor();
708 faceColor.a = alpha;
709 highlightColor = faceColor + 0x303030;
710 highlightColor.a = alpha;
711 shadowColor = faceColor - 0x303030;
712 shadowColor.a = alpha;
713
714 offset = 0;
715 }
716
717 graphics->setColor(faceColor);
718 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
719
720 graphics->setColor(highlightColor);
721 graphics->drawLine(0, 0, dim.width - 1, 0);
722 graphics->drawLine(0, 1, 0, dim.height - 1);
723
724 graphics->setColor(shadowColor);
725 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
726 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
727
728 graphics->setColor(getForegroundColor());
729
730 int i;
731 int w = dim.width / 2;
732 int h = w + 1;
733 for (i = 0; i < w / 2; ++i)
734 {
735 graphics->drawLine(-i + h + offset,
736 w - i + offset,
737 -i + h + offset,
738 w + i + offset);
739 }
740
741 graphics->popClipArea();
742 }
743
744 void ScrollArea::drawVMarker(Graphics* graphics)
745 {
746 Rectangle dim = getVerticalMarkerDimension();
747 graphics->pushClipArea(dim);
748
749 int alpha = getBaseColor().a;
750 Color faceColor = getBaseColor();
751 faceColor.a = alpha;
752 Color highlightColor = faceColor + 0x303030;
753 highlightColor.a = alpha;
754 Color shadowColor = faceColor - 0x303030;
755 shadowColor.a = alpha;
756
757 graphics->setColor(faceColor);
758 graphics->fillRectangle(Rectangle(1, 1, dim.width - 1, dim.height - 1));
759
760 graphics->setColor(highlightColor);
761 graphics->drawLine(0, 0, dim.width - 1, 0);
762 graphics->drawLine(0, 1, 0, dim.height - 1);
763
764 graphics->setColor(shadowColor);
765 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
766 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
767
768 graphics->popClipArea();
769 }
770
771 void ScrollArea::drawHMarker(Graphics* graphics)
772 {
773 Rectangle dim = getHorizontalMarkerDimension();
774 graphics->pushClipArea(dim);
775
776 int alpha = getBaseColor().a;
777 Color faceColor = getBaseColor();
778 faceColor.a = alpha;
779 Color highlightColor = faceColor + 0x303030;
780 highlightColor.a = alpha;
781 Color shadowColor = faceColor - 0x303030;
782 shadowColor.a = alpha;
783
784 graphics->setColor(faceColor);
785 graphics->fillRectangle(Rectangle(1, 1, dim.width - 1, dim.height - 1));
786
787 graphics->setColor(highlightColor);
788 graphics->drawLine(0, 0, dim.width - 1, 0);
789 graphics->drawLine(0, 1, 0, dim.height - 1);
790
791 graphics->setColor(shadowColor);
792 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
793 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
794
795 graphics->popClipArea();
796 }
797
798 void ScrollArea::logic()
799 {
800 checkPolicies();
801
802 setVerticalScrollAmount(getVerticalScrollAmount());
803 setHorizontalScrollAmount(getHorizontalScrollAmount());
804
805 if (getContent() != NULL)
806 {
807 getContent()->setPosition(-mHScroll + getContent()->getFrameSize(),
808 -mVScroll + getContent()->getFrameSize());
809 getContent()->logic();
810 }
811 }
812
813 void ScrollArea::checkPolicies()
814 {
815 int w = getWidth();
816 int h = getHeight();
817
818 mHBarVisible = false;
819 mVBarVisible = false;
820
821
822 if (!getContent())
823 {
824 mHBarVisible = (mHPolicy == SHOW_ALWAYS);
825 mVBarVisible = (mVPolicy == SHOW_ALWAYS);
826 return;
827 }
828
829 if (mHPolicy == SHOW_AUTO &&
830 mVPolicy == SHOW_AUTO)
831 {
832 if (getContent()->getWidth() <= w
833 && getContent()->getHeight() <= h)
834 {
835 mHBarVisible = false;
836 mVBarVisible = false;
837 }
838
839 if (getContent()->getWidth() > w)
840 {
841 mHBarVisible = true;
842 }
843
844 if ((getContent()->getHeight() > h)
845 || (mHBarVisible && getContent()->getHeight() > h - mScrollbarWidth))
846 {
847 mVBarVisible = true;
848 }
849
850 if (mVBarVisible && getContent()->getWidth() > w - mScrollbarWidth)
851 {
852 mHBarVisible = true;
853 }
854
855 return;
856 }
857
858 switch (mHPolicy)
859 {
860 case SHOW_NEVER:
861 mHBarVisible = false;
862 break;
863
864 case SHOW_ALWAYS:
865 mHBarVisible = true;
866 break;
867
868 case SHOW_AUTO:
869 if (mVPolicy == SHOW_NEVER)
870 {
871 mHBarVisible = getContent()->getWidth() > w;
872 }
873 else // (mVPolicy == SHOW_ALWAYS)
874 {
875 mHBarVisible = getContent()->getWidth() > w - mScrollbarWidth;
876 }
877 break;
878
879 default:
880 throw GCN_EXCEPTION("Horizontal scroll policy invalid.");
881 }
882
883 switch (mVPolicy)
884 {
885 case SHOW_NEVER:
886 mVBarVisible = false;
887 break;
888
889 case SHOW_ALWAYS:
890 mVBarVisible = true;
891 break;
892
893 case SHOW_AUTO:
894 if (mHPolicy == SHOW_NEVER)
895 {
896 mVBarVisible = getContent()->getHeight() > h;
897 }
898 else // (mHPolicy == SHOW_ALWAYS)
899 {
900 mVBarVisible = getContent()->getHeight() > h - mScrollbarWidth;
901 }
902 break;
903 default:
904 throw GCN_EXCEPTION("Vertical scroll policy invalid.");
905 }
906 }
907
908 Rectangle ScrollArea::getUpButtonDimension()
909 {
910 if (!mVBarVisible)
911 {
912 return Rectangle(0, 0, 0, 0);
913 }
914
915 return Rectangle(getWidth() - mScrollbarWidth,
916 0,
917 mScrollbarWidth,
918 mScrollbarWidth);
919 }
920
921 Rectangle ScrollArea::getDownButtonDimension()
922 {
923 if (!mVBarVisible)
924 {
925 return Rectangle(0, 0, 0, 0);
926 }
927
928 if (mVBarVisible && mHBarVisible)
929 {
930 return Rectangle(getWidth() - mScrollbarWidth,
931 getHeight() - mScrollbarWidth*2,
932 mScrollbarWidth,
933 mScrollbarWidth);
934 }
935
936 return Rectangle(getWidth() - mScrollbarWidth,
937 getHeight() - mScrollbarWidth,
938 mScrollbarWidth,
939 mScrollbarWidth);
940 }
941
942 Rectangle ScrollArea::getLeftButtonDimension()
943 {
944 if (!mHBarVisible)
945 {
946 return Rectangle(0, 0, 0, 0);
947 }
948
949 return Rectangle(0,
950 getHeight() - mScrollbarWidth,
951 mScrollbarWidth,
952 mScrollbarWidth);
953 }
954
955 Rectangle ScrollArea::getRightButtonDimension()
956 {
957 if (!mHBarVisible)
958 {
959 return Rectangle(0, 0, 0, 0);
960 }
961
962 if (mVBarVisible && mHBarVisible)
963 {
964 return Rectangle(getWidth() - mScrollbarWidth*2,
965 getHeight() - mScrollbarWidth,
966 mScrollbarWidth,
967 mScrollbarWidth);
968 }
969
970 return Rectangle(getWidth() - mScrollbarWidth,
971 getHeight() - mScrollbarWidth,
972 mScrollbarWidth,
973 mScrollbarWidth);
974 }
975
976 Rectangle ScrollArea::getChildrenArea()
977 {
978 if (mVBarVisible && mHBarVisible)
979 {
980 return Rectangle(0, 0, getWidth() - mScrollbarWidth,
981 getHeight() - mScrollbarWidth);
982 }
983
984 if (mVBarVisible)
985 {
986 return Rectangle(0, 0, getWidth() - mScrollbarWidth, getHeight());
987 }
988
989 if (mHBarVisible)
990 {
991 return Rectangle(0, 0, getWidth(), getHeight() - mScrollbarWidth);
992 }
993
994 return Rectangle(0, 0, getWidth(), getHeight());
995 }
996
997 Rectangle ScrollArea::getVerticalBarDimension()
998 {
999 if (!mVBarVisible)
1000 {
1001 return Rectangle(0, 0, 0, 0);
1002 }
1003
1004 if (mHBarVisible)
1005 {
1006 return Rectangle(getWidth() - mScrollbarWidth,
1007 getUpButtonDimension().height,
1008 mScrollbarWidth,
1009 getHeight()
1010 - getUpButtonDimension().height
1011 - getDownButtonDimension().height
1012 - mScrollbarWidth);
1013 }
1014
1015 return Rectangle(getWidth() - mScrollbarWidth,
1016 getUpButtonDimension().height,
1017 mScrollbarWidth,
1018 getHeight()
1019 - getUpButtonDimension().height
1020 - getDownButtonDimension().height);
1021 }
1022
1023 Rectangle ScrollArea::getHorizontalBarDimension()
1024 {
1025 if (!mHBarVisible)
1026 {
1027 return Rectangle(0, 0, 0, 0);
1028 }
1029
1030 if (mVBarVisible)
1031 {
1032 return Rectangle(getLeftButtonDimension().width,
1033 getHeight() - mScrollbarWidth,
1034 getWidth()
1035 - getLeftButtonDimension().width
1036 - getRightButtonDimension().width
1037 - mScrollbarWidth,
1038 mScrollbarWidth);
1039 }
1040
1041 return Rectangle(getLeftButtonDimension().width,
1042 getHeight() - mScrollbarWidth,
1043 getWidth()
1044 - getLeftButtonDimension().width
1045 - getRightButtonDimension().width,
1046 mScrollbarWidth);
1047 }
1048
1049 Rectangle ScrollArea::getVerticalMarkerDimension()
1050 {
1051 if (!mVBarVisible)
1052 {
1053 return Rectangle(0, 0, 0, 0);
1054 }
1055
1056 int length, pos;
1057 Rectangle barDim = getVerticalBarDimension();
1058
1059 if (getContent() && getContent()->getHeight() != 0)
1060 {
1061 length = (barDim.height * getChildrenArea().height)
1062 / getContent()->getHeight();
1063 }
1064 else
1065 {
1066 length = barDim.height;
1067 }
1068
1069 if (length < mScrollbarWidth)
1070 {
1071 length = mScrollbarWidth;
1072 }
1073
1074 if (length > barDim.height)
1075 {
1076 length = barDim.height;
1077 }
1078
1079 if (getVerticalMaxScroll() != 0)
1080 {
1081 pos = ((barDim.height - length) * getVerticalScrollAmount())
1082 / getVerticalMaxScroll();
1083 }
1084 else
1085 {
1086 pos = 0;
1087 }
1088
1089 return Rectangle(barDim.x, barDim.y + pos, mScrollbarWidth, length);
1090 }
1091
1092 Rectangle ScrollArea::getHorizontalMarkerDimension()
1093 {
1094 if (!mHBarVisible)
1095 {
1096 return Rectangle(0, 0, 0, 0);
1097 }
1098
1099 int length, pos;
1100 Rectangle barDim = getHorizontalBarDimension();
1101
1102 if (getContent() && getContent()->getWidth() != 0)
1103 {
1104 length = (barDim.width * getChildrenArea().width)
1105 / getContent()->getWidth();
1106 }
1107 else
1108 {
1109 length = barDim.width;
1110 }
1111
1112 if (length < mScrollbarWidth)
1113 {
1114 length = mScrollbarWidth;
1115 }
1116
1117 if (length > barDim.width)
1118 {
1119 length = barDim.width;
1120 }
1121
1122 if (getHorizontalMaxScroll() != 0)
1123 {
1124 pos = ((barDim.width - length) * getHorizontalScrollAmount())
1125 / getHorizontalMaxScroll();
1126 }
1127 else
1128 {
1129 pos = 0;
1130 }
1131
1132 return Rectangle(barDim.x + pos, barDim.y, length, mScrollbarWidth);
1133 }
1134
1135 void ScrollArea::showWidgetPart(Widget* widget, Rectangle area)
1136 {
1137 if (widget != getContent())
1138 {
1139 throw GCN_EXCEPTION("Widget not content widget");
1140 }
1141
1142 BasicContainer::showWidgetPart(widget, area);
1143
1144 setHorizontalScrollAmount(getContent()->getFrameSize() - getContent()->getX());
1145 setVerticalScrollAmount(getContent()->getFrameSize() - getContent()->getY());
1146 }
1147
1148 Widget *ScrollArea::getWidgetAt(int x, int y)
1149 {
1150 if (getChildrenArea().isPointInRect(x, y))
1151 {
1152 return getContent();
1153 }
1154
1155 return NULL;
1156 }
1157
1158 void ScrollArea::mouseWheelMovedUp(MouseEvent& mouseEvent)
1159 {
1160 if (mouseEvent.isConsumed())
1161 {
1162 return;
1163 }
1164
1165 setVerticalScrollAmount(getVerticalScrollAmount() - getChildrenArea().height / 8);
1166
1167 mouseEvent.consume();
1168 }
1169
1170 void ScrollArea::mouseWheelMovedDown(MouseEvent& mouseEvent)
1171 {
1172 if (mouseEvent.isConsumed())
1173 {
1174 return;
1175 }
1176
1177 setVerticalScrollAmount(getVerticalScrollAmount() + getChildrenArea().height / 8);
1178
1179 mouseEvent.consume();
1180 }
1181
1182 void ScrollArea::setWidth(int width)
1183 {
1184 Widget::setWidth(width);
1185 checkPolicies();
1186 }
1187
1188 void ScrollArea::setHeight(int height)
1189 {
1190 Widget::setHeight(height);
1191 checkPolicies();
1192 }
1193
1194 void ScrollArea::setDimension(const Rectangle& dimension)
1195 {
1196 Widget::setDimension(dimension);
1197 checkPolicies();
1198 }
1199
1200 void ScrollArea::setLeftButtonScrollAmount(int amount)
1201 {
1202 mLeftButtonScrollAmount = amount;
1203 }
1204
1205 void ScrollArea::setRightButtonScrollAmount(int amount)
1206 {
1207 mRightButtonScrollAmount = amount;
1208 }
1209
1210 void ScrollArea::setUpButtonScrollAmount(int amount)
1211 {
1212 mUpButtonScrollAmount = amount;
1213 }
1214
1215 void ScrollArea::setDownButtonScrollAmount(int amount)
1216 {
1217 mDownButtonScrollAmount = amount;
1218 }
1219
1220 int ScrollArea::getLeftButtonScrollAmount() const
1221 {
1222 return mLeftButtonScrollAmount;
1223 }
1224
1225 int ScrollArea::getRightButtonScrollAmount() const
1226 {
1227 return mRightButtonScrollAmount;
1228 }
1229
1230 int ScrollArea::getUpButtonScrollAmount() const
1231 {
1232 return mUpButtonScrollAmount;
1233 }
1234
1235 int ScrollArea::getDownButtonScrollAmount() const
1236 {
1237 return mDownButtonScrollAmount;
1238 }
1239
1240 void ScrollArea::setOpaque(bool opaque)
1241 {
1242 mOpaque = opaque;
1243 }
1244
1245
1246 bool ScrollArea::isOpaque() const
1247 {
1248 return mOpaque;
1249 }
1250 }
1251
1252 /*
1253 * Wow! This is a looooong source file.
1254 */