focushandler.cpp

00001 /*      _______   __   __   __   ______   __   __   _______   __   __
00002  *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
00003  *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
00004  *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
00005  *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
00006  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
00007  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
00008  *
00009  * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
00010  *
00011  *
00012  * Per Larsson a.k.a finalman
00013  * Olof Naessén a.k.a jansem/yakslem
00014  *
00015  * Visit: http://guichan.sourceforge.net
00016  *
00017  * License: (BSD)
00018  * Redistribution and use in source and binary forms, with or without
00019  * modification, are permitted provided that the following conditions
00020  * are met:
00021  * 1. Redistributions of source code must retain the above copyright
00022  *    notice, this list of conditions and the following disclaimer.
00023  * 2. Redistributions in binary form must reproduce the above copyright
00024  *    notice, this list of conditions and the following disclaimer in
00025  *    the documentation and/or other materials provided with the
00026  *    distribution.
00027  * 3. Neither the name of Guichan nor the names of its contributors may
00028  *    be used to endorse or promote products derived from this software
00029  *    without specific prior written permission.
00030  *
00031  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00032  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00033  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00034  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00035  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00036  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00037  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00038  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00039  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00040  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00041  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00042  */
00043 
00044 /*
00045  * For comments regarding functions please see the header file.
00046  */
00047 
00048 #include "guichan/focushandler.hpp"
00049 
00050 #include "guichan/focuslistener.hpp"
00051 #include "guichan/exception.hpp"
00052 #include "guichan/widget.hpp"
00053 
00054 namespace gcn
00055 {
00056     FocusHandler::FocusHandler()
00057         :mFocusedWidget(NULL),
00058          mModalFocusedWidget(NULL),
00059          mModalMouseInputFocusedWidget(NULL),
00060          mDraggedWidget(NULL),
00061          mLastWidgetWithMouse(NULL),
00062          mLastWidgetWithModalFocus(NULL),
00063          mLastWidgetWithModalMouseInputFocus(NULL),
00064          mLastWidgetPressed(NULL)
00065     {
00066 
00067     }
00068 
00069     void FocusHandler::requestFocus(Widget* widget)
00070     {
00071         if (widget == NULL
00072             || widget == mFocusedWidget)
00073         {
00074             return;
00075         }
00076         
00077         unsigned int i = 0;
00078         int toBeFocusedIndex = -1;
00079         for (i = 0; i < mWidgets.size(); ++i)
00080         {
00081             if (mWidgets[i] == widget)
00082             {
00083                 toBeFocusedIndex = i;
00084                 break;
00085             }
00086         }
00087         
00088         if (toBeFocusedIndex < 0)
00089         {
00090             throw GCN_EXCEPTION("Trying to focus a none existing widget.");
00091         }
00092         
00093         Widget *oldFocused = mFocusedWidget;
00094         
00095         if (oldFocused != widget)
00096         {
00097             mFocusedWidget = mWidgets.at(toBeFocusedIndex);
00098             
00099             if (oldFocused != NULL)
00100             {
00101                 Event focusEvent(oldFocused);
00102                 distributeFocusLostEvent(focusEvent);
00103             }
00104             
00105             Event focusEvent(mWidgets.at(toBeFocusedIndex));
00106             distributeFocusGainedEvent(focusEvent);
00107         }        
00108     }
00109 
00110     void FocusHandler::requestModalFocus(Widget* widget)
00111     {
00112         if (mModalFocusedWidget != NULL && mModalFocusedWidget != widget)
00113         {
00114             throw GCN_EXCEPTION("Another widget already has modal focus.");
00115         }
00116 
00117         mModalFocusedWidget = widget;
00118 
00119         if (mFocusedWidget != NULL 
00120             && !mFocusedWidget->isModalFocused())
00121         {
00122             focusNone();
00123         }
00124     }
00125 
00126     void FocusHandler::requestModalMouseInputFocus(Widget* widget)
00127     {
00128         if (mModalMouseInputFocusedWidget != NULL
00129             && mModalMouseInputFocusedWidget != widget)
00130         {
00131             throw GCN_EXCEPTION("Another widget already has modal input focus.");
00132         }
00133 
00134         mModalMouseInputFocusedWidget = widget;
00135     }
00136 
00137     void FocusHandler::releaseModalFocus(Widget* widget)
00138     {
00139         if (mModalFocusedWidget == widget)
00140         {
00141             mModalFocusedWidget = NULL;
00142         }
00143     }
00144 
00145     void FocusHandler::releaseModalMouseInputFocus(Widget* widget)
00146     {
00147         if (mModalMouseInputFocusedWidget == widget)
00148         {
00149             mModalMouseInputFocusedWidget = NULL;
00150         }
00151     }
00152 
00153     Widget* FocusHandler::getFocused() const
00154     {
00155         return mFocusedWidget;
00156     }
00157 
00158     Widget* FocusHandler::getModalFocused() const
00159     {
00160         return mModalFocusedWidget;
00161     }
00162 
00163     Widget* FocusHandler::getModalMouseInputFocused() const
00164     {
00165         return mModalMouseInputFocusedWidget;
00166     }
00167 
00168     void FocusHandler::focusNext()
00169     {
00170         int i;
00171         int focusedWidget = -1;
00172         for (i = 0; i < (int)mWidgets.size(); ++i)
00173         {
00174             if (mWidgets[i] == mFocusedWidget)
00175             {
00176                 focusedWidget = i;
00177             }
00178         }
00179         int focused = focusedWidget;
00180 
00181         // i is a counter that ensures that the following loop
00182         // won't get stuck in an infinite loop
00183         i = (int)mWidgets.size();
00184         do
00185         {
00186             ++focusedWidget;
00187 
00188             if (i==0)
00189             {
00190                 focusedWidget = -1;
00191                 break;
00192             }
00193 
00194             --i;
00195 
00196             if (focusedWidget >= (int)mWidgets.size())
00197             {
00198                 focusedWidget = 0;
00199             }
00200 
00201             if (focusedWidget == focused)
00202             {
00203                 return;
00204             }
00205         }
00206         while (!mWidgets.at(focusedWidget)->isFocusable());
00207 
00208         if (focusedWidget >= 0)
00209         {
00210             mFocusedWidget = mWidgets.at(focusedWidget);
00211 
00212             Event focusEvent(mFocusedWidget);
00213             distributeFocusGainedEvent(focusEvent);
00214         }
00215 
00216         if (focused >= 0)
00217         {
00218             Event focusEvent(mWidgets.at(focused));
00219             distributeFocusLostEvent(focusEvent);
00220         }
00221     }
00222 
00223     void FocusHandler::focusPrevious()
00224     {
00225         if (mWidgets.size() == 0)
00226         {
00227             mFocusedWidget = NULL;
00228             return;
00229         }
00230 
00231         int i;
00232         int focusedWidget = -1;
00233         for (i = 0; i < (int)mWidgets.size(); ++i)
00234         {
00235             if (mWidgets[i] == mFocusedWidget)
00236             {
00237                 focusedWidget = i;
00238             }
00239         }
00240         int focused = focusedWidget;
00241 
00242         // i is a counter that ensures that the following loop
00243         // won't get stuck in an infinite loop
00244         i = (int)mWidgets.size();
00245         do
00246         {
00247             --focusedWidget;
00248 
00249             if (i==0)
00250             {
00251                 focusedWidget = -1;
00252                 break;
00253             }
00254 
00255             --i;
00256 
00257             if (focusedWidget <= 0)
00258             {
00259                 focusedWidget = mWidgets.size() - 1;
00260             }
00261 
00262             if (focusedWidget == focused)
00263             {
00264                 return;
00265             }
00266         }
00267         while (!mWidgets.at(focusedWidget)->isFocusable());
00268 
00269         if (focusedWidget >= 0)
00270         {
00271             mFocusedWidget = mWidgets.at(focusedWidget);
00272             Event focusEvent(mFocusedWidget);
00273             distributeFocusGainedEvent(focusEvent);
00274         }
00275 
00276         if (focused >= 0)
00277         {
00278             Event focusEvent(mWidgets.at(focused));
00279             distributeFocusLostEvent(focusEvent);
00280         }
00281     }
00282 
00283     bool FocusHandler::isFocused(const Widget* widget) const
00284     {
00285         return mFocusedWidget == widget;
00286     }
00287 
00288     void FocusHandler::add(Widget* widget)
00289     {
00290         mWidgets.push_back(widget);
00291     }
00292 
00293     void FocusHandler::remove(Widget* widget)
00294     {
00295         if (isFocused(widget))
00296         {
00297             mFocusedWidget = NULL;
00298         }
00299 
00300         WidgetIterator iter;
00301 
00302         for (iter = mWidgets.begin(); iter != mWidgets.end(); ++iter)
00303         {
00304             if ((*iter) == widget)
00305             {
00306                 mWidgets.erase(iter);
00307                 break;
00308             }
00309         }
00310 
00311         if (mDraggedWidget == widget)
00312         {
00313             mDraggedWidget = NULL;
00314             return;
00315         }   
00316         
00317         if (mLastWidgetWithMouse == widget)
00318         {
00319             mLastWidgetWithMouse = NULL;
00320             return;
00321         }
00322 
00323         if (mLastWidgetWithModalFocus == widget)
00324         {
00325             mLastWidgetWithModalFocus = NULL;
00326             return;
00327         }
00328 
00329         if (mLastWidgetWithModalMouseInputFocus == widget)
00330         {
00331             mLastWidgetWithModalMouseInputFocus = NULL;
00332             return;
00333         }
00334 
00335         if (mLastWidgetPressed == widget)
00336         {
00337             mLastWidgetPressed = NULL;
00338             return;
00339         }
00340     }
00341 
00342     void FocusHandler::focusNone()
00343     {
00344         if (mFocusedWidget != NULL)
00345         {
00346             Widget* focused = mFocusedWidget;
00347             mFocusedWidget = NULL;
00348 
00349             Event focusEvent(focused);
00350             distributeFocusLostEvent(focusEvent);
00351         }
00352     }
00353 
00354     void FocusHandler::tabNext()
00355     {
00356         if (mFocusedWidget != NULL)
00357         {
00358             if (!mFocusedWidget->isTabOutEnabled())
00359             {
00360                 return;
00361             }
00362         }
00363 
00364         if (mWidgets.size() == 0)
00365         {
00366             mFocusedWidget = NULL;
00367             return;
00368         }
00369 
00370         int i;
00371         int focusedWidget = -1;
00372         for (i = 0; i < (int)mWidgets.size(); ++i)
00373         {
00374             if (mWidgets[i] == mFocusedWidget)
00375             {
00376                 focusedWidget = i;
00377             }
00378         }
00379         int focused = focusedWidget;
00380         bool done = false;
00381 
00382         // i is a counter that ensures that the following loop
00383         // won't get stuck in an infinite loop
00384         i = (int)mWidgets.size();
00385         do
00386         {
00387             ++focusedWidget;
00388 
00389             if (i==0)
00390             {
00391                 focusedWidget = -1;
00392                 break;
00393             }
00394 
00395             --i;
00396 
00397             if (focusedWidget >= (int)mWidgets.size())
00398             {
00399                 focusedWidget = 0;
00400             }
00401 
00402             if (focusedWidget == focused)
00403             {
00404                 return;
00405             }
00406 
00407             if (mWidgets.at(focusedWidget)->isFocusable() &&
00408                 mWidgets.at(focusedWidget)->isTabInEnabled() &&
00409                 (mModalFocusedWidget == NULL ||
00410                  mWidgets.at(focusedWidget)->isModalFocused()))
00411             {
00412                 done = true;
00413             }
00414         }
00415         while (!done);
00416 
00417         if (focusedWidget >= 0)
00418         {
00419             mFocusedWidget = mWidgets.at(focusedWidget);
00420             Event focusEvent(mFocusedWidget);
00421             distributeFocusGainedEvent(focusEvent);
00422         }
00423 
00424         if (focused >= 0)
00425         {
00426             Event focusEvent(mWidgets.at(focused));
00427             distributeFocusLostEvent(focusEvent);
00428         }
00429     }
00430 
00431     void FocusHandler::tabPrevious()
00432     {
00433         if (mFocusedWidget != NULL)
00434         {
00435             if (!mFocusedWidget->isTabOutEnabled())
00436             {
00437                 return;
00438             }
00439         }
00440 
00441         if (mWidgets.size() == 0)
00442         {
00443             mFocusedWidget = NULL;
00444             return;
00445         }
00446 
00447         int i;
00448         int focusedWidget = -1;
00449         for (i = 0; i < (int)mWidgets.size(); ++i)
00450         {
00451             if (mWidgets[i] == mFocusedWidget)
00452             {
00453                 focusedWidget = i;
00454             }
00455         }
00456         int focused = focusedWidget;
00457         bool done = false;
00458 
00459         // i is a counter that ensures that the following loop
00460         // won't get stuck in an infinite loop
00461         i = (int)mWidgets.size();
00462         do
00463         {
00464             --focusedWidget;
00465 
00466             if (i==0)
00467             {
00468                 focusedWidget = -1;
00469                 break;
00470             }
00471 
00472             --i;
00473 
00474             if (focusedWidget <= 0)
00475             {
00476                 focusedWidget = mWidgets.size() - 1;
00477             }
00478 
00479             if (focusedWidget == focused)
00480             {
00481                 return;
00482             }
00483 
00484             if (mWidgets.at(focusedWidget)->isFocusable() &&
00485                 mWidgets.at(focusedWidget)->isTabInEnabled() &&
00486                 (mModalFocusedWidget == NULL ||
00487                  mWidgets.at(focusedWidget)->isModalFocused()))
00488             {
00489                 done = true;
00490             }
00491         }
00492         while (!done);
00493 
00494         if (focusedWidget >= 0)
00495         {
00496             mFocusedWidget = mWidgets.at(focusedWidget);
00497             Event focusEvent(mFocusedWidget);
00498             distributeFocusGainedEvent(focusEvent);
00499         }
00500 
00501         if (focused >= 0)
00502         {
00503             Event focusEvent(mWidgets.at(focused));
00504             distributeFocusLostEvent(focusEvent);
00505         }
00506     }
00507 
00508     void FocusHandler::distributeFocusLostEvent(const Event& focusEvent)
00509     {
00510         Widget* sourceWidget = focusEvent.getSource();
00511 
00512         std::list<FocusListener*> focusListeners = sourceWidget->_getFocusListeners();
00513 
00514         // Send the event to all focus listeners of the widget.
00515         for (std::list<FocusListener*>::iterator it = focusListeners.begin();
00516              it != focusListeners.end();
00517              ++it)
00518         {
00519             (*it)->focusLost(focusEvent);
00520         }
00521     }
00522 
00523     void FocusHandler::distributeFocusGainedEvent(const Event& focusEvent)
00524     {
00525         Widget* sourceWidget = focusEvent.getSource();
00526 
00527         std::list<FocusListener*> focusListeners = sourceWidget->_getFocusListeners();
00528 
00529         // Send the event to all focus listeners of the widget.
00530         for (std::list<FocusListener*>::iterator it = focusListeners.begin();
00531              it != focusListeners.end();
00532              ++it)
00533         {
00534             (*it)->focusGained(focusEvent);
00535         }
00536     }
00537 
00538     Widget* FocusHandler::getDraggedWidget()
00539     {
00540         return mDraggedWidget;
00541     }
00542 
00543     void FocusHandler::setDraggedWidget(Widget* draggedWidget)
00544     {
00545         mDraggedWidget = draggedWidget;
00546     }
00547 
00548     Widget* FocusHandler::getLastWidgetWithMouse()
00549     {
00550         return mLastWidgetWithMouse;
00551     }
00552 
00553     void FocusHandler::setLastWidgetWithMouse(Widget* lastWidgetWithMouse)
00554     {
00555         mLastWidgetWithMouse = lastWidgetWithMouse;
00556     }
00557 
00558     Widget* FocusHandler::getLastWidgetWithModalFocus()
00559     {
00560         return mLastWidgetWithModalFocus;
00561     }
00562 
00563     void FocusHandler::setLastWidgetWithModalFocus(Widget* lastWidgetWithModalFocus)
00564     {
00565         mLastWidgetWithModalFocus = lastWidgetWithModalFocus;
00566     }
00567 
00568     Widget* FocusHandler::getLastWidgetWithModalMouseInputFocus()
00569     {
00570         return mLastWidgetWithModalMouseInputFocus;
00571     }
00572 
00573     void FocusHandler::setLastWidgetWithModalMouseInputFocus(Widget* lastWidgetWithModalMouseInputFocus)
00574     {
00575         mLastWidgetWithModalMouseInputFocus = lastWidgetWithModalMouseInputFocus;
00576     }
00577 
00578     Widget* FocusHandler::getLastWidgetPressed()
00579     {
00580         return mLastWidgetPressed;
00581     }
00582 
00583     void FocusHandler::setLastWidgetPressed(Widget* lastWidgetPressed)
00584     {
00585         mLastWidgetPressed = lastWidgetPressed;
00586     }
00587 }

Generated on Sat Apr 26 13:40:08 2008 for Guichan by  doxygen 1.5.2