comparison ext/guichan-0.8.2/src/widgets/scrollarea.cpp @ 378:64738befdf3b

bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author vtchill@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 11 Jan 2010 23:34:52 +0000
parents
children
comparison
equal deleted inserted replaced
377:fe6fb0e0ed23 378:64738befdf3b
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 Rectangle area = Rectangle(0,
979 0,
980 mVBarVisible ? getWidth() - mScrollbarWidth : getWidth(),
981 mHBarVisible ? getHeight() - mScrollbarWidth : getHeight());
982
983 if (area.width < 0 || area.height < 0)
984 return Rectangle();
985
986 return area;
987 }
988
989 Rectangle ScrollArea::getVerticalBarDimension()
990 {
991 if (!mVBarVisible)
992 {
993 return Rectangle(0, 0, 0, 0);
994 }
995
996 if (mHBarVisible)
997 {
998 return Rectangle(getWidth() - mScrollbarWidth,
999 getUpButtonDimension().height,
1000 mScrollbarWidth,
1001 getHeight()
1002 - getUpButtonDimension().height
1003 - getDownButtonDimension().height
1004 - mScrollbarWidth);
1005 }
1006
1007 return Rectangle(getWidth() - mScrollbarWidth,
1008 getUpButtonDimension().height,
1009 mScrollbarWidth,
1010 getHeight()
1011 - getUpButtonDimension().height
1012 - getDownButtonDimension().height);
1013 }
1014
1015 Rectangle ScrollArea::getHorizontalBarDimension()
1016 {
1017 if (!mHBarVisible)
1018 {
1019 return Rectangle(0, 0, 0, 0);
1020 }
1021
1022 if (mVBarVisible)
1023 {
1024 return Rectangle(getLeftButtonDimension().width,
1025 getHeight() - mScrollbarWidth,
1026 getWidth()
1027 - getLeftButtonDimension().width
1028 - getRightButtonDimension().width
1029 - mScrollbarWidth,
1030 mScrollbarWidth);
1031 }
1032
1033 return Rectangle(getLeftButtonDimension().width,
1034 getHeight() - mScrollbarWidth,
1035 getWidth()
1036 - getLeftButtonDimension().width
1037 - getRightButtonDimension().width,
1038 mScrollbarWidth);
1039 }
1040
1041 Rectangle ScrollArea::getVerticalMarkerDimension()
1042 {
1043 if (!mVBarVisible)
1044 {
1045 return Rectangle(0, 0, 0, 0);
1046 }
1047
1048 int length, pos;
1049 Rectangle barDim = getVerticalBarDimension();
1050
1051 if (getContent() && getContent()->getHeight() != 0)
1052 {
1053 length = (barDim.height * getChildrenArea().height)
1054 / getContent()->getHeight();
1055 }
1056 else
1057 {
1058 length = barDim.height;
1059 }
1060
1061 if (length < mScrollbarWidth)
1062 {
1063 length = mScrollbarWidth;
1064 }
1065
1066 if (length > barDim.height)
1067 {
1068 length = barDim.height;
1069 }
1070
1071 if (getVerticalMaxScroll() != 0)
1072 {
1073 pos = ((barDim.height - length) * getVerticalScrollAmount())
1074 / getVerticalMaxScroll();
1075 }
1076 else
1077 {
1078 pos = 0;
1079 }
1080
1081 return Rectangle(barDim.x, barDim.y + pos, mScrollbarWidth, length);
1082 }
1083
1084 Rectangle ScrollArea::getHorizontalMarkerDimension()
1085 {
1086 if (!mHBarVisible)
1087 {
1088 return Rectangle(0, 0, 0, 0);
1089 }
1090
1091 int length, pos;
1092 Rectangle barDim = getHorizontalBarDimension();
1093
1094 if (getContent() && getContent()->getWidth() != 0)
1095 {
1096 length = (barDim.width * getChildrenArea().width)
1097 / getContent()->getWidth();
1098 }
1099 else
1100 {
1101 length = barDim.width;
1102 }
1103
1104 if (length < mScrollbarWidth)
1105 {
1106 length = mScrollbarWidth;
1107 }
1108
1109 if (length > barDim.width)
1110 {
1111 length = barDim.width;
1112 }
1113
1114 if (getHorizontalMaxScroll() != 0)
1115 {
1116 pos = ((barDim.width - length) * getHorizontalScrollAmount())
1117 / getHorizontalMaxScroll();
1118 }
1119 else
1120 {
1121 pos = 0;
1122 }
1123
1124 return Rectangle(barDim.x + pos, barDim.y, length, mScrollbarWidth);
1125 }
1126
1127 void ScrollArea::showWidgetPart(Widget* widget, Rectangle area)
1128 {
1129 if (widget != getContent())
1130 {
1131 throw GCN_EXCEPTION("Widget not content widget");
1132 }
1133
1134 BasicContainer::showWidgetPart(widget, area);
1135
1136 setHorizontalScrollAmount(getContent()->getFrameSize() - getContent()->getX());
1137 setVerticalScrollAmount(getContent()->getFrameSize() - getContent()->getY());
1138 }
1139
1140 Widget *ScrollArea::getWidgetAt(int x, int y)
1141 {
1142 if (getChildrenArea().isPointInRect(x, y))
1143 {
1144 return getContent();
1145 }
1146
1147 return NULL;
1148 }
1149
1150 void ScrollArea::mouseWheelMovedUp(MouseEvent& mouseEvent)
1151 {
1152 if (mouseEvent.isConsumed())
1153 {
1154 return;
1155 }
1156
1157 setVerticalScrollAmount(getVerticalScrollAmount() - getChildrenArea().height / 8);
1158
1159 mouseEvent.consume();
1160 }
1161
1162 void ScrollArea::mouseWheelMovedDown(MouseEvent& mouseEvent)
1163 {
1164 if (mouseEvent.isConsumed())
1165 {
1166 return;
1167 }
1168
1169 setVerticalScrollAmount(getVerticalScrollAmount() + getChildrenArea().height / 8);
1170
1171 mouseEvent.consume();
1172 }
1173
1174 void ScrollArea::setWidth(int width)
1175 {
1176 Widget::setWidth(width);
1177 checkPolicies();
1178 }
1179
1180 void ScrollArea::setHeight(int height)
1181 {
1182 Widget::setHeight(height);
1183 checkPolicies();
1184 }
1185
1186 void ScrollArea::setDimension(const Rectangle& dimension)
1187 {
1188 Widget::setDimension(dimension);
1189 checkPolicies();
1190 }
1191
1192 void ScrollArea::setLeftButtonScrollAmount(int amount)
1193 {
1194 mLeftButtonScrollAmount = amount;
1195 }
1196
1197 void ScrollArea::setRightButtonScrollAmount(int amount)
1198 {
1199 mRightButtonScrollAmount = amount;
1200 }
1201
1202 void ScrollArea::setUpButtonScrollAmount(int amount)
1203 {
1204 mUpButtonScrollAmount = amount;
1205 }
1206
1207 void ScrollArea::setDownButtonScrollAmount(int amount)
1208 {
1209 mDownButtonScrollAmount = amount;
1210 }
1211
1212 int ScrollArea::getLeftButtonScrollAmount() const
1213 {
1214 return mLeftButtonScrollAmount;
1215 }
1216
1217 int ScrollArea::getRightButtonScrollAmount() const
1218 {
1219 return mRightButtonScrollAmount;
1220 }
1221
1222 int ScrollArea::getUpButtonScrollAmount() const
1223 {
1224 return mUpButtonScrollAmount;
1225 }
1226
1227 int ScrollArea::getDownButtonScrollAmount() const
1228 {
1229 return mDownButtonScrollAmount;
1230 }
1231
1232 void ScrollArea::setOpaque(bool opaque)
1233 {
1234 mOpaque = opaque;
1235 }
1236
1237
1238 bool ScrollArea::isOpaque() const
1239 {
1240 return mOpaque;
1241 }
1242 }
1243
1244 /*
1245 * Wow! This is a looooong source file.
1246 */