1 /* _______ __ __ __ ______ __ __ _______ __ __ 2 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\ 3 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / / 4 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / / 5 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / / 6 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ / 7 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ 8 * 9 * Copyright (c) 2004, 2005, 2006, 2007 Olof Naess�n and Per Larsson 10 * 11 * Js_./ 12 * Per Larsson a.k.a finalman _RqZ{a<^_aa 13 * Olof Naess�n a.k.a jansem/yakslem _asww7!uY`> )\a// 14 * _Qhm`] _f "'c 1!5m 15 * Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[ 16 * .)j(] .d_/ '-( P . S 17 * License: (BSD) <Td/Z <fP"5(\"??"\a. .L 18 * Redistribution and use in source and _dV>ws?a-?' ._/L #' 19 * binary forms, with or without )4d[#7r, . ' )d`)[ 20 * modification, are permitted provided _Q-5'5W..j/?' -?!\)cam' 21 * that the following conditions are met: j<<WP+k/);. _W=j f 22 * 1. Redistributions of source code must .$%w\/]Q . ."' . mj$ 23 * retain the above copyright notice, ]E.pYY(Q]>. a J@\ 24 * this list of conditions and the j(]1u<sE"L,. . ./^ ]{a 25 * following disclaimer. 4'_uomm\. )L);-4 (3= 26 * 2. Redistributions in binary form must )_]X{Z('a_"a7'<a"a, ]"[ 27 * reproduce the above copyright notice, #}<]m7`Za??4,P-"'7. ).m 28 * this list of conditions and the ]d2e)Q(<Q( ?94 b- LQ/ 29 * following disclaimer in the <B!</]C)d_, '(<' .f. =C+m 30 * documentation and/or other materials .Z!=J ]e []('-4f _ ) -.)m]' 31 * provided with the distribution. .w[5]' _[ /.)_-"+? _/ <W" 32 * 3. Neither the name of Guichan nor the :$we` _! + _/ . j? 33 * names of its contributors may be used =3)= _f (_yQmWW$#( " 34 * to endorse or promote products derived - W, sQQQQmZQ#Wwa].. 35 * from this software without specific (js, \[QQW$QWW#?!V"". 36 * prior written permission. ]y:.<\.. . 37 * -]n w/ ' [. 38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT )/ )/ ! 39 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY < (; sac , ' 40 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, ]^ .- % 41 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF c < r 42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR aga< <La 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5% )P'-3L 44 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR _bQf` y`..)a 45 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ,J?4P'.P"_(\?d'., 46 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES _Pa,)!f/<[]/ ?" 47 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT _2-..:. .r+_,.. . 48 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ?a.<%"' " -'.a_ _, 49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ^ 50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 53 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 54 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 */ 56 57 /* 58 * For comments regarding functions please see the header file. 59 */ 60 61 #include "guichan/widget.hpp" 62 63 #include "guichan/actionevent.hpp" 64 #include "guichan/actionlistener.hpp" 65 #include "guichan/basiccontainer.hpp" 66 #include "guichan/deathlistener.hpp" 67 #include "guichan/defaultfont.hpp" 68 #include "guichan/event.hpp" 69 #include "guichan/exception.hpp" 70 #include "guichan/focushandler.hpp" 71 #include "guichan/keyinput.hpp" 72 #include "guichan/keylistener.hpp" 73 #include "guichan/mouseinput.hpp" 74 #include "guichan/mouselistener.hpp" 75 76 namespace gcn 77 { 78 Font* Widget::mGlobalFont = NULL; 79 DefaultFont Widget::mDefaultFont; 80 std::list<Widget*> Widget::mWidgets; 81 Widget()82 Widget::Widget() 83 : mForegroundColor(0x000000), 84 mBackgroundColor(0xffffff), 85 mBaseColor(0x808090), 86 mFocusHandler(NULL), 87 mInternalFocusHandler(NULL), 88 mParent(NULL), 89 mBorderSize(0), 90 mFocusable(false), 91 mVisible(true), 92 mTabIn(true), 93 mTabOut(true), 94 mEnabled(true), 95 mCurrentFont(NULL) 96 { 97 mWidgets.push_back(this); 98 } 99 ~Widget()100 Widget::~Widget() 101 { 102 DeathListenerIterator iter; 103 104 for (iter = mDeathListeners.begin(); iter != mDeathListeners.end(); ++iter) 105 { 106 Event event(this); 107 (*iter)->death(event); 108 } 109 110 _setFocusHandler(NULL); 111 112 mWidgets.remove(this); 113 } 114 _setParent(Widget * parent)115 void Widget::_setParent(Widget* parent) 116 { 117 mParent = parent; 118 } 119 getParent() const120 Widget* Widget::getParent() const 121 { 122 return mParent; 123 } 124 setWidth(int width)125 void Widget::setWidth(int width) 126 { 127 mDimension.width = width; 128 } 129 getWidth() const130 int Widget::getWidth() const 131 { 132 return mDimension.width; 133 } 134 setHeight(int height)135 void Widget::setHeight(int height) 136 { 137 mDimension.height = height; 138 } 139 getHeight() const140 int Widget::getHeight() const 141 { 142 return mDimension.height; 143 } 144 setX(int x)145 void Widget::setX(int x) 146 { 147 mDimension.x = x; 148 } 149 getX() const150 int Widget::getX() const 151 { 152 return mDimension.x; 153 } 154 setY(int y)155 void Widget::setY(int y) 156 { 157 mDimension.y = y; 158 } 159 getY() const160 int Widget::getY() const 161 { 162 return mDimension.y; 163 } 164 setPosition(int x,int y)165 void Widget::setPosition(int x, int y) 166 { 167 mDimension.x = x; 168 mDimension.y = y; 169 } 170 setDimension(const Rectangle & dimension)171 void Widget::setDimension(const Rectangle& dimension) 172 { 173 mDimension = dimension; 174 } 175 setBorderSize(unsigned int borderSize)176 void Widget::setBorderSize(unsigned int borderSize) 177 { 178 mBorderSize = borderSize; 179 } 180 getBorderSize() const181 unsigned int Widget::getBorderSize() const 182 { 183 return mBorderSize; 184 } 185 getDimension() const186 const Rectangle& Widget::getDimension() const 187 { 188 return mDimension; 189 } 190 getActionEventId() const191 const std::string& Widget::getActionEventId() const 192 { 193 return mActionEventId; 194 } 195 setActionEventId(const std::string & actionEventId)196 void Widget::setActionEventId(const std::string& actionEventId) 197 { 198 mActionEventId = actionEventId; 199 } 200 isFocused() const201 bool Widget::isFocused() const 202 { 203 if (!mFocusHandler) 204 { 205 return false; 206 } 207 208 return (mFocusHandler->isFocused(this)); 209 } 210 setFocusable(bool focusable)211 void Widget::setFocusable(bool focusable) 212 { 213 if (!focusable && isFocused()) 214 { 215 mFocusHandler->focusNone(); 216 } 217 218 mFocusable = focusable; 219 } 220 isFocusable() const221 bool Widget::isFocusable() const 222 { 223 return mFocusable && isVisible() && isEnabled(); 224 } 225 requestFocus()226 void Widget::requestFocus() 227 { 228 if (mFocusHandler == NULL) 229 { 230 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?)."); 231 } 232 233 if (isFocusable()) 234 { 235 mFocusHandler->requestFocus(this); 236 } 237 } 238 requestMoveToTop()239 void Widget::requestMoveToTop() 240 { 241 if (mParent) 242 { 243 mParent->moveToTop(this); 244 } 245 } 246 requestMoveToBottom()247 void Widget::requestMoveToBottom() 248 { 249 if (mParent) 250 { 251 mParent->moveToBottom(this); 252 } 253 } 254 setVisible(bool visible)255 void Widget::setVisible(bool visible) 256 { 257 if (!visible && isFocused()) 258 { 259 mFocusHandler->focusNone(); 260 } 261 mVisible = visible; 262 } 263 isVisible() const264 bool Widget::isVisible() const 265 { 266 if (getParent() == NULL) 267 { 268 return mVisible; 269 } 270 else 271 { 272 return mVisible && getParent()->isVisible(); 273 } 274 } 275 setBaseColor(const Color & color)276 void Widget::setBaseColor(const Color& color) 277 { 278 mBaseColor = color; 279 } 280 getBaseColor() const281 const Color& Widget::getBaseColor() const 282 { 283 return mBaseColor; 284 } 285 setForegroundColor(const Color & color)286 void Widget::setForegroundColor(const Color& color) 287 { 288 mForegroundColor = color; 289 } 290 getForegroundColor() const291 const Color& Widget::getForegroundColor() const 292 { 293 return mForegroundColor; 294 } 295 setBackgroundColor(const Color & color)296 void Widget::setBackgroundColor(const Color& color) 297 { 298 mBackgroundColor = color; 299 } 300 getBackgroundColor() const301 const Color& Widget::getBackgroundColor() const 302 { 303 return mBackgroundColor; 304 } 305 _setFocusHandler(FocusHandler * focusHandler)306 void Widget::_setFocusHandler(FocusHandler* focusHandler) 307 { 308 if (mFocusHandler) 309 { 310 releaseModalFocus(); 311 mFocusHandler->remove(this); 312 } 313 314 if (focusHandler) 315 { 316 focusHandler->add(this); 317 } 318 319 mFocusHandler = focusHandler; 320 } 321 _getFocusHandler()322 FocusHandler* Widget::_getFocusHandler() 323 { 324 return mFocusHandler; 325 } 326 addActionListener(ActionListener * actionListener)327 void Widget::addActionListener(ActionListener* actionListener) 328 { 329 mActionListeners.push_back(actionListener); 330 } 331 removeActionListener(ActionListener * actionListener)332 void Widget::removeActionListener(ActionListener* actionListener) 333 { 334 mActionListeners.remove(actionListener); 335 } 336 addDeathListener(DeathListener * deathListener)337 void Widget::addDeathListener(DeathListener* deathListener) 338 { 339 mDeathListeners.push_back(deathListener); 340 } 341 removeDeathListener(DeathListener * deathListener)342 void Widget::removeDeathListener(DeathListener* deathListener) 343 { 344 mDeathListeners.remove(deathListener); 345 } 346 addKeyListener(KeyListener * keyListener)347 void Widget::addKeyListener(KeyListener* keyListener) 348 { 349 mKeyListeners.push_back(keyListener); 350 } 351 removeKeyListener(KeyListener * keyListener)352 void Widget::removeKeyListener(KeyListener* keyListener) 353 { 354 mKeyListeners.remove(keyListener); 355 } 356 addMouseListener(MouseListener * mouseListener)357 void Widget::addMouseListener(MouseListener* mouseListener) 358 { 359 mMouseListeners.push_back(mouseListener); 360 } 361 removeMouseListener(MouseListener * mouseListener)362 void Widget::removeMouseListener(MouseListener* mouseListener) 363 { 364 mMouseListeners.remove(mouseListener); 365 } 366 getAbsolutePosition(int & x,int & y) const367 void Widget::getAbsolutePosition(int& x, int& y) const 368 { 369 if (getParent() == NULL) 370 { 371 x = mDimension.x; 372 y = mDimension.y; 373 return; 374 } 375 376 int parentX; 377 int parentY; 378 379 getParent()->getAbsolutePosition(parentX, parentY); 380 381 x = parentX + mDimension.x + getParent()->getChildrenArea().x; 382 y = parentY + mDimension.y + getParent()->getChildrenArea().y; 383 } 384 generateAction()385 void Widget::generateAction() 386 { 387 ActionListenerIterator iter; 388 for (iter = mActionListeners.begin(); iter != mActionListeners.end(); ++iter) 389 { 390 ActionEvent actionEvent(this, mActionEventId); 391 (*iter)->action(actionEvent); 392 } 393 } 394 getFont() const395 Font* Widget::getFont() const 396 { 397 if (mCurrentFont == NULL) 398 { 399 if (mGlobalFont == NULL) 400 { 401 return &mDefaultFont; 402 } 403 404 return mGlobalFont; 405 } 406 407 return mCurrentFont; 408 } 409 setGlobalFont(Font * font)410 void Widget::setGlobalFont(Font* font) 411 { 412 mGlobalFont = font; 413 414 std::list<Widget*>::iterator iter; 415 for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter) 416 { 417 if ((*iter)->mCurrentFont == NULL) 418 { 419 (*iter)->fontChanged(); 420 } 421 } 422 } 423 setFont(Font * font)424 void Widget::setFont(Font* font) 425 { 426 mCurrentFont = font; 427 fontChanged(); 428 } 429 widgetExists(const Widget * widget)430 bool Widget::widgetExists(const Widget* widget) 431 { 432 bool result = false; 433 434 std::list<Widget*>::iterator iter; 435 for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter) 436 { 437 if (*iter == widget) 438 { 439 return true; 440 } 441 } 442 443 return result; 444 } 445 isTabInEnabled() const446 bool Widget::isTabInEnabled() const 447 { 448 return mTabIn; 449 } 450 setTabInEnabled(bool enabled)451 void Widget::setTabInEnabled(bool enabled) 452 { 453 mTabIn = enabled; 454 } 455 isTabOutEnabled() const456 bool Widget::isTabOutEnabled() const 457 { 458 return mTabOut; 459 } 460 setTabOutEnabled(bool enabled)461 void Widget::setTabOutEnabled(bool enabled) 462 { 463 mTabOut = enabled; 464 } 465 setSize(int width,int height)466 void Widget::setSize(int width, int height) 467 { 468 setWidth(width); 469 setHeight(height); 470 } 471 setEnabled(bool enabled)472 void Widget::setEnabled(bool enabled) 473 { 474 mEnabled = enabled; 475 } 476 isEnabled() const477 bool Widget::isEnabled() const 478 { 479 return mEnabled && isVisible(); 480 } 481 requestModalFocus()482 void Widget::requestModalFocus() 483 { 484 if (mFocusHandler == NULL) 485 { 486 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?)."); 487 } 488 489 mFocusHandler->requestModalFocus(this); 490 } 491 requestModalMouseInputFocus()492 void Widget::requestModalMouseInputFocus() 493 { 494 if (mFocusHandler == NULL) 495 { 496 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?)."); 497 } 498 499 mFocusHandler->requestModalMouseInputFocus(this); 500 } 501 releaseModalFocus()502 void Widget::releaseModalFocus() 503 { 504 if (mFocusHandler == NULL) 505 { 506 return; 507 } 508 509 mFocusHandler->releaseModalFocus(this); 510 } 511 releaseModalMouseInputFocus()512 void Widget::releaseModalMouseInputFocus() 513 { 514 if (mFocusHandler == NULL) 515 { 516 return; 517 } 518 519 mFocusHandler->releaseModalMouseInputFocus(this); 520 } 521 hasModalFocus() const522 bool Widget::hasModalFocus() const 523 { 524 if (mFocusHandler == NULL) 525 { 526 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?)."); 527 } 528 529 if (getParent() != NULL) 530 { 531 return (mFocusHandler->getModalFocused() == this) || getParent()->hasModalFocus(); 532 } 533 534 return mFocusHandler->getModalFocused() == this; 535 } 536 hasModalMouseInputFocus() const537 bool Widget::hasModalMouseInputFocus() const 538 { 539 if (mFocusHandler == NULL) 540 { 541 throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?)."); 542 } 543 544 if (getParent() != NULL) 545 { 546 return (mFocusHandler->getModalMouseInputFocused() == this) || getParent()->hasModalMouseInputFocus(); 547 } 548 549 return mFocusHandler->getModalMouseInputFocused() == this; 550 } 551 getWidgetAt(int x,int y)552 Widget *Widget::getWidgetAt(int x, int y) 553 { 554 return NULL; 555 } 556 _getMouseListeners()557 const std::list<MouseListener*>& Widget::_getMouseListeners() 558 { 559 return mMouseListeners; 560 } 561 _getKeyListeners()562 const std::list<KeyListener*>& Widget::_getKeyListeners() 563 { 564 return mKeyListeners; 565 } 566 getChildrenArea()567 Rectangle Widget::getChildrenArea() 568 { 569 return Rectangle(0, 0, 0, 0); 570 } 571 _getInternalFocusHandler()572 FocusHandler* Widget::_getInternalFocusHandler() 573 { 574 return mInternalFocusHandler; 575 } 576 setInternalFocusHandler(FocusHandler * focusHandler)577 void Widget::setInternalFocusHandler(FocusHandler* focusHandler) 578 { 579 mInternalFocusHandler = focusHandler; 580 } 581 } 582