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.hpp"
00060 #include "guichan/widgets/scrollarea.hpp"
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 }
00400 if (mHorizontalMarkerPressed)
00401 {
00402 int pos = x - getHorizontalBarDimension().x - mHorizontalMarkerMousePosition;
00403 int length = getHorizontalMarkerDimension().width;
00404
00405 Rectangle barDim = getHorizontalBarDimension();
00406
00407 if ((barDim.width - length) > 0)
00408 {
00409 setHorizontalScrollAmount((getHorizontalMaxScroll() * pos)
00410 / (barDim.width - length));
00411 }
00412 else
00413 {
00414 setHorizontalScrollAmount(0);
00415 }
00416 }
00417 }
00418
00419 void ScrollArea::draw(Graphics *graphics)
00420 {
00421 graphics->setColor(getBackgroundColor());
00422 graphics->fillRectangle(getContentDimension());
00423
00424 int alpha = getBaseColor().a;
00425 Color highlightColor = getBaseColor() + 0x303030;
00426 highlightColor.a = alpha;
00427 Color shadowColor = getBaseColor() - 0x303030;
00428 shadowColor.a = alpha;
00429
00430 if (mVBarVisible)
00431 {
00432 drawUpButton(graphics);
00433 drawDownButton(graphics);
00434 drawVBar(graphics);
00435 drawVMarker(graphics);
00436 }
00437
00438 if (mHBarVisible)
00439 {
00440 drawLeftButton(graphics);
00441 drawRightButton(graphics);
00442 drawHBar(graphics);
00443 drawHMarker(graphics);
00444 }
00445
00446 if (mHBarVisible && mVBarVisible)
00447 {
00448 graphics->setColor(getBaseColor());
00449 graphics->fillRectangle(Rectangle(getWidth() - mScrollbarWidth,
00450 getHeight() - mScrollbarWidth,
00451 mScrollbarWidth,
00452 mScrollbarWidth));
00453 }
00454
00455 if (mContent)
00456 {
00457 Rectangle contdim = mContent->getDimension();
00458 graphics->pushClipArea(getContentDimension());
00459
00460 if (mContent->getBorderSize() > 0)
00461 {
00462 Rectangle rec = mContent->getDimension();
00463 rec.x -= mContent->getBorderSize();
00464 rec.y -= mContent->getBorderSize();
00465 rec.width += 2 * mContent->getBorderSize();
00466 rec.height += 2 * mContent->getBorderSize();
00467 graphics->pushClipArea(rec);
00468 mContent->drawBorder(graphics);
00469 graphics->popClipArea();
00470 }
00471
00472 graphics->pushClipArea(contdim);
00473 mContent->draw(graphics);
00474 graphics->popClipArea();
00475 graphics->popClipArea();
00476 }
00477 }
00478
00479 void ScrollArea::drawBorder(Graphics* graphics)
00480 {
00481 Color faceColor = getBaseColor();
00482 Color highlightColor, shadowColor;
00483 int alpha = getBaseColor().a;
00484 int width = getWidth() + getBorderSize() * 2 - 1;
00485 int height = getHeight() + getBorderSize() * 2 - 1;
00486 highlightColor = faceColor + 0x303030;
00487 highlightColor.a = alpha;
00488 shadowColor = faceColor - 0x303030;
00489 shadowColor.a = alpha;
00490
00491 unsigned int i;
00492 for (i = 0; i < getBorderSize(); ++i)
00493 {
00494 graphics->setColor(shadowColor);
00495 graphics->drawLine(i,i, width - i, i);
00496 graphics->drawLine(i,i + 1, i, height - i - 1);
00497 graphics->setColor(highlightColor);
00498 graphics->drawLine(width - i,i + 1, width - i, height - i);
00499 graphics->drawLine(i,height - i, width - i - 1, height - i);
00500 }
00501 }
00502
00503 void ScrollArea::drawHBar(Graphics* graphics)
00504 {
00505 Rectangle dim = getHorizontalBarDimension();
00506
00507 graphics->pushClipArea(dim);
00508
00509 int alpha = getBaseColor().a;
00510 Color trackColor = getBaseColor() - 0x101010;
00511 trackColor.a = alpha;
00512 Color shadowColor = getBaseColor() - 0x303030;
00513 shadowColor.a = alpha;
00514
00515 graphics->setColor(trackColor);
00516 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00517
00518 graphics->setColor(shadowColor);
00519 graphics->drawLine(0, 0, dim.width, 0);
00520
00521 graphics->popClipArea();
00522 }
00523
00524 void ScrollArea::drawVBar(Graphics* graphics)
00525 {
00526 Rectangle dim = getVerticalBarDimension();
00527
00528 graphics->pushClipArea(dim);
00529
00530 int alpha = getBaseColor().a;
00531 Color trackColor = getBaseColor() - 0x101010;
00532 trackColor.a = alpha;
00533 Color shadowColor = getBaseColor() - 0x303030;
00534 shadowColor.a = alpha;
00535
00536 graphics->setColor(trackColor);
00537 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00538
00539 graphics->setColor(shadowColor);
00540 graphics->drawLine(0, 0, 0, dim.height);
00541
00542 graphics->popClipArea();
00543 }
00544
00545 void ScrollArea::drawUpButton(Graphics* graphics)
00546 {
00547 Rectangle dim = getUpButtonDimension();
00548 graphics->pushClipArea(dim);
00549
00550 Color highlightColor;
00551 Color shadowColor;
00552 Color faceColor;
00553 int offset;
00554 int alpha = getBaseColor().a;
00555
00556 if (mUpButtonPressed)
00557 {
00558 faceColor = getBaseColor() - 0x303030;
00559 faceColor.a = alpha;
00560 highlightColor = faceColor - 0x303030;
00561 highlightColor.a = alpha;
00562 shadowColor = getBaseColor();
00563 shadowColor.a = alpha;
00564
00565 offset = 1;
00566 }
00567 else
00568 {
00569 faceColor = getBaseColor();
00570 faceColor.a = alpha;
00571 highlightColor = faceColor + 0x303030;
00572 highlightColor.a = alpha;
00573 shadowColor = faceColor - 0x303030;
00574 shadowColor.a = alpha;
00575
00576 offset = 0;
00577 }
00578
00579 graphics->setColor(faceColor);
00580 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00581
00582 graphics->setColor(highlightColor);
00583 graphics->drawLine(0, 0, dim.width - 1, 0);
00584 graphics->drawLine(0, 1, 0, dim.height - 1);
00585
00586 graphics->setColor(shadowColor);
00587 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00588 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00589
00590 graphics->setColor(getForegroundColor());
00591
00592 int i;
00593 int w = dim.height / 2;
00594 int h = w / 2 + 2;
00595 for (i = 0; i < w / 2; ++i)
00596 {
00597 graphics->drawLine(w - i + offset,
00598 i + h + offset,
00599 w + i + offset,
00600 i + h + offset);
00601 }
00602
00603 graphics->popClipArea();
00604 }
00605
00606 void ScrollArea::drawDownButton(Graphics* graphics)
00607 {
00608 Rectangle dim = getDownButtonDimension();
00609 graphics->pushClipArea(dim);
00610
00611 Color highlightColor;
00612 Color shadowColor;
00613 Color faceColor;
00614 int offset;
00615 int alpha = getBaseColor().a;
00616
00617 if (mDownButtonPressed)
00618 {
00619 faceColor = getBaseColor() - 0x303030;
00620 faceColor.a = alpha;
00621 highlightColor = faceColor - 0x303030;
00622 highlightColor.a = alpha;
00623 shadowColor = getBaseColor();
00624 shadowColor.a = alpha;
00625
00626 offset = 1;
00627 }
00628 else
00629 {
00630 faceColor = getBaseColor();
00631 faceColor.a = alpha;
00632 highlightColor = faceColor + 0x303030;
00633 highlightColor.a = alpha;
00634 shadowColor = faceColor - 0x303030;
00635 shadowColor.a = alpha;
00636
00637 offset = 0;
00638 }
00639
00640 graphics->setColor(faceColor);
00641 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00642
00643 graphics->setColor(highlightColor);
00644 graphics->drawLine(0, 0, dim.width - 1, 0);
00645 graphics->drawLine(0, 1, 0, dim.height - 1);
00646
00647 graphics->setColor(shadowColor);
00648 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00649 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00650
00651 graphics->setColor(getForegroundColor());
00652
00653 int i;
00654 int w = dim.height / 2;
00655 int h = w + 1;
00656 for (i = 0; i < w / 2; ++i)
00657 {
00658 graphics->drawLine(w - i + offset,
00659 -i + h + offset,
00660 w + i + offset,
00661 -i + h + offset);
00662 }
00663
00664 graphics->popClipArea();
00665 }
00666
00667 void ScrollArea::drawLeftButton(Graphics* graphics)
00668 {
00669 Rectangle dim = getLeftButtonDimension();
00670 graphics->pushClipArea(dim);
00671
00672 Color highlightColor;
00673 Color shadowColor;
00674 Color faceColor;
00675 int offset;
00676 int alpha = getBaseColor().a;
00677
00678 if (mLeftButtonPressed)
00679 {
00680 faceColor = getBaseColor() - 0x303030;
00681 faceColor.a = alpha;
00682 highlightColor = faceColor - 0x303030;
00683 highlightColor.a = alpha;
00684 shadowColor = getBaseColor();
00685 shadowColor.a = alpha;
00686
00687 offset = 1;
00688 }
00689 else
00690 {
00691 faceColor = getBaseColor();
00692 faceColor.a = alpha;
00693 highlightColor = faceColor + 0x303030;
00694 highlightColor.a = alpha;
00695 shadowColor = faceColor - 0x303030;
00696 shadowColor.a = alpha;
00697
00698 offset = 0;
00699 }
00700
00701 graphics->setColor(faceColor);
00702 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00703
00704 graphics->setColor(highlightColor);
00705 graphics->drawLine(0, 0, dim.width - 1, 0);
00706 graphics->drawLine(0, 1, 0, dim.height - 1);
00707
00708 graphics->setColor(shadowColor);
00709 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00710 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00711
00712 graphics->setColor(getForegroundColor());
00713
00714 int i;
00715 int w = dim.width / 2;
00716 int h = w - 2;
00717 for (i = 0; i < w / 2; ++i)
00718 {
00719 graphics->drawLine(i + h + offset,
00720 w - i + offset,
00721 i + h + offset,
00722 w + i + offset);
00723 }
00724
00725 graphics->popClipArea();
00726 }
00727
00728 void ScrollArea::drawRightButton(Graphics* graphics)
00729 {
00730 Rectangle dim = getRightButtonDimension();
00731 graphics->pushClipArea(dim);
00732
00733 Color highlightColor;
00734 Color shadowColor;
00735 Color faceColor;
00736 int offset;
00737 int alpha = getBaseColor().a;
00738
00739 if (mRightButtonPressed)
00740 {
00741 faceColor = getBaseColor() - 0x303030;
00742 faceColor.a = alpha;
00743 highlightColor = faceColor - 0x303030;
00744 highlightColor.a = alpha;
00745 shadowColor = getBaseColor();
00746 shadowColor.a = alpha;
00747
00748 offset = 1;
00749 }
00750 else
00751 {
00752 faceColor = getBaseColor();
00753 faceColor.a = alpha;
00754 highlightColor = faceColor + 0x303030;
00755 highlightColor.a = alpha;
00756 shadowColor = faceColor - 0x303030;
00757 shadowColor.a = alpha;
00758
00759 offset = 0;
00760 }
00761
00762 graphics->setColor(faceColor);
00763 graphics->fillRectangle(Rectangle(0, 0, dim.width, dim.height));
00764
00765 graphics->setColor(highlightColor);
00766 graphics->drawLine(0, 0, dim.width - 1, 0);
00767 graphics->drawLine(0, 1, 0, dim.height - 1);
00768
00769 graphics->setColor(shadowColor);
00770 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00771 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00772
00773 graphics->setColor(getForegroundColor());
00774
00775 int i;
00776 int w = dim.width / 2;
00777 int h = w + 1;
00778 for (i = 0; i < w / 2; ++i)
00779 {
00780 graphics->drawLine(-i + h + offset,
00781 w - i + offset,
00782 -i + h + offset,
00783 w + i + offset);
00784 }
00785
00786 graphics->popClipArea();
00787 }
00788
00789 void ScrollArea::drawVMarker(Graphics* graphics)
00790 {
00791 Rectangle dim = getVerticalMarkerDimension();
00792 graphics->pushClipArea(dim);
00793
00794 int alpha = getBaseColor().a;
00795 Color faceColor = getBaseColor();
00796 faceColor.a = alpha;
00797 Color highlightColor = faceColor + 0x303030;
00798 highlightColor.a = alpha;
00799 Color shadowColor = faceColor - 0x303030;
00800 shadowColor.a = alpha;
00801
00802 graphics->setColor(faceColor);
00803 graphics->fillRectangle(Rectangle(1, 1, dim.width - 1, dim.height - 1));
00804
00805 graphics->setColor(highlightColor);
00806 graphics->drawLine(0, 0, dim.width - 1, 0);
00807 graphics->drawLine(0, 1, 0, dim.height - 1);
00808
00809 graphics->setColor(shadowColor);
00810 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00811 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00812
00813 graphics->popClipArea();
00814 }
00815
00816 void ScrollArea::drawHMarker(Graphics* graphics)
00817 {
00818 Rectangle dim = getHorizontalMarkerDimension();
00819 graphics->pushClipArea(dim);
00820
00821 int alpha = getBaseColor().a;
00822 Color faceColor = getBaseColor();
00823 faceColor.a = alpha;
00824 Color highlightColor = faceColor + 0x303030;
00825 highlightColor.a = alpha;
00826 Color shadowColor = faceColor - 0x303030;
00827 shadowColor.a = alpha;
00828
00829 graphics->setColor(faceColor);
00830 graphics->fillRectangle(Rectangle(1, 1, dim.width - 1, dim.height - 1));
00831
00832 graphics->setColor(highlightColor);
00833 graphics->drawLine(0, 0, dim.width - 1, 0);
00834 graphics->drawLine(0, 1, 0, dim.height - 1);
00835
00836 graphics->setColor(shadowColor);
00837 graphics->drawLine(1, dim.height - 1, dim.width - 1, dim.height - 1);
00838 graphics->drawLine(dim.width - 1, 0, dim.width - 1, dim.height - 1);
00839
00840 graphics->popClipArea();
00841 }
00842
00843 void ScrollArea::logic()
00844 {
00845 checkPolicies();
00846
00847 setVerticalScrollAmount(getVerticalScrollAmount());
00848 setHorizontalScrollAmount(getHorizontalScrollAmount());
00849
00850 if (mContent != NULL)
00851 {
00852 mContent->setPosition(-mHScroll + getContentDimension().x + mContent->getBorderSize(),
00853 -mVScroll + getContentDimension().y + mContent->getBorderSize());
00854
00855 mContent->logic();
00856 }
00857 }
00858
00859 void ScrollArea::moveToTop(Widget* widget)
00860 {
00861 if (widget == mContent)
00862 {
00863 if (getParent())
00864 {
00865 getParent()->moveToTop(this);
00866 }
00867 }
00868 else
00869 {
00870 throw GCN_EXCEPTION("Only a ScrollArea's content may be moved to top.");
00871 }
00872 }
00873
00874 void ScrollArea::moveToBottom(Widget* widget)
00875 {
00876 if (widget == mContent)
00877 {
00878 if (getParent())
00879 {
00880 getParent()->moveToBottom(this);
00881 }
00882 }
00883 else
00884 {
00885 throw GCN_EXCEPTION("Only a ScrollArea's content may be moved to bottom.");
00886 }
00887 }
00888
00889 void ScrollArea::_announceDeath(Widget *widget)
00890 {
00891 if (widget == mContent)
00892 {
00893 mContent = NULL;
00894 checkPolicies();
00895 }
00896 else
00897 {
00898 throw GCN_EXCEPTION("Called by not-child.");
00899 }
00900 }
00901
00902 void ScrollArea::getDrawSize(int& width, int& height, Widget* widget)
00903 {
00904 if (mContent == widget)
00905 {
00906 width = getContentDimension().width;
00907 height = getContentDimension().height;
00908 }
00909 else
00910 {
00911 throw GCN_EXCEPTION("Widget not in scrollarea.");
00912 }
00913 }
00914
00915 void ScrollArea::drawContent(Graphics* graphics)
00916 {
00917 if (mContent)
00918 {
00919 mContent->draw(graphics);
00920 }
00921 }
00922
00923 void ScrollArea::checkPolicies()
00924 {
00925 int w = getWidth();
00926 int h = getHeight();
00927
00928 mHBarVisible = false;
00929 mVBarVisible = false;
00930
00931
00932 if (!mContent)
00933 {
00934 mHBarVisible = (mHPolicy == SHOW_ALWAYS);
00935 mVBarVisible = (mVPolicy == SHOW_ALWAYS);
00936 return;
00937 }
00938
00939 if (mHPolicy == SHOW_AUTO &&
00940 mVPolicy == SHOW_AUTO)
00941 {
00942 if (mContent->getWidth() <= w
00943 && mContent->getHeight() <= h)
00944 {
00945 mHBarVisible = false;
00946 mVBarVisible = false;
00947 }
00948
00949 if (mContent->getWidth() > w)
00950 {
00951 mHBarVisible = true;
00952 }
00953
00954 if ((mContent->getHeight() > h)
00955 || (mHBarVisible && mContent->getHeight() > h - mScrollbarWidth))
00956 {
00957 mVBarVisible = true;
00958 }
00959
00960 if (mVBarVisible && mContent->getWidth() > w - mScrollbarWidth)
00961 {
00962 mHBarVisible = true;
00963 }
00964
00965 return;
00966 }
00967
00968 switch (mHPolicy)
00969 {
00970 case SHOW_NEVER:
00971 mHBarVisible = false;
00972 break;
00973
00974 case SHOW_ALWAYS:
00975 mHBarVisible = true;
00976 break;
00977
00978 case SHOW_AUTO:
00979 if (mVPolicy == SHOW_NEVER)
00980 {
00981 mHBarVisible = mContent->getWidth() > w;
00982 }
00983 else
00984 {
00985 mHBarVisible = mContent->getWidth() > w - mScrollbarWidth;
00986 }
00987 break;
00988
00989 default:
00990 throw GCN_EXCEPTION("Horizontal scroll policy invalid.");
00991 }
00992
00993 switch (mVPolicy)
00994 {
00995 case SHOW_NEVER:
00996 mVBarVisible = false;
00997 break;
00998
00999 case SHOW_ALWAYS:
01000 mVBarVisible = true;
01001 break;
01002
01003 case SHOW_AUTO:
01004 if (mHPolicy == SHOW_NEVER)
01005 {
01006 mVBarVisible = mContent->getHeight() > h;
01007 }
01008 else
01009 {
01010 mVBarVisible = mContent->getHeight() > h - mScrollbarWidth;
01011 }
01012 break;
01013 default:
01014 throw GCN_EXCEPTION("Vertical scroll policy invalid.");
01015 }
01016 }
01017
01018 Rectangle ScrollArea::getUpButtonDimension()
01019 {
01020 if (!mVBarVisible)
01021 {
01022 return Rectangle(0, 0, 0, 0);
01023 }
01024
01025 return Rectangle(getWidth() - mScrollbarWidth,
01026 0,
01027 mScrollbarWidth,
01028 mScrollbarWidth);
01029 }
01030
01031 Rectangle ScrollArea::getDownButtonDimension()
01032 {
01033 if (!mVBarVisible)
01034 {
01035 return Rectangle(0, 0, 0, 0);
01036 }
01037
01038 if (mVBarVisible && mHBarVisible)
01039 {
01040 return Rectangle(getWidth() - mScrollbarWidth,
01041 getHeight() - mScrollbarWidth*2,
01042 mScrollbarWidth,
01043 mScrollbarWidth);
01044 }
01045
01046 return Rectangle(getWidth() - mScrollbarWidth,
01047 getHeight() - mScrollbarWidth,
01048 mScrollbarWidth,
01049 mScrollbarWidth);
01050 }
01051
01052 Rectangle ScrollArea::getLeftButtonDimension()
01053 {
01054 if (!mHBarVisible)
01055 {
01056 return Rectangle(0, 0, 0, 0);
01057 }
01058
01059 return Rectangle(0,
01060 getHeight() - mScrollbarWidth,
01061 mScrollbarWidth,
01062 mScrollbarWidth);
01063 }
01064
01065 Rectangle ScrollArea::getRightButtonDimension()
01066 {
01067 if (!mHBarVisible)
01068 {
01069 return Rectangle(0, 0, 0, 0);
01070 }
01071
01072 if (mVBarVisible && mHBarVisible)
01073 {
01074 return Rectangle(getWidth() - mScrollbarWidth*2,
01075 getHeight() - mScrollbarWidth,
01076 mScrollbarWidth,
01077 mScrollbarWidth);
01078 }
01079
01080 return Rectangle(getWidth() - mScrollbarWidth,
01081 getHeight() - mScrollbarWidth,
01082 mScrollbarWidth,
01083 mScrollbarWidth);
01084 }
01085
01086 Rectangle ScrollArea::getContentDimension()
01087 {
01088 if (mVBarVisible && mHBarVisible)
01089 {
01090 return Rectangle(0, 0, getWidth() - mScrollbarWidth,
01091 getHeight() - mScrollbarWidth);
01092 }
01093
01094 if (mVBarVisible)
01095 {
01096 return Rectangle(0, 0, getWidth() - mScrollbarWidth, getHeight());
01097 }
01098
01099 if (mHBarVisible)
01100 {
01101 return Rectangle(0, 0, getWidth(), getHeight() - mScrollbarWidth);
01102 }
01103
01104 return Rectangle(0, 0, getWidth(), getHeight());
01105 }
01106
01107 Rectangle ScrollArea::getVerticalBarDimension()
01108 {
01109 if (!mVBarVisible)
01110 {
01111 return Rectangle(0, 0, 0, 0);
01112 }
01113
01114 if (mHBarVisible)
01115 {
01116 return Rectangle(getWidth() - mScrollbarWidth,
01117 getUpButtonDimension().height,
01118 mScrollbarWidth,
01119 getHeight()
01120 - getUpButtonDimension().height
01121 - getDownButtonDimension().height
01122 - mScrollbarWidth);
01123 }
01124
01125 return Rectangle(getWidth() - mScrollbarWidth,
01126 getUpButtonDimension().height,
01127 mScrollbarWidth,
01128 getHeight()
01129 - getUpButtonDimension().height
01130 - getDownButtonDimension().height);
01131 }
01132
01133 Rectangle ScrollArea::getHorizontalBarDimension()
01134 {
01135 if (!mHBarVisible)
01136 {
01137 return Rectangle(0, 0, 0, 0);
01138 }
01139
01140 if (mVBarVisible)
01141 {
01142 return Rectangle(getLeftButtonDimension().width,
01143 getHeight() - mScrollbarWidth,
01144 getWidth()
01145 - getLeftButtonDimension().width
01146 - getRightButtonDimension().width
01147 - mScrollbarWidth,
01148 mScrollbarWidth);
01149 }
01150
01151 return Rectangle(getLeftButtonDimension().width,
01152 getHeight() - mScrollbarWidth,
01153 getWidth()
01154 - getLeftButtonDimension().width
01155 - getRightButtonDimension().width,
01156 mScrollbarWidth);
01157 }
01158
01159 Rectangle ScrollArea::getVerticalMarkerDimension()
01160 {
01161 if (!mVBarVisible)
01162 {
01163 return Rectangle(0, 0, 0, 0);
01164 }
01165
01166 int length, pos;
01167 Rectangle barDim = getVerticalBarDimension();
01168
01169 if (mContent && mContent->getHeight() != 0)
01170 {
01171 length = (barDim.height * getContentDimension().height)
01172 / mContent->getHeight();
01173 }
01174 else
01175 {
01176 length = barDim.height;
01177 }
01178
01179 if (length < mScrollbarWidth)
01180 {
01181 length = mScrollbarWidth;
01182 }
01183
01184 if (length > barDim.height)
01185 {
01186 length = barDim.height;
01187 }
01188
01189 if (getVerticalMaxScroll() != 0)
01190 {
01191 pos = ((barDim.height - length) * getVerticalScrollAmount())
01192 / getVerticalMaxScroll();
01193 }
01194 else
01195 {
01196 pos = 0;
01197 }
01198
01199 return Rectangle(barDim.x, barDim.y + pos, mScrollbarWidth, length);
01200 }
01201
01202 Rectangle ScrollArea::getHorizontalMarkerDimension()
01203 {
01204 if (!mHBarVisible)
01205 {
01206 return Rectangle(0, 0, 0, 0);
01207 }
01208
01209 int length, pos;
01210 Rectangle barDim = getHorizontalBarDimension();
01211
01212 if (mContent && mContent->getWidth() != 0)
01213 {
01214 length = (barDim.width * getContentDimension().width)
01215 / mContent->getWidth();
01216 }
01217 else
01218 {
01219 length = barDim.width;
01220 }
01221
01222 if (length < mScrollbarWidth)
01223 {
01224 length = mScrollbarWidth;
01225 }
01226
01227 if (length > barDim.width)
01228 {
01229 length = barDim.width;
01230 }
01231
01232 if (getHorizontalMaxScroll() != 0)
01233 {
01234 pos = ((barDim.width - length) * getHorizontalScrollAmount())
01235 / getHorizontalMaxScroll();
01236 }
01237 else
01238 {
01239 pos = 0;
01240 }
01241
01242 return Rectangle(barDim.x + pos, barDim.y, length, mScrollbarWidth);
01243 }
01244
01245 void ScrollArea::scrollToRectangle(const Rectangle& rectangle)
01246 {
01247 Rectangle contentDim = getContentDimension();
01248
01249 if (rectangle.x + rectangle.width
01250 > getHorizontalScrollAmount() + contentDim.width)
01251 {
01252 setHorizontalScrollAmount(rectangle.x + rectangle.width - contentDim.width);
01253 }
01254
01255 if (rectangle.y + rectangle.height
01256 > getVerticalScrollAmount() + contentDim.height)
01257 {
01258 setVerticalScrollAmount(rectangle.y + rectangle.height - contentDim.height);
01259 }
01260
01261 if (rectangle.x < getHorizontalScrollAmount())
01262 {
01263 setHorizontalScrollAmount(rectangle.x);
01264 }
01265
01266 if (rectangle.y < getVerticalScrollAmount())
01267 {
01268 setVerticalScrollAmount(rectangle.y);
01269 }
01270 }
01271
01272 void ScrollArea::mouseWheelUp(int x, int y)
01273 {
01274 if (hasMouse())
01275 {
01276 setVerticalScrollAmount(getVerticalScrollAmount() - getContentDimension().height / 8);
01277 }
01278 }
01279
01280 void ScrollArea::mouseWheelDown(int x, int y)
01281 {
01282 if (hasMouse())
01283 {
01284 setVerticalScrollAmount(getVerticalScrollAmount() + getContentDimension().height / 8);
01285 }
01286 }
01287 }
01288
01289
01290
01291