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/basiccontainer.h"
00060 #include "guichan/exception.h"
00061 #include "guichan/focushandler.h"
00062 #include "guichan/widget.h"
00063
00064 #include <iostream>
00065
00066 #include "guichan/sdl/sdlinput.h"
00067 #include "SDL.h"
00068 extern int Str2SdlKey(const char *str);
00069
00070 int convertKey(const char *key)
00071 {
00072 SDL_keysym keysym;
00073 memset(&keysym, 0, sizeof(keysym));
00074 keysym.sym = (SDLKey)Str2SdlKey(key);
00075 gcn::Key k = gcn::SDLInput::convertKeyCharacter(keysym);
00076 return k.getValue();
00077 }
00078
00079 namespace gcn
00080 {
00081 Font* Widget::mGlobalFont = NULL;
00082 DefaultFont Widget::mDefaultFont;
00083 std::list<Widget*> Widget::mWidgets;
00084
00085 Widget::Widget()
00086 {
00087 mParent = NULL;
00088 mForegroundColor = Color(0x000000);
00089 mBackgroundColor = Color(0xffffff);
00090 mBaseColor = Color(0x808090);
00091 mBorderSize = 0;
00092 mFocusHandler = NULL;
00093 mFocusable = false;
00094 mClickTimeStamp = 0;
00095 mClickCount = 0;
00096 mHasMouse = false;
00097 mVisible = true;
00098 mTabIn = true;
00099 mTabOut = true;
00100 mEnabled = true;
00101 mClickButton = 0;
00102 mHotKey = 0;
00103
00104 mCurrentFont = NULL;
00105 mWidgets.push_back(this);
00106 mDirty = true;
00107 }
00108
00109 Widget::~Widget()
00110 {
00111 if (getParent() != NULL)
00112 {
00113 getParent()->_announceDeath(this);
00114 }
00115
00116 _setFocusHandler(NULL);
00117
00118 mWidgets.remove(this);
00119 }
00120
00121 void Widget::_setParent(BasicContainer* parent)
00122 {
00123 mParent = parent;
00124 }
00125
00126 BasicContainer* Widget::getParent() const
00127 {
00128 return mParent;
00129 }
00130
00131 void Widget::setWidth(int width)
00132 {
00133 mDimension.width = width;
00134 }
00135
00136 int Widget::getWidth() const
00137 {
00138 return mDimension.width;
00139 }
00140
00141 void Widget::setHeight(int height)
00142 {
00143 mDimension.height = height;
00144 }
00145
00146 int Widget::getHeight() const
00147 {
00148 return mDimension.height;
00149 }
00150
00151 void Widget::setX(int x)
00152 {
00153 mDimension.x = x;
00154 }
00155
00156 int Widget::getX() const
00157 {
00158 return mDimension.x;
00159 }
00160
00161 void Widget::setY(int y)
00162 {
00163 mDimension.y = y;
00164 }
00165
00166 int Widget::getY() const
00167 {
00168 return mDimension.y;
00169 }
00170
00171 void Widget::setPosition(int x, int y)
00172 {
00173 mDimension.x = x;
00174 mDimension.y = y;
00175 }
00176
00177 void Widget::setDimension(const Rectangle& dimension)
00178 {
00179 mDimension = dimension;
00180 }
00181
00182 void Widget::setBorderSize(unsigned int borderSize)
00183 {
00184 mBorderSize = borderSize;
00185 }
00186
00187 unsigned int Widget::getBorderSize() const
00188 {
00189 return mBorderSize;
00190 }
00191
00192 const Rectangle& Widget::getDimension() const
00193 {
00194 return mDimension;
00195 }
00196
00197 const std::string& Widget::getEventId() const
00198 {
00199 return mEventId;
00200 }
00201
00202 void Widget::setEventId(const std::string& eventId)
00203 {
00204 mEventId = eventId;
00205 }
00206
00207 bool Widget::hasFocus() const
00208 {
00209 if (!mFocusHandler)
00210 {
00211 return false;
00212 }
00213
00214 return (mFocusHandler->hasFocus(this));
00215 }
00216
00217 bool Widget::hasMouse() const
00218 {
00219 return mHasMouse;
00220 }
00221
00222 void Widget::setFocusable(bool focusable)
00223 {
00224 if (!focusable && hasFocus())
00225 {
00226 mFocusHandler->focusNone();
00227 }
00228
00229 mFocusable = focusable;
00230 }
00231
00232 bool Widget::isFocusable() const
00233 {
00234 return mFocusable && isVisible() && isEnabled();
00235 }
00236
00237 void Widget::requestFocus()
00238 {
00239 if (mFocusHandler == NULL)
00240 {
00241 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00242 }
00243
00244 if (isFocusable())
00245 {
00246 mFocusHandler->requestFocus(this);
00247 }
00248 }
00249
00250 void Widget::requestMoveToTop()
00251 {
00252 if (mParent)
00253 {
00254 mParent->moveToTop(this);
00255 }
00256 }
00257
00258 void Widget::requestMoveToBottom()
00259 {
00260 if (mParent)
00261 {
00262 mParent->moveToBottom(this);
00263 }
00264 }
00265
00266 void Widget::setVisible(bool visible)
00267 {
00268 if (!visible && hasFocus())
00269 {
00270 mFocusHandler->focusNone();
00271 }
00272 mVisible = visible;
00273 }
00274
00275 bool Widget::isVisible() const
00276 {
00277 if (getParent() == NULL)
00278 {
00279 return mVisible;
00280 }
00281 else
00282 {
00283 return mVisible && getParent()->isVisible();
00284 }
00285 }
00286
00287 void Widget::setBaseColor(const Color& color)
00288 {
00289 mBaseColor = color;
00290 }
00291
00292 const Color& Widget::getBaseColor() const
00293 {
00294 return mBaseColor;
00295 }
00296
00297 void Widget::setForegroundColor(const Color& color)
00298 {
00299 mForegroundColor = color;
00300 }
00301
00302 const Color& Widget::getForegroundColor() const
00303 {
00304 return mForegroundColor;
00305 }
00306
00307 void Widget::setBackgroundColor(const Color& color)
00308 {
00309 mBackgroundColor = color;
00310 }
00311
00312 const Color& Widget::getBackgroundColor() const
00313 {
00314 return mBackgroundColor;
00315 }
00316
00317 void Widget::setDisabledColor(const Color& color)
00318 {
00319 mDisabledColor = color;
00320 }
00321
00322 const Color& Widget::getDisabledColor() const
00323 {
00324 return mDisabledColor;
00325 }
00326
00327 void Widget::_setFocusHandler(FocusHandler* focusHandler)
00328 {
00329 if (mFocusHandler)
00330 {
00331 releaseModalFocus();
00332 mFocusHandler->remove(this);
00333 }
00334
00335 if (focusHandler)
00336 {
00337 focusHandler->add(this);
00338 }
00339
00340 mFocusHandler = focusHandler;
00341 }
00342
00343 FocusHandler* Widget::_getFocusHandler()
00344 {
00345 return mFocusHandler;
00346 }
00347
00348 void Widget::addActionListener(ActionListener* actionListener)
00349 {
00350 mActionListeners.push_back(actionListener);
00351 }
00352
00353 void Widget::removeActionListener(ActionListener* actionListener)
00354 {
00355 mActionListeners.remove(actionListener);
00356 }
00357
00358 void Widget::addKeyListener(KeyListener* keyListener)
00359 {
00360 mKeyListeners.push_back(keyListener);
00361 }
00362
00363 void Widget::removeKeyListener(KeyListener* keyListener)
00364 {
00365 mKeyListeners.remove(keyListener);
00366 }
00367
00368 void Widget::addMouseListener(MouseListener* mouseListener)
00369 {
00370 mMouseListeners.push_back(mouseListener);
00371 }
00372
00373 void Widget::removeMouseListener(MouseListener* mouseListener)
00374 {
00375 mMouseListeners.remove(mouseListener);
00376 }
00377
00378 void Widget::_mouseInputMessage(const MouseInput& mouseInput)
00379 {
00380 if (mFocusHandler == NULL)
00381 {
00382 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00383 }
00384
00385 if (!mEnabled || (mFocusHandler->getModalFocused() != NULL &&
00386 !hasModalFocus()))
00387 {
00388 return;
00389 }
00390
00391 int x = mouseInput.x;
00392 int y = mouseInput.y;
00393 int b = mouseInput.getButton();
00394 int ts = mouseInput.getTimeStamp();
00395
00396 MouseListenerIterator iter;
00397
00398 switch(mouseInput.getType())
00399 {
00400 case MouseInput::MOTION:
00401 for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00402 {
00403 (*iter)->mouseMotion(x, y);
00404 }
00405 break;
00406
00407 case MouseInput::PRESS:
00408 if (hasMouse())
00409 {
00410 requestFocus();
00411 mFocusHandler->requestDrag(this);
00412 }
00413
00414 if (b != MouseInput::WHEEL_UP && b != MouseInput::WHEEL_DOWN)
00415 {
00416
00417 for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00418 {
00419 (*iter)->mousePress(x, y, b);
00420 }
00421
00422 if (hasMouse())
00423 {
00424 if (ts - mClickTimeStamp < 300 && mClickButton == b)
00425 {
00426 mClickCount++;
00427 }
00428 else
00429 {
00430 mClickCount = 0;
00431 }
00432 mClickButton = b;
00433 mClickTimeStamp = ts;
00434 }
00435 else
00436 {
00437 mClickButton = 0;
00438 }
00439 }
00440 else if (b == MouseInput::WHEEL_UP)
00441 {
00442 for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00443 {
00444 (*iter)->mouseWheelUp(x, y);
00445 }
00446 }
00447 else
00448 {
00449 for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00450 {
00451 (*iter)->mouseWheelDown(x, y);
00452 }
00453 }
00454 setDirty(true);
00455 break;
00456
00457 case MouseInput::RELEASE:
00458 if (isDragged())
00459 {
00460 mFocusHandler->dragNone();
00461 }
00462
00463 if (b != MouseInput::WHEEL_UP && b != MouseInput::WHEEL_DOWN)
00464 {
00465 for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00466 {
00467 (*iter)->mouseRelease(x, y, b);
00468 }
00469 }
00470
00471 if (mHasMouse)
00472 {
00473 if (b == mClickButton)
00474 {
00475 for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00476 {
00477 (*iter)->mouseClick(x, y, b, mClickCount + 1);
00478 }
00479 }
00480 else
00481 {
00482 mClickButton = 0;
00483 mClickCount = 0;
00484 }
00485 }
00486 else
00487 {
00488 mClickCount = 0;
00489 mClickTimeStamp = 0;
00490 }
00491 setDirty(true);
00492 break;
00493 }
00494 }
00495
00496 bool Widget::_keyInputMessage(const KeyInput& keyInput)
00497 {
00498 if (mFocusHandler == NULL)
00499 {
00500 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00501 }
00502
00503 if (!mEnabled || (mFocusHandler->getModalFocused() != NULL &&
00504 !hasModalFocus()))
00505 {
00506 return false;
00507 }
00508
00509 KeyListenerIterator iter;
00510 bool keyProcessed = false;
00511
00512 switch(keyInput.getType())
00513 {
00514 case KeyInput::PRESS:
00515 for (iter = mKeyListeners.begin(); iter != mKeyListeners.end(); ++iter)
00516 {
00517 if ((*iter)->keyPress(keyInput.getKey()))
00518 {
00519 keyProcessed = true;
00520 }
00521 }
00522 break;
00523
00524 case KeyInput::RELEASE:
00525 for (iter = mKeyListeners.begin(); iter != mKeyListeners.end(); ++iter)
00526 {
00527 if ((*iter)->keyRelease(keyInput.getKey()))
00528 {
00529 keyProcessed = true;
00530 }
00531 }
00532 break;
00533 }
00534
00535 return keyProcessed;
00536 }
00537
00538 void Widget::_mouseInMessage()
00539 {
00540 if (!mEnabled)
00541 {
00542 return;
00543 }
00544
00545 mHasMouse = true;
00546 setDirty(true);
00547
00548 MouseListenerIterator iter;
00549 for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00550 {
00551 (*iter)->mouseIn();
00552 }
00553 }
00554
00555 void Widget::_mouseOutMessage()
00556 {
00557 mHasMouse = false;
00558 setDirty(true);
00559
00560 MouseListenerIterator iter;
00561 for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00562 {
00563 (*iter)->mouseOut();
00564 }
00565 }
00566
00567 void Widget::getAbsolutePosition(int& x, int& y) const
00568 {
00569 if (getParent() == NULL)
00570 {
00571 x = mDimension.x;
00572 y = mDimension.y;
00573 return;
00574 }
00575
00576 int parentX;
00577 int parentY;
00578
00579 getParent()->getAbsolutePosition(parentX, parentY);
00580
00581 x = parentX + mDimension.x;
00582 y = parentY + mDimension.y;
00583 }
00584
00585 void Widget::generateAction()
00586 {
00587 ActionListenerIterator iter;
00588 for (iter = mActionListeners.begin(); iter != mActionListeners.end(); ++iter)
00589 {
00590 (*iter)->action(mEventId);
00591 }
00592 }
00593
00594 Font* Widget::getFont() const
00595 {
00596 if (mCurrentFont == NULL)
00597 {
00598 if (mGlobalFont == NULL)
00599 {
00600 return &mDefaultFont;
00601 }
00602
00603 return mGlobalFont;
00604 }
00605
00606 return mCurrentFont;
00607 }
00608
00609 void Widget::setGlobalFont(Font* font)
00610 {
00611 mGlobalFont = font;
00612
00613 std::list<Widget*>::iterator iter;
00614 for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter)
00615 {
00616 if ((*iter)->mCurrentFont == NULL)
00617 {
00618 (*iter)->fontChanged();
00619 }
00620 }
00621 }
00622
00623 void Widget::setFont(Font* font)
00624 {
00625 mCurrentFont = font;
00626 fontChanged();
00627 }
00628
00629 void Widget::setHotKey(const int key)
00630 {
00631 if (isascii(key))
00632 {
00633 mHotKey = tolower(key);
00634 }
00635 else
00636 {
00637 mHotKey = key;
00638 }
00639 }
00640
00641 void Widget::setHotKey(const char *key)
00642 {
00643 if (key)
00644 {
00645 mHotKey = ::convertKey(key);
00646 if (mHotKey == 0)
00647 {
00648 throw GCN_EXCEPTION("Could not parse hot key");
00649 }
00650 }
00651 }
00652
00653 bool Widget::widgetExists(const Widget* widget)
00654 {
00655 bool result = false;
00656
00657 std::list<Widget*>::iterator iter;
00658 for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter)
00659 {
00660 if (*iter == widget)
00661 {
00662 return true;
00663 }
00664 }
00665
00666 return result;
00667 }
00668
00669 bool Widget::isTabInEnabled() const
00670 {
00671 return mTabIn;
00672 }
00673
00674 void Widget::setTabInEnabled(bool enabled)
00675 {
00676 mTabIn = enabled;
00677 }
00678
00679 bool Widget::isTabOutEnabled() const
00680 {
00681 return mTabOut;
00682 }
00683
00684 void Widget::setTabOutEnabled(bool enabled)
00685 {
00686 mTabOut = enabled;
00687 }
00688
00689 void Widget::setSize(int width, int height)
00690 {
00691 setWidth(width);
00692 setHeight(height);
00693 }
00694
00695 void Widget::setEnabled(bool enabled)
00696 {
00697 mEnabled = enabled;
00698 }
00699
00700 bool Widget::isEnabled() const
00701 {
00702 return mEnabled && isVisible();
00703 }
00704
00705 bool Widget::isDragged() const
00706 {
00707 if (mFocusHandler == NULL)
00708 {
00709 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00710 }
00711
00712 return mFocusHandler->isDragged(this);
00713 }
00714
00715 void Widget::requestModalFocus()
00716 {
00717 if (mFocusHandler == NULL)
00718 {
00719 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00720 }
00721
00722 mFocusHandler->requestModalFocus(this);
00723 }
00724
00725 void Widget::releaseModalFocus()
00726 {
00727 if (mFocusHandler == NULL)
00728 {
00729 return;
00730 }
00731
00732 mFocusHandler->releaseModalFocus(this);
00733 }
00734
00735 bool Widget::hasModalFocus() const
00736 {
00737 if (mFocusHandler == NULL)
00738 {
00739 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00740 }
00741
00742 if (getParent() != NULL)
00743 {
00744 return (mFocusHandler->getModalFocused() == this) || getParent()->hasModalFocus();
00745 }
00746
00747 return mFocusHandler->getModalFocused() == this;
00748 }
00749
00750 void Widget::setDirty(bool dirty)
00751 {
00752 mDirty = dirty;
00753 }
00754
00755 bool Widget::getDirty() const
00756 {
00757 return mDirty;
00758 }
00759 }