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

window.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/widgets/window.hpp"
00060 #include "guichan/exception.hpp"
00061 #include "guichan/mouseinput.hpp"
00062 
00063 namespace gcn
00064 {
00065     Window::Window()
00066     {
00067         mContent = NULL;
00068         mMouseDrag = false;
00069         setBorderSize(1);
00070         setPadding(2);
00071         setTitleBarHeight(16);
00072         setAlignment(Graphics::CENTER);
00073         addMouseListener(this);
00074         setMovable(true);
00075         setOpaque(true);
00076     }
00077 
00078     Window::Window(const std::string& caption)
00079     {
00080         mContent = NULL;
00081         mMouseDrag = false;
00082         setCaption(caption);    
00083         setBorderSize(1);
00084         setPadding(2);
00085         setTitleBarHeight(16);
00086         setAlignment(Graphics::CENTER);
00087         addMouseListener(this);
00088         setMovable(true);
00089         setOpaque(true);
00090     }
00091 
00092     Window::Window(Widget* content, const std::string& caption)
00093     {
00094         mContent = NULL;
00095         mMouseDrag = false;    
00096         setContent(content);
00097         setCaption(caption);
00098         setBorderSize(1);
00099         setPadding(2);
00100         setTitleBarHeight(16);
00101         setAlignment(Graphics::CENTER);
00102         addMouseListener(this);    
00103         setMovable(true);
00104         setOpaque(true);
00105     }
00106 
00107     Window::~Window()
00108     {
00109         setContent(NULL);
00110     }
00111   
00112     void Window::setPadding(unsigned int padding)
00113     {
00114         mPadding = padding;
00115         repositionContent();
00116     }
00117 
00118     unsigned int Window::getPadding() const
00119     {
00120         return mPadding;
00121     }
00122 
00123     void Window::setTitleBarHeight(unsigned int height)
00124     {
00125         mTitleBarHeight = height;
00126         repositionContent();
00127     }
00128 
00129     unsigned int Window::getTitleBarHeight()
00130     {
00131         return mTitleBarHeight;
00132     }
00133 
00134     void Window:: _announceDeath(Widget *widget)
00135     {
00136         mContent = NULL;
00137     }
00138 
00139     void Window::setContent(Widget* widget)
00140     {
00141         if (getContent() != NULL)
00142         {
00143             getContent()->_setParent(NULL);
00144             getContent()->_setFocusHandler(NULL);
00145         }
00146     
00147         if (widget != NULL)
00148         {
00149             widget->_setParent(this);
00150             widget->_setFocusHandler(_getFocusHandler());
00151         }
00152 
00153         mContent = widget;
00154         repositionContent();
00155     }
00156 
00157     Widget* Window::getContent() const
00158     {
00159         return mContent;
00160     }
00161 
00162     void Window::setCaption(const std::string& caption)
00163     {
00164         mCaption = caption;
00165     }
00166 
00167     const std::string& Window::getCaption() const
00168     {
00169         return mCaption;    
00170     }
00171 
00172     void Window::setAlignment(unsigned int alignment)
00173     {
00174         mAlignment = alignment;
00175     }
00176 
00177     unsigned int Window::getAlignment() const
00178     {
00179         return mAlignment;
00180     }
00181 
00182     void Window::draw(Graphics* graphics)
00183     {
00184         Color faceColor = getBaseColor();
00185         Color highlightColor, shadowColor;
00186         int alpha = getBaseColor().a;
00187         int width = getWidth() + getBorderSize() * 2 - 1;
00188         int height = getHeight() + getBorderSize() * 2 - 1;
00189         highlightColor = faceColor + 0x303030;
00190         highlightColor.a = alpha;
00191         shadowColor = faceColor - 0x303030;
00192         shadowColor.a = alpha;
00193 
00194         Rectangle d = getContentDimension();
00195 
00196         // Fill the background around the content
00197         graphics->setColor(faceColor);
00198         // Fill top
00199         graphics->fillRectangle(Rectangle(0,0,getWidth(),d.y - 1));
00200         // Fill left
00201         graphics->fillRectangle(Rectangle(0,d.y - 1, d.x - 1, getHeight() - d.y + 1));
00202         // Fill right
00203         graphics->fillRectangle(Rectangle(d.x + d.width + 1,
00204                                           d.y - 1,
00205                                           getWidth() - d.x - d.width - 1,
00206                                           getHeight() - d.y + 1));
00207         // Fill bottom
00208         graphics->fillRectangle(Rectangle(d.x - 1,
00209                                           d.y + d.height + 1,
00210                                           d.width + 2,
00211                                           getHeight() - d.height - d.y - 1));    
00212 
00213         if (isOpaque())
00214         {      
00215             graphics->fillRectangle(d);
00216         }
00217     
00218         // Construct a rectangle one pixel bigger than the content
00219         d.x -= 1;
00220         d.y -= 1;
00221         d.width += 2;
00222         d.height += 2;
00223 
00224         // Draw a border around the content
00225         graphics->setColor(shadowColor);
00226         // Top line
00227         graphics->drawLine(d.x,
00228                            d.y,
00229                            d.x + d.width - 2,
00230                            d.y);
00231 
00232         // Left line
00233         graphics->drawLine(d.x,
00234                            d.y + 1,
00235                            d.x,
00236                            d.y + d.height - 1);
00237     
00238         graphics->setColor(highlightColor);
00239         // Right line
00240         graphics->drawLine(d.x + d.width - 1,
00241                            d.y,
00242                            d.x + d.width - 1,
00243                            d.y + d.height - 2);
00244         // Bottom line
00245         graphics->drawLine(d.x + 1,
00246                            d.y + d.height - 1,
00247                            d.x + d.width - 1,
00248                            d.y + d.height - 1);
00249 
00250         drawContent(graphics);
00251         
00252         int textX;
00253         int textY;
00254         textY = (getTitleBarHeight() - getFont()->getHeight()) / 2;
00255         switch (getAlignment())
00256         {
00257           case Graphics::LEFT:
00258               textX = 4;
00259               break;
00260           case Graphics::CENTER:
00261               textX = getWidth() / 2;
00262               break;
00263           case Graphics::RIGHT:
00264               textX = getWidth() - 4;
00265               break;
00266           default:
00267               throw GCN_EXCEPTION("Unknown alignment.");
00268         }
00269 
00270         graphics->setColor(getForegroundColor());
00271         graphics->setFont(getFont());
00272         graphics->drawText(getCaption(), textX, textY, getAlignment());
00273     }
00274 
00275     void Window::drawBorder(Graphics* graphics)
00276     {
00277         Color faceColor = getBaseColor();
00278         Color highlightColor, shadowColor;
00279         int alpha = getBaseColor().a;
00280         int width = getWidth() + getBorderSize() * 2 - 1;
00281         int height = getHeight() + getBorderSize() * 2 - 1;
00282         highlightColor = faceColor + 0x303030;
00283         highlightColor.a = alpha;
00284         shadowColor = faceColor - 0x303030;
00285         shadowColor.a = alpha;
00286         
00287         unsigned int i;
00288         for (i = 0; i < getBorderSize(); ++i)
00289         {
00290             graphics->setColor(highlightColor);
00291             graphics->drawLine(i,i, width - i, i);
00292             graphics->drawLine(i,i + 1, i, height - i - 1);
00293             graphics->setColor(shadowColor);
00294             graphics->drawLine(width - i,i + 1, width - i, height - i); 
00295             graphics->drawLine(i,height - i, width - i - 1, height - i); 
00296         }
00297     }
00298 
00299     void Window::drawContent(Graphics* graphics)
00300     {
00301         if (getContent() != NULL)
00302         {
00303             graphics->pushClipArea(getContentDimension());
00304             graphics->pushClipArea(Rectangle(0, 0, getContent()->getWidth(),
00305                                              getContent()->getHeight()));
00306             getContent()->draw(graphics);
00307             graphics->popClipArea();
00308             graphics->popClipArea();
00309         }
00310     }
00311     
00312     void Window::mousePress(int x, int y, int button)
00313     {    
00314         if (getParent() != NULL)
00315         {
00316             getParent()->moveToTop(this);
00317         }
00318     
00319         if (isMovable() && hasMouse()
00320             && y < (int)(getTitleBarHeight() + getPadding()) && button == 1)
00321         {
00322             mMouseDrag = true;
00323             mMouseXOffset = x;
00324             mMouseYOffset = y;
00325         }
00326     }
00327   
00328     void Window::mouseRelease(int x, int y, int button)
00329     {
00330         if (button == 1)
00331         {
00332             mMouseDrag = false;
00333         }
00334     }
00335 
00336     void Window::mouseMotion(int x, int y)
00337     {
00338         if (mMouseDrag && isMovable())
00339         {
00340             setPosition(x - mMouseXOffset + getX(),
00341                         y - mMouseYOffset + getY());
00342         }
00343     }
00344   
00345     void Window::moveToTop(Widget* widget)
00346     {
00347         if (widget != getContent())
00348         {
00349             throw GCN_EXCEPTION("Widget is not content of window.");      
00350         }
00351     }
00352   
00353     void Window::moveToBottom(Widget* widget)
00354     {
00355         if (widget != getContent())
00356         {
00357             throw GCN_EXCEPTION("Widget is not content of window");      
00358         }
00359     }
00360   
00361     void Window::getDrawSize(int& width, int& height, Widget* widget)
00362     {
00363         if (widget != getContent())
00364         {
00365             throw GCN_EXCEPTION("Widget is not content of window");      
00366         }
00367 
00368         Rectangle d = getContentDimension();
00369         width = d.width;
00370         height = d.height;
00371     }
00372 
00373     void Window::repositionContent()
00374     {
00375         if (getContent() == NULL)
00376         {
00377             return;
00378         }
00379 
00380         Rectangle d = getContentDimension();
00381         mContent->setPosition(d.x, d.y);
00382     }
00383   
00384     Rectangle Window::getContentDimension()
00385     {
00386         return Rectangle(getPadding(),
00387                          getTitleBarHeight(),
00388                          getWidth() - getPadding() * 2,
00389                          getHeight() - getPadding() - getTitleBarHeight());
00390     }
00391 
00392     void Window::setMovable(bool movable)
00393     {
00394         mMovable = movable;
00395     }
00396 
00397     bool Window::isMovable() const
00398     {
00399         return mMovable;
00400     }
00401 
00402     void Window::resizeToContent()
00403     {
00404         if (getContent() != NULL)
00405         {      
00406             setSize(getContent()->getWidth() + 2*getPadding(),
00407                     getContent()->getHeight() + getPadding()
00408                     + getTitleBarHeight());
00409         }
00410     }
00411 
00412     void Window::_mouseInputMessage(const MouseInput &mouseInput)
00413     {
00414         BasicContainer::_mouseInputMessage(mouseInput);
00415     
00416         if (getContent() != NULL)
00417         {
00418             if (getContentDimension().isPointInRect(mouseInput.x, mouseInput.y) &&
00419                 getContent()->getDimension().isPointInRect(mouseInput.x, mouseInput.y))
00420             {
00421                 if (!getContent()->hasMouse())
00422                 {
00423                     getContent()->_mouseInMessage();          
00424                 }
00425         
00426                 MouseInput mi = mouseInput;
00427                 mi.x -= getContent()->getX();
00428                 mi.y -= getContent()->getY();
00429                 getContent()->_mouseInputMessage(mi);
00430             }
00431             else if (getContent()->hasMouse())
00432             {
00433                 getContent()->_mouseOutMessage();
00434             }
00435         }
00436     }
00437   
00438     void Window::_mouseOutMessage()
00439     {
00440         BasicContainer::_mouseOutMessage();
00441         
00442         if (getContent() != NULL && getContent()->hasMouse())
00443         {
00444             getContent()->_mouseOutMessage();
00445         }   
00446     }
00447 
00448     void Window::_setFocusHandler(FocusHandler *focusHandler)
00449     {
00450         if (getContent() != NULL)
00451         {
00452             getContent()->_setFocusHandler(focusHandler);
00453         }
00454     
00455         BasicContainer::_setFocusHandler(focusHandler);
00456     }
00457 
00458     void Window::setOpaque(bool opaque)
00459     {
00460         mOpaque = opaque;
00461     }
00462 
00463     bool Window::isOpaque()
00464     {
00465         return mOpaque;    
00466     }
00467 
00468     void Window::logic()
00469     {
00470         if (getContent() != NULL)
00471         {
00472             getContent()->logic();
00473         }
00474     }   
00475 }

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