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

focushandler.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/focushandler.hpp"
00060 #include "guichan/exception.hpp"
00061 
00062 namespace gcn
00063 {
00064     FocusHandler::FocusHandler()
00065     {
00066         mFocusedWidget = NULL;
00067         mDraggedWidget = NULL; 
00068         mToBeFocused = NULL;
00069         mToBeDragged = NULL;
00070         mModalFocusedWidget = NULL;
00071     }
00072 
00073     void FocusHandler::requestFocus(Widget* widget)
00074     {
00075         mToBeFocused = widget;        
00076     }
00077 
00078     void FocusHandler::requestDrag(Widget* widget)
00079     {
00080         mToBeDragged = widget;
00081     }
00082 
00083     void FocusHandler::requestModalFocus(Widget* widget)
00084     {
00085         if (mModalFocusedWidget != NULL && mModalFocusedWidget != widget)
00086         {
00087             throw GCN_EXCEPTION("Another widget allready has modal focus.");
00088         }
00089 
00090         mModalFocusedWidget = widget;
00091 
00092         if (mFocusedWidget != NULL && !mFocusedWidget->hasModalFocus())
00093         {
00094             focusNone();
00095         }
00096 
00097         if (mDraggedWidget != NULL && !mDraggedWidget->hasModalFocus())
00098         {
00099             dragNone();
00100         }
00101     }
00102 
00103     void FocusHandler::releaseModalFocus(Widget* widget)
00104     {
00105         if (mModalFocusedWidget == widget)
00106         {
00107             mModalFocusedWidget = NULL;
00108         }
00109     }
00110     
00111     Widget* FocusHandler::getFocused() const
00112     {
00113         return mFocusedWidget;
00114     }
00115 
00116     Widget* FocusHandler::getDragged() const
00117     {
00118         return mDraggedWidget;
00119     }
00120 
00121     Widget* FocusHandler::getModalFocused() const
00122     {
00123         return mModalFocusedWidget;
00124     }
00125     
00126     void FocusHandler::focusNext()
00127     {
00128         int i;
00129         int focusedWidget = -1;
00130         for (i = 0; i < (int)mWidgets.size(); ++i)
00131         {
00132             if (mWidgets[i] == mFocusedWidget)
00133             {
00134                 focusedWidget = i;
00135             }
00136         }
00137         int focused = focusedWidget;
00138         
00139         // i is a counter that ensures that the following loop
00140         // won't get stuck in an infinite loop
00141         i = (int)mWidgets.size();
00142         do
00143         {
00144             ++focusedWidget;
00145             
00146             if (i==0)
00147             {
00148                 focusedWidget = -1;
00149                 break;
00150             }
00151             
00152             --i;
00153 
00154             if (focusedWidget >= (int)mWidgets.size())
00155             {
00156                 focusedWidget = 0;      
00157             }
00158 
00159             if (focusedWidget == focused)
00160             {
00161                 return;
00162             }            
00163         }
00164         while (!mWidgets.at(focusedWidget)->isFocusable());
00165 
00166         if (focusedWidget >= 0)
00167         {
00168             mFocusedWidget = mWidgets.at(focusedWidget);
00169             mWidgets.at(focusedWidget)->gotFocus();         
00170         }
00171         
00172         if (focused >= 0)
00173         {
00174             mWidgets.at(focused)->lostFocus();
00175         }    
00176     }
00177     
00178     void FocusHandler::focusPrevious()
00179     {        
00180         if (mWidgets.size() == 0)
00181         {
00182             mFocusedWidget = NULL;
00183             return;
00184         }    
00185 
00186         int i;
00187         int focusedWidget = -1;
00188         for (i = 0; i < (int)mWidgets.size(); ++i)
00189         {
00190             if (mWidgets[i] == mFocusedWidget)
00191             {
00192                 focusedWidget = i;
00193             }
00194         }
00195         int focused = focusedWidget;               
00196         
00197         // i is a counter that ensures that the following loop
00198         // won't get stuck in an infinite loop
00199         i = (int)mWidgets.size();
00200         do
00201         {
00202             --focusedWidget;
00203 
00204             if (i==0)
00205             {
00206                 focusedWidget = -1;
00207                 break;
00208             }
00209 
00210             --i;
00211             
00212             if (focusedWidget <= 0)
00213             {
00214                 focusedWidget = mWidgets.size() - 1;      
00215             }
00216 
00217             if (focusedWidget == focused)
00218             {
00219                 return;
00220             }
00221         }
00222         while (!mWidgets.at(focusedWidget)->isFocusable());
00223 
00224         if (focusedWidget >= 0)
00225         {
00226             mFocusedWidget = mWidgets.at(focusedWidget);
00227             mWidgets.at(focusedWidget)->gotFocus();
00228         }
00229                 
00230         if (focused >= 0)
00231         {
00232             mWidgets.at(focused)->lostFocus();
00233         }    
00234     }
00235 
00236     bool FocusHandler::hasFocus(const Widget* widget) const
00237     {
00238         return mFocusedWidget == widget;
00239     }
00240 
00241      bool FocusHandler::isDragged(const Widget* widget) const
00242      {
00243         return mDraggedWidget == widget;
00244      }
00245 
00246     void FocusHandler::add(Widget* widget)
00247     {
00248         mWidgets.push_back(widget);    
00249     }
00250     
00251     void FocusHandler::remove(Widget* widget)
00252     {
00253         if (widget == mToBeFocused)
00254         {
00255             mToBeFocused = NULL;
00256         }
00257         if (widget == mToBeDragged)
00258         {
00259             mToBeDragged = NULL;
00260         }
00261 
00262         if (hasFocus(widget))
00263         {
00264             mFocusedWidget = NULL;
00265             mToBeFocused = NULL;
00266         }
00267         
00268         int i = 0;
00269         WidgetIterator iter;
00270         
00271         for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter)
00272         {
00273             ++i;
00274             
00275             if ((*iter) == widget)
00276             {        
00277                 mWidgets.erase(iter);                
00278                 return;
00279             }      
00280         }        
00281     }
00282     
00283     void FocusHandler::focusNone()
00284     {
00285          
00286         if (mFocusedWidget != NULL)
00287         {
00288             Widget* focused = mFocusedWidget;
00289             mFocusedWidget = NULL; 
00290             focused->lostFocus();            
00291         }
00292         
00293         mToBeFocused = NULL;
00294     }
00295 
00296     void FocusHandler::dragNone()
00297     {
00298         mDraggedWidget = NULL;
00299     }
00300     
00301     void FocusHandler::tabNext()
00302     {
00303         if (mFocusedWidget != NULL)
00304         {
00305             if (!mFocusedWidget->isTabOutEnabled())
00306             {
00307                 return;
00308             }
00309         }
00310 
00311         if (mWidgets.size() == 0)
00312         {
00313             mFocusedWidget = NULL;
00314             return;
00315         }    
00316 
00317         int i;
00318         int focusedWidget = -1;
00319         for (i = 0; i < (int)mWidgets.size(); ++i)
00320         {
00321             if (mWidgets[i] == mFocusedWidget)
00322             {
00323                 focusedWidget = i;
00324             }
00325         }
00326         int focused = focusedWidget;               
00327         bool done = false;
00328         
00329         // i is a counter that ensures that the following loop
00330         // won't get stuck in an infinite loop
00331         i = (int)mWidgets.size();
00332         do
00333         {
00334             ++focusedWidget;
00335             
00336             if (i==0)
00337             {
00338                 focusedWidget = -1;
00339                 break;
00340             }
00341             
00342             --i;
00343 
00344             if (focusedWidget >= (int)mWidgets.size())
00345             {
00346                 focusedWidget = 0;      
00347             }
00348 
00349             if (focusedWidget == focused)
00350             {
00351                 return;
00352             }
00353             
00354             if (mWidgets.at(focusedWidget)->isFocusable() &&
00355                 mWidgets.at(focusedWidget)->isTabInEnabled() &&
00356                 (mModalFocusedWidget == NULL ||
00357                  mWidgets.at(focusedWidget)->hasModalFocus()))
00358             {
00359                 done = true;
00360             }
00361         }
00362         while (!done);
00363 
00364         if (focusedWidget >= 0)
00365         {
00366             mFocusedWidget = mWidgets.at(focusedWidget);
00367             mWidgets.at(focusedWidget)->gotFocus();
00368         }
00369         
00370         if (focused >= 0)
00371         {
00372             mWidgets.at(focused)->lostFocus();
00373         }
00374     }
00375 
00376     void FocusHandler::tabPrevious()
00377     {
00378         if (mFocusedWidget != NULL)
00379         {
00380             if (!mFocusedWidget->isTabOutEnabled())
00381             {
00382                 return;
00383             }
00384         }
00385                 
00386         if (mWidgets.size() == 0)
00387         {
00388             mFocusedWidget = NULL;
00389             return;
00390         }    
00391 
00392         int i;
00393         int focusedWidget = -1;
00394         for (i = 0; i < (int)mWidgets.size(); ++i)
00395         {
00396             if (mWidgets[i] == mFocusedWidget)
00397             {
00398                 focusedWidget = i;
00399             }
00400         }
00401         int focused = focusedWidget;               
00402         bool done = false;
00403         
00404         // i is a counter that ensures that the following loop
00405         // won't get stuck in an infinite loop
00406         i = (int)mWidgets.size();
00407         do
00408         {
00409             --focusedWidget;
00410 
00411             if (i==0)
00412             {
00413                 focusedWidget = -1;
00414                 break;
00415             }
00416 
00417             --i;
00418             
00419             if (focusedWidget <= 0)
00420             {
00421                 focusedWidget = mWidgets.size() - 1;      
00422             }
00423 
00424             if (focusedWidget == focused)
00425             {
00426                 return;
00427             }
00428 
00429             if (mWidgets.at(focusedWidget)->isFocusable() &&
00430                 mWidgets.at(focusedWidget)->isTabInEnabled() &&
00431                 (mModalFocusedWidget == NULL ||
00432                  mWidgets.at(focusedWidget)->hasModalFocus()))
00433             {
00434                 done = true;
00435             }
00436         }
00437         while (!done);
00438 
00439         if (focusedWidget >= 0)
00440         {
00441             mFocusedWidget = mWidgets.at(focusedWidget);
00442             mWidgets.at(focusedWidget)->gotFocus();
00443         }    
00444 
00445         if (focused >= 0)
00446         {
00447             mWidgets.at(focused)->lostFocus();
00448         }    
00449     }
00450 
00451     void FocusHandler::applyChanges()
00452     {
00453         if (mToBeFocused != NULL)
00454         {
00455             unsigned int i = 0;
00456             int toBeFocusedIndex = -1;
00457             for (i = 0; i < mWidgets.size(); ++i)
00458             {      
00459                 if (mWidgets[i] == mToBeFocused)
00460                 {
00461                     toBeFocusedIndex = i;
00462                     break;                
00463                 }
00464             }    
00465             
00466             if (toBeFocusedIndex < 0)
00467             {
00468                 throw GCN_EXCEPTION("Trying to focus a none existing widget.");
00469             }
00470 
00471             Widget *oldFocused = mFocusedWidget;
00472 
00473             if (oldFocused != mToBeFocused)
00474             {
00475                 mFocusedWidget = mWidgets.at(toBeFocusedIndex);
00476                 
00477                 if (oldFocused != NULL)
00478                 {
00479                     oldFocused->lostFocus();
00480                 }
00481                 
00482                 mWidgets.at(toBeFocusedIndex)->gotFocus();
00483             }
00484             mToBeFocused = NULL;
00485         }
00486 
00487         if (mToBeDragged != NULL)
00488         {
00489             unsigned int i = 0;
00490             int toBeDraggedIndex = -1;
00491             for (i = 0; i < mWidgets.size(); ++i)
00492             {      
00493                 if (mWidgets[i] == mToBeDragged)
00494                 {
00495                     toBeDraggedIndex = i;                
00496                     break;
00497                 }
00498             }    
00499 
00500             if (toBeDraggedIndex < 0)
00501             {
00502                 throw GCN_EXCEPTION("Trying to give drag to a none existing widget");
00503             }
00504             
00505              mDraggedWidget = mWidgets.at(toBeDraggedIndex);
00506              mToBeDragged = NULL;            
00507         }
00508     }    
00509 }

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