00001
00002
00003
00004
00005
00006
00007 #ifndef OglGui_IntervalChooser_h
00008 #define OglGui_IntervalChooser_h
00009
00010 #include "OglGui/IntervalChooserListener.h"
00011 #include "OglGui/SizableDirectionButton.h"
00012
00013 namespace OglGui {
00014
00015 class IntervalChooser : public Window
00016 {
00017 public:
00018 IntervalChooser(Window* parent, int x, int y, int w, int h,
00019 int minVal, int maxVal, int startVal, int endVal) :
00020 Window(parent, x, y, w, h)
00021 {
00022 Init(w,h,minVal,maxVal,startVal,endVal);
00023 }
00024
00025 void SetIntervalChooserListener(IntervalChooserListener* li, void* userData)
00026 {
00027 mListener = li;
00028 mUserData = userData;
00029 }
00030
00031 SizableDirectionButton* StartThumb() { return mStartThumb; }
00032 SizableDirectionButton* EndThumb() { return mEndThumb; }
00033
00034 void IntervalColor(ULONG col) { mIntervalColor = col; }
00035 void IntervalY(int y) { mIntervalY = y; }
00036
00037 void MinInterval(int sz)
00038 {
00039 mMinInterval = sz;
00040 mMinSizePix = Val2Pixel(sz);
00041 }
00042
00043 int Val2Pixel(int val)
00044 {
00045 return ((val-mMinVal)*W())/(float)(mMaxVal-mMinVal+1);
00046 }
00047 int Pixel2Val(int pix)
00048 {
00049 return mMinVal + (pix*(mMaxVal-mMinVal+1))/(float)W();
00050 }
00051
00052 int NeedleX(SizableDirectionButton* szBtn)
00053 {
00054 return szBtn->X() + szBtn->W()/2;
00055 }
00056 int SetNeedleX(SizableDirectionButton* szBtn, int x)
00057 {
00058 ClampX(x);
00059 szBtn->SetDimensions(x-szBtn->W()/2,RETAIN,RETAIN,RETAIN);
00060 return x;
00061 }
00062
00063 void SetHighlightBorderType(int mode)
00064 {
00065 mStartThumb->SetHighLightBorderType(mode);
00066 mEndThumb->SetHighLightBorderType(mode);
00067 }
00068
00069 virtual void DisplayFunc()
00070 {
00071 int bInfo[3];
00072 OGC myOGC;
00073
00074 OGCSave(&myOGC);
00075 Window::DisplayFunc();
00076
00077 if (!mReshaping)
00078 HandleThumbs();
00079 mReshaping = false;
00080
00081 oglSys.StartBlend(bInfo);
00082 SetSolidFillColor(mIntervalColor);
00083 int sX = NeedleX(mStartThumb);
00084 int eX = NeedleX(mEndThumb);
00085 FillRectangle(sX,mIntervalY,eX-sX,H()-mIntervalY);
00086 oglSys.EndBlend(bInfo);
00087 OGCRestore(&myOGC);
00088 }
00089
00090 virtual void ReshapeFunc(int w, int h)
00091 {
00092 Window::ReshapeFunc(w,h);
00093 SetNeedleX(mStartThumb,Val2Pixel(mStartVal));
00094 SetNeedleX(mEndThumb,Val2Pixel(mEndVal));
00095 mMinSizePix = Val2Pixel(mMinInterval);
00096 mReshaping = true;
00097 }
00098
00099 virtual void
00100 MouseFunc(int msg, int but, int state, int x, int y)
00101 {
00102 if (!GetState()) return;
00103
00104 Window::MouseFunc(msg, but, state, x, y);
00105
00106 if (mDragging && !(state & oglLeftButton))
00107 {
00108 mDragging = false;
00109 mMinSizePix = mOldMinSizePix;
00110 }
00111 if (msg==oglMouseDown && state==oglLeftButton)
00112 {
00113 mDragging = true;
00114 int sX = NeedleX(mStartThumb);
00115 int eX = NeedleX(mEndThumb);
00116 mDragDiffX = x - sX;
00117 mOldMinSizePix = mMinSizePix;
00118 mMinSizePix = eX - sX;
00119 }
00120 if (msg == oglMouseMove && state==oglLeftButton)
00121 {
00122 int nX = SetNeedleX(mStartThumb, x - mDragDiffX);
00123 SetNeedleX(mEndThumb,nX + mMinSizePix);
00124 }
00125 }
00126
00127 protected:
00128 void ClampX(int& x)
00129 {
00130 int w = W();
00131 if (x<0) x = 0;
00132 if (x>w) x = w;
00133 }
00134
00135 void HandleThumbs()
00136 {
00137 int oldStartVal = mStartVal;
00138 int oldEndVal = mEndVal;
00139 int sX = NeedleX(mStartThumb);
00140 int eX = NeedleX(mEndThumb);
00141
00142 ClampX(sX);
00143 ClampX(eX);
00144 if (mOldStartX < sX && sX >= eX-mMinSizePix)
00145 {
00146 if (eX==W())
00147 sX = eX-mMinSizePix+1;
00148 else
00149 eX = sX+mMinSizePix;
00150 }
00151 else if (mOldEndX > eX && eX <= sX+mMinSizePix)
00152 {
00153 if (sX == 0)
00154 eX = mMinSizePix;
00155 else
00156 sX = eX-mMinSizePix;
00157 }
00158 mOldStartX = sX = SetNeedleX(mStartThumb,sX);
00159 mOldEndX = eX = SetNeedleX(mEndThumb,eX);
00160 mStartVal = Pixel2Val(sX);
00161 mEndVal = mStartVal + Pixel2Val(eX-sX);
00162
00163 if (mEndVal > mMaxVal)
00164 mEndVal = mMaxVal;
00165
00166 if (oldStartVal == mStartVal && oldEndVal == mEndVal)
00167 return;
00168
00169 if (mListener)
00170 mListener->IntervalChanged(this,mStartVal,mEndVal,mUserData);
00171 }
00172
00173 SizableDirectionButton*
00174 MakeThumb(Window* parent, int x, int y, int w, int h, ULONG col, ULONG hCol)
00175 {
00176 SizableDirectionButton* szBtn =
00177 new SizableDirectionButton(parent,x,y,w,h,1,0);
00178 szBtn->SetBorderType(0);
00179
00180
00181 szBtn->SetHighLightBorderType(col==hCol?BEV_RAISED:0);
00182 szBtn->SetAllowHighlight(false);
00183
00184 szBtn->SetAllowMoveDirections(SizableWindow::AllDir,false);
00185 szBtn->SetAllowMoveDirections(SizableWindow::EastWest,true);
00186 szBtn->SetAllowSizeDirections(SizableWindow::AllDir,false);
00187 szBtn->DirButton()->SetFilled(true);
00188 szBtn->SetColors(col,hCol);
00189 return szBtn;
00190 }
00191
00192 private :
00193
00194 void Init(int w, int h, int minVal, int maxVal, int startVal, int endVal)
00195 {
00196 mMinVal = minVal;
00197 mMaxVal = maxVal;
00198 mStartVal = startVal;
00199 mEndVal = endVal;
00200 mMinInterval= 1;
00201 mMinSizePix = Val2Pixel(mMinInterval);
00202
00203 mStartColor = oglTrRED;
00204 mEndColor = oglTrGREEN;
00205 mIntervalColor = oglTrLIGHTGREY;
00206
00207 mOldStartX = Val2Pixel(mStartVal);
00208 mStartThumb = MakeThumb(this,mOldStartX-8,0,15,15,oglTrRED,0x80a00000);
00209
00210 mOldEndX = Val2Pixel(mEndVal);
00211 mEndThumb = MakeThumb(this,mOldEndX-8,0,15,15,oglTrGREEN,0x8000a000);
00212
00213 mIntervalY = 2;
00214 mDragging = false;
00215 mListener = 0;
00216 }
00217
00218 IntervalChooserListener* mListener;
00219 void* mUserData;
00220
00221 SizableDirectionButton* mStartThumb;
00222 SizableDirectionButton* mEndThumb;
00223
00224 ULONG mStartColor;
00225 ULONG mEndColor;
00226 ULONG mIntervalColor;
00227 int mMinVal;
00228 int mMaxVal;
00229 int mStartVal;
00230 int mEndVal;
00231 int mMinInterval;
00232 int mMinSizePix;
00233 int mOldMinSizePix;
00234 int mIntervalY;
00235 int mOldStartX;
00236 int mOldEndX;
00237 int mDragDiffX;
00238 bool mDragging;
00239 bool mReshaping;
00240 };
00241
00242 }
00243
00244 #endif // IntervalChooser_h