00001
00002
00003
00004 #ifndef OglGui_AlertTimeLine_h
00005 #define OglGui_AlertTimeLine_h
00006
00007 #include <iostream>
00008
00009 #ifndef OglGui_Button_h
00010 #include "OglGui/Button.h"
00011 #endif
00012
00013 #ifndef OglGui_AlertTimeLineListener_h
00014 #include "OglGui/AlertTimeLineListener.h"
00015 #endif
00016
00017 namespace OglGui
00018 {
00019
00020 class AlertTimeLine : public Window, ButtonListener
00021 {
00022 public:
00023
00024 AlertTimeLine(int x,int y,int w,int h) :
00025 Window(x, y, w, h)
00026 {
00027 Init(w, h);
00028 }
00029
00030 AlertTimeLine(Window *parent, int w, int h) :
00031 Window(parent, w, h)
00032 {
00033 Init(w, h);
00034 }
00035
00036 AlertTimeLine(Window *parent,int x,int y,int w,int h) :
00037 Window(parent, x, y, w, h)
00038 {
00039 Init(w, h);
00040 }
00041
00042 void
00043 SetAlertTimeLineListener(AlertTimeLineListener* listener, void* listenerData = 0)
00044 {
00045 mListener = listener;
00046 mListenerData = listenerData;
00047 }
00048
00050
00051 class GenerateAlertListener : public ButtonListener
00052 {
00053 virtual void ButtonSelectionEvent(Button* src, void* userData)
00054 {
00055 AlertTimeLine* timeLine = (AlertTimeLine*) userData;
00056 ULONG col = src->GetBorderBackground();
00057 int id = ABSRND(12);
00058 timeLine->AddAlert(id, col, (void*)id);
00059 }
00060 };
00061
00062 class AdvanceTimeListener : public ButtonListener
00063 {
00064 virtual void ButtonSelectionEvent(Button* src, void* userData)
00065 {
00066 AlertTimeLine* timeLine = (AlertTimeLine*) userData;
00067 timeLine->AdvanceTime(60);
00068 }
00069 };
00070
00071 void TestOnly_ManualTimeLineEvents()
00072 {
00073 GenerateAlertListener* genAlert = new GenerateAlertListener();
00074 Button* btn;
00075 btn = new Button(this, 0, H()-44, 80, 20, "test event");
00076 btn->SetBorderBackground(0xffffff00);
00077 btn->SetDoStateFeedback(false);
00078 btn->SetButtonListener(genAlert, (void*) this);
00079 btn->ConnectTo(this, T2T|B2T);
00080
00081 btn = new Button(this, 0, H()-66, 80, 20, "test alert");
00082 btn->SetBorderBackground(0xffff0000);
00083 btn->SetDoStateFeedback(false);
00084 btn->SetButtonListener(genAlert, (void*) this);
00085 btn->ConnectTo(this, T2T|B2T);
00086
00087 btn = new Button(this, 0, H()-88, 80, 20, "1 min");
00088 btn->SetButtonListener(new AdvanceTimeListener(), (void*) this);
00089
00090 btn->ConnectTo(this, T2T|B2T);
00091 }
00092
00094
00095
00096 void SetTimeSpan(long seconds) { mTimeSpan = seconds; }
00097 void SetOlderThanText(strconst str) { mOlderThanStr = str; }
00098 void AdvanceTime(long seconds) { mStartTime += seconds; }
00099 long GetCurrentTime() { return mCurrentTime; }
00100 long GetStartTime() { return mStartTime; }
00101 long GetStartTimeOffset() { return mStartTimeOffset; }
00102
00103 Button* OlderThanButton() { return mOlderThanBtn; }
00104
00105
00106
00107
00108
00109
00110 void SetTime(long startTimeSec, int currentTimeOffsetSec = 0)
00111 {
00112 mStartTime = startTimeSec - oglWndSecondsSinceStart;
00113 mStartTimeOffset = (long) currentTimeOffsetSec;
00114 mCurrentTime = mStartTime + mStartTimeOffset;
00115 }
00116
00117
00118 virtual void ButtonSelectionEvent(Button *src, void* userData)
00119 {
00120 if (!mListener)
00121 return;
00122 int id = atoi(src->GetText().c_str());
00123 mListener->AlertSelectionEvent(this, id, userData, mListenerData);
00124 }
00125
00126 void AddAlert(int alertId, ULONG col, void* userData, long seconds)
00127 {
00128 char buf[40];
00129 sprintf(buf, "%d", alertId);
00130
00131 int h = mLineY;
00132 int base = h;
00133 int nX = ComputeX(seconds);
00134 int nBtns = mAlertButtons.size();
00135
00136 Button* lastBtn = nBtns ? mAlertButtons[nBtns-1] : 0;
00137 if (lastBtn && nX-lastBtn->X() < mAlertW)
00138 {
00139 int i = nBtns-1;
00140 while (i>=0 && mAlertButtons[i]->Y() > base)
00141 i--;
00142 while (i<nBtns && mAlertButtons[i]->X() > nX-mAlertW)
00143 {
00144 h = mAlertButtons[i]->Y() + mAlertH;
00145 i++;
00146 }
00147 }
00148 Button* btn = AlertButton(nX, h, mAlertW, mAlertH, col, buf);
00149 oglSys.SetUserData(btn->GetOGLWND(), 1, (void*) seconds);
00150 oglSys.SetUserData(btn->GetOGLWND(), 2, (void*) userData);
00151 btn->SetButtonListener(this, userData);
00152 mAlertButtons.push_back(btn);
00153 mNrAlerts++;
00154 }
00155
00156 void AddAlert(int alertId, ULONG col, void* userData)
00157 {
00158 AddAlert(alertId, col, userData, mCurrentTime);
00159 }
00160
00161 static void
00162 GetTimeUnits(long timeInSeconds, int& hours, int& minutes, int& seconds)
00163 {
00164 hours = timeInSeconds / 3600;
00165 minutes = (timeInSeconds % 3600) / 60;
00166 seconds = (timeInSeconds % 3600) % 60;
00167 }
00168
00169 static long UnitsToSeconds(int h, int m, int s)
00170 {
00171 return h * 3600 + m * 60 + s;
00172 }
00173
00174 virtual void DisplayFunc()
00175 {
00176 mCurrentTime = mStartTime + mStartTimeOffset + oglWndSecondsSinceStart;
00177
00178 OGC oldOGC;
00179 OGCSave(&oldOGC);
00180
00181 int h = H(), w = W();
00182 SetSolidLineColor(oglBLACK);
00183 DrawLine(0, mLineY, w-mAlertW, mLineY);
00184 SetSolidLineColor(oglWHITE);
00185 DrawLine(0, mLineY-1, w-mAlertW, mLineY-1);
00186
00187 DrawTicks();
00188 DrawCurrentTime();
00189 PositionAlerts();
00190
00191 oglSys.PosColPrintf(mOglWnd, w/2, 0, oglBLACK, "total: %d", mNrAlerts);
00192
00193 char buf[100];
00194 sprintf(buf, "%d %s", mNrOlderAlerts, mOlderThanStr.c_str());
00195 mOlderThanBtn->SetText(buf);
00196 mOlderThanBtn->SetState(mNrOlderAlerts==0 ? 0 : 1);
00197
00198 oglSys.UpdateSceneFlag(mOglWnd, 1);
00199 OGCRestore(&oldOGC);
00200 Window::DisplayFunc();
00201 }
00202
00203 protected:
00204
00205 long GetButtonTime(Button* btn)
00206 {
00207 OGLWND* oglWnd = btn->GetOGLWND();
00208 return (long) oglSys.GetUserData(oglWnd, 1);
00209 }
00210
00211 void DrawCurrentTime()
00212 {
00213 int h, m, s;
00214 GetTimeUnits(mCurrentTime, h, m, s);
00215 oglSys.PosColPrintf(mOglWnd, W()-130, 0, oglBLACK,
00216 "current time: %02d:%02d:%02d", h, m, s);
00217 }
00218
00219 void DrawTicks(bool detailed=true, int detailResolution=10)
00220 {
00221 int h, m, s;
00222 long tickT = mCurrentTime;
00223
00224 while (tickT >= (mCurrentTime - mTimeSpan))
00225 {
00226 GetTimeUnits(tickT, h, m, s);
00227 int x = ComputeX(tickT);
00228 if ( !(m%5) && !(s%60)){
00229 DrawLine(x, mLineY, x, mLineY - 7);
00230 oglSys.PosColPrintf(mOglWnd, x-16, mLineY-20, 0xff505050,
00231 "%02d:%02d", h, m);
00232 }
00233 else if (!(s%60))
00234 {
00235 DrawLine(x, mLineY, x, mLineY - 5);
00236 oglSys.PosColPrintf(mOglWnd, x-6, mLineY-18, 0xff757575,
00237 "%02d", m);
00238
00239
00240 }
00241 else if(detailed && !(s%detailResolution))
00242 DrawLine(x, mLineY, x, mLineY - 3);
00243
00244 tickT--;
00245 }
00246 }
00247 int ComputeX(long btnTime)
00248 {
00249 float x = W() - ((mCurrentTime - btnTime)/(float)mTimeSpan) * W();
00250 x -= mAlertW;
00251 return (int) x;
00252 }
00253 int ComputeX(Button* btn)
00254 {
00255 long btnTime = GetButtonTime(btn);
00256 return ComputeX(btnTime);
00257 }
00258
00259 void PositionAlerts()
00260 {
00261 for (int i=0; i<mAlertButtons.size(); i++)
00262 {
00263 Button* btn = mAlertButtons[i];
00264 int x = ComputeX(btn);
00265 btn->SetDimensions(x, RETAIN, RETAIN, RETAIN);
00266 }
00267
00268 for (int i=mAlertButtons.size()-1; i >= 0; i--)
00269 {
00270 Button* btn = mAlertButtons[i];
00271 if (btn->X() < -btn->W()/2)
00272 {
00273 mAlertButtons.erase(mAlertButtons.begin()+i);
00274 mNrOlderAlerts++;
00275 delete btn;
00276 }
00277 }
00278 }
00279
00280 Button* AlertButton(int x, int y, int w, int h, ULONG col, strconst str)
00281 {
00282 Button* btn = new Button(this, x, y, w, h, str, BEV_ETCHED, true);
00283 btn->SetBorderType(1);
00284 btn->SetBorderBackground(col);
00285 btn->SetDoStateFeedback(false);
00286 return btn;
00287 }
00288
00289 private:
00290 void Init(int w, int h)
00291 {
00292 mLineY = 40;
00293 mAlertW = 20;
00294 mAlertH = 16;
00295 mTimeSpan = 900;
00296
00297 mOlderThanStr = "older than 15 minutes ...";
00298 mOlderThanBtn = new Button(this, 0, 0, 140, 18, "", BEV_ETCHED, true);
00299 mNrAlerts = 0;
00300 mNrOlderAlerts = 0;
00301
00302 mListener = 0;
00303
00304 SetAllowChildScaling(false);
00305 }
00306
00307 std::vector<Button*> mAlertButtons;
00308 std::string mOlderThanStr;
00309 Button* mOlderThanBtn;
00310
00311 AlertTimeLineListener* mListener;
00312 void* mListenerData;
00313
00314 int mNrAlerts;
00315 int mNrOlderAlerts;
00316
00317 int mLineY;
00318 int mAlertW;
00319 int mAlertH;
00320 long mStartTime;
00321 long mStartTimeOffset;
00322 long mCurrentTime;
00323 long mTimeSpan;
00324 };
00325
00326 }
00327
00328 #endif