00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include "guichan/exception.h"
00060 #include "guichan/widgets/scrollarea.h"
00061
00062 namespace gcn
00063 {
00064 ScrollArea::ScrollArea()
00065 {
00066 mVScroll = 0;
00067 mHScroll = 0;
00068 mHPolicy = SHOW_AUTO;
00069 mVPolicy = SHOW_AUTO;
00070 mScrollbarWidth = 12;
00071 mContent = NULL;
00072 mUpButtonPressed = false;
00073 mDownButtonPressed = false;
00074 mLeftButtonPressed = false;
00075 mRightButtonPressed = false;
00076 mVerticalMarkerPressed = false;
00077 mVerticalMarkerMousePosition = 0;
00078 mHorizontalMarkerPressed = false;
00079 mHorizontalMarkerMousePosition = 0;
00080
00081 addMouseListener(this);
00082 }
00083
00084 ScrollArea::ScrollArea(Widget *content)
00085 {
00086 mVScroll = 0;
00087 mHScroll = 0;
00088 mHPolicy = SHOW_AUTO;
00089 mVPolicy = SHOW_AUTO;
00090 mScrollbarWidth = 12;
00091 mContent = NULL;
00092 mUpButtonPressed = false;
00093 mDownButtonPressed = false;
00094 mLeftButtonPressed = false;
00095 mRightButtonPressed = false;
00096 mVerticalMarkerPressed = false;
00097 mVerticalMarkerMousePosition = 0;
00098 mHorizontalMarkerPressed = false;
00099 mHorizontalMarkerMousePosition = 0;
00100
00101 setContent(content);
00102 addMouseListener(this);
00103 }
00104
00105 ScrollArea::ScrollArea(Widget *content, unsigned int hPolicy, unsigned int vPolicy)
00106 {
00107 mVScroll = 0;
00108 mHScroll = 0;
00109 mHPolicy = hPolicy;
00110 mVPolicy = vPolicy;
00111 mScrollbarWidth = 12;
00112 mContent = NULL;
00113 mUpButtonPressed = false;
00114 mDownButtonPressed = false;
00115 mLeftButtonPressed = false;
00116 mRightButtonPressed = false;
00117 mVerticalMarkerPressed = false;
00118 mVerticalMarkerMousePosition = 0;
00119 mHorizontalMarkerPressed = false;
00120 mHorizontalMarkerMousePosition = 0;
00121
00122 setContent(content);
00123 addMouseListener(this);
00124 }
00125
00126 ScrollArea::~ScrollArea()
00127 {
00128 setContent(NULL);
00129 }
00130
00131 void ScrollArea::setContent(Widget* widget)
00132 {
00133 if (mContent != NULL)
00134 {
00135 mContent->_setFocusHandler(NULL);
00136 mContent->_setParent(NULL);
00137 }
00138
00139 mContent = widget;
00140
00141 if (mContent != NULL)
00142 {
00143 mContent->_setFocusHandler(_getFocusHandler());
00144 mContent->_setParent(this);
00145 }
00146
00147 checkPolicies();
00148 }
00149
00150 Widget* ScrollArea::getContent()
00151 {
00152 return mContent;
00153 }
00154
00155 void ScrollArea::setHorizontalScrollPolicy(unsigned int hPolicy)
00156 {
00157 mHPolicy = hPolicy;
00158 checkPolicies();
00159 }
00160
00161 unsigned int ScrollArea::getHorizontalScrollPolicy()
00162 {
00163 return mHPolicy;
00164 }
00165
00166 void ScrollArea::setVerticalScrollPolicy(unsigned int vPolicy)
00167 {
00168 mVPolicy = vPolicy;
00169 checkPolicies();
00170 }
00171
00172 unsigned int ScrollArea::getVerticalScrollPolicy()
00173 {
00174 return mVPolicy;
00175 }
00176
00177 void ScrollArea::setScrollPolicy(unsigned int hPolicy, unsigned int vPolicy)
00178 {
00179 mHPolicy = hPolicy;
00180 mVPolicy = vPolicy;
00181 checkPolicies();
00182 }
00183
00184 void ScrollArea::setVerticalScrollAmount(int vScroll)
00185 {
00186 int max = getVerticalMaxScroll();
00187
00188 mVScroll = vScroll;
00189
00190 if (vScroll > max)
00191 {
00192 mVScroll = max;
00193 }
00194
00195 if (vScroll < 0)
00196 {
00197 mVScroll = 0;
00198 }
00199 }
00200
00201 int ScrollArea::getVerticalScrollAmount()
00202 {
00203 return mVScroll;
00204 }
00205
00206 void ScrollArea::setHorizontalScrollAmount(int hScroll)
00207 {
00208 int max = getHorizontalMaxScroll();
00209
00210 mHScroll = hScroll;
00211
00212 if (hScroll > max)
00213 {
00214 mHScroll = max;
00215 }
00216 else if (hScroll < 0)
00217 {
00218 mHScroll = 0;
00219 }
00220 }
00221
00222 int ScrollArea::getHorizontalScrollAmount()
00223 {
00224 return mHScroll;
00225 }
00226
00227 void ScrollArea::setScrollAmount(int hScroll, int vScroll)
00228 {
00229 setHorizontalScrollAmount(hScroll);
00230 setVerticalScrollAmount(vScroll);
00231 }
00232
00233 int ScrollArea::getHorizontalMaxScroll()
00234 {
00235 checkPolicies();
00236
00237 if (mContent == NULL)
00238 {
00239 return 0;
00240 }
00241
00242 int value = mContent->getWidth() - getContentDimension().width + 2 * mContent->getBorderSize();
00243
00244 if (value < 0)
00245 {
00246 return 0;
00247 }
00248
00249 return value;
00250 }
00251
00252 int ScrollArea::getVerticalMaxScroll()
00253 {
00254 checkPolicies();
00255
00256 if (mContent == NULL)
00257 {
00258 return 0;
00259 }
00260
00261 int value;
00262
00263 value = mContent->getHeight() - getContentDimension().height + 2 * mContent->getBorderSize();
00264
00265 if (value < 0)
00266 {
00267 return 0;
00268 }
00269
00270 return value;
00271 }
00272
00273 void ScrollArea::setScrollbarWidth(int width)
00274 {
00275 if (width > 0)
00276 {
00277 mScrollbarWidth = width;
00278 }
00279 else
00280 {
00281 throw GCN_EXCEPTION("Width should be greater then 0.");
00282 }
00283 }
00284
00285 int ScrollArea::getScrollbarWidth()
00286 {
00287 return mScrollbarWidth;
00288 }
00289
00290 void ScrollArea::_setFocusHandler(FocusHandler* focusHandler)
00291 {
00292 BasicContainer::_setFocusHandler(focusHandler);
00293
00294 if (mContent)
00295 {
00296 mContent->_setFocusHandler(focusHandler);
00297 }
00298 }
00299
00300 void ScrollArea::_mouseInputMessage(const MouseInput &mouseInput)
00301 {
00302 BasicContainer::_mouseInputMessage(mouseInput);
00303
00304 if (getContentDimension().isPointInRect(mouseInput.x, mouseInput.y))
00305 {
00306 if (mContent != NULL)
00307 {
00308 if (!mContent->hasMouse())
00309 {
00310 mContent->_mouseInMessage();
00311 }
00312
00313 MouseInput mi = mouseInput;
00314
00315 mi.x -= mContent->getX();
00316 mi.y -= mContent->getY();
00317
00318 mContent->_mouseInputMessage(mi);
00319 }
00320 }
00321 else if (mContent && mContent->hasMouse())
00322 {
00323 mContent->_mouseOutMessage();
00324 }
00325 }
00326
00327 void ScrollArea::_mouseOutMessage()
00328 {
00329 if (mContent && mContent->hasMouse())
00330 {
00331 mContent->_mouseOutMessage();
00332 }
00333
00334 BasicContainer::_mouseOutMessage();
00335 }
00336
00337 void ScrollArea::mousePress(int x, int y, int button)
00338 {
00339 if (getUpButtonDimension().isPointInRect(x, y))
00340 {
00341 setVerticalScrollAmount(getVerticalScrollAmount() - 10);
00342 mUpButtonPressed = true;
00343 }
00344 else if (getDownButtonDimension().isPointInRect(x, y))
00345 {
00346 setVerticalScrollAmount(getVerticalScrollAmount() + 10);
00347 mDownButtonPressed = true;
00348 }
00349 else if (getLeftButtonDimension().isPointInRect(x, y))
00350 {
00351 setHorizontalScrollAmount(getHorizontalScrollAmount() - 10);
00352 mLeftButtonPressed = true;
00353 }
00354 else if (getRightButtonDimension().isPointInRect(x, y))
00355 {
00356 setHorizontalScrollAmount(getHorizontalScrollAmount() + 10);
00357 mRightButtonPressed = true;
00358 }
00359 else if (getVerticalMarkerDimension().isPointInRect(x, y))
00360 {
00361 mVerticalMarkerPressed = true;
00362 mVerticalMarkerMousePosition = y - getVerticalMarkerDimension().y;
00363 }
00364 else if (getHorizontalMarkerDimension().isPointInRect(x, y))
00365 {
00366 mHorizontalMarkerPressed = true;
00367 mHorizontalMarkerMousePosition = x - getHorizontalMarkerDimension().x;
00368 }
00369 }
00370
00371 void ScrollArea::mouseRelease(int x, int y, int button)
00372 {
00373 mUpButtonPressed = false;
00374 mDownButtonPressed = false;
00375 mLeftButtonPressed = false;
00376 mRightButtonPressed = false;
00377 mVerticalMarkerPressed = false;
00378 mHorizontalMarkerPressed = false;
00379 }
00380
00381 void ScrollArea::mouseMotion(int x, int y)
00382 {
00383 if (mVerticalMarkerPressed)
00384 {
00385 int pos = y - getVerticalBarDimension().y - mVerticalMarkerMousePosition;
00386 int length = getVerticalMarkerDimension().height;
00387
00388 Rectangle barDim = getVerticalBarDimension();
00389
00390 if ((barDim.height - length) > 0)
00391 {
00392 setVerticalScrollAmount((getVerticalMaxScroll() * pos)
00393 / (barDim.height - length));
00394 }
00395 else
00396 {
00397 setVerticalScrollAmount(0);
00398 }
00399 setDirty(true);
00400 }
00401 if (mHorizontalMarkerPressed)
00402 {
00403 int pos = x - getHorizontalBarDimension().x - mHorizontalMarkerMousePosition;
00404 int length = getHorizontalMarkerDimension().width;
00405
00406 Rectangle barDim = getHorizontalBarDimension();
00407
00408 if ((barDim.width - length) > 0)
00409 {
00410 setHorizontalScrollAmount((getHorizontalMaxScroll() * pos)
00411 / (barDim.width - length));
00412 }
00413 else
00414 {
00415 setHorizontalScrollAmount(0);
00416 }
00417 setDirty(true);
00418 }
00419 }
00420
00421 void ScrollArea::draw(Graphics *graphics)
00422 {
00423 graphics->setColor(getBackgroundColor());
00424 graphics->fillRectangle(getContentDimension());
00425
00426 int alpha = getBaseColor().a;
00427 Color highlightColor = getBaseColor() + 0x303030;
00428 highlightColor.a = alpha;
00429 Color shadowColor = getBaseColor() - 0x303030;
00430 shadowColor.a = alpha;
00431
00432 if (mVBarVisible)
00433 {
00434 drawUpButton(graphics);
00435 drawDownButton(graphics);
00436 drawVBar(graphics);
00437 drawVMarker(graphics);
00438 }
00439
00440 if (mHBarVisible)
00441 {
00442 drawLeftButton(graphics);
00443 drawRightButton(graphics);
00444 drawHBar(graphics);
00445 drawHMarker(graphics);
00446 }
00447
00448 if (mHBarVisible && mVBarVisible)
00449 {
00450 graphics->setColor(getBaseColor());
00451 graphics->fillRectangle(Rectangle(getWidth() - mScrollbarWidth,
00452 getHeight() - mScrollbarWidth,
00453 mScrollbarWidth,
00454 mScrollbarWidth));
00455 }
00456
00457 if (mContent)
00458 {
00459 Rectangle contdim = mContent->getDimension();
00460 graphics->pushClipArea(getContentDimension());
00461
00462 if (mContent->getBorderSize() > 0)
00463 {
00464 Rectangle rec = mContent->getDimension();
00465 rec.x -= mContent->getBorderSize();
00466 rec.y -= mContent->getBorderSize();
00467 rec.width += 2 * mContent->getBorderSize();
00468 rec.height += 2 * mContent->getBorderSize();
00469 graphics->pushClipArea(rec);
00470 mContent->drawBorder(graphics);
00471 graphics->popClipArea();
00472 }
00473
00474 graphics->pushClipArea(contdim);
00475 mContent->draw(graphics);
00476 graphics->popClipArea();
00477 graphics->popClipArea();
00478 }
00479 }
00480
00481 void ScrollArea::drawBorder(Graphics* graphics)
00482 {
00483 Color faceColor = getBaseColor();
00484 Color highlightColor, shadowColor;
00485 int alpha = getBaseColor().a;
00486 int width = getWidth() + getBorderSize() * 2 - 1;
00487 int height = getHeight() + getBorderSize() * 2 - 1;
00488 highlightColor = faceColor + 0x303030;
00489 highlightColor.a = alpha;
00490 shadowColor = faceColor - 0x303030;
00491 shadowColor.a = alpha;
00492
00493 unsigned int i;
00494 for (i = 0; i < getBorderSize(); ++i)
00495 {
00496 graphics->setColor(shadowColor);
00497 graphics->drawLine(i,i, width - i, i);
00498 graphics->drawLine(i,i + 1, i, height - i - 1);
00499 graphics->setColor(highlightColor);
00500 graphics->drawLine(width - i,i + 1, width - i, height - i);
00501 graphics->drawLine(i,height - i, width - i - 1, height - i);
00502 }
00503 }
00504
00505 void ScrollArea::drawHBar(Graphics* graphics)
00506 {
00507 Rectangle dim = getHorizontalBarDimension();
00508
00509 graphics->pushClipArea(dim);
00510
00511 int alpha = getBaseColor().a;
00512 Color trackColor = getBaseColor() - 0x101010;
00513 trackColor.a = alpha;
00514 Color shadowColor = getBaseColor() - 0x303030;
00515 shadowColor.a = alpha;
00516
00517 graphics->setColor(trackColor);
00518 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00519
00520 graphics->setColor(shadowColor);
00521 graphics->drawLine(0, 0, dim.width, 0);
00522
00523 graphics->popClipArea();
00524 }
00525
00526 void ScrollArea::drawVBar(Graphics* graphics)
00527 {
00528 Rectangle dim = getVerticalBarDimension();
00529
00530 graphics->pushClipArea(dim);
00531
00532 int alpha = getBaseColor().a;
00533 Color trackColor = getBaseColor() - 0x101010;
00534 trackColor.a = alpha;
00535 Color shadowColor = getBaseColor() - 0x303030;
00536 shadowColor.a = alpha;
00537
00538 graphics->setColor(trackColor);
00539 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00540
00541 graphics->setColor(shadowColor);
00542 graphics->drawLine(0, 0, 0, dim.height);
00543
00544 graphics->popClipArea();
00545 }
00546
00547 void ScrollArea::drawUpButton(Graphics* graphics)
00548 {
00549 Rectangle dim = getUpButtonDimension();
00550 graphics->pushClipArea(dim);
00551
00552 Color highlightColor;
00553 Color shadowColor;
00554 Color faceColor;
00555 int offset;
00556 int alpha = getBaseColor().a;
00557
00558 if (mUpButtonPressed)
00559 {
00560 faceColor = getBaseColor() - 0x303030;
00561 faceColor.a = alpha;
00562 highlightColor = faceColor - 0x303030;
00563 highlightColor.a = alpha;
00564 shadowColor = getBaseColor();
00565 shadowColor.a = alpha;
00566
00567 offset = 1;
00568 }
00569 else
00570 {
00571 faceColor = getBaseColor();
00572 faceColor.a = alpha;
00573 highlightColor = faceColor + 0x303030;
00574 highlightColor.a = alpha;
00575 shadowColor = faceColor - 0x303030;
00576 shadowColor.a = alpha;
00577
00578 offset = 0;
00579 }
00580
00581 graphics->setColor(faceColor);
00582 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00583
00584 graphics->setColor(highlightColor);
00585 graphics->drawLine(0, 0, dim.width - 1, 0);
00586 graphics->drawLine(0, 1, 0, dim.height - 1);
00587
00588 graphics->setColor(shadowColor);
00589 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00590 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00591
00592 graphics->setColor(getForegroundColor());
00593
00594 int i;
00595 int w = dim.height / 2;
00596 int h = w / 2 + 2;
00597 for (i = 0; i < w / 2; ++i)
00598 {
00599 graphics->drawLine(w - i + offset,
00600 i + h + offset,
00601 w + i + offset,
00602 i + h + offset);
00603 }
00604
00605 graphics->popClipArea();
00606 }
00607
00608 void ScrollArea::drawDownButton(Graphics* graphics)
00609 {
00610 Rectangle dim = getDownButtonDimension();
00611 graphics->pushClipArea(dim);
00612
00613 Color highlightColor;
00614 Color shadowColor;
00615 Color faceColor;
00616 int offset;
00617 int alpha = getBaseColor().a;
00618
00619 if (mDownButtonPressed)
00620 {
00621 faceColor = getBaseColor() - 0x303030;
00622 faceColor.a = alpha;
00623 highlightColor = faceColor - 0x303030;
00624 highlightColor.a = alpha;
00625 shadowColor = getBaseColor();
00626 shadowColor.a = alpha;
00627
00628 offset = 1;
00629 }
00630 else
00631 {
00632 faceColor = getBaseColor();
00633 faceColor.a = alpha;
00634 highlightColor = faceColor + 0x303030;
00635 highlightColor.a = alpha;
00636 shadowColor = faceColor - 0x303030;
00637 shadowColor.a = alpha;
00638
00639 offset = 0;
00640 }
00641
00642 graphics->setColor(faceColor);
00643 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00644
00645 graphics->setColor(highlightColor);
00646 graphics->drawLine(0, 0, dim.width - 1, 0);
00647 graphics->drawLine(0, 1, 0, dim.height - 1);
00648
00649 graphics->setColor(shadowColor);
00650 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00651 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00652
00653 graphics->setColor(getForegroundColor());
00654
00655 int i;
00656 int w = dim.height / 2;
00657 int h = w + 1;
00658 for (i = 0; i < w / 2; ++i)
00659 {
00660 graphics->drawLine(w - i + offset,
00661 -i + h + offset,
00662 w + i + offset,
00663 -i + h + offset);
00664 }
00665
00666 graphics->popClipArea();
00667 }
00668
00669 void ScrollArea::drawLeftButton(Graphics* graphics)
00670 {
00671 Rectangle dim = getLeftButtonDimension();
00672 graphics->pushClipArea(dim);
00673
00674 Color highlightColor;
00675 Color shadowColor;
00676 Color faceColor;
00677 int offset;
00678 int alpha = getBaseColor().a;
00679
00680 if (mLeftButtonPressed)
00681 {
00682 faceColor = getBaseColor() - 0x303030;
00683 faceColor.a = alpha;
00684 highlightColor = faceColor - 0x303030;
00685 highlightColor.a = alpha;
00686 shadowColor = getBaseColor();
00687 shadowColor.a = alpha;
00688
00689 offset = 1;
00690 }
00691 else
00692 {
00693 faceColor = getBaseColor();
00694 faceColor.a = alpha;
00695 highlightColor = faceColor + 0x303030;
00696 highlightColor.a = alpha;
00697 shadowColor = faceColor - 0x303030;
00698 shadowColor.a = alpha;
00699
00700 offset = 0;
00701 }
00702
00703 graphics->setColor(faceColor);
00704 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00705
00706 graphics->setColor(highlightColor);
00707 graphics->drawLine(0, 0, dim.width - 1, 0);
00708 graphics->drawLine(0, 1, 0, dim.height - 1);
00709
00710 graphics->setColor(shadowColor);
00711 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00712 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00713
00714 graphics->setColor(getForegroundColor());
00715
00716 int i;
00717 int w = dim.width / 2;
00718 int h = w - 2;
00719 for (i = 0; i < w / 2; ++i)
00720 {
00721 graphics->drawLine(i + h + offset,
00722 w - i + offset,
00723 i + h + offset,
00724 w + i + offset);
00725 }
00726
00727 graphics->popClipArea();
00728 }
00729
00730 void ScrollArea::drawRightButton(Graphics* graphics)
00731 {
00732 Rectangle dim = getRightButtonDimension();
00733 graphics->pushClipArea(dim);
00734
00735 Color highlightColor;
00736 Color shadowColor;
00737 Color faceColor;
00738 int offset;
00739 int alpha = getBaseColor().a;
00740
00741 if (mRightButtonPressed)
00742 {
00743 faceColor = getBaseColor() - 0x303030;
00744 faceColor.a = alpha;
00745 highlightColor = faceColor - 0x303030;
00746 highlightColor.a = alpha;
00747 shadowColor = getBaseColor();
00748 shadowColor.a = alpha;
00749
00750 offset = 1;
00751 }
00752 else
00753 {
00754 faceColor = getBaseColor();
00755 faceColor.a = alpha;
00756 highlightColor = faceColor + 0x303030;
00757 highlightColor.a = alpha;
00758 shadowColor = faceColor - 0x303030;
00759 shadowColor.a = alpha;
00760
00761 offset = 0;
00762 }
00763
00764 graphics->setColor(faceColor);
00765 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00766
00767 graphics->setColor(highlightColor);
00768 graphics->drawLine(0, 0, dim.width - 1, 0);
00769 graphics->drawLine(0, 1, 0, dim.height - 1);
00770
00771 graphics->setColor(shadowColor);
00772 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00773 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00774
00775 graphics->setColor(getForegroundColor());
00776
00777 int i;
00778 int w = dim.width / 2;
00779 int h = w + 1;
00780 for (i = 0; i < w / 2; ++i)
00781 {
00782 graphics->drawLine(-i + h + offset,
00783 w - i + offset,
00784 -i + h + offset,
00785 w + i + offset);
00786 }
00787
00788 graphics->popClipArea();
00789 }
00790
00791 void ScrollArea::drawVMarker(Graphics* graphics)
00792 {
00793 Rectangle dim = getVerticalMarkerDimension();
00794 graphics->pushClipArea(dim);
00795
00796 int alpha = getBaseColor().a;
00797 Color faceColor = getBaseColor();
00798 faceColor.a = alpha;
00799 Color highlightColor = faceColor + 0x303030;
00800 highlightColor.a = alpha;
00801 Color shadowColor = faceColor - 0x303030;
00802 shadowColor.a = alpha;
00803
00804 graphics->setColor(faceColor);
00805 graphics->fillRectangle(Rectangle(1, 1, dim.width - 1, dim.height - 1));
00806
00807 graphics->setColor(highlightColor);
00808 graphics->drawLine(0, 0, dim.width - 1, 0);
00809 graphics->drawLine(0, 1, 0, dim.height - 1);
00810
00811 graphics->setColor(shadowColor);
00812 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00813 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00814
00815 graphics->popClipArea();
00816 }
00817
00818 void ScrollArea::drawHMarker(Graphics* graphics)
00819 {
00820 Rectangle dim = getHorizontalMarkerDimension();
00821 graphics->pushClipArea(dim);
00822
00823 int alpha = getBaseColor().a;
00824 Color faceColor = getBaseColor();
00825 faceColor.a = alpha;
00826 Color highlightColor = faceColor + 0x303030;
00827 highlightColor.a = alpha;
00828 Color shadowColor = faceColor - 0x303030;
00829 shadowColor.a = alpha;
00830
00831 graphics->setColor(faceColor);
00832 graphics->fillRectangle(Rectangle(1, 1, dim.width - 1, dim.height - 1));
00833
00834 graphics->setColor(highlightColor);
00835 graphics->drawLine(0, 0, dim.width - 1, 0);
00836 graphics->drawLine(0, 1, 0, dim.height - 1);
00837
00838 graphics->setColor(shadowColor);
00839 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00840 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00841
00842 graphics->popClipArea();
00843 }
00844
00845 void ScrollArea::logic()
00846 {
00847 checkPolicies();
00848
00849 setVerticalScrollAmount(getVerticalScrollAmount());
00850 setHorizontalScrollAmount(getHorizontalScrollAmount());
00851
00852 if (mContent != NULL)
00853 {
00854 mContent->setPosition(-mHScroll + getContentDimension().x + mContent->getBorderSize(),
00855 -mVScroll + getContentDimension().y + mContent->getBorderSize());
00856
00857 mContent->logic();
00858 }
00859 }
00860
00861 void ScrollArea::moveToTop(Widget* widget)
00862 {
00863 if (widget == mContent)
00864 {
00865 if (getParent())
00866 {
00867 getParent()->moveToTop(this);
00868 }
00869 }
00870 else
00871 {
00872 throw GCN_EXCEPTION("Only a ScrollArea's content may be moved to top.");
00873 }
00874 }
00875
00876 void ScrollArea::moveToBottom(Widget* widget)
00877 {
00878 if (widget == mContent)
00879 {
00880 if (getParent())
00881 {
00882 getParent()->moveToBottom(this);
00883 }
00884 }
00885 else
00886 {
00887 throw GCN_EXCEPTION("Only a ScrollArea's content may be moved to bottom.");
00888 }
00889 }
00890
00891 void ScrollArea::_announceDeath(Widget *widget)
00892 {
00893 if (widget == mContent)
00894 {
00895 mContent = NULL;
00896 checkPolicies();
00897 }
00898 else
00899 {
00900 throw GCN_EXCEPTION("Called by not-child.");
00901 }
00902 }
00903
00904 void ScrollArea::getDrawSize(int& width, int& height, Widget* widget)
00905 {
00906 if (mContent == widget)
00907 {
00908 width = getContentDimension().width;
00909 height = getContentDimension().height;
00910 }
00911 else
00912 {
00913 throw GCN_EXCEPTION("Widget not in scrollarea.");
00914 }
00915 }
00916
00917 void ScrollArea::drawContent(Graphics* graphics)
00918 {
00919 if (mContent)
00920 {
00921 mContent->draw(graphics);
00922 }
00923 }
00924
00925 void ScrollArea::checkPolicies()
00926 {
00927 int w = getWidth();
00928 int h = getHeight();
00929
00930 mHBarVisible = false;
00931 mVBarVisible = false;
00932
00933
00934 if (!mContent)
00935 {
00936 mHBarVisible = (mHPolicy == SHOW_ALWAYS);
00937 mVBarVisible = (mVPolicy == SHOW_ALWAYS);
00938 return;
00939 }
00940
00941 if (mHPolicy == SHOW_AUTO &&
00942 mVPolicy == SHOW_AUTO)
00943 {
00944 if (mContent->getWidth() <= w
00945 && mContent->getHeight() <= h)
00946 {
00947 mHBarVisible = false;
00948 mVBarVisible = false;
00949 }
00950
00951 if (mContent->getWidth() > w)
00952 {
00953 mHBarVisible = true;
00954 }
00955
00956 if ((mContent->getHeight() > h)
00957 || (mHBarVisible && mContent->getHeight() > h - mScrollbarWidth))
00958 {
00959 mVBarVisible = true;
00960 }
00961
00962 if (mVBarVisible && mContent->getWidth() > w - mScrollbarWidth)
00963 {
00964 mHBarVisible = true;
00965 }
00966
00967 return;
00968 }
00969
00970 switch (mHPolicy)
00971 {
00972 case SHOW_NEVER:
00973 mHBarVisible = false;
00974 break;
00975
00976 case SHOW_ALWAYS:
00977 mHBarVisible = true;
00978 break;
00979
00980 case SHOW_AUTO:
00981 if (mVPolicy == SHOW_NEVER)
00982 {
00983 mHBarVisible = mContent->getWidth() > w;
00984 }
00985 else
00986 {
00987 mHBarVisible = mContent->getWidth() > w - mScrollbarWidth;
00988 }
00989 break;
00990
00991 default:
00992 throw GCN_EXCEPTION("Horizontal scroll policy invalid.");
00993 }
00994
00995 switch (mVPolicy)
00996 {
00997 case SHOW_NEVER:
00998 mVBarVisible = false;
00999 break;
01000
01001 case SHOW_ALWAYS:
01002 mVBarVisible = true;
01003 break;
01004
01005 case SHOW_AUTO:
01006 if (mHPolicy == SHOW_NEVER)
01007 {
01008 mVBarVisible = mContent->getHeight() > h;
01009 }
01010 else
01011 {
01012 mVBarVisible = mContent->getHeight() > h - mScrollbarWidth;
01013 }
01014 break;
01015 default:
01016 throw GCN_EXCEPTION("Vertical scroll policy invalid.");
01017 }
01018 }
01019
01020 Rectangle ScrollArea::getUpButtonDimension()
01021 {
01022 if (!mVBarVisible)
01023 {
01024 return Rectangle(0, 0, 0, 0);
01025 }
01026
01027 return Rectangle(getWidth() - mScrollbarWidth,
01028 0,
01029 mScrollbarWidth,
01030 mScrollbarWidth);
01031 }
01032
01033 Rectangle ScrollArea::getDownButtonDimension()
01034 {
01035 if (!mVBarVisible)
01036 {
01037 return Rectangle(0, 0, 0, 0);
01038 }
01039
01040 if (mVBarVisible && mHBarVisible)
01041 {
01042 return Rectangle(getWidth() - mScrollbarWidth,
01043 getHeight() - mScrollbarWidth*2,
01044 mScrollbarWidth,
01045 mScrollbarWidth);
01046 }
01047
01048 return Rectangle(getWidth() - mScrollbarWidth,
01049 getHeight() - mScrollbarWidth,
01050 mScrollbarWidth,
01051 mScrollbarWidth);
01052 }
01053
01054 Rectangle ScrollArea::getLeftButtonDimension()
01055 {
01056 if (!mHBarVisible)
01057 {
01058 return Rectangle(0, 0, 0, 0);
01059 }
01060
01061 return Rectangle(0,
01062 getHeight() - mScrollbarWidth,
01063 mScrollbarWidth,
01064 mScrollbarWidth);
01065 }
01066
01067 Rectangle ScrollArea::getRightButtonDimension()
01068 {
01069 if (!mHBarVisible)
01070 {
01071 return Rectangle(0, 0, 0, 0);
01072 }
01073
01074 if (mVBarVisible && mHBarVisible)
01075 {
01076 return Rectangle(getWidth() - mScrollbarWidth*2,
01077 getHeight() - mScrollbarWidth,
01078 mScrollbarWidth,
01079 mScrollbarWidth);
01080 }
01081
01082 return Rectangle(getWidth() - mScrollbarWidth,
01083 getHeight() - mScrollbarWidth,
01084 mScrollbarWidth,
01085 mScrollbarWidth);
01086 }
01087
01088 Rectangle ScrollArea::getContentDimension()
01089 {
01090 if (mVBarVisible && mHBarVisible)
01091 {
01092 return Rectangle(0, 0, getWidth() - mScrollbarWidth,
01093 getHeight() - mScrollbarWidth);
01094 }
01095
01096 if (mVBarVisible)
01097 {
01098 return Rectangle(0, 0, getWidth() - mScrollbarWidth, getHeight());
01099 }
01100
01101 if (mHBarVisible)
01102 {
01103 return Rectangle(0, 0, getWidth(), getHeight() - mScrollbarWidth);
01104 }
01105
01106 return Rectangle(0, 0, getWidth(), getHeight());
01107 }
01108
01109 Rectangle ScrollArea::getVerticalBarDimension()
01110 {
01111 if (!mVBarVisible)
01112 {
01113 return Rectangle(0, 0, 0, 0);
01114 }
01115
01116 if (mHBarVisible)
01117 {
01118 return Rectangle(getWidth() - mScrollbarWidth,
01119 getUpButtonDimension().height,
01120 mScrollbarWidth,
01121 getHeight()
01122 - getUpButtonDimension().height
01123 - getDownButtonDimension().height
01124 - mScrollbarWidth);
01125 }
01126
01127 return Rectangle(getWidth() - mScrollbarWidth,
01128 getUpButtonDimension().height,
01129 mScrollbarWidth,
01130 getHeight()
01131 - getUpButtonDimension().height
01132 - getDownButtonDimension().height);
01133 }
01134
01135 Rectangle ScrollArea::getHorizontalBarDimension()
01136 {
01137 if (!mHBarVisible)
01138 {
01139 return Rectangle(0, 0, 0, 0);
01140 }
01141
01142 if (mVBarVisible)
01143 {
01144 return Rectangle(getLeftButtonDimension().width,
01145 getHeight() - mScrollbarWidth,
01146 getWidth()
01147 - getLeftButtonDimension().width
01148 - getRightButtonDimension().width
01149 - mScrollbarWidth,
01150 mScrollbarWidth);
01151 }
01152
01153 return Rectangle(getLeftButtonDimension().width,
01154 getHeight() - mScrollbarWidth,
01155 getWidth()
01156 - getLeftButtonDimension().width
01157 - getRightButtonDimension().width,
01158 mScrollbarWidth);
01159 }
01160
01161 Rectangle ScrollArea::getVerticalMarkerDimension()
01162 {
01163 if (!mVBarVisible)
01164 {
01165 return Rectangle(0, 0, 0, 0);
01166 }
01167
01168 int length, pos;
01169 Rectangle barDim = getVerticalBarDimension();
01170
01171 if (mContent && mContent->getHeight() != 0)
01172 {
01173 length = (barDim.height * getContentDimension().height)
01174 / mContent->getHeight();
01175 }
01176 else
01177 {
01178 length = barDim.height;
01179 }
01180
01181 if (length < mScrollbarWidth)
01182 {
01183 length = mScrollbarWidth;
01184 }
01185
01186 if (length > barDim.height)
01187 {
01188 length = barDim.height;
01189 }
01190
01191 if (getVerticalMaxScroll() != 0)
01192 {
01193 pos = ((barDim.height - length) * getVerticalScrollAmount())
01194 / getVerticalMaxScroll();
01195 }
01196 else
01197 {
01198 pos = 0;
01199 }
01200
01201 return Rectangle(barDim.x, barDim.y + pos, mScrollbarWidth, length);
01202 }
01203
01204 Rectangle ScrollArea::getHorizontalMarkerDimension()
01205 {
01206 if (!mHBarVisible)
01207 {
01208 return Rectangle(0, 0, 0, 0);
01209 }
01210
01211 int length, pos;
01212 Rectangle barDim = getHorizontalBarDimension();
01213
01214 if (mContent && mContent->getWidth() != 0)
01215 {
01216 length = (barDim.width * getContentDimension().width)
01217 / mContent->getWidth();
01218 }
01219 else
01220 {
01221 length = barDim.width;
01222 }
01223
01224 if (length < mScrollbarWidth)
01225 {
01226 length = mScrollbarWidth;
01227 }
01228
01229 if (length > barDim.width)
01230 {
01231 length = barDim.width;
01232 }
01233
01234 if (getHorizontalMaxScroll() != 0)
01235 {
01236 pos = ((barDim.width - length) * getHorizontalScrollAmount())
01237 / getHorizontalMaxScroll();
01238 }
01239 else
01240 {
01241 pos = 0;
01242 }
01243
01244 return Rectangle(barDim.x + pos, barDim.y, length, mScrollbarWidth);
01245 }
01246
01247 void ScrollArea::scrollToRectangle(const Rectangle& rectangle)
01248 {
01249 Rectangle contentDim = getContentDimension();
01250
01251 if (rectangle.x + rectangle.width
01252 > getHorizontalScrollAmount() + contentDim.width)
01253 {
01254 setHorizontalScrollAmount(rectangle.x + rectangle.width - contentDim.width);
01255 }
01256
01257 if (rectangle.y + rectangle.height
01258 > getVerticalScrollAmount() + contentDim.height)
01259 {
01260 setVerticalScrollAmount(rectangle.y + rectangle.height - contentDim.height);
01261 }
01262
01263 if (rectangle.x < getHorizontalScrollAmount())
01264 {
01265 setHorizontalScrollAmount(rectangle.x);
01266 }
01267
01268 if (rectangle.y < getVerticalScrollAmount())
01269 {
01270 setVerticalScrollAmount(rectangle.y);
01271 }
01272 }
01273
01274 void ScrollArea::mouseWheelUp(int x, int y)
01275 {
01276 if (hasMouse())
01277 {
01278 setVerticalScrollAmount(getVerticalScrollAmount() - getContentDimension().height / 8);
01279 }
01280 }
01281
01282 void ScrollArea::mouseWheelDown(int x, int y)
01283 {
01284 if (hasMouse())
01285 {
01286 setVerticalScrollAmount(getVerticalScrollAmount() + getContentDimension().height / 8);
01287 }
01288 }
01289 }
01290
01291
01292
01293