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 #include "guichan/exception.h"
00056 #include "guichan/widgets/dropdown.h"
00057
00058 namespace gcn
00059 {
00060 DropDown::DropDown()
00061 {
00062 mDroppedDown = false;
00063 mPushed = false;
00064 mOldH = 0;
00065
00066 setWidth(100);
00067 setFocusable(true);
00068
00069 mDefaultScrollArea = new ScrollArea();
00070 mDefaultScrollArea->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
00071 mDefaultListBox = new ListBox();
00072
00073 mScrollArea = mDefaultScrollArea;
00074 mScrollArea->_setFocusHandler(&mFocusHandler);
00075 mScrollArea->_setParent(this);
00076
00077 mListBox = mDefaultListBox;
00078 mListBox->addActionListener(this);
00079 mScrollArea->setContent(mListBox);
00080
00081 addMouseListener(this);
00082 addKeyListener(this);
00083 adjustHeight();
00084 setBorderSize(1);
00085 }
00086
00087 DropDown::DropDown(ListModel *listModel)
00088 {
00089 setWidth(100);
00090 setFocusable(true);
00091 mDroppedDown = false;
00092 mPushed = false;
00093 mOldH = 0;
00094
00095 mDefaultScrollArea = new ScrollArea();
00096 mDefaultScrollArea->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
00097 mDefaultListBox = new ListBox();
00098
00099 mScrollArea = mDefaultScrollArea;
00100 mScrollArea->_setParent(this);
00101 mListBox = mDefaultListBox;
00102 mListBox->addActionListener(this);
00103
00104 mScrollArea->setContent(mListBox);
00105 mScrollArea->_setFocusHandler(&mFocusHandler);
00106 mScrollArea->_setParent(this);
00107
00108 setListModel(listModel);
00109
00110 if (mListBox->getSelected() < 0)
00111 {
00112 mListBox->setSelected(0);
00113 }
00114
00115 addMouseListener(this);
00116 addKeyListener(this);
00117 adjustHeight();
00118 setBorderSize(1);
00119 }
00120
00121 DropDown::DropDown(ListModel *listModel,
00122 ScrollArea *scrollArea,
00123 ListBox *listBox)
00124 {
00125 setWidth(100);
00126 setFocusable(true);
00127 mDroppedDown = false;
00128 mPushed = false;
00129 mOldH = 0;
00130
00131 mDefaultScrollArea = NULL;
00132 mDefaultListBox = NULL;
00133
00134 mScrollArea = scrollArea;
00135 mScrollArea->_setFocusHandler(&mFocusHandler);
00136
00137 mListBox = listBox;
00138 mListBox->addActionListener(this);
00139 mScrollArea->setContent(mListBox);
00140 mScrollArea->_setParent(this);
00141
00142 setListModel(listModel);
00143
00144 if (mListBox->getSelected() < 0)
00145 {
00146 mListBox->setSelected(0);
00147 }
00148
00149 addMouseListener(this);
00150 addKeyListener(this);
00151 adjustHeight();
00152 setBorderSize(1);
00153 }
00154
00155 DropDown::~DropDown()
00156 {
00157 if (mScrollArea != NULL)
00158 {
00159 mScrollArea->_setFocusHandler(NULL);
00160 }
00161
00162 if (mDefaultScrollArea != NULL)
00163 {
00164 delete mDefaultScrollArea;
00165 }
00166
00167 if (mDefaultListBox != NULL)
00168 {
00169 delete mDefaultListBox;
00170 }
00171
00172 if (widgetExists(mListBox))
00173 {
00174 mListBox->removeActionListener(this);
00175 }
00176 }
00177
00178 void DropDown::logic()
00179 {
00180 if (mScrollArea == NULL || mScrollArea->getContent() == NULL)
00181 {
00182 throw GCN_EXCEPTION("ScrollArea or ListBox is NULL.");
00183 }
00184
00185 mScrollArea->logic();
00186 mFocusHandler.applyChanges();
00187 }
00188
00189 void DropDown::draw(Graphics* graphics)
00190 {
00191 if (mScrollArea == NULL || mScrollArea->getContent() == NULL)
00192 {
00193 throw GCN_EXCEPTION("ScrollArea or ListBox is NULL.");
00194 }
00195
00196 int h;
00197
00198 if (mDroppedDown)
00199 {
00200 h = mOldH;
00201 }
00202 else
00203 {
00204 h = getHeight();
00205 }
00206
00207 int alpha = getBaseColor().a;
00208 Color faceColor = getBaseColor();
00209 faceColor.a = alpha;
00210 Color highlightColor = faceColor + 0x303030;
00211 highlightColor.a = alpha;
00212 Color shadowColor = faceColor - 0x303030;
00213 shadowColor.a = alpha;
00214
00215
00216 graphics->setColor(getBackgroundColor());
00217 graphics->fillRectangle(Rectangle(0, 0, getWidth(), h));
00218
00219 graphics->setColor(getForegroundColor());
00220 graphics->setFont(getFont());
00221
00222 if (mListBox->getListModel() && mListBox->getSelected() >= 0)
00223 {
00224 graphics->drawText(mListBox->getListModel()->getElementAt(mListBox->getSelected()),
00225 1, (h - getFont()->getHeight()) / 2);
00226 }
00227
00228 if (hasFocus())
00229 {
00230 graphics->drawRectangle(Rectangle(0, 0, getWidth() - h, h));
00231 }
00232
00233 drawButton(graphics);
00234
00235 if (mDroppedDown)
00236 {
00237 graphics->pushClipArea(mScrollArea->getDimension());
00238 mScrollArea->draw(graphics);
00239 graphics->popClipArea();
00240
00241
00242
00243 graphics->setColor(highlightColor);
00244 graphics->drawLine(0, h, getWidth(), h);
00245 graphics->setColor(shadowColor);
00246 graphics->drawLine(0, h + 1,getWidth(),h + 1);
00247 }
00248 }
00249
00250 void DropDown::drawBorder(Graphics* graphics)
00251 {
00252 Color faceColor = getBaseColor();
00253 Color highlightColor, shadowColor;
00254 int alpha = getBaseColor().a;
00255 int width = getWidth() + getBorderSize() * 2 - 1;
00256 int height = getHeight() + getBorderSize() * 2 - 1;
00257 highlightColor = faceColor + 0x303030;
00258 highlightColor.a = alpha;
00259 shadowColor = faceColor - 0x303030;
00260 shadowColor.a = alpha;
00261
00262 unsigned int i;
00263 for (i = 0; i < getBorderSize(); ++i)
00264 {
00265 graphics->setColor(shadowColor);
00266 graphics->drawLine(i,i, width - i, i);
00267 graphics->drawLine(i,i + 1, i, height - i - 1);
00268 graphics->setColor(highlightColor);
00269 graphics->drawLine(width - i,i + 1, width - i, height - i);
00270 graphics->drawLine(i,height - i, width - i - 1, height - i);
00271 }
00272 }
00273
00274 void DropDown::drawButton(Graphics *graphics)
00275 {
00276 Color faceColor, highlightColor, shadowColor;
00277 int offset;
00278 int alpha = getBaseColor().a;
00279
00280 if (mPushed)
00281 {
00282 faceColor = getBaseColor() - 0x303030;
00283 faceColor.a = alpha;
00284 highlightColor = faceColor - 0x303030;
00285 highlightColor.a = alpha;
00286 shadowColor = faceColor + 0x303030;
00287 shadowColor.a = alpha;
00288 offset = 1;
00289 }
00290 else
00291 {
00292 faceColor = getBaseColor();
00293 faceColor.a = alpha;
00294 highlightColor = faceColor + 0x303030;
00295 highlightColor.a = alpha;
00296 shadowColor = faceColor - 0x303030;
00297 shadowColor.a = alpha;
00298 offset = 0;
00299 }
00300
00301 int h;
00302 if (mDroppedDown)
00303 {
00304 h = mOldH;
00305 }
00306 else
00307 {
00308 h = getHeight();
00309 }
00310 int x = getWidth() - h;
00311 int y = 0;
00312
00313 graphics->setColor(faceColor);
00314 graphics->fillRectangle(Rectangle(x+1, y+1, h-2, h-2));
00315
00316 graphics->setColor(highlightColor);
00317 graphics->drawLine(x, y, x+h-1, y);
00318 graphics->drawLine(x, y+1, x, y+h-1);
00319
00320 graphics->setColor(shadowColor);
00321 graphics->drawLine(x+h-1, y+1, x+h-1, y+h-1);
00322 graphics->drawLine(x+1, y+h-1, x+h-2, y+h-1);
00323
00324 graphics->setColor(getForegroundColor());
00325
00326 int i;
00327 int hh = h / 3;
00328 int hx = x + h / 2;
00329 int hy = y + (h * 2) / 3;
00330 for (i=0; i<hh; i++)
00331 {
00332 graphics->drawLine(hx - i + offset,
00333 hy - i + offset,
00334 hx + i + offset,
00335 hy - i + offset);
00336 }
00337 }
00338
00339 int DropDown::getSelected()
00340 {
00341 if (mScrollArea == NULL || mScrollArea->getContent() == NULL)
00342 {
00343 throw GCN_EXCEPTION("ScrollArea or ListBox is NULL.");
00344 }
00345
00346 return mListBox->getSelected();
00347 }
00348
00349 void DropDown::setSelected(int selected)
00350 {
00351 if (mScrollArea == NULL || mScrollArea->getContent() == NULL)
00352 {
00353 throw GCN_EXCEPTION("ScrollArea or ListBox is NULL.");
00354 }
00355
00356 if (selected >= 0)
00357 {
00358 mListBox->setSelected(selected);
00359 }
00360 }
00361
00362 bool DropDown::keyPress(const Key& key)
00363 {
00364 if (mScrollArea == NULL || mScrollArea->getContent() == NULL)
00365 {
00366 throw GCN_EXCEPTION("ScrollArea or ListBox is NULL.");
00367 }
00368
00369 if ((key.getValue() == Key::ENTER || key.getValue() == Key::SPACE)
00370 && !mDroppedDown)
00371 {
00372 dropDown();
00373 return true;
00374 }
00375 return false;
00376 }
00377
00378 void DropDown::mousePress(int x, int y, int button)
00379 {
00380 if (button == MouseInput::LEFT && hasMouse() && !mDroppedDown)
00381 {
00382 mPushed = true;
00383 dropDown();
00384 }
00385
00386 else if (button == MouseInput::LEFT && hasMouse() && mDroppedDown
00387 && y < mOldH)
00388 {
00389 foldUp();
00390 }
00391 else if (!hasMouse())
00392 {
00393 foldUp();
00394 }
00395 }
00396
00397 void DropDown::mouseRelease(int x, int y, int button)
00398 {
00399 if (button == MouseInput::LEFT)
00400 {
00401 mPushed = false;
00402 }
00403 }
00404
00405 void DropDown::setListModel(ListModel *listModel)
00406 {
00407 if (mScrollArea == NULL || mScrollArea->getContent() == NULL)
00408 {
00409 throw GCN_EXCEPTION("ScrollArea or ListBox is NULL.");
00410 }
00411
00412 mListBox->setListModel(listModel);
00413
00414 if (mListBox->getSelected() < 0)
00415 {
00416 mListBox->setSelected(0);
00417 }
00418
00419 adjustHeight();
00420 }
00421
00422 ListModel *DropDown::getListModel()
00423 {
00424 if (mScrollArea == NULL || mScrollArea->getContent() == NULL)
00425 {
00426 throw GCN_EXCEPTION("ScrollArea or ListBox is NULL.");
00427 }
00428
00429 return mListBox->getListModel();
00430 }
00431
00432 void DropDown::setScrollArea(ScrollArea *scrollArea)
00433 {
00434 mScrollArea->_setFocusHandler(NULL);
00435 mScrollArea->_setParent(NULL);
00436 mScrollArea = scrollArea;
00437 mScrollArea->_setFocusHandler(&mFocusHandler);
00438 mScrollArea->setContent(mListBox);
00439 mScrollArea->_setParent(this);
00440 adjustHeight();
00441 }
00442
00443 ScrollArea *DropDown::getScrollArea()
00444 {
00445 return mScrollArea;
00446 }
00447
00448 void DropDown::setListBox(ListBox *listBox)
00449 {
00450 listBox->setSelected(mListBox->getSelected());
00451 listBox->setListModel(mListBox->getListModel());
00452 listBox->addActionListener(this);
00453
00454 if (mScrollArea->getContent() != NULL)
00455 {
00456 mListBox->removeActionListener(this);
00457 }
00458
00459 mListBox = listBox;
00460
00461 mScrollArea->setContent(mListBox);
00462
00463 if (mListBox->getSelected() < 0)
00464 {
00465 mListBox->setSelected(0);
00466 }
00467 }
00468
00469 ListBox *DropDown::getListBox()
00470 {
00471 return mListBox;
00472 }
00473
00474 void DropDown::adjustHeight()
00475 {
00476 if (mScrollArea == NULL || mScrollArea->getContent() == NULL)
00477 {
00478 throw GCN_EXCEPTION("ScrollArea or ListBox is NULL.");
00479 }
00480
00481 int listBoxHeight = mListBox->getHeight();
00482 int h2 = mOldH ? mOldH : getFont()->getHeight();
00483
00484 setHeight(h2);
00485
00486
00487
00488
00489 if (mDroppedDown && getParent())
00490 {
00491 int h = getParent()->getHeight() - getY();
00492
00493 if (listBoxHeight > h - h2 - 2)
00494 {
00495 mScrollArea->setHeight(h - h2 - 2);
00496 setHeight(h);
00497 }
00498 else
00499 {
00500 setHeight(listBoxHeight + h2 + 2);
00501 mScrollArea->setHeight(listBoxHeight);
00502 }
00503 }
00504
00505 mScrollArea->setWidth(getWidth());
00506 mScrollArea->setPosition(0, h2 + 2);
00507 }
00508
00509 void DropDown::dropDown()
00510 {
00511 if (!mDroppedDown)
00512 {
00513 mDroppedDown = true;
00514 mOldH = getHeight();
00515 adjustHeight();
00516
00517 if (getParent())
00518 {
00519 getParent()->moveToTop(this);
00520 }
00521 }
00522
00523 mFocusHandler.requestFocus(mScrollArea->getContent());
00524 }
00525
00526 void DropDown::foldUp()
00527 {
00528 if (mDroppedDown)
00529 {
00530 mDroppedDown = false;
00531 mFocusHandler.focusNone();
00532 adjustHeight();
00533 }
00534 }
00535
00536 bool DropDown::_keyInputMessage(const KeyInput& keyInput)
00537 {
00538 if (mDroppedDown)
00539 {
00540 if (mScrollArea == NULL || mScrollArea->getContent() == NULL)
00541 {
00542 throw GCN_EXCEPTION("ScrollArea or ListBox is NULL.");
00543 }
00544
00545 if (mFocusHandler.getFocused() != NULL)
00546 {
00547 return mFocusHandler.getFocused()->_keyInputMessage(keyInput);
00548 }
00549 else
00550 {
00551 return false;
00552 }
00553 }
00554 else
00555 {
00556 return BasicContainer::_keyInputMessage(keyInput);
00557 }
00558 }
00559
00560 void DropDown::_mouseInputMessage(const MouseInput &mouseInput)
00561 {
00562 BasicContainer::_mouseInputMessage(mouseInput);
00563
00564 if (mDroppedDown)
00565 {
00566 if (mScrollArea == NULL || mScrollArea->getContent() == NULL)
00567 {
00568 throw GCN_EXCEPTION("ScrollArea or ListBox is NULL.");
00569 }
00570
00571 if (mouseInput.y >= mOldH)
00572 {
00573 MouseInput mi = mouseInput;
00574 mi.y -= mScrollArea->getY();
00575 mScrollArea->_mouseInputMessage(mi);
00576
00577 if (mListBox->hasFocus())
00578 {
00579 mi.y -= mListBox->getY();
00580 mListBox->_mouseInputMessage(mi);
00581 }
00582 }
00583 }
00584 }
00585
00586 void DropDown::lostFocus()
00587 {
00588 foldUp();
00589 }
00590
00591 void DropDown::moveToTop(Widget* widget)
00592 {
00593 if (getParent())
00594 {
00595 getParent()->moveToTop(this);
00596 }
00597 }
00598
00599 void DropDown::moveToBottom(Widget* widget)
00600 {
00601 if (getParent())
00602 {
00603 getParent()->moveToBottom(this);
00604 }
00605 }
00606
00607 void DropDown::_announceDeath(Widget* widget)
00608 {
00609 if (widget == mScrollArea)
00610 {
00611 mScrollArea = NULL;
00612 }
00613 else
00614 {
00615 throw GCN_EXCEPTION("Death announced for unknown widget..");
00616 }
00617 }
00618
00619 void DropDown::action(const std::string& eventId)
00620 {
00621 foldUp();
00622 generateAction();
00623 }
00624
00625 void DropDown::getDrawSize(int& width, int& height, Widget* widget)
00626 {
00627 if (widget == mScrollArea)
00628 {
00629 if (mDroppedDown)
00630 {
00631 height = getHeight() - mOldH;
00632 width = getWidth();
00633 }
00634 else
00635 {
00636 width = height = 0;
00637 }
00638 }
00639 else
00640 {
00641 throw GCN_EXCEPTION("DropDown::getDrawSize. widget is not the ScrollArea (wieeerd...)");
00642 }
00643 }
00644
00645 void DropDown::setBaseColor(const Color& color)
00646 {
00647 if (mDefaultScrollArea == mScrollArea && mScrollArea != NULL)
00648 {
00649 mScrollArea->setBaseColor(color);
00650 }
00651
00652 if (mDefaultListBox == mListBox && mListBox != NULL)
00653 {
00654 mListBox->setBaseColor(color);
00655 }
00656
00657 Widget::setBaseColor(color);
00658 }
00659
00660 void DropDown::setBackgroundColor(const Color& color)
00661 {
00662 if (mDefaultScrollArea == mScrollArea && mScrollArea != NULL)
00663 {
00664 mScrollArea->setBackgroundColor(color);
00665 }
00666
00667 if (mDefaultListBox == mListBox && mListBox != NULL)
00668 {
00669 mListBox->setBackgroundColor(color);
00670 }
00671
00672 Widget::setBackgroundColor(color);
00673 }
00674
00675 void DropDown::setForegroundColor(const Color& color)
00676 {
00677 if (mDefaultScrollArea == mScrollArea && mScrollArea != NULL)
00678 {
00679 mScrollArea->setForegroundColor(color);
00680 }
00681
00682 if (mDefaultListBox == mListBox && mListBox != NULL)
00683 {
00684 mListBox->setForegroundColor(color);
00685 }
00686
00687 Widget::setForegroundColor(color);
00688 }
00689
00690 void DropDown::setFont(Font *font)
00691 {
00692 Widget::setFont(font);
00693 mListBox->setFont(font);
00694 }
00695
00696 bool DropDown::getDirty() const
00697 {
00698 if (mDroppedDown)
00699 {
00700 return mScrollArea->getDirty();
00701 }
00702 return mDirty;
00703 }
00704 }
00705