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