00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include "guichan/widgets/slider.h"
00060 #include "guichan/mouseinput.h"
00061
00062 namespace gcn
00063 {
00064 Slider::Slider(double scaleEnd)
00065 {
00066 mMouseDrag = false;
00067
00068
00069 mScaleStart = 0;
00070 mScaleEnd = scaleEnd;
00071
00072 setFocusable(true);
00073 setBorderSize(1);
00074 setOrientation(HORIZONTAL);
00075 setValue(0);
00076 setStepLength(scaleEnd / 10);
00077 setMarkerLength(10);
00078
00079 addMouseListener(this);
00080 addKeyListener(this);
00081 }
00082
00083 Slider::Slider(double scaleStart, double scaleEnd)
00084 {
00085 mMouseDrag = false;
00086
00087 mScaleStart = scaleStart;
00088 mScaleEnd = scaleEnd;
00089
00090 setFocusable(true);
00091 setBorderSize(1);
00092 setOrientation(HORIZONTAL);
00093 setValue(scaleStart);
00094 setStepLength((scaleEnd - scaleStart)/ 10);
00095 setMarkerLength(10);
00096
00097 addMouseListener(this);
00098 addKeyListener(this);
00099 }
00100
00101 void Slider::setScale(double scaleStart, double scaleEnd)
00102 {
00103 mScaleStart = scaleStart;
00104 mScaleEnd = scaleEnd;
00105 }
00106
00107 double Slider::getScaleStart() const
00108 {
00109 return mScaleStart;
00110 }
00111
00112 void Slider::setScaleStart(double scaleStart)
00113 {
00114 mScaleStart = scaleStart;
00115 }
00116
00117 double Slider::getScaleEnd() const
00118 {
00119 return mScaleEnd;
00120 }
00121
00122 void Slider::setScaleEnd(double scaleEnd)
00123 {
00124 mScaleEnd = scaleEnd;
00125 }
00126
00127 void Slider::draw(gcn::Graphics* graphics)
00128 {
00129 Color shadowColor = getBaseColor() - 0x101010;
00130 int alpha = getBaseColor().a;
00131 shadowColor.a = alpha;
00132
00133 graphics->setColor(shadowColor);
00134 graphics->fillRectangle(gcn::Rectangle(0,0,getWidth(),getHeight()));
00135
00136 drawMarker(graphics);
00137 }
00138
00139 void Slider::drawBorder(gcn::Graphics* graphics)
00140 {
00141 Color faceColor = getBaseColor();
00142 Color highlightColor, shadowColor;
00143 int alpha = getBaseColor().a;
00144 int width = getWidth() + getBorderSize() * 2 - 1;
00145 int height = getHeight() + getBorderSize() * 2 - 1;
00146 highlightColor = faceColor + 0x303030;
00147 highlightColor.a = alpha;
00148 shadowColor = faceColor - 0x303030;
00149 shadowColor.a = alpha;
00150
00151 unsigned int i;
00152 for (i = 0; i < getBorderSize(); ++i)
00153 {
00154 graphics->setColor(shadowColor);
00155 graphics->drawLine(i,i, width - i, i);
00156 graphics->drawLine(i,i + 1, i, height - i - 1);
00157 graphics->setColor(highlightColor);
00158 graphics->drawLine(width - i,i + 1, width - i, height - i);
00159 graphics->drawLine(i,height - i, width - i - 1, height - i);
00160 }
00161 }
00162
00163 void Slider::drawMarker(gcn::Graphics* graphics)
00164 {
00165 gcn::Color faceColor = getBaseColor();
00166 Color highlightColor, shadowColor;
00167 int alpha = getBaseColor().a;
00168 highlightColor = faceColor + 0x303030;
00169 highlightColor.a = alpha;
00170 shadowColor = faceColor - 0x303030;
00171 shadowColor.a = alpha;
00172
00173 graphics->setColor(faceColor);
00174
00175 if (getOrientation() == HORIZONTAL)
00176 {
00177 int v = getMarkerPosition();
00178 graphics->fillRectangle(gcn::Rectangle(v + 1, 1, getMarkerLength() - 2, getHeight() - 2));
00179 graphics->setColor(highlightColor);
00180 graphics->drawLine(v, 0, v + getMarkerLength() - 1,0);
00181 graphics->drawLine(v, 0, v, getHeight() - 1);
00182 graphics->setColor(shadowColor);
00183 graphics->drawLine(v + getMarkerLength() - 1, 1, v + getMarkerLength() - 1, getHeight() - 1);
00184 graphics->drawLine(v + 1, getHeight() - 1, v + getMarkerLength() - 1, getHeight() - 1);
00185
00186 if (hasFocus())
00187 {
00188 graphics->setColor(getForegroundColor());
00189 graphics->drawRectangle(Rectangle(v + 2, 2, getMarkerLength() - 4, getHeight() - 4));
00190 }
00191 }
00192 else
00193 {
00194 int v = (getHeight() - getMarkerLength()) - getMarkerPosition();
00195 graphics->fillRectangle(gcn::Rectangle(1, v + 1, getWidth() - 2, getMarkerLength() - 2));
00196 graphics->setColor(highlightColor);
00197 graphics->drawLine(0, v, 0, v + getMarkerLength() - 1);
00198 graphics->drawLine(0, v, getWidth() - 1, v);
00199 graphics->setColor(shadowColor);
00200 graphics->drawLine(1, v + getMarkerLength() - 1, getWidth() - 1, v + getMarkerLength() - 1);
00201 graphics->drawLine(getWidth() - 1, v + 1, getWidth() - 1, v + getMarkerLength() - 1);
00202
00203 if (hasFocus())
00204 {
00205 graphics->setColor(getForegroundColor());
00206 graphics->drawRectangle(Rectangle(2, v + 2, getWidth() - 4, getMarkerLength() - 4));
00207 }
00208 }
00209 }
00210
00211 void Slider::mousePress(int x, int y, int button)
00212 {
00213 if (button == gcn::MouseInput::LEFT
00214 && x >= 0 && x <= getWidth()
00215 && y >= 0 && y <= getHeight())
00216 {
00217 if (getOrientation() == HORIZONTAL)
00218 {
00219 setValue(markerPositionToValue(x - getMarkerLength() / 2));
00220 }
00221 else
00222 {
00223 setValue(markerPositionToValue(getHeight() - y - getMarkerLength() / 2));
00224 }
00225
00226 mMouseDrag = true;
00227 generateAction();
00228 }
00229 else
00230 {
00231 mMouseDrag = false;
00232 }
00233 }
00234
00235 void Slider::mouseRelease(int x, int y, int button)
00236 {
00237 mMouseDrag = false;
00238 }
00239
00240 void Slider::lostFocus()
00241 {
00242 mMouseDrag = false;
00243 }
00244
00245 void Slider::mouseMotion(int x, int y)
00246 {
00247 if (mMouseDrag)
00248 {
00249 if (getOrientation() == HORIZONTAL)
00250 {
00251 setValue(markerPositionToValue(x - getMarkerLength() / 2));
00252 }
00253 else
00254 {
00255 setValue(markerPositionToValue(getHeight() - y - getMarkerLength() / 2));
00256 }
00257
00258 generateAction();
00259 setDirty(true);
00260 }
00261 }
00262
00263 void Slider::setValue(double value)
00264 {
00265 if (value > getScaleEnd())
00266 {
00267 mValue = getScaleEnd();
00268 return;
00269 }
00270
00271 if (value < getScaleStart())
00272 {
00273 mValue = getScaleStart();
00274 return;
00275 }
00276
00277 mValue = value;
00278 }
00279
00280 double Slider::getValue() const
00281 {
00282 return mValue;
00283 }
00284
00285 int Slider::getMarkerLength() const
00286 {
00287 return mMarkerLength;
00288 }
00289
00290 void Slider::setMarkerLength(int length)
00291 {
00292 mMarkerLength = length;
00293 }
00294
00295 bool Slider::keyPress(const Key& key)
00296 {
00297 bool ret = false;
00298
00299 if (getOrientation() == HORIZONTAL)
00300 {
00301 if (key.getValue() == Key::RIGHT)
00302 {
00303 setValue(getValue() + getStepLength());
00304 generateAction();
00305 ret = true;
00306 }
00307 else if (key.getValue() == Key::LEFT)
00308 {
00309 setValue(getValue() - getStepLength());
00310 generateAction();
00311 ret = true;
00312 }
00313 }
00314 else
00315 {
00316 if (key.getValue() == Key::UP)
00317 {
00318 setValue(getValue() + getStepLength());
00319 generateAction();
00320 ret = true;
00321 }
00322 else if (key.getValue() == Key::DOWN)
00323 {
00324 setValue(getValue() - getStepLength());
00325 generateAction();
00326 ret = true;
00327 }
00328 }
00329 return ret;
00330 }
00331
00332 void Slider::setOrientation(unsigned int orientation)
00333 {
00334 mOrientation = orientation;
00335 }
00336
00337 unsigned int Slider::getOrientation() const
00338 {
00339 return mOrientation;
00340 }
00341
00342 double Slider::markerPositionToValue(int v) const
00343 {
00344 int w;
00345 if (getOrientation() == HORIZONTAL)
00346 {
00347 w = getWidth();
00348 }
00349 else
00350 {
00351 w = getHeight();
00352 }
00353
00354 double pos = v / ((double)w - getMarkerLength());
00355 return (1.0 - pos) * getScaleStart() + pos * getScaleEnd();
00356
00357 }
00358
00359 int Slider::valueToMarkerPosition(double value) const
00360 {
00361 int v;
00362 if (getOrientation() == HORIZONTAL)
00363 {
00364 v = getWidth();
00365 }
00366 else
00367 {
00368 v = getHeight();
00369 }
00370
00371 int w = (int)((v - getMarkerLength())
00372 * (value - getScaleStart())
00373 / (getScaleEnd() - getScaleStart()));
00374
00375 if (w < 0)
00376 {
00377 return 0;
00378 }
00379
00380 if (w > v - getMarkerLength())
00381 {
00382 return v - getMarkerLength();
00383 }
00384
00385 return w;
00386 }
00387
00388 void Slider::setStepLength(double length)
00389 {
00390 mStepLength = length;
00391 }
00392
00393 double Slider::getStepLength() const
00394 {
00395 return mStepLength;
00396 }
00397
00398 int Slider::getMarkerPosition() const
00399 {
00400 return valueToMarkerPosition(getValue());
00401 }
00402 }