Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

slider.cpp

00001 /*      _______   __   __   __   ______   __   __   _______   __   __                 
00002  *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\                
00003  *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /                 
00004  *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /                  
00005  *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /                   
00006  * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /                    
00007  * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/                      
00008  *
00009  * Copyright (c) 2004, 2005 darkbits                        Js_./
00010  * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
00011  * Olof Naessén a.k.a jansem/yakslem                _asww7!uY`>  )\a//
00012  *                                                 _Qhm`] _f "'c  1!5m
00013  * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
00014  *                                               .)j(] .d_/ '-(  P .   S
00015  * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
00016  * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
00017  * binary forms, with or without                 )4d[#7r, .   '     )d`)[
00018  * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
00019  * that the following conditions are met:       j<<WP+k/);.        _W=j f
00020  * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
00021  *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
00022  *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
00023  *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
00024  * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
00025  *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
00026  *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
00027  *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
00028  *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
00029  *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
00030  * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
00031  *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
00032  *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
00033  *    from this software without specific        (js, \[QQW$QWW#?!V"".
00034  *    prior written permission.                    ]y:.<\..          .
00035  *                                                 -]n w/ '         [.
00036  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
00037  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
00038  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
00039  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
00040  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
00041  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
00042  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
00043  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
00044  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
00045  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
00046  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
00047  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
00048  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00049  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00050  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00051  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00052  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00053  */
00054 
00055 /*
00056  * For comments regarding functions please see the header file. 
00057  */
00058 
00059 #include "guichan/widgets/slider.hpp"
00060 #include "guichan/mouseinput.hpp"
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         }
00260     }
00261     
00262     void Slider::setValue(double value)
00263     {
00264         if (value > getScaleEnd())
00265         {
00266             mValue = getScaleEnd();
00267             return;
00268         }
00269 
00270         if (value < getScaleStart())
00271         {
00272             mValue = getScaleStart();
00273             return;
00274         }
00275 
00276         mValue = value;
00277     }
00278     
00279     double Slider::getValue() const
00280     {
00281         return mValue;
00282     }
00283 
00284     int Slider::getMarkerLength() const
00285     {
00286         return mMarkerLength;
00287     }
00288 
00289     void Slider::setMarkerLength(int length)
00290     {
00291         mMarkerLength = length;
00292     }
00293 
00294     void Slider::keyPress(const Key& key)
00295     {
00296         if (getOrientation() == HORIZONTAL)
00297         {
00298             if (key.getValue() == Key::RIGHT)
00299             {
00300                 setValue(getValue() + getStepLength());
00301                 generateAction();
00302             }
00303             else if (key.getValue() == Key::LEFT)
00304             {
00305                 setValue(getValue() - getStepLength());
00306                 generateAction();
00307             }
00308         }
00309         else
00310         {
00311             if (key.getValue() == Key::UP)
00312             {
00313                 setValue(getValue() + getStepLength());
00314                 generateAction();
00315             }
00316             else if (key.getValue() == Key::DOWN)
00317             {
00318                 setValue(getValue() - getStepLength());
00319                 generateAction();
00320             }
00321         }
00322     }
00323 
00324     void Slider::setOrientation(unsigned int orientation)
00325     {
00326         mOrientation = orientation;    
00327     }
00328 
00329     unsigned int Slider::getOrientation() const
00330     {
00331         return mOrientation;
00332     }
00333 
00334     double Slider::markerPositionToValue(int v) const
00335     {
00336         int w;
00337         if (getOrientation() == HORIZONTAL)
00338         {
00339             w = getWidth();
00340         }
00341         else
00342         {
00343             w = getHeight();
00344         }
00345     
00346         double pos = v / ((double)w - getMarkerLength());
00347         return (1.0 - pos) * getScaleStart() + pos * getScaleEnd();
00348     
00349     }
00350   
00351     int Slider::valueToMarkerPosition(double value) const
00352     {
00353         int v;
00354         if (getOrientation() == HORIZONTAL)
00355         {
00356             v = getWidth();
00357         }
00358         else
00359         {
00360             v = getHeight();
00361         }
00362 
00363         int w =  (int)((v - getMarkerLength())
00364                        * (value  - getScaleStart())
00365                        / (getScaleEnd() - getScaleStart()));
00366     
00367         if (w < 0)
00368         {
00369             return 0;
00370         }
00371       
00372         if (w > v - getMarkerLength())
00373         {
00374             return v - getMarkerLength();
00375         }
00376       
00377         return w;
00378     }
00379 
00380     void Slider::setStepLength(double length)
00381     {
00382         mStepLength = length;
00383     }
00384 
00385     double Slider::getStepLength() const
00386     {
00387         return mStepLength;
00388     }
00389 
00390     int Slider::getMarkerPosition() const
00391     {
00392         return valueToMarkerPosition(getValue());
00393     }    
00394 }

Generated on Tue May 17 21:23:26 2005 for Guichan by  doxygen 1.4.1