src/GUIRectangle.cpp

Go to the documentation of this file.
00001 #include "glwx.h"
00002 
00003 GUIRectangle::GUIRectangle(const std::string &callback)
00004 {
00005   setCallbackString(callback);
00006   setDimensions(5, 5);
00007   setPosition(0.5f, 0.5f);
00008 
00009   lastAction =          0;
00010   widgetType = WT_UNKNOWN;
00011   anchor     =  AT_CENTER;
00012   parent     =       NULL;
00013   z          =          1;
00014 
00015   mouseOver  =  false;
00016   released   =  false;
00017   pressed    =  false;
00018   clicked    =  false;
00019   focused    =  false;
00020   visible    =   true;
00021   active     =   true;
00022   update     =  false;
00023 }
00024 
00025 void GUIRectangle::setParent(GUIRectangle *parentArg)
00026 {
00027   parent = parentArg;
00028   update = (parent != NULL);
00029 }
00030 
00031 GUIRectangle *GUIRectangle::getParent()
00032 {
00033   return parent;
00034 }
00035 
00036 int   GUIRectangle::getWidgetType()
00037 { 
00038   return widgetType; 
00039 }
00040 
00041 void  GUIRectangle::forceUpdate(bool updateArg)
00042 {
00043   update = updateArg;
00044 }
00045 
00046 bool GUIRectangle::loadXMLSettings(const TiXmlElement *element)
00047 {
00048   if(!element)
00049     return false;
00050 
00051   const char *cbString = element->Attribute("callbackString");
00052               cbString = cbString ? cbString : element->Attribute("name");
00053 
00054   if(cbString)
00055     setCallbackString(cbString);
00056   else
00057     return Logger::writeErrorLog(std::string("Need a <name> or <callbackString> attribute, check ")
00058                                  + element->Value());
00059 
00060   if(element->Attribute("anchorPoint"))
00061     setAnchorPoint(element->Attribute("anchorPoint"));
00062 
00063   setVisible(XMLArbiter::analyzeBooleanAttr(element, "visible", true));
00064   setActive(XMLArbiter::analyzeBooleanAttr(element,  "active", true));
00065 
00066   for(const TiXmlElement *child = element->FirstChildElement(); 
00067       child;
00068           child = child->NextSiblingElement() )
00069   {
00070     const char * value = child->Value();
00071 
00072     if(value)
00073     {
00074       if(!strcmp(value, "Position"))
00075         setPosition(XMLArbiter::fillComponents2f(child, position));
00076  
00077       if(!strcmp(value, "Dimensions"))
00078         setDimensions(XMLArbiter::fillComponents2f(child, dimensions));
00079     }
00080   }
00081 
00082   return true;
00083 }
00084 
00085 void  GUIRectangle::enableGUITexture()
00086 {
00087   if(parent)
00088     parent->enableGUITexture();
00089 }
00090 
00091 void  GUIRectangle::disableGUITexture()
00092 {
00093   if(parent)
00094     parent->disableGUITexture();
00095 }
00096 
00097 void  GUIRectangle::setCallbackString(const std::string& callback)
00098 {
00099   callbackString = callback;
00100 }
00101 
00102 const std::string & GUIRectangle::getCallbackString()
00103 {
00104   return callbackString;
00105 }  
00106 
00107 void  GUIRectangle::setAnchorPoint(const std::string &anchorArg)
00108 {
00109   if(!anchorArg.size())
00110     return;
00111 
00112   if(anchorArg == "CENTER"  ){ anchor = AT_CENTER;   return; }
00113   if(anchorArg == "CORNERLU"){ anchor = AT_CORNERLU; return; }
00114   if(anchorArg == "CORNERRU"){ anchor = AT_CORNERRU; return; }
00115   if(anchorArg == "CORNERLD"){ anchor = AT_CORNERLD; return; }
00116   if(anchorArg == "CORNERRD"){ anchor = AT_CORNERRD; return; }
00117 }
00118 
00119 void  GUIRectangle::setAnchorPoint(int anchorArg)
00120 {
00121   switch(anchorArg)
00122   {
00123     case AT_CORNERLU:
00124     case AT_CORNERRU:
00125     case AT_CORNERLD:
00126     case AT_CORNERRD:
00127       anchor = anchorArg;
00128     break;
00129     default:
00130       anchor = AT_CENTER;
00131   }
00132   update = true;
00133 }
00134 
00135 int   GUIRectangle::getAnchorPoint()
00136 {
00137   return anchor;
00138 }
00139 
00140 GUITexCoordDescriptor *GUIRectangle::getTexCoordsInfo(int type)
00141 {
00142   return !parent? NULL : parent->getTexCoordsInfo(type);
00143 }
00144 
00145 void GUIRectangle::setDimensions(const Tuple2f &dimensions)
00146 {
00147   setDimensions(dimensions.x, dimensions.y);
00148 }
00149 
00150 void GUIRectangle::setDimensions(float width, float height)
00151 {
00152   dimensions.set(clamp(width , 0.01f, 2048.0f),
00153                  clamp(height, 0.01f, 2048.0f));
00154   update = true;
00155 }
00156 
00157 const Tuple2f &GUIRectangle::getDimensions()
00158 {
00159   return  dimensions;
00160 }
00161 
00162 void GUIRectangle::setPosition(const Tuple2f &scales)
00163 {
00164   setPosition(scales.x, scales.y);
00165 }
00166 
00167 void GUIRectangle::setPosition(float xScale, float yScale)
00168 {
00169   position.set(xScale, yScale);
00170   update = true;
00171 }
00172 
00173 const Tuple2f &GUIRectangle::getPosition()
00174 {
00175   return position;
00176 }
00177 
00178 void GUIRectangle::setActive(bool activeArg)
00179 {
00180   active = activeArg;
00181 }
00182 
00183 bool GUIRectangle::isActive()
00184 {
00185   return active;
00186 }
00187 
00188 void GUIRectangle::setVisible(bool visibleArg)
00189 {
00190   visible = visibleArg;
00191 }
00192 
00193 bool  GUIRectangle::isVisible()
00194 {
00195   return visible;
00196 }
00197 
00198 bool  GUIRectangle::isAttached()
00199 {
00200   return (parent != NULL);
00201 }
00202 
00203 int GUIRectangle::getWidth()
00204 {
00205   return windowBounds.z - windowBounds.x;
00206 }
00207 
00208 int GUIRectangle::getHeight()
00209 {
00210   return windowBounds.w - windowBounds.y;
00211 }
00212 
00213 const Tuple4i &GUIRectangle::getWindowBounds()
00214 {
00215   computeWindowBounds();
00216   return windowBounds;
00217 }
00218 
00219 const void GUIRectangle::computeWindowBounds()
00220 {
00221   if(parent && update)
00222   {
00223     const Tuple4i &parentBounds = parent->getWindowBounds();
00224     z  = parent->getZCoordinate() + 1;
00225     Tuple2f newDimensions,
00226             newPosition;
00227  
00228     newDimensions.x  = float(parentBounds.z - parentBounds.x);
00229     newDimensions.y  = float(parentBounds.w - parentBounds.y);
00230 
00231     newPosition.x    = float(parentBounds.x);
00232     newPosition.y    = float(parentBounds.y);
00233 
00234     newPosition.x    = (position.x <= 1.0f) && (position.x >= 0.0f) ? 
00235                         newDimensions.x*position.x + parentBounds.x :
00236                        (position.x < 0.0f) ?
00237                         parentBounds.z + position.x    :
00238                         position.x     + parentBounds.x;
00239 
00240     newPosition.y    = (position.y <= 1.0f) && (position.y >= 0.0f) ? 
00241                         newDimensions.y*position.y + parentBounds.y :
00242                        (position.y < 0.0f) ?
00243                         parentBounds.w + position.y    :
00244                         position.y     + parentBounds.y;
00245 
00246     newDimensions.x  = (dimensions.x <= 1.0f) ? newDimensions.x*dimensions.x :
00247                                                 dimensions.x;
00248     newDimensions.y  = (dimensions.y <= 1.0f) ? newDimensions.y*dimensions.y :
00249                                                 dimensions.y;
00250 
00251     windowBounds.x = int(newPosition.x);
00252     windowBounds.y = int(newPosition.y);
00253     windowBounds.z = int(newPosition.x + newDimensions.x);
00254     windowBounds.w = int(newPosition.y + newDimensions.y);
00255 
00256     switch(anchor)
00257     {
00258       case AT_CORNERLD:
00259         windowBounds.y -= int(newDimensions.y);
00260         windowBounds.w -= int(newDimensions.y);
00261       break;
00262 
00263       case AT_CORNERRU:
00264         windowBounds.x -= int(newDimensions.x);
00265         windowBounds.z -= int(newDimensions.x);
00266       break;
00267 
00268       case AT_CORNERRD:
00269         windowBounds.y -= int(newDimensions.y);
00270         windowBounds.w -= int(newDimensions.y);
00271         windowBounds.x -= int(newDimensions.x);
00272         windowBounds.z -= int(newDimensions.x);
00273       break;
00274 
00275       case AT_CENTER:
00276         newDimensions /= 2;
00277 
00278         windowBounds.y -= int(newDimensions.y);
00279         windowBounds.w -= int(newDimensions.y);
00280         windowBounds.x -= int(newDimensions.x);
00281         windowBounds.z -= int(newDimensions.x);
00282       break;
00283     }
00284   }
00285 }
00286 
00287 GUIEventListener *GUIRectangle::getEventsListener()
00288 {
00289   return !parent ? NULL : parent->getEventsListener();
00290 }
00291 
00292 void GUIRectangle::checkKeyboardEvents(KeyEvent &evt, int extraInfo){}
00293 void GUIRectangle::checkMouseEvents(MouseEvent &newEvent, int extraInfo, bool bits)
00294 {
00295   GUIEventListener *eventsListener = getEventsListener();
00296   bool              nRelease = pressed;
00297 
00298   mouseOver  = (newEvent.getY() >= windowBounds.y) &&
00299                (newEvent.getY() <= windowBounds.w) &&
00300                (newEvent.getX() >= windowBounds.x) &&
00301                (newEvent.getX() <= windowBounds.z);
00302 
00303 
00304   if(!mouseOver)
00305   {
00306     pressed = (extraInfo == ME_RELEASED) ? false : pressed;
00307     if(extraInfo == ME_PRESSED || extraInfo == ME_RELEASED)  focused = false;
00308     return;
00309   }
00310 
00311   if(extraInfo == ME_RELEASED && (lastAction == ME_CLICKED|| pressed))
00312   {
00313     clicked = true;
00314     pressed = false;
00315   }
00316 
00317   if(clicked) 
00318     focused = true;
00319 
00320   if(extraInfo == ME_CLICKED)
00321     pressed = true;
00322 
00323   lastAction = extraInfo;
00324   released   = !pressed && nRelease;
00325 
00326   if(eventsListener && eventDetected()){
00327 
00328         // If the widget is not a panel type,
00329         // and it uses the mouse event, set the
00330         // used flag to alert interested observers.
00331         // The reason I exclude panel type is because
00332         // the root panel usually covers the entire render
00333         // window, so this would trigger the use flag
00334         // for almost any interaction.
00335         if (this->getWidgetType() != WT_PANEL
00336                 && (eventDetected() == clicked
00337                         || eventDetected() == pressed))
00338                 newEvent.setUsed(true);
00339 
00340     GUIEvent event = GUIEvent(this);
00341     eventsListener->actionPerformed(event);
00342   }
00343 
00344   if(!bits)
00345   {
00346     released = false;
00347     clicked  = false;
00348   }
00349 }
00350 
00351 bool GUIRectangle::eventDetected(){ return mouseOver ||
00352                                            released  ||
00353                                            focused   ||
00354                                            pressed   ||
00355                                            clicked;   }
00356 
00357 bool GUIRectangle::isMouseOver()  { return mouseOver; }
00358 bool GUIRectangle::isReleased()   { return released;  }
00359 bool GUIRectangle::isFocused()    { return focused;   }
00360 bool GUIRectangle::isPressed()    { return pressed;   }
00361 bool GUIRectangle::isClicked()    { return clicked;   }
00362 
00363 void GUIRectangle::setZCoordinate(int zArg)
00364 {
00365   z = clamp(zArg, 0, 65553);
00366 }
00367 
00368 int    GUIRectangle::getZCoordinate()
00369 {
00370   return z;
00371 }
00372 
00373 Tuple2i  GUIRectangle::getCenter()
00374 {
00375   getWindowBounds();
00376   return Tuple2i((windowBounds.x + windowBounds.z)/2,
00377                  (windowBounds.y + windowBounds.w)/2);
00378 }

Generated on Wed Dec 5 20:32:03 2007 for GLWX by  doxygen 1.5.3