Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

widget.cpp

00001 /*      _______   __   __   __   ______   __   __   _______   __   __                 
00002  *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\                
00003  *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /                 
00004  *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /                  
00005  *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /                   
00006  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /                    
00007  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/                      
00008  *
00009  * Copyright (c) 2004, 2005 darkbits                        Js_./
00010  * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
00011  * Olof Naessén a.k.a jansem/yakslem                _asww7!uY`>  )\a//
00012  *                                                 _Qhm`] _f "'c  1!5m
00013  * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
00014  *                                               .)j(] .d_/ '-(  P .   S
00015  * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
00016  * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
00017  * binary forms, with or without                 )4d[#7r, .   '     )d`)[
00018  * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
00019  * that the following conditions are met:       j<<WP+k/);.        _W=j f
00020  * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
00021  *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
00022  *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
00023  *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
00024  * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
00025  *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
00026  *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
00027  *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
00028  *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
00029  *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
00030  * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
00031  *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
00032  *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
00033  *    from this software without specific        (js, \[QQW$QWW#?!V"".
00034  *    prior written permission.                    ]y:.<\..          .
00035  *                                                 -]n w/ '         [.
00036  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
00037  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
00038  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
00039  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
00040  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
00041  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
00042  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
00043  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
00044  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
00045  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
00046  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
00047  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
00048  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00049  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00050  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00051  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00052  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00053  */
00054 
00055 /*
00056  * For comments regarding functions please see the header file. 
00057  */
00058 
00059 #include "guichan/basiccontainer.hpp"
00060 #include "guichan/exception.hpp"
00061 #include "guichan/focushandler.hpp"
00062 #include "guichan/widget.hpp"
00063 
00064 #include <iostream>
00065 
00066 namespace gcn
00067 {
00068     Font* Widget::mGlobalFont = NULL;
00069     DefaultFont Widget::mDefaultFont;
00070     std::list<Widget*> Widget::mWidgets;
00071 
00072     Widget::Widget()
00073     {
00074         mParent = NULL;
00075         mForegroundColor = Color(0x000000);
00076         mBackgroundColor = Color(0xffffff);
00077         mBaseColor = Color(0x808090);
00078         mBorderSize = 0;
00079         mFocusHandler = NULL;
00080         mFocusable = false;
00081         mClickTimeStamp = 0;
00082         mClickCount = 0;        
00083         mHasMouse = false;
00084         mVisible = true;
00085         mTabIn = true;
00086         mTabOut = true;
00087         mEnabled = true;
00088         mClickButton = 0;
00089         
00090         mCurrentFont = NULL;
00091         mWidgets.push_back(this); 
00092     }
00093 
00094     Widget::~Widget()
00095     {
00096         if (getParent() != NULL)
00097         {
00098             getParent()->_announceDeath(this);
00099         }
00100         
00101         _setFocusHandler(NULL);
00102     
00103         mWidgets.remove(this);
00104     }
00105 
00106     void Widget::_setParent(BasicContainer* parent)
00107     {
00108         mParent = parent;
00109     }
00110 
00111     BasicContainer* Widget::getParent() const
00112     {
00113         return mParent;    
00114     }
00115 
00116     void Widget::setWidth(int width)
00117     {
00118         mDimension.width = width;
00119     }
00120 
00121     int Widget::getWidth() const
00122     {
00123         return mDimension.width;
00124     }
00125 
00126     void Widget::setHeight(int height)
00127     {
00128         mDimension.height = height;
00129     }
00130 
00131     int Widget::getHeight() const
00132     {
00133         return mDimension.height;
00134     }
00135 
00136     void Widget::setX(int x)
00137     {
00138         mDimension.x = x;
00139     }
00140 
00141     int Widget::getX() const
00142     {
00143         return mDimension.x;
00144     }
00145 
00146     void Widget::setY(int y)
00147     {
00148         mDimension.y = y;
00149     }
00150 
00151     int Widget::getY() const
00152     {
00153         return mDimension.y;
00154     }
00155   
00156     void Widget::setPosition(int x, int y)
00157     {
00158         mDimension.x = x;
00159         mDimension.y = y;
00160     }
00161 
00162     void Widget::setDimension(const Rectangle& dimension)
00163     {
00164         mDimension = dimension;
00165     }
00166 
00167     void Widget::setBorderSize(unsigned int borderSize)
00168     {
00169         mBorderSize = borderSize;
00170     }
00171 
00172     unsigned int Widget::getBorderSize() const
00173     {
00174         return mBorderSize;
00175     }
00176     
00177     const Rectangle& Widget::getDimension() const
00178     {
00179         return mDimension;
00180     }
00181   
00182     const std::string& Widget::getEventId() const
00183     {
00184         return mEventId;
00185     }
00186 
00187     void Widget::setEventId(const std::string& eventId)
00188     {
00189         mEventId = eventId;
00190     }
00191   
00192     bool Widget::hasFocus() const
00193     {
00194         if (!mFocusHandler)
00195         {
00196             return false;
00197         }
00198 
00199         return (mFocusHandler->hasFocus(this));
00200     }
00201 
00202     bool Widget::hasMouse() const
00203     {
00204         return mHasMouse;
00205     }
00206 
00207     void Widget::setFocusable(bool focusable)
00208     {
00209         if (!focusable && hasFocus())
00210         {
00211             mFocusHandler->focusNone();
00212         }
00213     
00214         mFocusable = focusable;
00215     }
00216 
00217     bool Widget::isFocusable() const
00218     {
00219         return mFocusable && isVisible() && isEnabled();        
00220     }
00221   
00222     void Widget::requestFocus()
00223     {
00224         if (mFocusHandler == NULL)
00225         {
00226             throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00227         }
00228         
00229         if (isFocusable())
00230         {
00231             mFocusHandler->requestFocus(this);
00232         }
00233     }
00234 
00235     void Widget::requestMoveToTop()
00236     {
00237         if (mParent)
00238         {
00239             mParent->moveToTop(this);
00240         }
00241     }
00242 
00243     void Widget::requestMoveToBottom()
00244     {
00245         if (mParent)
00246         {
00247             mParent->moveToBottom(this);
00248         }    
00249     }
00250 
00251     void Widget::setVisible(bool visible)
00252     {
00253         if (!visible && hasFocus())
00254         {
00255             mFocusHandler->focusNone();
00256         }    
00257         mVisible = visible;
00258     }
00259   
00260     bool Widget::isVisible() const
00261     {
00262         if (getParent() == NULL)
00263         {            
00264             return mVisible;
00265         }
00266         else
00267         {
00268             return mVisible && getParent()->isVisible();
00269         }            
00270     }
00271 
00272     void Widget::setBaseColor(const Color& color)
00273     {
00274         mBaseColor = color;
00275     }
00276 
00277     const Color& Widget::getBaseColor() const
00278     {
00279         return mBaseColor;
00280     }
00281 
00282     void Widget::setForegroundColor(const Color& color)
00283     {
00284         mForegroundColor = color;
00285     }
00286 
00287     const Color& Widget::getForegroundColor() const
00288     {
00289         return mForegroundColor;
00290     }
00291   
00292     void Widget::setBackgroundColor(const Color& color)
00293     {
00294         mBackgroundColor = color;
00295     }
00296 
00297     const Color& Widget::getBackgroundColor() const
00298     {
00299         return mBackgroundColor;
00300     }
00301 
00302     void Widget::_setFocusHandler(FocusHandler* focusHandler)
00303     {
00304         if (mFocusHandler)
00305         {
00306             releaseModalFocus();
00307             mFocusHandler->remove(this);
00308         }
00309     
00310         if (focusHandler)
00311         {
00312             focusHandler->add(this);
00313         }
00314     
00315         mFocusHandler = focusHandler;
00316     }
00317 
00318     FocusHandler* Widget::_getFocusHandler()
00319     {
00320         return mFocusHandler;
00321     }
00322 
00323     void Widget::addActionListener(ActionListener* actionListener)
00324     {
00325         mActionListeners.push_back(actionListener);    
00326     }
00327   
00328     void Widget::removeActionListener(ActionListener* actionListener)
00329     {
00330         mActionListeners.remove(actionListener);    
00331     }
00332   
00333     void Widget::addKeyListener(KeyListener* keyListener)
00334     {
00335         mKeyListeners.push_back(keyListener);    
00336     }
00337   
00338     void Widget::removeKeyListener(KeyListener* keyListener)
00339     {
00340         mKeyListeners.remove(keyListener);    
00341     }
00342   
00343     void Widget::addMouseListener(MouseListener* mouseListener)
00344     {
00345         mMouseListeners.push_back(mouseListener);    
00346     }
00347   
00348     void Widget::removeMouseListener(MouseListener* mouseListener)
00349     {
00350         mMouseListeners.remove(mouseListener);    
00351     }
00352   
00353     void Widget::_mouseInputMessage(const MouseInput& mouseInput)
00354     {
00355         if (mFocusHandler == NULL)
00356         {
00357             throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00358         }
00359                 
00360         if (!mEnabled || (mFocusHandler->getModalFocused() != NULL &&
00361                           !hasModalFocus()))
00362         {
00363             return;
00364         }
00365                 
00366         int x = mouseInput.x;
00367         int y = mouseInput.y;
00368         int b = mouseInput.getButton();
00369         int ts = mouseInput.getTimeStamp();
00370 
00371         MouseListenerIterator iter;
00372     
00373         switch(mouseInput.getType())
00374         {
00375           case MouseInput::MOTION:
00376               for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00377               {
00378                   (*iter)->mouseMotion(x, y);
00379               }
00380               break;
00381         
00382           case MouseInput::PRESS:
00383               if (hasMouse())
00384               {
00385                   requestFocus();
00386                   mFocusHandler->requestDrag(this);
00387               }
00388                 
00389               if (b != MouseInput::WHEEL_UP && b != MouseInput::WHEEL_DOWN)
00390               {
00391                     
00392                   for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00393                   {
00394                       (*iter)->mousePress(x, y, b);
00395                   }
00396 
00397                   if (hasMouse())
00398                   {
00399                       if (ts - mClickTimeStamp < 300 && mClickButton == b)
00400                       {
00401                           mClickCount++;
00402                       }
00403                       else
00404                       {
00405                           mClickCount = 0;
00406                       }
00407                       mClickButton = b;
00408                       mClickTimeStamp = ts;
00409                   }
00410                   else
00411                   {
00412                       mClickButton = 0;
00413                   }
00414               }
00415               else if (b == MouseInput::WHEEL_UP)
00416               {
00417                   for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00418                   {
00419                       (*iter)->mouseWheelUp(x, y);
00420                   }
00421               }
00422               else
00423               {
00424                   for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00425                   {
00426                       (*iter)->mouseWheelDown(x, y);
00427                   }
00428               }
00429               break;
00430 
00431           case MouseInput::RELEASE:
00432               if (isDragged())
00433               {
00434                   mFocusHandler->dragNone();
00435               }
00436                 
00437               if (b != MouseInput::WHEEL_UP && b != MouseInput::WHEEL_DOWN)
00438               {
00439                   for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00440                   {
00441                       (*iter)->mouseRelease(x, y, b);
00442                   }
00443               }
00444 
00445               if (mHasMouse)
00446               {
00447                   if (b == mClickButton)
00448                   {
00449                       for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00450                       {
00451                           (*iter)->mouseClick(x, y, b, mClickCount + 1);
00452                       }
00453                   }
00454                   else
00455                   {
00456                       mClickButton = 0;
00457                       mClickCount = 0;            
00458                   }
00459               }
00460               else
00461               {
00462                   mClickCount = 0;
00463                   mClickTimeStamp = 0;
00464               }
00465               break;
00466         }    
00467     }
00468 
00469     void Widget::_keyInputMessage(const KeyInput& keyInput)
00470     {
00471         if (mFocusHandler == NULL)
00472         {
00473             throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00474         }
00475                 
00476         if (!mEnabled || (mFocusHandler->getModalFocused() != NULL &&
00477                           !hasModalFocus()))
00478         {
00479             return;
00480         }
00481         
00482         KeyListenerIterator iter;
00483     
00484         switch(keyInput.getType())
00485         {
00486           case KeyInput::PRESS:
00487               for (iter = mKeyListeners.begin(); iter != mKeyListeners.end(); ++iter)
00488               {
00489                   (*iter)->keyPress(keyInput.getKey());
00490               }        
00491               break;
00492         
00493           case KeyInput::RELEASE:
00494               for (iter = mKeyListeners.begin(); iter != mKeyListeners.end(); ++iter)
00495               {
00496                   (*iter)->keyRelease(keyInput.getKey());
00497               }        
00498               break;
00499         }    
00500     }
00501 
00502     void Widget::_mouseInMessage()
00503     {
00504         if (!mEnabled)
00505         {
00506             return;
00507         }
00508 
00509         mHasMouse = true;
00510 
00511         MouseListenerIterator iter;
00512         for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00513         {
00514             (*iter)->mouseIn();
00515         }    
00516     }
00517 
00518     void Widget::_mouseOutMessage()
00519     {
00520         mHasMouse = false;
00521 
00522         MouseListenerIterator iter;
00523         for (iter = mMouseListeners.begin(); iter != mMouseListeners.end(); ++iter)
00524         {
00525             (*iter)->mouseOut();
00526         }    
00527     }
00528 
00529     void Widget::getAbsolutePosition(int& x, int& y) const
00530     {
00531         if (getParent() == NULL)
00532         {
00533             x = mDimension.x;
00534             y = mDimension.y;
00535             return;
00536         }
00537 
00538         int parentX;
00539         int parentY;
00540 
00541         getParent()->getAbsolutePosition(parentX, parentY);
00542 
00543         x = parentX + mDimension.x;
00544         y = parentY + mDimension.y;    
00545     }
00546     
00547     void Widget::generateAction()
00548     {
00549         ActionListenerIterator iter;
00550         for (iter = mActionListeners.begin(); iter != mActionListeners.end(); ++iter)
00551         {
00552             (*iter)->action(mEventId);
00553         }        
00554     }
00555     
00556     Font* Widget::getFont() const
00557     {
00558         if (mCurrentFont == NULL)
00559         {
00560             if (mGlobalFont == NULL)
00561             {
00562                 return &mDefaultFont;
00563             }
00564 
00565             return mGlobalFont;
00566         }    
00567     
00568         return mCurrentFont;
00569     }
00570   
00571     void Widget::setGlobalFont(Font* font)
00572     {
00573         mGlobalFont = font;
00574         
00575         std::list<Widget*>::iterator iter;
00576         for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter)
00577         {
00578             if ((*iter)->mCurrentFont == NULL)
00579             {
00580                 (*iter)->fontChanged();
00581             }
00582         }    
00583     }
00584   
00585     void Widget::setFont(Font* font)
00586     {
00587         mCurrentFont = font;
00588         fontChanged();    
00589     } 
00590 
00591     bool Widget::widgetExists(const Widget* widget)
00592     {
00593         bool result = false;
00594         
00595         std::list<Widget*>::iterator iter;
00596         for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter)
00597         {
00598             if (*iter == widget)
00599             {
00600                 return true;
00601             }
00602         }
00603 
00604         return result;
00605     }
00606 
00607     bool Widget::isTabInEnabled() const
00608     {
00609         return mTabIn;
00610     }
00611         
00612     void Widget::setTabInEnabled(bool enabled)
00613     {
00614         mTabIn = enabled;
00615     }
00616 
00617     bool Widget::isTabOutEnabled() const
00618     {
00619         return mTabOut;
00620     }
00621         
00622     void Widget::setTabOutEnabled(bool enabled)
00623     {
00624         mTabOut = enabled;
00625     }
00626 
00627     void Widget::setSize(int width, int height)
00628     {
00629         setWidth(width);
00630         setHeight(height);
00631     }
00632 
00633     void Widget::setEnabled(bool enabled)
00634     {
00635         mEnabled = enabled;
00636     }
00637 
00638     bool Widget::isEnabled() const
00639     {
00640         return mEnabled && isVisible();
00641     }
00642 
00643     bool Widget::isDragged() const
00644     {
00645         if (mFocusHandler == NULL)
00646         {
00647             throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00648         }
00649         
00650         return mFocusHandler->isDragged(this);
00651     }    
00652 
00653     void Widget::requestModalFocus()
00654     {
00655         if (mFocusHandler == NULL)
00656         {
00657             throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00658         }
00659 
00660         mFocusHandler->requestModalFocus(this);
00661     }
00662 
00663     void Widget::releaseModalFocus()
00664     {
00665         if (mFocusHandler == NULL)
00666         {
00667             return;
00668         }
00669 
00670         mFocusHandler->releaseModalFocus(this);
00671     }
00672     
00673     bool Widget::hasModalFocus() const
00674     {
00675         if (mFocusHandler == NULL)
00676         {
00677             throw GCN_EXCEPTION("No focushandler set (did you add the widget to the gui?).");
00678         }
00679 
00680         if (getParent() != NULL)
00681         {
00682             return (mFocusHandler->getModalFocused() == this) || getParent()->hasModalFocus();
00683         }
00684 
00685         return mFocusHandler->getModalFocused() == this;
00686     }
00687 }

Generated on Tue May 17 21:23:26 2005 for Guichan by  doxygen 1.4.1