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