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 #ifndef OglGui_ZoomShiftRuler_h
00033 #define OglGui_ZoomShiftRuler_h
00034
00035 #ifndef OglGui_Window_h
00036 #include "OglGui/Window.h"
00037 #endif
00038
00039 #ifndef OglGui_DocDimensions_h
00040 #include "OglGui/DocDimensions.h"
00041 #endif
00042
00043 #ifndef OglGui_RepeatTimer_h
00044 #include "OglGui/RepeatTimer.h"
00045 #endif
00046
00047 #ifndef OglGui_ZoomShiftRulerListener_h
00048 #include "OglGui/ZoomShiftRulerListener.h"
00049 #endif
00050
00051 namespace OglGui
00052 {
00053
00054 class ZoomShiftRuler : public Window,
00055 public DocDimensions,
00056 public RepeatTimer
00057 {
00058 public:
00059 ZoomShiftRuler(int x, int y, int w, int h, long start=0, long span=10000) :
00060 Window(x,y,w,h)
00061 {
00062 Init(w,h,start,span);
00063 }
00064
00065 ZoomShiftRuler(Window* parent, int w, int h, long start=0, long span=10000) :
00066 Window(parent,w,h)
00067 {
00068 Init(w,h,start,span);
00069 }
00070
00071 ZoomShiftRuler(Window* parent, int x, int y, int w, int h,
00072 long start=0, long span=10000) :
00073 Window(parent,x,y,w,h)
00074 {
00075 Init(w,h,start,span);
00076 }
00077
00078 void
00079 SetListener(ZoomShiftRulerListener* listener, void* listenerData = 0)
00080 {
00081 mListener = listener;
00082 mZoomShiftListenerData = listenerData;
00083 }
00084
00085 virtual void PublishCurrentChanged()
00086 {
00087 if (mListener)
00088 mListener->CurrentChanged(this, mCurrent, mZoomShiftListenerData);
00089 }
00090
00091 void SetMinMaxDocWidth(long minW=-1, long maxW=-1)
00092 {
00093 mMinDocWidth = (minW == -1) ? 20 : minW;
00094 mMaxDocWidth = (maxW == -1) ? (1<<30) : maxW;
00095 mDocW = (mDocW < mMinDocWidth) ? mMinDocWidth : mDocW;
00096 mDocW = (mDocW > mMaxDocWidth) ? mMaxDocWidth : mDocW;
00097 }
00098 void GetMinMaxDocWidth(long& minW, long& maxW)
00099 {
00100 minW = mMinDocWidth;
00101 maxW = mMaxDocWidth;
00102 }
00103
00104 void SetNeedleColor(ULONG col) { mNeedleColor = col; }
00105 ULONG GetNeedleColor() { return mNeedleColor; }
00106
00107 void ShowNeedle(bool show) { mShowNeedle = show; }
00108 bool ShowNeedle() { return mShowNeedle; }
00109
00110 void SetSpan(long span) { mSpan = span; }
00111 long GetSpan() { return mSpan; }
00112
00113 void SetStart(long start) { mStart = start; }
00114 long GetStart() { return mStart; }
00115
00116 bool IsDragging() { return mDragging; }
00117
00118 void SetAxisY(int y) { mAxisY = y; }
00119 int GetAxisY() { return mAxisY; }
00120
00121 void SetTextColor(ULONG col) { mTextColor = col; }
00122 ULONG GetTextColor() { return mTextColor; }
00123
00124 void SetTextShaded(bool mode) { mTextShaded = mode; }
00125 bool GetTextShaded() { return mTextShaded; }
00126
00127 void SetTextShadowColors(ULONG shadBg, ULONG shadFg)
00128 {
00129 mTextShadowFg = shadFg;
00130 mTextShadowBg = shadBg;
00131 }
00132 void GetTextShadowColors(ULONG& shadBg, ULONG shadFg)
00133 {
00134 shadFg = mTextShadowFg;
00135 shadBg = mTextShadowBg;
00136 }
00137
00138 void SetNeedleUpDownHeight(int upH, int downH)
00139 {
00140 mNeedleUpH = upH;
00141 mNeedleDownH = downH;
00142 }
00143 void GetNeedleUpDownHeight(int& upH, int &downH)
00144 {
00145 upH = mNeedleUpH;
00146 downH = mNeedleDownH;
00147 }
00148
00149 void SetRange(long start, long span)
00150 {
00151 mStart = start;
00152 mSpan = span;
00153 }
00154 void GetRange(long& start, long& span)
00155 {
00156 start = mStart;
00157 span = mSpan;
00158 }
00159
00160 void Current(long cur)
00161 {
00162 long oldCur = mCurrent;
00163
00164 if (cur > mStart + mSpan)
00165 cur = mStart + mSpan;
00166 if (cur < mStart)
00167 cur = mStart;
00168 if ((mCurrent = cur) != oldCur)
00169 PublishCurrentChanged();
00170 }
00171 long Current()
00172 {
00173 return mCurrent;
00174 }
00175
00176 void ShowCurrentAt(long x)
00177 {
00178 int presX = Unit2Pixel(mCurrent);
00179 mDocX += x-presX;
00180 }
00181
00182 void MakeCurrentVisible()
00183 {
00184 int presX = Unit2Pixel(mCurrent);
00185 if (presX < mPropagateMargin)
00186 ShowCurrentAt(mPropagateMargin);
00187 if (presX > W()-mPropagateMargin)
00188 ShowCurrentAt(W()-mPropagateMargin);
00189 }
00190
00191 long Pixel2Unit(int pX)
00192 {
00193 return mStart + ((pX-mDocX)/(double)mDocW)*mSpan;
00194 }
00195
00196 int Unit2Pixel(long u)
00197 {
00198 u -= mStart;
00199 return mDocX + (u/(double)mSpan)*mDocW;
00200 }
00201
00202 virtual void DrawNeedle()
00203 {
00204 int curX = Unit2Pixel(mCurrent);
00205 SetSolidLineColor(mNeedleColor);
00206 DrawLine(curX,mAxisY-mNeedleDownH,curX,mAxisY+mNeedleUpH);
00207 }
00208
00209 virtual void DisplayFunc()
00210 {
00211 Window::DisplayFunc();
00212
00213 if (mPropagateScrolling && RepeatTime())
00214 {
00215 if (!(mMouseState & (oglShift | oglControl)))
00216 {
00217 int lastX = mLastX;
00218 mLastX += (mLastX < mPropagateMargin) ? -40 : 40;
00219
00220
00221 MouseFunc(oglMouseMove, oglLeftButton, mMouseState, lastX, 10);
00222
00223 }
00224 }
00225
00226 OGC myOGC;
00227 OGCSave(&myOGC);
00228
00229 SetStipple((short)oglSolid);
00230 SetSolidLineColor(mForeGroundColor);
00231 DrawLine(mDocX, mAxisY, mDocX+mDocW, mAxisY);
00232 DrawTicks();
00233
00234 if (mShowNeedle)
00235 DrawNeedle();
00236
00237 OGCRestore(&myOGC);
00238 }
00239
00240 void SetDocXClamped(int x)
00241 {
00242 int w = W();
00243 if (x > w/2)
00244 x = w/2;
00245 if (x+mDocW < w/2)
00246 x = -mDocW + w/2;
00247 mDocX = x;
00248 }
00249
00250 void CheckPropagateScrolling(int x)
00251 {
00252 mPropagateScrolling = (x > W()-mPropagateMargin || x < mPropagateMargin);
00253 oglSys.SetAlwaysDraw(mOglWnd,mPropagateScrolling);
00254 }
00255
00256 virtual void MouseFunc(int msg, int btn, int state, int x, int y)
00257 {
00258 Window::MouseFunc(msg,btn,state,x,y);
00259
00260 if (state & oglAlt) return;
00261
00262 bool shift = (state & oglShift) != 0;
00263 bool control = (state & oglControl) != 0;
00264
00265 mMouseState = state;
00266
00267 if ((msg==oglMouseDown && btn==oglLeftButton) || (!mScaling && control))
00268 {
00269 StartRepeatTime();
00270 CheckPropagateScrolling(x);
00271 mClickedUnit = Pixel2Unit(x);
00272 if (!(shift||control))
00273 Current(mClickedUnit);
00274 mLastX = mClickedX = x;
00275 mDragging = true;
00276 if (control)
00277 mScaling = true;
00278 }
00279
00280 if (mScaling && !control)
00281 mScaling = false;
00282
00283 if (msg == oglMouseUp)
00284 {
00285 mPropagateScrolling = mDragging = mScaling = false;
00286 oglSys.SetAlwaysDraw(mOglWnd, 0);
00287 }
00288
00289 if (msg == oglMouseMove && mDragging)
00290 {
00291 CheckPropagateScrolling(x);
00292 int dx = x - mLastX;
00293 if (mScaling)
00294 {
00295 int oldDocW = mDocW;
00296 mDocW *= (1 + .02*dx);
00297 if (oldDocW > 0 && mDocW<0)
00298 mDocW = oldDocW;
00299
00300 if (mDocW < mMinDocWidth)
00301 mDocW = mMinDocWidth;
00302 if (mDocW > mMaxDocWidth)
00303 mDocW = mMaxDocWidth;
00304
00305 long clickedPixelNow = Unit2Pixel(mClickedUnit);
00306 mDocX += mLastX - clickedPixelNow;
00307 mDocX -= mLastX - mClickedX;
00308 }
00309 else if (shift)
00310 SetDocXClamped(mDocX+dx);
00311 else
00312 Current(Pixel2Unit(x));
00313
00314 mLastX = x;
00315 }
00316 }
00317
00318 protected:
00319 virtual void DrawTick(long val,int x,int y,long tickSpan,int tickLen=6)
00320 {
00321 DrawLine(x, y-tickLen, x, y);
00322 }
00323
00324 virtual void DrawMicroTicks(long x, long nextX)
00325 {
00326 long minX = Unit2Pixel(mStart);
00327 long maxX = Unit2Pixel(mStart+mSpan);
00328 int cnt = 0;
00329
00330 if (nextX-x <= 0)
00331 nextX = x + 1;
00332
00333 for (double j=x; j<nextX; j+= (nextX-x)/10.)
00334 {
00335 if (j>minX && j<maxX)
00336 DrawLine(j,mAxisY-((++cnt%6)?2:4),j,mAxisY);
00337 }
00338 }
00339
00340 virtual void DrawTicks()
00341 {
00342 int startUnit = Pixel2Unit(0);
00343 int endUnit = Pixel2Unit(W());
00344
00345 if (startUnit < mStart)
00346 startUnit = mStart;
00347
00348 int pixRange = Unit2Pixel(endUnit) - Unit2Pixel(startUnit);
00349 double range = endUnit - startUnit;
00350 double order = floor(log10(range));
00351 double tmpSpan = mTickSpan = pow(10.,order);
00352 double quanta[9]= {.5,.2,.1, .05,.02,.01, .005,.002,.001};
00353
00354
00355
00356 int i = 0;
00357 while (i<9 && range/tmpSpan < (pixRange/140))
00358 tmpSpan = mTickSpan * quanta[i++];
00359 mTickSpan = tmpSpan;
00360 int firstTick = ceil(startUnit / mTickSpan);
00361 int tickCount = floor(endUnit / mTickSpan) - firstTick + 1;
00362
00363 SetStipple((short)oglSolid);
00364 DrawTick(startUnit, Unit2Pixel(startUnit), mAxisY, mTickSpan);
00365
00366 int startI = Unit2Pixel(mStart)<0 ? -1 : 0;
00367 for (i=startI; i<tickCount; i++)
00368 {
00369 long val = (i+firstTick) * mTickSpan;
00370 long x = Unit2Pixel(val);
00371 long nextX = Unit2Pixel(val+mTickSpan);
00372
00373 if (val > mStart+mSpan || x>W())
00374 break;
00375 DrawMicroTicks(x, nextX);
00376 DrawTick(val, x, mAxisY, mTickSpan);
00377 }
00378 }
00379
00380 protected:
00381 int mAxisY;
00382
00383 long mStart;
00384 long mSpan;
00385 double mTickSpan;
00386
00387 long mCurrent;
00388 bool mShowNeedle;
00389 ULONG mNeedleColor;
00390 int mNeedleUpH;
00391 int mNeedleDownH;
00392
00393 bool mDragging;
00394 bool mScaling;
00395
00396 long mMinDocWidth;
00397 long mMaxDocWidth;
00398
00399 int mMouseState;
00400 int mPropagateMargin;
00401 bool mPropagateScrolling;
00402 long mClickedUnit;
00403 int mClickedX;
00404 int mLastX;
00405
00406 bool mTextShaded;
00407 ULONG mTextShadowFg;
00408 ULONG mTextShadowBg;
00409 ULONG mTextColor;
00410
00411 private:
00412 void Init(int w, int h, long start, long span)
00413 {
00414 mListener = 0;
00415 SetDocDimensions(0,0,w,h);
00416 SetMinMaxDocWidth(-1,-1);
00417 SetRange(start,span);
00418 mDragging = mScaling = false;
00419 mCurrent = start;
00420 mShowNeedle = true;
00421 mNeedleColor = oglRED;
00422 mNeedleUpH = mNeedleDownH = 8;
00423 mTextShadowFg = oglDARKGREY;
00424 mTextShadowBg = oglWHITE;
00425 mTextColor = oglBLACK;
00426 mTextShaded = true;
00427 mAxisY = 20;
00428 SetRepeatDelays(40,10);
00429 mPropagateMargin = 50;
00430 mPropagateScrolling = false;
00431 SetDisableOGLViewKeys(true);
00432 SetDisableOGLViewMouse(true);
00433 }
00434
00435 ZoomShiftRulerListener* mListener;
00436 void* mZoomShiftListenerData;
00437 };
00438 }
00439
00440 #endif