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

container.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/widgets/container.hpp"
00061 
00062 namespace gcn
00063 {
00064 
00065     Container::Container()
00066     {
00067         mWidgetWithMouse = NULL;
00068         mOpaque = true;        
00069     }
00070 
00071     Container::~Container()
00072     {
00073         clear();        
00074     }
00075     
00076     void Container::logic()
00077     {
00078         logicChildren();
00079     }
00080    
00081     void Container::draw(Graphics* graphics)
00082     {
00083         if (isOpaque())
00084         {
00085             graphics->setColor(getBaseColor());
00086             graphics->fillRectangle(Rectangle(0, 0, getWidth(), getHeight()));
00087         }
00088     
00089         drawChildren(graphics);
00090     }
00091 
00092     void Container::drawBorder(Graphics* graphics)
00093     {
00094         Color faceColor = getBaseColor();
00095         Color highlightColor, shadowColor;
00096         int alpha = getBaseColor().a;
00097         int width = getWidth() + getBorderSize() * 2 - 1;
00098         int height = getHeight() + getBorderSize() * 2 - 1;
00099         highlightColor = faceColor + 0x303030;
00100         highlightColor.a = alpha;
00101         shadowColor = faceColor - 0x303030;
00102         shadowColor.a = alpha;
00103         
00104         unsigned int i;
00105         for (i = 0; i < getBorderSize(); ++i)
00106         {
00107             graphics->setColor(shadowColor);
00108             graphics->drawLine(i,i, width - i, i);
00109             graphics->drawLine(i,i + 1, i, height - i - 1);
00110             graphics->setColor(highlightColor);
00111             graphics->drawLine(width - i,i + 1, width - i, height - i); 
00112             graphics->drawLine(i,height - i, width - i - 1, height - i); 
00113         }
00114     }
00115     
00116     void Container::logicChildren()
00117     {
00118         WidgetIterator iter;
00119         for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00120         {
00121             (*iter)->logic();
00122         }
00123     }
00124   
00125     void Container::drawChildren(Graphics* graphics)
00126     {
00127         WidgetIterator iter;
00128         for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00129         {
00130             if ((*iter)->isVisible())
00131             {
00132                 // If the widget has a border,
00133                 // draw it before drawing the widget
00134                 if ((*iter)->getBorderSize() > 0)
00135                 {
00136                     Rectangle rec = (*iter)->getDimension();
00137                     rec.x -= (*iter)->getBorderSize();
00138                     rec.y -= (*iter)->getBorderSize();
00139                     rec.width += 2 * (*iter)->getBorderSize();
00140                     rec.height += 2 * (*iter)->getBorderSize();                    
00141                     graphics->pushClipArea(rec);
00142                     (*iter)->drawBorder(graphics);
00143                     graphics->popClipArea();
00144                 }
00145                 
00146                 graphics->pushClipArea((*iter)->getDimension());
00147                 (*iter)->draw(graphics);
00148                 graphics->popClipArea();
00149             }
00150         }
00151     }
00152 
00153     void Container::setOpaque(bool opaque)
00154     {
00155         mOpaque = opaque;
00156     }
00157 
00158     bool Container::isOpaque() const
00159     {
00160         return mOpaque;
00161     }
00162 
00163     void Container::moveToTop(Widget* widget)
00164     {
00165         WidgetIterator iter;
00166         for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00167         {
00168             if (*iter == widget)
00169             {
00170                 mWidgets.erase(iter);
00171                 mWidgets.push_back(widget);
00172                 return;
00173             }
00174         }
00175 
00176         throw GCN_EXCEPTION("There is no such widget in this container.");
00177     }
00178 
00179     void Container::moveToBottom(Widget* widget)
00180     {
00181         WidgetIterator iter;
00182         for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00183         {
00184             if (*iter == widget)
00185             {
00186                 mWidgets.erase(iter);
00187                 mWidgets.push_front(widget);
00188                 return;
00189             }
00190         }
00191 
00192         throw GCN_EXCEPTION("There is no such widget in this container.");
00193     }
00194 
00195     void Container::_announceDeath(Widget *widget)
00196     {
00197         if (mWidgetWithMouse == widget)
00198         {
00199             mWidgetWithMouse = NULL;
00200         }
00201           
00202         WidgetIterator iter;
00203         for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00204         {
00205             if (*iter == widget)
00206             {
00207                 mWidgets.erase(iter);
00208                 return;
00209             }
00210         }
00211 
00212         throw GCN_EXCEPTION("There is no such widget in this container.");
00213     }
00214     
00215     void Container::getDrawSize(int& width, int& height, Widget* widget)
00216     {
00217         WidgetIterator iter;
00218         bool contains = false;
00219 
00220         for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00221         {
00222             if (widget == *iter)
00223             {
00224                 contains = true;
00225                 break;
00226             }
00227         }
00228     
00229         if (contains)
00230         {
00231             Rectangle widgetDim = widget->getDimension();
00232             Rectangle dim = getDimension();
00233 
00234             width = widgetDim.width;
00235             height = widgetDim.height;
00236 
00237             if (widgetDim.x < 0)
00238             {
00239                 width += widgetDim.x;
00240             }
00241 
00242             if (widgetDim.y < 0)
00243             {
00244                 height += widgetDim.y;
00245             }
00246 
00247             if (widgetDim.x + widgetDim.width > dim.width)
00248             {
00249                 width -= (widgetDim.x + widgetDim.width) - dim.width;
00250             }
00251 
00252             if (widgetDim.y + widgetDim.height > dim.height)
00253             {
00254                 height -= (widgetDim.y + widgetDim.height) - dim.height;
00255             }
00256 
00257             if (width < 0)
00258             {
00259                 width = 0;
00260             }
00261 
00262             if (height < 0)
00263             {
00264                 height = 0;
00265             }
00266         }
00267         else
00268         {
00269             throw GCN_EXCEPTION("Widget not in container.");
00270         }    
00271     }
00272   
00273     void Container::add(Widget* widget)
00274     {
00275         mWidgets.push_back(widget);
00276         widget->_setFocusHandler(_getFocusHandler());
00277         widget->_setParent(this);
00278     }
00279 
00280     void Container::add(Widget* widget, int x, int y)
00281     {
00282         widget->setPosition(x, y);
00283         add(widget);
00284     }
00285 
00286     void Container::remove(Widget* widget)
00287     {
00288         if (mWidgetWithMouse == widget)
00289         {
00290             mWidgetWithMouse = NULL;
00291         }
00292     
00293         WidgetIterator iter;
00294         for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00295         {
00296             if (*iter == widget)
00297             {
00298                 mWidgets.erase(iter);
00299                 widget->_setFocusHandler(NULL);
00300                 widget->_setParent(NULL);
00301                 return;
00302             }
00303         }
00304 
00305         throw GCN_EXCEPTION("There is no such widget in this container.");
00306     }
00307 
00308     void Container::clear()
00309     { 
00310         mWidgetWithMouse = NULL;
00311     
00312         WidgetIterator iter;
00313 
00314         for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00315         {      
00316             (*iter)->_setFocusHandler(NULL);
00317             (*iter)->_setParent(NULL);
00318         }
00319     
00320         mWidgets.clear();
00321     }
00322 
00323     void Container::_setFocusHandler(FocusHandler* focusHandler)
00324     {
00325         Widget::_setFocusHandler(focusHandler);
00326     
00327         WidgetIterator iter;
00328         for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00329         {
00330             (*iter)->_setFocusHandler(focusHandler);
00331         }   
00332     }
00333   
00334     void Container::_mouseInputMessage(const MouseInput &mouseInput)
00335     {        
00336         Widget* tempWidgetWithMouse = NULL;
00337         
00338         WidgetIterator iter;    
00339         for (iter = mWidgets.begin(); iter != mWidgets.end(); iter++)
00340         {
00341             if ((*iter)->getDimension().isPointInRect(mouseInput.x, mouseInput.y)
00342                 && (*iter)->isVisible())
00343             {
00344                 tempWidgetWithMouse = (*iter);
00345             }
00346         }
00347 
00348         if (tempWidgetWithMouse != mWidgetWithMouse)
00349         {
00350             if (mWidgetWithMouse)
00351             {
00352                 mWidgetWithMouse->_mouseOutMessage();
00353             }
00354 
00355             if (tempWidgetWithMouse)
00356             {
00357                 tempWidgetWithMouse->_mouseInMessage();
00358             }
00359 
00360             mWidgetWithMouse = tempWidgetWithMouse;
00361         }
00362     
00363         if (mWidgetWithMouse != NULL)
00364         {
00365             MouseInput mi = mouseInput;
00366             mi.x -= mWidgetWithMouse->getX();
00367             mi.y -= mWidgetWithMouse->getY();      
00368             mWidgetWithMouse->_mouseInputMessage(mi);
00369         }
00370 
00371          if (mWidgetWithMouse == NULL)
00372          {
00373              BasicContainer::_mouseInputMessage(mouseInput);
00374          }        
00375     }
00376 
00377     void Container::_mouseOutMessage()
00378     {
00379         if (mWidgetWithMouse)
00380         {
00381             mWidgetWithMouse->_mouseOutMessage();
00382             mWidgetWithMouse = NULL;
00383         }
00384 
00385         Widget::_mouseOutMessage();
00386     }  
00387 }

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