Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreGuiElement.cpp

Go to the documentation of this file.
00001 
00002 /*
00003 -----------------------------------------------------------------------------
00004 This source file is part of OGRE
00005     (Object-oriented Graphics Rendering Engine)
00006 For the latest info, see http://www.ogre3d.org/
00007 
00008 Copyright © 2000-2002 The OGRE Team
00009 Also see acknowledgements in Readme.html
00010 
00011 This program is free software you can redistribute it and/or modify it under
00012 the terms of the GNU Lesser General Public License as published by the Free Software
00013 Foundation either version 2 of the License, or (at your option) any later
00014 version.
00015 
00016 This program is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS
00018 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00019 
00020 You should have received a copy of the GNU Lesser General Public License along with
00021 this program if not, write to the Free Software Foundation, Inc., 59 Temple
00022 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00023 http://www.gnu.org/copyleft/lesser.txt.
00024 -----------------------------------------------------------------------------
00025 */
00026 #include "OgreStableHeaders.h"
00027 
00028 #include "OgreGuiElement.h"
00029 #include "OgreMaterialManager.h"
00030 #include "OgreOverlay.h"
00031 #include "OgreGuiContainer.h"
00032 #include "OgreMouseEvent.h"
00033 #include "OgreEventMulticaster.h"
00034 #include "OgreEventListeners.h"
00035 #include "OgreOverlayManager.h"
00036 #include "OgreException.h"
00037 #include "OgreRenderQueue.h"
00038 
00039 namespace Ogre {
00040 
00041 
00042     //---------------------------------------------------------------------
00043     // Define static members
00044     GuiElementCommands::CmdLeft GuiElement::msLeftCmd;
00045     GuiElementCommands::CmdTop GuiElement::msTopCmd;
00046     GuiElementCommands::CmdWidth GuiElement::msWidthCmd;
00047     GuiElementCommands::CmdHeight GuiElement::msHeightCmd;
00048     GuiElementCommands::CmdMaterial GuiElement::msMaterialCmd;
00049     GuiElementCommands::CmdCaption GuiElement::msCaptionCmd;
00050     GuiElementCommands::CmdMetricsMode GuiElement::msMetricsModeCmd;
00051     GuiElementCommands::CmdHorizontalAlign GuiElement::msHorizontalAlignCmd;
00052     GuiElementCommands::CmdVerticalAlign GuiElement::msVerticalAlignCmd;
00053     GuiElementCommands::CmdVisible GuiElement::msVisibleCmd;
00054     //---------------------------------------------------------------------
00055     GuiElement::GuiElement(const String& name)
00056         : MouseTarget(),
00057           MouseMotionTarget(),
00058           mName(name)
00059     {
00060         mParent = 0;
00061         mLeft = 0.0f;
00062         mTop = 0.0f;
00063         mWidth = 1.0f;
00064         mHeight = 1.0f;
00065         mMouseListener = 0;
00066         mVisible = true;
00067         mpMaterial = 0;
00068         mDerivedOutOfDate = true;
00069         mZOrder = 0;
00070         mCloneable = true;
00071         mMetricsMode = GMM_RELATIVE;
00072         mHorzAlign = GHA_LEFT;
00073         mVertAlign = GVA_TOP;
00074         mGeomPositionsOutOfDate = true;       
00075         mEnabled = true;
00076     }
00077     //---------------------------------------------------------------------
00078     GuiElement::~GuiElement()
00079     {
00080     }
00081     //---------------------------------------------------------------------
00082     const String& GuiElement::getName(void) const
00083     {
00084         return mName;
00085     }
00086     //---------------------------------------------------------------------
00087     void GuiElement::show(void)
00088     {
00089         mVisible = true;
00090     }
00091     //---------------------------------------------------------------------
00092     void GuiElement::hide(void)
00093     {
00094         mVisible = false;
00095     }
00096     //---------------------------------------------------------------------
00097     bool GuiElement::isVisible(void) const
00098     {
00099         return mVisible;
00100     }
00101     //---------------------------------------------------------------------
00102     void GuiElement::setDimensions(Real width, Real height)
00103     {
00104         if (mMetricsMode == GMM_PIXELS)
00105         {
00106             mPixelWidth = (short int)width;
00107             mPixelHeight = (short int)height;
00108         }
00109         else
00110         {
00111             mWidth = width;
00112             mHeight = height;
00113         }
00114         mDerivedOutOfDate = true;
00115         _positionsOutOfDate();
00116     }
00117     //---------------------------------------------------------------------
00118     void GuiElement::setPosition(Real left, Real top)
00119     {
00120         if (mMetricsMode == GMM_PIXELS)
00121         {
00122             mPixelLeft = (short int)left;
00123             mPixelTop = (short int)top;
00124         }
00125         else
00126         {
00127             mLeft = left;
00128             mTop = top;
00129         }
00130         mDerivedOutOfDate = true;
00131         _positionsOutOfDate();
00132 
00133     }
00134     //---------------------------------------------------------------------
00135     void GuiElement::setWidth(Real width)
00136     {
00137         if (mMetricsMode == GMM_PIXELS)
00138         {
00139             mPixelWidth = (short int)width;
00140         }
00141         else
00142         {
00143             mWidth = width;
00144         }
00145         _positionsOutOfDate();
00146     }
00147     //---------------------------------------------------------------------
00148     Real GuiElement::getWidth(void) const
00149     {
00150         if (mMetricsMode == GMM_PIXELS)
00151         {
00152             return (Real)mPixelWidth;
00153         }
00154         else
00155         {
00156             return mWidth;
00157         }
00158     }
00159     //---------------------------------------------------------------------
00160     void GuiElement::setHeight(Real height)
00161     {
00162         if (mMetricsMode == GMM_PIXELS)
00163         {
00164             mPixelHeight = (short int)height;
00165         }
00166         else
00167         {
00168             mHeight = height;
00169         }
00170         _positionsOutOfDate();
00171     }
00172     //---------------------------------------------------------------------
00173     Real GuiElement::getHeight(void) const
00174     {
00175         if (mMetricsMode == GMM_PIXELS)
00176         {
00177             return (Real)mPixelHeight;
00178         }
00179         else
00180         {
00181             return mHeight;
00182         }
00183     }
00184     //---------------------------------------------------------------------
00185     void GuiElement::setLeft(Real left)
00186     {
00187         if (mMetricsMode == GMM_PIXELS)
00188         {
00189             mPixelLeft = (short int)left;
00190         }
00191         else
00192         {
00193             mLeft = left;
00194         }
00195         mDerivedOutOfDate = true;
00196         _positionsOutOfDate();
00197     }
00198     //---------------------------------------------------------------------
00199     Real GuiElement::getLeft(void) const
00200     {
00201         if (mMetricsMode == GMM_PIXELS)
00202         {
00203             return (Real)mPixelLeft;
00204         }
00205         else
00206         {
00207             return mLeft;
00208         }
00209     }
00210     //---------------------------------------------------------------------
00211     void GuiElement::setTop(Real top)
00212     {
00213         if (mMetricsMode == GMM_PIXELS)
00214         {
00215             mPixelTop = (short int)top;
00216         }
00217         else
00218         {
00219             mTop = top;
00220         }
00221 
00222         mDerivedOutOfDate = true;
00223         _positionsOutOfDate();
00224     }
00225     //---------------------------------------------------------------------
00226     Real GuiElement::getTop(void) const
00227     {
00228         if (mMetricsMode == GMM_PIXELS)
00229         {
00230             return (Real)mPixelTop;
00231         }
00232         else
00233         {
00234             return mTop;
00235         }
00236     }
00237     //---------------------------------------------------------------------
00238     const String& GuiElement::getMaterialName(void) const
00239     {
00240         return mMaterialName;
00241 
00242     }
00243     //---------------------------------------------------------------------
00244     void GuiElement::setMaterialName(const String& matName)
00245     {
00246         mMaterialName = matName;
00247         mpMaterial = (Material*)MaterialManager::getSingleton().getByName(matName);
00248         if (!mpMaterial)
00249             Except( Exception::ERR_ITEM_NOT_FOUND, "Could not find material " + matName,
00250                 "GuiElement::setMaterialName" );
00251         mpMaterial->load();
00252         // Set some prerequisites to be sure
00253         mpMaterial->setLightingEnabled(false);
00254         mpMaterial->setDepthCheckEnabled(false);
00255 
00256     }
00257     //---------------------------------------------------------------------
00258     Material* GuiElement::getMaterial(void) const
00259     {
00260         return mpMaterial;
00261     }
00262     //---------------------------------------------------------------------
00263     void GuiElement::getWorldTransforms(Matrix4* xform) const
00264     {
00265         mOverlay->_getWorldTransforms(xform);
00266     }
00267     //-----------------------------------------------------------------------
00268     const Quaternion& GuiElement::getWorldOrientation(void) const
00269     {
00270         return mOverlay->getWorldOrientation();
00271     }
00272     //-----------------------------------------------------------------------
00273     const Vector3& GuiElement::getWorldPosition(void) const
00274     {
00275         return mOverlay->getWorldPosition();
00276     }
00277     //---------------------------------------------------------------------
00278     bool GuiElement::useIdentityProjection(void) const
00279     {
00280         return true;
00281     }
00282     //---------------------------------------------------------------------
00283     bool GuiElement::useIdentityView(void) const
00284     {
00285         return true;
00286     }
00287 
00288     //---------------------------------------------------------------------
00289     void GuiElement::_positionsOutOfDate(void)
00290     {
00291         mGeomPositionsOutOfDate = true;
00292     }
00293 
00294     //---------------------------------------------------------------------
00295     void GuiElement::_update(void)
00296     {
00297         // Check size if pixel-based
00298         if (mMetricsMode == GMM_PIXELS &&
00299             (OverlayManager::getSingleton().hasViewportChanged() || mGeomPositionsOutOfDate))
00300         {
00301             // Derive parametric version of dimensions
00302             Real vpWidth, vpHeight;
00303             vpWidth = (Real) (OverlayManager::getSingleton().getViewportWidth());
00304             vpHeight = (Real) (OverlayManager::getSingleton().getViewportHeight());
00305 
00306             mLeft = (Real) mPixelLeft / vpWidth;
00307             mWidth = (Real) mPixelWidth / vpWidth;
00308             mTop = (Real) mPixelTop / vpHeight;
00309             mHeight = (Real) mPixelHeight / vpHeight;
00310             mGeomPositionsOutOfDate = true;
00311         }
00312         _updateFromParent();
00313         // NB container subclasses will update children too
00314 
00315         // Tell self to update own position geometry
00316         if (mGeomPositionsOutOfDate)
00317         {
00318             updatePositionGeometry();
00319             mGeomPositionsOutOfDate = false;
00320         }
00321     }
00322     //---------------------------------------------------------------------
00323     void GuiElement::_updateFromParent(void)
00324     {
00325         Real parentLeft, parentTop, parentBottom, parentRight;
00326 
00327         if (mParent)
00328         {
00329             parentLeft = mParent->_getDerivedLeft();
00330             parentTop = mParent->_getDerivedTop();
00331             if (mHorzAlign == GHA_CENTER || mHorzAlign == GHA_RIGHT)
00332             {
00333                 parentRight = parentLeft + mParent->getWidth();
00334             }
00335             if (mVertAlign == GVA_CENTER || mVertAlign == GVA_BOTTOM)
00336             {
00337                 parentBottom = parentTop + mParent->getHeight();
00338             }
00339 
00340         }
00341         else
00342         {
00343             parentLeft = parentTop = 0.0f;
00344             parentRight = parentBottom = 1.0f;
00345         }
00346 
00347         // Sort out position based on alignment
00348         // NB all we do is derived the origin, we don't automatically sort out the position
00349         // This is more flexible than forcing absolute right & middle 
00350         switch(mHorzAlign)
00351         {
00352         case GHA_CENTER:
00353             mDerivedLeft = ((parentLeft + parentRight) * 0.5f) + mLeft;
00354             break;
00355         case GHA_LEFT:
00356             mDerivedLeft = parentLeft + mLeft;
00357             break;
00358         case GHA_RIGHT:
00359             mDerivedLeft = parentRight + mLeft;
00360             break;
00361         };
00362         switch(mVertAlign)
00363         {
00364         case GVA_CENTER:
00365             mDerivedTop = ((parentTop + parentBottom) * 0.5f) + mTop;
00366             break;
00367         case GVA_TOP:
00368             mDerivedTop = parentTop + mTop;
00369             break;
00370         case GVA_BOTTOM:
00371             mDerivedTop = parentBottom + mTop;
00372             break;
00373         };
00374 
00375         mDerivedOutOfDate = false;
00376 
00377     }
00378     //---------------------------------------------------------------------
00379     void GuiElement::_notifyParent(GuiContainer* parent, Overlay* overlay)
00380     {
00381         mParent = parent;
00382         mOverlay = overlay;
00383 
00384         mDerivedOutOfDate = true;
00385     }
00386     //---------------------------------------------------------------------
00387     Real GuiElement::_getDerivedLeft(void)
00388     {
00389         if (mDerivedOutOfDate)
00390         {
00391             _updateFromParent();
00392         }
00393         return mDerivedLeft;
00394     }
00395     //---------------------------------------------------------------------
00396     Real GuiElement::_getDerivedTop(void)
00397     {
00398         if (mDerivedOutOfDate)
00399         {
00400             _updateFromParent();
00401         }
00402         return mDerivedTop;
00403     }
00404     //---------------------------------------------------------------------
00405     void GuiElement::_notifyZOrder(ushort newZOrder)
00406     {
00407         mZOrder = newZOrder;
00408     }
00409     //---------------------------------------------------------------------
00410     void GuiElement::_updateRenderQueue(RenderQueue* queue)
00411     {
00412         if (mVisible)
00413         {
00414             queue->addRenderable(this, RENDER_QUEUE_OVERLAY, mZOrder);
00415         }
00416       
00417     }
00418     //-----------------------------------------------------------------------
00419     void GuiElement::addBaseParameters(void)    
00420     {
00421         ParamDictionary* dict = getParamDictionary();
00422 
00423         dict->addParameter(ParameterDef("left", 
00424             "The position of the left border of the gui element."
00425             , PT_REAL),
00426             &msLeftCmd);
00427         dict->addParameter(ParameterDef("top", 
00428             "The position of the top border of the gui element."
00429             , PT_REAL),
00430             &msTopCmd);
00431         dict->addParameter(ParameterDef("width", 
00432             "The width of the element."
00433             , PT_REAL),
00434             &msWidthCmd);
00435         dict->addParameter(ParameterDef("height", 
00436             "The height of the element."
00437             , PT_REAL),
00438             &msHeightCmd);
00439         dict->addParameter(ParameterDef("material", 
00440             "The name of the material to use."
00441             , PT_STRING),
00442             &msMaterialCmd);
00443         dict->addParameter(ParameterDef("caption", 
00444             "The element caption, if supported."
00445             , PT_STRING),
00446             &msCaptionCmd);
00447         dict->addParameter(ParameterDef("metrics_mode", 
00448             "The type of metrics to use, either 'relative' to the screen, or 'pixels'."
00449             , PT_STRING),
00450             &msMetricsModeCmd);
00451         dict->addParameter(ParameterDef("horz_align", 
00452             "The horizontal alignment, 'left', 'right' or 'center'."
00453             , PT_STRING),
00454             &msHorizontalAlignCmd);
00455         dict->addParameter(ParameterDef("vert_align", 
00456             "The vertical alignment, 'top', 'bottom' or 'center'."
00457             , PT_STRING),
00458             &msVerticalAlignCmd);
00459         dict->addParameter(ParameterDef("visible", 
00460             "Initial visibility of element, either 'true' or 'false' (default true)."
00461             , PT_STRING),
00462             &msVisibleCmd);
00463     }
00464     //-----------------------------------------------------------------------
00465     void GuiElement::setCaption( const String& caption )
00466     {
00467         mCaption = caption;
00468         _positionsOutOfDate();
00469     }
00470     //-----------------------------------------------------------------------
00471     const String& GuiElement::getCaption() const
00472     {
00473         return mCaption;
00474     }
00475     //-----------------------------------------------------------------------
00476     void GuiElement::setColour(const ColourValue& col)
00477     {
00478         mColour = col;
00479     }
00480     //-----------------------------------------------------------------------
00481     const ColourValue& GuiElement::getColour(void) const
00482     {
00483         return mColour;
00484     }
00485     //-----------------------------------------------------------------------
00486     void GuiElement::setMetricsMode(GuiMetricsMode gmm)
00487     {
00488         mMetricsMode = gmm;
00489         if (mMetricsMode == GMM_PIXELS)
00490         {
00491             // Copy settings into pixel versions
00492             // Relative versions will be derived at viewport change time
00493             mPixelLeft = (short int)mLeft;
00494             mPixelTop = (short int)mTop;
00495             mPixelWidth = (short int)mWidth;
00496             mPixelHeight = (short int)mHeight;
00497         }
00498         mDerivedOutOfDate = true;
00499         _positionsOutOfDate();
00500     }
00501     //-----------------------------------------------------------------------
00502     GuiMetricsMode GuiElement::getMetricsMode(void) const
00503     {
00504         return mMetricsMode;
00505     }
00506     //-----------------------------------------------------------------------
00507     void GuiElement::setHorizontalAlignment(GuiHorizontalAlignment gha)
00508     {
00509         mHorzAlign = gha;
00510         _positionsOutOfDate();
00511     }
00512     //-----------------------------------------------------------------------
00513     GuiHorizontalAlignment GuiElement::getHorizontalAlignment(void) const
00514     {
00515         return mHorzAlign;
00516     }
00517     //-----------------------------------------------------------------------
00518     void GuiElement::setVerticalAlignment(GuiVerticalAlignment gva)
00519     {
00520         mVertAlign = gva;
00521         _positionsOutOfDate();
00522     }
00523     //-----------------------------------------------------------------------
00524     GuiVerticalAlignment GuiElement::getVerticalAlignment(void) const
00525     {
00526         return mVertAlign;
00527     }
00528     //-----------------------------------------------------------------------
00529 
00530 
00531     //-----------------------------------------------------------------------
00532     bool GuiElement::contains(Real x, Real y) const
00533     {
00534     return (x >= mDerivedLeft) && (x < mDerivedLeft + mWidth ) && (y >= mDerivedTop) && (y < mDerivedTop + mHeight );
00535     }
00536 
00537     //-----------------------------------------------------------------------
00538     GuiElement* GuiElement::findElementAt(Real x, Real y)       // relative to parent
00539     {
00540         GuiElement* ret = NULL;
00541         if (contains(x , y ))
00542         {
00543             ret = this;
00544         }
00545         return ret;
00546     }
00547 
00548     //-----------------------------------------------------------------------
00549     void GuiElement::processEvent(InputEvent* e) 
00550     {
00551 
00552         if (!mEnabled || e->isConsumed())
00553         {
00554             return;
00555         }
00556         switch(e->getID()) 
00557         {
00558         case ActionEvent::AE_ACTION_PERFORMED:
00559             processActionEvent(static_cast<ActionEvent*>(e));
00560             break;
00561         case MouseEvent::ME_MOUSE_PRESSED:
00562         case MouseEvent::ME_MOUSE_RELEASED:
00563         case MouseEvent::ME_MOUSE_CLICKED:
00564         case MouseEvent::ME_MOUSE_ENTERED:
00565         case MouseEvent::ME_MOUSE_EXITED:
00566         case MouseEvent::ME_MOUSE_DRAGENTERED:
00567         case MouseEvent::ME_MOUSE_DRAGEXITED:
00568         case MouseEvent::ME_MOUSE_DRAGDROPPED:
00569             processMouseEvent(static_cast<MouseEvent*>(e));
00570             break;
00571         case MouseEvent::ME_MOUSE_MOVED:
00572         case MouseEvent::ME_MOUSE_DRAGGED:
00573         case MouseEvent::ME_MOUSE_DRAGMOVED:
00574             processMouseMotionEvent(static_cast<MouseEvent*>(e));
00575             break;
00576         }
00577     }
00578 
00579     //-----------------------------------------------------------------------
00580     PositionTarget* GuiElement::getPositionTargetParent() 
00581     { 
00582         return static_cast<MouseTarget*> (mParent);     // need to choose 1 parent of the EventTarget
00583     }
00584     //-----------------------------------------------------------------------
00585     GuiContainer* GuiElement::getParent() 
00586     { 
00587         return mParent;     
00588     }
00589 
00590     void GuiElement::copyFromTemplate(GuiElement* templateGui)
00591     {
00592         templateGui->copyParametersTo(this);
00593         return;
00594     }
00595 
00596     //-----------------------------------------------------------------------
00597     bool GuiElement::isEnabled() const
00598     { 
00599         return mEnabled;
00600     }
00601 
00602     //-----------------------------------------------------------------------
00603     void GuiElement::setEnabled(bool b) 
00604     {
00605         mEnabled = b;
00606     }
00607 
00608 
00609 }
00610 

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:13 2004