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
00329
00330
00331
00332
00333
00334
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 }