00001 #ifndef OglGui_SpinWheel_h
00002 #define OglGui_SpinWheel_h
00003
00004
00005 #include "OglGui/RepeatTimer.h"
00006 #include "OglGui/Window.h"
00007 #include "OglGui/SpinWheelListener.h"
00008
00009 namespace OglGui
00010 {
00011
00012 class SpinWheel : public Window, RepeatTimer
00013 {
00014 public:
00015
00016 SpinWheel(Window* parent, int x, int y, int w, int h,
00017 int minVal, int maxVal, int val) :
00018 Window(parent, x, y, w, h)
00019 {
00020 Init(true, minVal, maxVal, val);
00021 }
00022
00023 SpinWheel(Window* parent, int w, int h, int minVal, int maxVal, int val) :
00024 Window(parent, w, h)
00025 {
00026 Init(true, minVal, maxVal, val);
00027 }
00028
00029 SpinWheel(Window* parent, int x, int y, int w, int h,
00030 float minVal, float maxVal, float val) :
00031 Window(parent, x, y, w, h)
00032 {
00033 Init(false, minVal, maxVal, val);
00034 }
00035
00036 SpinWheel(Window* parent, int w, int h,
00037 float minVal, float maxVal, float val) :
00038 Window(parent, w, h)
00039 {
00040 Init(false, minVal, maxVal, val);
00041 }
00042
00043 void SetSpinWheelListener(SpinWheelListener* l, void* userData=0)
00044 {
00045 mSpinWheelListener = l;
00046 mSpinWheelListenerData = userData;
00047 }
00048 void SetSpinWheelListener(SpinWheelListener* l, int userData)
00049 {
00050 SetSpinWheelListener(l, (void*) userData);
00051 }
00052
00053 void CenterValStr(int dX, int dY) const
00054 {
00055 char buf[25];
00056 int rX, rY;
00057 int w, h, state = GetState();
00058
00059 if (mAsInt && mShowAsPercentage)
00060 sprintf(buf, "%.2f", mVal / 100.0f);
00061 else if (mAsInt)
00062 sprintf(buf, "%d", (int) mVal);
00063 else
00064 sprintf(buf, "%.2f", mVal);
00065
00066 oglSys.GetTextExtent(mOglWnd, buf, &w, &h);
00067 oglSys.StartOrtho(mOglWnd);
00068
00069 rX = mOglWnd->width/2 - w/2 + dX;
00070 rY = mOglWnd->height/2 - h/2 + dY;
00071
00072 SetSolidFillColor(oglLIGHTGREY | (state==2 ? mStateFeedbackColor : 0));
00073 FillRoundRectExt(rX-4, rY-1, w+8, h+1, 6, 6, 6, 6);
00074 DrawBevRoundRectExt(BEV_SUNKEN, rX-4, rY-1, w+8, h+1, 6, 6, 6, 6);
00075
00076 oglSys.ShadowPrintf(mOglWnd, rX, rY+1, state ? oglLIGHTGREY : oglGREY,
00077 state ? oglBLACK : oglLIGHTGREY, buf);
00078 oglSys.EndOrtho();
00079 }
00080
00081 virtual void DrawWheel()
00082 {
00083 int start = - abs((int)(3*mVal)) % mOglWnd->height;
00084 int n = 0, lDist = mLineDistance;
00085
00086 for(int i = start; i < mOglWnd->height; i += lDist){
00087 n++;
00088 if (i < 0) continue;
00089 SetSolidLineColor(mDrawLineEtched ? oglWHITE : oglBLACK);
00090 DrawLine(0, i, mOglWnd->width, i);
00091 SetSolidLineColor(mDrawLineEtched ? oglBLACK : oglWHITE);
00092 DrawLine(0, i+1, mOglWnd->width, i+1);
00093
00094 if (mLineDistance > 7 && !(n % 5)){
00095 SetSolidLineColor(oglBLUE);
00096 DrawLine(0, i+lDist/2, mOglWnd->width, i+lDist/2);
00097 }
00098 }
00099
00100 if (mShowValInWheel)
00101 CenterValStr(0, 0);
00102 }
00103
00104 virtual void DisplayFunc()
00105 {
00106 OGC oldOGC;
00107
00108 OGCSave(&oldOGC);
00109
00110 if (mIsPressed && RepeatTime())
00111 PropagateScrolling();
00112
00113 Window::DisplayFunc();
00114
00115 DrawWheel();
00116 OGCRestore(&oldOGC);
00117 }
00118
00119 void PropagateScrolling()
00120 {
00121 SetValue(mVal + (mDownDir ? -mIncrement : mIncrement));
00122 }
00123
00124 virtual void MouseFunc(INT msg, INT but, INT state, INT x, INT y)
00125 {
00126 Window::MouseFunc(msg, but, state, x, y);
00127
00128 if (!GetState()) return;
00129
00130 if (msg == oglMouseWheelUp || msg == oglMouseWheelDown)
00131 SetValue(mVal + (msg==oglMouseWheelUp ? mIncrement : -mIncrement));
00132
00133 mDownDir = (y < mOglWnd->height/2);
00134
00135 if ((msg == oglMouseDown) && (but == oglLeftButton)){
00136 mIsPressed = true;
00137 StartRepeatTime();
00138 SetValue(mVal + (mDownDir ? -mIncrement : mIncrement));
00139 oglSys.SetAlwaysDraw(mOglWnd, true);
00140 }
00141 if (msg == oglMouseMove && (state & oglLeftButton))
00142 mIsPressed = (x>0 && x<mOglWnd->width && y>0 && y<mOglWnd->height);
00143
00144 if (msg == oglMouseUp) {
00145 oglSys.SetAlwaysDraw(mOglWnd, false);
00146 mIsPressed = false;
00147 }
00148 }
00149
00150 virtual void KeyboardFunc(INT c, INT state)
00151 {
00152 Window::KeyboardFunc(c, state);
00153
00154 if (state & (oglControl|oglAlt|oglShift))
00155 return;
00156
00157 if (c == oglLEFT || c== oglRIGHT || c == oglUP || c == oglDOWN)
00158 SetValue(mVal + ((c==oglLEFT||c==oglUP) ? -mIncrement:mIncrement));
00159 if (c == oglPAGEUP || c == oglPAGEDOWN)
00160 SetValue(mVal + ((c==oglPAGEUP) ? -mPageIncrement:mPageIncrement));
00161 if (c == oglHOME || c == oglEND)
00162 SetValue((c==oglHOME) ? mMinVal : mMaxVal);
00163 }
00164
00165 bool IsPressed() const
00166 {
00167 return mIsPressed;
00168 }
00169
00170 float GetValue() const
00171 {
00172 return mVal;
00173 }
00174
00175 void SetValue(float val)
00176 {
00177 if (val < mMinVal)
00178 val = mMinVal;
00179 if (val > mMaxVal)
00180 val = mMaxVal;
00181 if (val == mVal)
00182 return;
00183
00184 mVal = val;
00185 if (mSpinWheelListener)
00186 mSpinWheelListener->SpinWheelChanged(this, mSpinWheelListenerData);
00187 }
00188
00189 void SetMinimum(float min)
00190 {
00191 mMinVal = min;
00192 }
00193
00194 float GetMinimum() const
00195 {
00196 return mMinVal;
00197 }
00198
00199 void SetMaximum(float max)
00200 {
00201 mMaxVal = max;
00202 }
00203
00204 float GetMaximum() const
00205 {
00206 return mMaxVal;
00207 }
00208
00209 void SetDrawLineEtched(bool mode)
00210 {
00211 mDrawLineEtched = mode;
00212 }
00213
00214 bool GetDrawLineEtched() const
00215 {
00216 return mDrawLineEtched;
00217 }
00218
00219 void SetIncrement(float inc)
00220 {
00221 mIncrement = inc;
00222 }
00223
00224 float GetIncrement() const
00225 {
00226 return mIncrement;
00227 }
00228
00229 void SetPageIncrement(float inc)
00230 {
00231 mPageIncrement = inc;
00232 }
00233
00234 float GetPageIncrement() const
00235 {
00236 return mPageIncrement;
00237 }
00238
00239 void SetLineDistance(int len)
00240 {
00241 mLineDistance = len;
00242 }
00243
00244 int GetLineDistance() const
00245 {
00246 return mLineDistance;
00247 }
00248
00249 void SetShowValInWheel(bool doShow=true)
00250 {
00251 mShowValInWheel = doShow;
00252 }
00253
00254 bool GetShowValInWheel() const
00255 {
00256 return mShowValInWheel;
00257 }
00258
00259 void
00260 SetShowAsPercentage(bool doShow=true)
00261 {
00262 mShowAsPercentage = doShow;
00263 }
00264
00265 bool GetShowAsPercentage() const
00266 {
00267 return mShowAsPercentage;
00268 }
00269
00270 private:
00271
00272 void Init(bool asInt, float minVal, float maxVal, float val)
00273 {
00274 mSpinWheelListener = 0;
00275
00276 mIsPressed = false;
00277
00278 mAsInt = asInt;
00279 mVal = val;
00280 mMinVal = minVal;
00281 mMaxVal = maxVal;
00282
00283 mIncrement = 1;
00284 mPageIncrement = 10;
00285
00286 mDrawLineEtched = false;
00287 mLineDistance = 8;
00288 mIsPressed = false;
00289
00290 mShowAsPercentage = false;
00291 mShowValInWheel = true;
00292
00293 SetBorderType(BEV_RAISED);
00294 SetBorderFillShaded(2);
00295 SetRoundness(12, 12, 12, 12);
00296 mOglWnd->clipRounded = 1;
00297 SetDoStateFeedback(true);
00298
00299
00300
00301 oglSys.SetAllowCameraMove(mOglWnd, false);
00302
00303 SetDisableOGLViewKeys(true);
00304 SetDisableOGLViewMouse(true);
00305 }
00306
00307 protected:
00308 SpinWheelListener* mSpinWheelListener;
00309
00310 void* mSpinWheelListenerData;
00311
00312 float mMinVal, mMaxVal, mVal;
00313 float mIncrement;
00314 float mPageIncrement;
00315
00316 bool mDownDir;
00317 bool mIsPressed;
00318
00319 bool mDrawLineEtched;
00320 int mLineDistance;
00321 bool mAsInt;
00322 bool mShowAsPercentage;
00323 bool mShowValInWheel;
00324 };
00325
00326 }
00327
00328 #endif