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

gui.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/exception.hpp"
00060 #include "guichan/focushandler.hpp"
00061 #include "guichan/gui.hpp"
00062 #include "guichan/key.hpp"
00063 
00064 namespace gcn
00065 {
00066     Gui::Gui()
00067     {
00068         mTop = NULL;
00069         mInput = NULL;
00070         mGraphics = NULL;
00071         mFocusHandler = new FocusHandler();
00072         mTopHasMouse = false;
00073         mTabbing = true;
00074     }
00075 
00076     Gui::~Gui()
00077     {
00078         if (Widget::widgetExists(mTop))
00079         {
00080             setTop(NULL);
00081         }
00082         
00083         delete mFocusHandler;
00084     }
00085   
00086     void Gui::setTop(Widget* top)
00087     {
00088         if (mTop)
00089         {
00090             mTop->_setFocusHandler(NULL);
00091         }
00092         if (top)
00093         {
00094             top->_setFocusHandler(mFocusHandler);
00095         }
00096     
00097         mTop = top;
00098     }
00099 
00100     Widget* Gui::getTop() const
00101     {
00102         return mTop;
00103     }
00104 
00105     void Gui::setGraphics(Graphics* graphics)
00106     {
00107         mGraphics = graphics;
00108     }
00109 
00110     Graphics* Gui::getGraphics() const
00111     {
00112         return mGraphics;
00113     }
00114 
00115     void Gui::setInput(Input* input)
00116     {
00117         mInput = input;
00118     }
00119   
00120     Input* Gui::getInput() const
00121     {
00122         return mInput;
00123     }
00124 
00125     void Gui::logic()
00126     {
00127         if (!mTop)
00128         {
00129             throw GCN_EXCEPTION("No top widget set");
00130         }
00131 
00132         if(mInput)
00133         {
00134             mInput->_pollInput();
00135 
00136             while (!mInput->isMouseQueueEmpty())
00137             {
00138                 MouseInput mi = mInput->dequeueMouseInput();
00139 
00140                 // Send mouse input to every widget that has the mouse.
00141                 if (mi.x > 0 && mi.y > 0
00142                     && mTop->getDimension().isPointInRect(mi.x, mi.y))
00143                 {
00144                     if (!mTop->hasMouse())
00145                     {
00146                         mTop->_mouseInMessage();
00147                     }
00148 
00149                     MouseInput mio = mi;
00150                     mio.x -= mTop->getX();
00151                     mio.y -= mTop->getY();
00152                     mTop->_mouseInputMessage(mio);
00153                 }
00154                 else if (mTop->hasMouse())
00155                 {
00156                     mTop->_mouseOutMessage();
00157                 }                
00158 
00159                 Widget* f = mFocusHandler->getFocused();
00160                 Widget* d = mFocusHandler->getDragged();
00161 
00162                 // If the focused widget doesn't have the mouse,
00163                 // send the mouse input to the focused widget.
00164                 if (f != NULL && !f->hasMouse())
00165                 {
00166                     int xOffset, yOffset;
00167                     f->getAbsolutePosition(xOffset, yOffset);
00168                     
00169                     MouseInput mio = mi;
00170                     mio.x -= xOffset;
00171                     mio.y -= yOffset;
00172                     
00173                     f->_mouseInputMessage(mio);
00174                 }
00175 
00176                 // If the dragged widget is different from the focused
00177                 // widget, send the mouse input to the dragged widget.
00178                 if (d != NULL && d != f && !d->hasMouse())
00179                 {
00180                     int xOffset, yOffset;
00181                     d->getAbsolutePosition(xOffset, yOffset);
00182                     
00183                     MouseInput mio = mi;
00184                     mio.x -= xOffset;
00185                     mio.y -= yOffset;
00186                     
00187                     d->_mouseInputMessage(mio);                    
00188                 }
00189                 
00190                 mFocusHandler->applyChanges();
00191                 
00192             } // end while
00193             
00194             while (!mInput->isKeyQueueEmpty())        
00195             {
00196                 KeyInput ki = mInput->dequeueKeyInput();
00197 
00198                 if (mTabbing
00199                     && ki.getKey().getValue() == Key::TAB
00200                     && ki.getType() == KeyInput::PRESS)
00201                 {
00202                     if (ki.getKey().isShiftPressed())
00203                     {
00204                         mFocusHandler->tabPrevious();
00205                     }
00206                     else
00207                     {
00208                         mFocusHandler->tabNext();
00209                     }
00210                 }
00211                 else
00212                 {
00213                     // Send key inputs to the focused widgets
00214                     if (mFocusHandler->getFocused())                        
00215                     {
00216                         if (mFocusHandler->getFocused()->isFocusable())
00217                         {
00218                             mFocusHandler->getFocused()->_keyInputMessage(ki);
00219                         }
00220                         else
00221                         {
00222                             mFocusHandler->focusNone();
00223                         }
00224                     }
00225                 }
00226                 
00227                 mFocusHandler->applyChanges();
00228 
00229             } // end while
00230             
00231         } // end if
00232     
00233         mTop->logic();        
00234     }
00235     
00236     void Gui::draw()
00237     {
00238         if (!mTop)
00239         {
00240             throw GCN_EXCEPTION("No top widget set");
00241         }
00242         if (!mGraphics)
00243         {
00244             throw GCN_EXCEPTION("No graphics set");
00245         }
00246 
00247         mGraphics->_beginDraw();
00248 
00249         // If top has a border,
00250         // draw it before drawing top
00251         if (mTop->getBorderSize() > 0)
00252         {
00253             Rectangle rec = mTop->getDimension();
00254             rec.x -= mTop->getBorderSize();
00255             rec.y -= mTop->getBorderSize();
00256             rec.width += 2 * mTop->getBorderSize();
00257             rec.height += 2 * mTop->getBorderSize();                    
00258             mGraphics->pushClipArea(rec);
00259             mTop->drawBorder(mGraphics);
00260             mGraphics->popClipArea();
00261         }
00262 
00263         mGraphics->pushClipArea(mTop->getDimension());    
00264         mTop->draw(mGraphics);
00265         mGraphics->popClipArea();
00266 
00267 
00268         mGraphics->_endDraw();    
00269     }
00270 
00271     void Gui::focusNone()
00272     {
00273         mFocusHandler->focusNone();
00274     }
00275 
00276     void Gui::setTabbingEnabled(bool tabbing)
00277     {
00278         mTabbing = tabbing;
00279     }
00280     
00281     bool Gui::isTabbingEnabled()
00282     {
00283         return mTabbing;
00284     }    
00285 }

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