00001 //345678901234567890123456789012345678901234567890123456789012345678901234567890 00002 // Author: Richard van Balen 00003 #ifndef OglGui_DocFlowDrag_h 00004 #define OglGui_DocFlowDrag_h 00005 00006 #ifndef OglGui_Window_h 00007 #include "OglGui/Window.h" 00008 #endif 00009 00010 #ifndef OglGui_DocDimensions_h 00011 #include "OglGui/DocDimensions.h" 00012 #endif 00013 00014 /* 00015 #ifndef OglGui_time_included 00016 #include <time.h> 00017 #define OglGui_time_included 00018 #endif 00019 */ 00020 00021 #ifndef OglGui_RepeateTimer_h 00022 #include "OglGui/RepeatTimer.h" 00023 #endif 00024 00025 namespace OglGui { 00026 00027 // RvB: NOTE RepeatTimer only for test purpose. 00028 // Will be removed in future 00029 class DocFlowDrag : RepeatTimer 00030 { 00031 public: 00032 DocFlowDrag() 00033 { 00034 mFlowing = mFlowDragging = false; 00035 mMyMouseButton = oglLeftButton; 00036 mFlowPageThresh = 1500; 00037 mFlowPageExtra = 0; 00038 mKineticScrolling = true; 00039 mFriction = -500; 00040 //SetRepeatDelays(50,50); 00041 SetRepeatDelays(0,0); 00042 } 00043 00044 void SetDocWnd(Window* wnd, DocDimensions* doc) 00045 { 00046 mFlowWnd = wnd; 00047 mFlowDoc = doc; 00048 } 00049 00050 void Friction(double f) { mFriction = f; } 00051 double Friction() { return mFriction; } 00052 void UseMouseButton(int btn) { mMyMouseButton = btn; } 00053 00054 void SetFlowPageExtra(int extra) 00055 { 00056 mFlowPageExtra = extra; 00057 } 00058 00059 void FlowPageThreshold(double t) 00060 { 00061 mFlowPageThresh = t; 00062 } 00063 00064 void ClampDocY(int docY) 00065 { 00066 int docH = mFlowDoc->DocH(); 00067 int wndH = mFlowWnd->H(); 00068 if (docY > 0 || docY < -docH + wndH) 00069 { 00070 mFlowWnd->SetAlwaysDraw(mFlowing = false); 00071 docY = (docY>0) ? 0 : -docH + wndH; 00072 mFlowWnd->UpdateScene(); 00073 } 00074 mFlowDoc->DocY(docY); 00075 } 00076 00077 void FlowDragDisplay() 00078 { 00079 if (!mFlowing) 00080 return; 00081 00082 int docY = mFlowDoc->DocY(); 00083 int wndH = mFlowWnd->H(); 00084 float d; 00085 00086 if (mOldDocY != docY) 00087 { 00088 mFlowWnd->SetAlwaysDraw(mFlowing=false); 00089 return; 00090 } 00091 00092 if (mKineticScrolling) 00093 { 00094 float t = (OglClock() - mFlowDragStartTime); 00095 float endT = fabs(mFlowSpeed / mFriction); 00096 //printf("t %f endT %f flowSpeed %f\n", t, endT, mFlowSpeed); 00097 if (t >= endT) 00098 { 00099 t = endT; 00100 mFlowWnd->SetAlwaysDraw(mFlowing=false); 00101 mFlowWnd->UpdateScene(); 00102 } 00103 d = mFlowSpeed*t + (0.5*(mFlowSpeed>0?1:-1)*mFriction * (t*t)); 00104 docY = mFlowStartY - d; 00105 } 00106 else 00107 { 00108 // To prevent rushing by images that cause flicker 00109 if (mFlowSpeed > mFlowPageThresh || mFlowSpeed <-mFlowPageThresh) 00110 { 00111 d = (mFlowSpeed>0) ? -wndH+mFlowPageExtra : wndH-mFlowPageExtra; 00112 if (RepeatTime()) 00113 docY += d; 00114 } 00115 else 00116 { 00117 d = -mFlowSpeed * (OglClock()-mFlowDragStartTime); 00118 docY = mFlowStartY + d; 00119 } 00120 } 00121 ClampDocY(docY); 00122 mOldDocY = mFlowDoc->DocY(); 00123 } 00124 00125 void MouseFunc(int msg, int but, int state, int x, int y) 00126 { 00127 if (msg == oglMouseDown && but == mMyMouseButton) 00128 { 00129 mKineticScrolling = !(state & oglControl); 00130 if (mFlowing) 00131 mFlowWnd->SetAlwaysDraw(mFlowing = false); 00132 mFlowDragging = true; 00133 mFlowDragDiff = 0; 00134 mFlowDragStartY = mFlowDragLastY = y; 00135 mFlowDragStartTime = OglClock(); 00136 } 00137 if (msg == oglMouseMove && mFlowDragging) 00138 { 00139 mFlowDragDiff = mFlowDragLastY - y; 00140 ClampDocY(mFlowDoc->DocY() - mFlowDragDiff); 00141 mFlowDragLastY = y; 00142 } 00143 if (mFlowDragging && msg == oglMouseUp && but == mMyMouseButton) 00144 { 00145 mOldDocY = mFlowStartY = mFlowDoc->DocY(); 00146 mFlowDragging = false; 00147 mFlowSpeed = ((double)mFlowDragStartY-y) / 00148 (OglClock() - mFlowDragStartTime); 00149 //printf("FlowSpeed %f\n", mFlowSpeed); 00150 if (abs(mFlowDragDiff) < 3) 00151 mFlowSpeed = 0; 00152 if (mFlowSpeed > 100 || mFlowSpeed < -100) 00153 mFlowWnd->SetAlwaysDraw(mFlowing = true); 00154 mFlowDragStartTime = OglClock(); 00155 StartRepeatTime(); 00156 } 00157 if (!(state & mMyMouseButton)) 00158 mFlowDragging = false; 00159 } 00160 00161 void KeyboardFunc(int c, int state) 00162 { 00163 if (c>='0' && c <= '9') 00164 SetRepeatDelays((c-'0')*10,(c-'0')*10); 00165 } 00166 00167 protected: 00168 DocDimensions* mFlowDoc; 00169 Window* mFlowWnd; 00170 00171 bool mKineticScrolling; 00172 bool mFlowing; 00173 bool mFlowDragging; 00174 int mMyMouseButton; 00175 int mOldDocY; 00176 int mFlowDragDiff; 00177 int mFlowDragStartY; 00178 int mFlowDragLastY; 00179 int mFlowStartY; 00180 int mFlowPageExtra; 00181 double mFlowSpeed; 00182 double mFlowPageThresh; 00183 double mFriction; 00184 double mFlowDragStartTime; 00185 }; 00186 } // namespace OglGui 00187 #endif