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 }