00001 #include "glwx.h"
00002
00003 GUISlider::GUISlider(const std::string &callback, const int orientation_) : GUIAlphaElement(callback)
00004 {
00005 setDiscDimensions(18, 18);
00006 setProgress(0.0);
00007 orientation = orientation_ == OR_VERTICAL ? OR_VERTICAL : OR_HORIZONTAL;
00008 widgetType = WT_SLIDER ;
00009 offset = 0;
00010
00011 setDimensions((orientation_ == OR_VERTICAL) ? 18.0f : 100.0f,
00012 (orientation_ == OR_VERTICAL) ? 85.0f : 18.0f);
00013 }
00014
00015 bool GUISlider::loadXMLSettings(const TiXmlElement *element)
00016 {
00017 if(!XMLArbiter::inspectElementInfo(element, "Slider"))
00018 return Logger::writeErrorLog("Need a Slider node in the xml file");
00019
00020 const char * orient = element->Attribute("orientation");
00021
00022 orientation = (orient && !strcmp(orient, "VERTICAL")) ? OR_VERTICAL : OR_HORIZONTAL;
00023
00024 setDiscDimensions(XMLArbiter::fillComponents1i(element, "discWidth", discDimensions.x),
00025 XMLArbiter::fillComponents1i(element, "discHeight", discDimensions.y));
00026 setProgress(XMLArbiter::fillComponents1f(element, "progress", progress));
00027 setDimensions((orientation == OR_VERTICAL) ? 18.0f : 100.0f,
00028 (orientation == OR_VERTICAL) ? 85.0f : 18.0f);
00029 return GUIAlphaElement::loadXMLSettings(element);
00030 }
00031
00032 void GUISlider::setDiscDimensions(const Tuple2i& dimensions)
00033 {
00034 setDiscDimensions(dimensions.x, dimensions.y);
00035 }
00036
00037 void GUISlider::setDiscDimensions(int width, int height)
00038 {
00039 discDimensions.set(clamp(width, 5, 500), clamp(height, 5, 500));
00040 setDimensions((orientation == OR_HORIZONTAL) ? dimensions.x : float(discDimensions.x),
00041 (orientation == OR_HORIZONTAL) ? float(discDimensions.y) : dimensions.y);
00042 }
00043
00044 const Tuple2i &GUISlider::getDiscDimensions()
00045 {
00046 return discDimensions;
00047 }
00048
00049 void GUISlider::setProgress(float zeroToOne)
00050 {
00051 if(!pressed)
00052 progress = clamp(zeroToOne, 0.0f, 1.0f);
00053 }
00054
00055 float GUISlider::getProgress()
00056 {
00057 return progress;
00058 }
00059
00060 void GUISlider::render(float clockTick)
00061 {
00062 if(!parent || !visible)
00063 return;
00064
00065 modifyCurrentAlpha(clockTick);
00066
00067 if(orientation == OR_VERTICAL)
00068 {
00069 renderVertical();
00070 return;
00071 }
00072
00073 GUITexCoordDescriptor *descriptor = parent->getTexCoordsInfo(WT_SLIDER );
00074 Tuple2i discXBounds,
00075 center = getCenter();
00076
00077
00078 discXBounds.x = windowBounds.x;
00079 discXBounds.x += int(float(windowBounds.z - windowBounds.x)*progress);
00080 discXBounds.x -= discDimensions.x/2;
00081 discXBounds.y = discXBounds.x + discDimensions.x;
00082
00083 glTranslatef(float(offset), 0, 0);
00084 glEnable(GL_BLEND);
00085 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00086 glColor4fv(color);
00087
00088 glBegin(GL_TRIANGLE_STRIP);
00089 glVertex2i(windowBounds.x, center.y - 1);
00090 glVertex2i(windowBounds.x, center.y + 1);
00091 glVertex2i(windowBounds.z, center.y - 1);
00092 glVertex2i(windowBounds.z, center.y + 1);
00093 glEnd();
00094
00095 if(descriptor)
00096 {
00097 const Tuple4f &texCoords = descriptor->getTexCoords();
00098 parent->enableGUITexture();
00099
00100 glBegin(GL_TRIANGLE_STRIP);
00101 glTexCoord2f(texCoords.x, texCoords.y);
00102 glVertex2i(discXBounds.x, windowBounds.y);
00103
00104 glTexCoord2f(texCoords.x, texCoords.w);
00105 glVertex2i(discXBounds.x, windowBounds.w);
00106
00107 glTexCoord2f(texCoords.z, texCoords.y);
00108 glVertex2i(discXBounds.y, windowBounds.y);
00109
00110 glTexCoord2f(texCoords.z, texCoords.w);
00111 glVertex2i(discXBounds.y, windowBounds.w);
00112 glEnd();
00113
00114 parent->disableGUITexture();
00115 }
00116 else
00117 {
00118 glBegin(GL_TRIANGLE_STRIP);
00119 glVertex2i(discXBounds.x, windowBounds.y);
00120 glVertex2i(discXBounds.x, windowBounds.w);
00121 glVertex2i(discXBounds.y, windowBounds.y);
00122 glVertex2i(discXBounds.y, windowBounds.w);
00123 glEnd();
00124 }
00125 glDisable(GL_BLEND);
00126 glTranslatef(float(-offset), 0, 0);
00127 label.printCenteredX(center.x + offset, windowBounds.w);
00128 }
00129
00130 void GUISlider::renderVertical()
00131 {
00132 GUITexCoordDescriptor *descriptor = parent->getTexCoordsInfo(WT_SLIDER );
00133 Tuple2i discYBounds,
00134 center = getCenter();
00135
00136 discYBounds.x = windowBounds.w;
00137 discYBounds.x -= int(float(getHeight())*progress);
00138 discYBounds.x -= discDimensions.y/2;
00139 discYBounds.y = discYBounds.x + discDimensions.y;
00140
00141 glEnable(GL_BLEND);
00142 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00143 glColor4fv(color);
00144
00145 glTranslatef(0, float(+offset), 0);
00146
00147 glBegin(GL_TRIANGLE_STRIP);
00148 glVertex2i(center.x - 1, windowBounds.y );
00149 glVertex2i(center.x - 1, windowBounds.w);
00150 glVertex2i(center.x + 1, windowBounds.y);
00151 glVertex2i(center.x + 1, windowBounds.w);
00152 glEnd();
00153
00154 if(descriptor)
00155 {
00156 const Tuple4f &texCoords = descriptor->getTexCoords();
00157 parent->enableGUITexture();
00158
00159 glBegin(GL_TRIANGLE_STRIP);
00160 glTexCoord2f(texCoords.x, texCoords.y);
00161 glVertex2i(windowBounds.x, discYBounds.x);
00162
00163 glTexCoord2f(texCoords.x, texCoords.w);
00164 glVertex2i(windowBounds.x, discYBounds.y);
00165
00166 glTexCoord2f(texCoords.z, texCoords.y);
00167 glVertex2i(windowBounds.z, discYBounds.x);
00168
00169 glTexCoord2f(texCoords.z, texCoords.w);
00170 glVertex2i(windowBounds.z, discYBounds.y);
00171 glEnd();
00172
00173 parent->disableGUITexture();
00174 }
00175 else
00176 {
00177 glBegin(GL_TRIANGLE_STRIP);
00178 glVertex2i(windowBounds.x, discYBounds.x);
00179 glVertex2i(windowBounds.x, discYBounds.y);
00180 glVertex2i(windowBounds.z, discYBounds.x);
00181 glVertex2i(windowBounds.z, discYBounds.y);
00182 glEnd();
00183 }
00184 glDisable(GL_BLEND);
00185 glTranslatef(0, float(-offset), 0);
00186 }
00187
00188 const Tuple4i &GUISlider::getWindowBounds()
00189 {
00190 if(parent && update)
00191 {
00192 GUIRectangle::computeWindowBounds();
00193 label.computeDimensions();
00194 realWindowBounds = windowBounds;
00195
00196 if(orientation == OR_HORIZONTAL)
00197 {
00198 int difference = label.getWidth() - getWidth();
00199
00200 realWindowBounds.x -= discDimensions.x/2;
00201 realWindowBounds.z += discDimensions.x/2;
00202
00203 if(difference > 0)
00204 {
00205 difference /= 2;
00206 realWindowBounds.x -= difference;
00207 realWindowBounds.z += difference;
00208 }
00209
00210 realWindowBounds.w += int(label.getHeight()/1.25f);
00211 offset = clamp(windowBounds.x - realWindowBounds.x, 0, 500);
00212 }
00213 else
00214 {
00215 offset = discDimensions.y/2;
00216 realWindowBounds.y -= discDimensions.y/2;
00217 realWindowBounds.w += discDimensions.y/2;
00218 }
00219 }
00220 return realWindowBounds;
00221 }
00222
00223 void GUISlider::checkMouseEvents(MouseEvent &evt, int extraInfo, bool reservedBits)
00224 {
00225 GUIEventListener *eventsListener = getEventsListener();
00226 bool nRelease = pressed;
00227
00228 windowBounds.x += (orientation == OR_HORIZONTAL) ? offset : 0;
00229 windowBounds.y += (orientation != OR_HORIZONTAL) ? offset : 0;
00230 windowBounds.z += (orientation == OR_HORIZONTAL) ? offset : 0;
00231 windowBounds.w += (orientation != OR_HORIZONTAL) ? offset : 0;
00232
00233 GUIRectangle::checkMouseEvents(evt, extraInfo, reservedBits);
00234
00235 released = !pressed && nRelease;
00236
00237 if(pressed || released)
00238 {
00239 progress = (orientation == OR_HORIZONTAL) ?
00240 clamp(float(evt.getX() - windowBounds.x)/ (windowBounds.z - windowBounds.x), 0.0f, 1.0f) :
00241 clamp(1.0f - float(evt.getY() - windowBounds.y)/ (windowBounds.w - windowBounds.y), 0.0f, 1.0f);
00242
00243 if(eventsListener){
00244 GUIEvent event = GUIEvent(this);
00245 eventsListener->actionPerformed(event);
00246 }
00247 }
00248
00249 windowBounds.x -= (orientation == OR_HORIZONTAL) ? offset : 0;
00250 windowBounds.y -= (orientation != OR_HORIZONTAL) ? offset : 0;
00251 windowBounds.z -= (orientation == OR_HORIZONTAL) ? offset : 0;
00252 windowBounds.w -= (orientation != OR_HORIZONTAL) ? offset : 0;
00253 }