Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

WindowTimeLine.h

Go to the documentation of this file.
00001 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00002 /*
00003     WindowTimeLine :    A time-line that can display any OGL window connected
00004                         to a point in time.
00005 
00006     BRAINSTORM
00007     ==========
00008     Scrolling and sizing of the time-line will be based on the DocDimensions.h
00009     interface. In this way the time-line can externally be supplied with
00010     scrollbars and scrolling behaviour through the use of a DocScroller.h
00011 
00012     In a first version implement mouse-gesture based shifting/scaling of
00013     the time-line. Later also implement visual controls.
00014 
00015     Let the user add any OGL window inside the time-line connected
00016     to a certain point, or maybe to a certain time-span, in time.
00017 
00018     The time-line than becomes responsible for repositioning the
00019     added OGL windows based on the position of its connection to the
00020     time-line in time.
00021 
00022     Implement a WindowTimeLineListener interface to allow for outsiders
00023     to be involved with interaction.
00024 
00025     ADDENDUM 29-09-2009
00026     ===================
00027     Support to also allow OGLVIEW* objects to be connected to a point in time.
00028 
00029     Rationale:
00030     Using OglGui::WindowView2D objects to display OGLVIEW* objects on a
00031     WindowTimeLine is not well suited for displaying thousands of them,
00032     for reasons of speed and because of the difficulty to use
00033     image caching across separate OglGui::Window derived components.
00034     
00035     By also supporting the direct display of OGLVIEW* objects, while utilizing
00036     OglGui::OglImageCache, many thousands of them can be placed on a
00037     WindowTimeLine.
00038     
00039     Added to WindowTimeLine directly rather then in a derived class,
00040     because there is almost no overhead when the new functionality
00041     is not used. So if you do not add OGLVIEW* objects the overhead is
00042     neglectable.
00043 
00044     Author: Richard van Balen
00045 */
00046 #ifndef OglGui_WindowTimeLine_h
00047 #define OglGui_WindowTimeLine_h
00048 
00049 #ifndef OglGui_ZoomShiftRuler_h
00050 #include "OglGui/ZoomShiftRuler.h"
00051 #endif
00052 
00053 #ifndef OglGui_WindowTimeLineListener_h
00054 #include "OglGui/WindowTimeLineListener.h"
00055 #endif
00056 
00057 #ifndef OglGui_GetOglImageByIdInterface_h
00058 #include "OglGui/GetOglImageByIdInterface.h"
00059 #endif
00060 
00061 #ifndef OglGui_OglImageCache_h
00062 #include "OglGui/OglImageCache.h"
00063 #endif
00064 
00065 namespace OglGui {
00066 
00067 class WindowTimeLine :  public ZoomShiftRuler
00068 {
00069 public:
00070     WindowTimeLine(int x, int y, int w, int h,
00071                    long startTimeMs=0, long timeSpanMs=60000) :
00072         ZoomShiftRuler(x,y,w,h,startTimeMs,timeSpanMs)
00073     {
00074         Init(w,h,startTimeMs,timeSpanMs);
00075     }
00076     WindowTimeLine(Window* parent, int w, int h,
00077                    long startTimeMs=0, long timeSpanMs=60000) :
00078         ZoomShiftRuler(parent,w,h,startTimeMs,timeSpanMs)
00079     {
00080         Init(w,h,startTimeMs,timeSpanMs);
00081     }
00082 
00083     WindowTimeLine(Window* parent, int x, int y, int w, int h,
00084                    long startTimeMs=0, long timeSpanMs=60000) :
00085         ZoomShiftRuler(parent,x,y,w,h,startTimeMs,timeSpanMs)
00086     {
00087         Init(w,h,startTimeMs,timeSpanMs);
00088     }
00089 
00090     void
00091     SetListener(WindowTimeLineListener* listener, void* listenerData = 0)
00092     {
00093         mListener = listener;
00094         mWndTimeLineListenerData = listenerData;
00095     }
00096 
00097     void SetGetOglImageByIdInterface(GetOglImageByIdInterface* i)
00098     {
00099         mGetOglImageByIdI = i;
00100     }
00101 
00102     void SetOglImageCache(OglImageCache* oglImageCache)
00103     {
00104         mOglImageCache = oglImageCache;
00105     }
00106 
00107     OGLIMAGE* LoadViewImage(long long id)
00108     {
00109         if (!mOglImageCache || !mGetOglImageByIdI)
00110             return 0;
00111 
00112         OGLIMAGE* im = mOglImageCache->GetImage(id);
00113 
00114         if (!im && (im = mGetOglImageByIdI->GetOglImageById(id)))
00115             mOglImageCache->Add(im, id);
00116         return im;
00117     }
00118 
00119     virtual void PublishCurrentChanged()
00120     {
00121         if (!mListener) return;
00122         mListener->CurrentChanged(this, mCurrent, mWndTimeLineListenerData);
00123     }
00124 
00125     // RvB: Not sure yet how to handle this.
00126     // If done as below the user must delete the added objects first
00127     // and then call ClearWindows() or ClearViews().
00128     // Not used yet, so placed in comment
00129     /*
00130     void ClearWindows()
00131     {
00132         mWindows.clear();
00133         mTimes.clear();
00134         mOffX.clear();
00135         mOffY.clear();
00136         mShowAtTickSpan.clear();
00137         mLineColor.clear();
00138     }
00139 
00140     void ClearViews()
00141     {
00142         mViews.clear();
00143         mViewTimes.clear();
00144         mViewOffX.clear();
00145         mViewOffY.clear();
00146         mViewShowAtTickSpan.clear();
00147         mViewLineColor.clear();
00148     }
00149     */
00150 
00151     int AddWindow(Window* wnd, long timeMs, int offX = 0, int offY=8)
00152     {
00153         mWindows.push_back(wnd);
00154         mTimes.push_back(timeMs);
00155         mOffX.push_back(offX);
00156         mOffY.push_back(offY);
00157         mShowAtTickSpan.push_back(-1);
00158         mLineColor.push_back(oglBLACK);
00159         wnd->SetAllowReposition(false);
00160         return mWindows.size()-1;
00161     }
00162 
00163     int AddImIdOGLVIEW(OGLVIEW* view, long timeMs, long long imId,
00164                    int offX = 0, int offY=8)
00165     {
00166         mViews.push_back(view);
00167         mViewTimes.push_back(timeMs);
00168         mViewImIds.push_back(imId);
00169         mViewOffX.push_back(offX);
00170         mViewOffY.push_back(offY);
00171         mViewShowAtTickSpan.push_back(-1);
00172         mViewLineColor.push_back(oglBLACK);
00173         return mViews.size()-1;
00174     }
00175 
00176     int AddOGLVIEW(OGLVIEW* view, long timeMs, int offX = 0, int offY=8)
00177     {
00178         return AddImIdOGLVIEW(view, timeMs, 0, offX, offY);
00179     }
00180 
00181 
00182     void SetDrawLines(bool mode=true)           { mDrawLineFlag = mode; }
00183     void SetLineStipple(short stipple)          { mLineStipple = stipple; }
00184 
00185     void SetViewDrawLines(bool mode=true)       { mViewDrawLineFlag = mode; }
00186     void SetViewLineStipple(short stipple)      { mViewLineStipple = stipple; }
00187 
00188     void  MaxVisibleImages(int m)               { mMaxVisibleImages = m; }
00189     int   MaxVisibleImages()                    { return mMaxVisibleImages; }
00190 
00191     void SetLineColor(Window* wnd, long col)
00192     {
00193         int idx = FindWindowIdx(wnd);
00194         
00195         if (idx == -1)
00196             return;
00197         mLineColor[idx] = col;
00198     }
00199 
00200     void SetLineColor(OGLVIEW* view, long col)
00201     {
00202         int idx = FindViewIdx(view);
00203         
00204         if (idx == -1)
00205             return;
00206         mViewLineColor[idx] = col;
00207     }
00208 
00209     void ShowAtTickSpanIdx(int idx, long ms)
00210     {
00211         if (idx < 0 || idx >= mShowAtTickSpan.size())
00212             return;
00213         mShowAtTickSpan[idx] = ms;
00214     }
00215     void ShowAtTickSpan(Window* wnd, long ms)
00216     {
00217         return ShowAtTickSpanIdx(FindWindowIdx(wnd), ms);
00218     }
00219 
00220     void ShowViewAtTickSpanIdx(int idx, long ms)
00221     {
00222         if (idx < 0 || idx >= mViewShowAtTickSpan.size())
00223             return;
00224         mViewShowAtTickSpan[idx] = ms;
00225     }
00226     void ShowAtTickSpan(OGLVIEW* view, long ms)
00227     {
00228         return ShowViewAtTickSpanIdx(FindViewIdx(view), ms);
00229     }
00230 
00231     static void
00232     GetTimeUnits(long timeInMs, int& hours, int& minutes, int& seconds, int& ms)
00233     {
00234         hours   = timeInMs / 3600000;
00235         minutes = (timeInMs % 3600000) / 60000;
00236         seconds = (timeInMs % 60000) / 1000;
00237         ms      = (timeInMs % 1000);
00238     }
00239 
00240     virtual void DisplayFunc()
00241     {
00242         LayoutViews();
00243         ZoomShiftRuler::DisplayFunc();
00244         LayoutWindows();
00245     }
00246 
00247 protected:
00248     int FindWindowIdx(Window* wnd)
00249     {
00250         for (int i=0; i<mWindows.size(); i++)
00251             if (mWindows[i] == wnd)
00252                 return i;
00253         return -1;
00254     }
00255 
00256     int FindViewIdx(OGLVIEW* view)
00257     {
00258         for (int i=0; i<mViews.size(); i++)
00259             if (mViews[i] == view)
00260                 return i;
00261         return -1;
00262     }
00263 
00264     virtual void DrawTick(long timeMs,int x,int y,long tickSpanMs,int tickLen=5)
00265     {
00266         DrawLine(x, y-tickLen, x, y);
00267 
00268         int         h,m,s,ms;
00269         GetTimeUnits(timeMs,h,m,s,ms);
00270 
00271         std::string format = h ? "%02d:%02d:%02d" : "%02d:%02d";
00272 
00273         if (tickSpanMs <= 500 && tickSpanMs > 100){
00274             format += ".%d";
00275             ms /= 100;
00276         }
00277         if (tickSpanMs <= 100 && tickSpanMs > 10){
00278             format += ".%02d";
00279             ms /= 10;
00280         }
00281         if (tickSpanMs <= 10)
00282             format += ".%03d";
00283 
00284         char    charBuf[256];
00285         if (h) // hours
00286             sprintf(charBuf, format.c_str(), h, m, s, ms);
00287         else
00288             sprintf(charBuf, format.c_str(), m, s, ms);
00289 
00290         int     txtY = y - tickLen - 10;
00291         int     txtX = x - ((x<15) ? 2 : 15);
00292 
00293         if (!mTextShaded)
00294             oglSys.PosColPrintf(mOglWnd, txtX, txtY, mTextColor, charBuf);
00295         else
00296             oglSys.ShadowPrintf(mOglWnd, txtX, txtY, mTextShadowBg,
00297                                 mTextShadowFg, charBuf);
00298     }
00299 
00300     virtual void LayoutWindows()
00301     {
00302         SetStipple(mLineStipple);
00303         for (int i=0; i<mWindows.size(); i++)
00304         {
00305             long showAtSpan = mShowAtTickSpan[i];
00306             SetSolidLineColor(mLineColor[i]);
00307             if (showAtSpan != -1 && mTickSpan > showAtSpan)
00308             {
00309                 mWindows[i]->SetVisible(false);
00310                 glPointSize(3);
00311                 int x = Unit2Pixel(mTimes[i]);
00312                 DrawPoint(x, mAxisY+mOffY[i]);
00313                 if (mDrawLineFlag)
00314                     DrawLine(x, mAxisY, x, mAxisY+mOffY[i]);
00315                 glPointSize(1);
00316             }
00317             else
00318             {
00319                 int x, y, w, h;
00320                 mWindows[i]->GetDimensions(x,y,w,h);
00321                 mWindows[i]->SetVisible(true);
00322                 x = Unit2Pixel(mTimes[i]);
00323                 mWindows[i]->SetDimensions(x-w/2+mOffX[i],mAxisY+mOffY[i],w,h);
00324                 if (mDrawLineFlag)
00325                     DrawLine(x, mAxisY, x+mOffX[i], mAxisY+mOffY[i]);
00326             }
00327         }
00328         SetStipple((short)oglSolid);
00329     }
00330 
00331     virtual void LayoutViews()
00332     {
00333         SetStipple(mViewLineStipple);
00334         int nrVisible = 0;
00335         for (int i=0; i<mViews.size(); i++)
00336         {
00337             int x = Unit2Pixel(mViewTimes[i]);
00338 
00339             SetSolidLineColor(mViewLineColor[i]);
00340             long showAtSpan = mViewShowAtTickSpan[i];
00341             if (showAtSpan != -1 && mTickSpan > showAtSpan)
00342                 ViewIdxPointLine(i, x, x, true, mViewDrawLineFlag);
00343             else
00344             {
00345                 int y, w, h, wW = W();
00346                 int x2 = x + mViewOffX[i];
00347                 OGLVIEW* view = mViews[i];
00348                 viewSys.SetTags(view, visibleTag);
00349                 viewSys.GetDimensions(view, 0, &y, &w, &h);
00350                 viewSys.SetDimensions(view, x2-w/2, mAxisY+mViewOffY[i], w, h);
00351 
00352                 if (mViewDrawLineFlag && (x>0 && x<wW && x2>0 && x2<wW))
00353                     DrawLine(x, mAxisY, x2, mAxisY+mViewOffY[i]);
00354                 if (x2+w/2<0 || x2-w/2>wW || y+h<0 || y>H())
00355                 {
00356                     HideView(view);
00357                     continue;
00358                 }
00359                 if (++nrVisible > mMaxVisibleImages)
00360                 {
00361                     ViewIdxPointLine(i, x2, x, true, false);
00362                     continue;
00363                 }
00364                 if (view->im || (view->im=LoadViewImage(mViewImIds[i])))
00365                 {
00366                     view->zoomX = view->h / (float) view->im->w;
00367                     view->zoomY = view->w / (float) view->im->h;
00368                 }
00369             }
00370         }
00371         SetStipple((short)oglSolid);
00372     }
00373 
00374     void
00375     ViewIdxPointLine(int idx, int pX, int lX, bool drawPoint, bool drawLine)
00376     {
00377         int w = W();
00378         if (drawPoint)
00379         {
00380             HideView(mViews[idx]);
00381             if (pX > 0 && pX < w)
00382             {
00383                 glPointSize(3);
00384                 DrawPoint(pX, mAxisY+mViewOffY[idx]);
00385                 glPointSize(1);
00386             }
00387         }
00388         if (drawLine && ((lX > 0 && lX < w) || (pX >0 && pX < w)))
00389             DrawLine(lX, mAxisY, pX, mAxisY+mViewOffY[idx]);
00390     }
00391 
00392 
00393     void HideView(OGLVIEW* view)
00394     {
00395         viewSys.ClearTags(view, visibleTag);
00396         if (mOglImageCache)
00397             viewSys.SetImage(view, 0);
00398     }
00399 
00400     std::vector<Window*>    mWindows;
00401     std::vector<long>       mTimes;
00402     std::vector<long>       mShowAtTickSpan;
00403     std::vector<int>        mOffX;
00404     std::vector<int>        mOffY;
00405     std::vector<long>       mLineColor;
00406     short                   mLineStipple;
00407     bool                    mDrawLineFlag;
00408 
00409     // RvB: 29-09-2009 added these for OGLVIEW* support
00410     std::vector<OGLVIEW*>   mViews;
00411     std::vector<long>       mViewTimes;
00412     std::vector<long long>  mViewImIds;
00413     std::vector<long>       mViewShowAtTickSpan;
00414     std::vector<int>        mViewOffX;
00415     std::vector<int>        mViewOffY;
00416     std::vector<long>       mViewLineColor;
00417     short                   mViewLineStipple;
00418     bool                    mViewDrawLineFlag;
00419 
00420     int                         mMaxVisibleImages;
00421     OglImageCache*              mOglImageCache;
00422     GetOglImageByIdInterface*   mGetOglImageByIdI;
00423 
00424 
00425 private:
00426     void Init(int w, int h, long startTime, long timeSpan)
00427     {
00428         SetDocDimensions(0,0,w,h);
00429         SetRange(startTime,timeSpan);
00430         mListener = 0;
00431         mDrawLineFlag = mViewDrawLineFlag = true;
00432         mLineStipple = mViewLineStipple = (short) oglSolid;
00433         mAxisY = 20;
00434         SetTextShadowColors(oglDARKGREY, oglLIGHTGREY);
00435 
00436         mMaxVisibleImages = 200;
00437         mOglImageCache    = 0;
00438         mGetOglImageByIdI = 0;
00439     }
00440 
00441     WindowTimeLineListener* mListener;
00442     void*                   mWndTimeLineListenerData;
00443 };
00444 } // namespace OglGui
00445 #endif

Generated on Fri Mar 19 09:31:41 2010 for ImpalaSrc by  doxygen 1.5.1