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

TagsWeekPlot.h

Go to the documentation of this file.
00001 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00002 // Author: Richard van Balen
00003 #ifndef Impala_Application_TagsLife_TagsWeekPlot_h
00004 #define Impala_Application_TagsLife_TagsWeekPlot_h
00005 
00006 #ifndef OglGui_WindowView2D_h
00007 #include "OglGui/WindowView2D.h"
00008 #endif
00009 
00010 #include "Tag.h"
00011 
00012 namespace Impala {
00013 namespace Application {
00014 namespace TagsLife {
00015 
00016 class TagsWeekPlot :    public OglGui::Window,
00017                         public OglGui::WindowListener
00018 {
00019 public:
00020     typedef OglGui::Window          Window;
00021     typedef OglGui::WindowView2D    WindowView2D;
00022     typedef OglGui::StaticText      StaticText;
00023 
00024     TagsWeekPlot(Window* parent, int x, int y, int w, int h, int nrView=100) :
00025         Window(parent,x,y,w,h)
00026     {
00027         Init(w,h,nrView);
00028     }
00029 
00030     void SetImage(int idx, OGLIMAGE* im)
00031     {
00032         if (idx < 0 || idx >= mOglImages.size())
00033             return;
00034         ReleaseOglImage(mOglImages[idx]);
00035         if (im)
00036             im->refCount++;
00037         mOglImages[idx] = im;
00038     }
00039 
00040     void ShowRange(int first, int last)
00041     {
00042         mFirstVisible = first;
00043         mLastVisible = last;
00044     }
00045 
00046     void BarColors(ULONG borderCol, ULONG bgCol, ULONG fillCol)
00047     {
00048         mBarBorderColor = borderCol;
00049         mBarBgColor     = bgCol;
00050         mBarFillColor   = fillCol;
00051     }
00052 
00053     int  FirstVisible()                 { return mFirstVisible; }
00054     int  LastVisible()                  { return mLastVisible; }
00055     void MinimumViewSize(int sz)        { mMinViewSize = sz; }
00056     int  MinimumViewSize()              { return mMinViewSize; }
00057 
00058 
00059     void Clear()
00060     {
00061         mMaxFreq = 0;
00062         mHistogram.clear();
00063         mFills.clear();
00064 
00065         for (int i=0; i<mOglImages.size(); i++)
00066             ReleaseOglImage(mOglImages[i]);
00067         mOglImages.clear();
00068     }
00069 
00070     void AddToHistogram(int val, float fillPerc = 0.f, OGLIMAGE* oglIm=0)
00071     {
00072         if (val > mMaxFreq) {
00073             mMaxFreq = val;
00074             double newMin, newMax;
00075             double step = findStep(0.0, (double) mMaxFreq, newMin, newMax);
00076             mStep = ceil(step);
00077             mMaxFreq = ceil(newMax);
00078         }
00079 
00080         mHistogram.push_back(val);
00081         mFills.push_back(fillPerc);
00082         mOglImages.push_back(oglIm);
00083         if (oglIm !=0 )
00084             oglIm->refCount++;
00085     }
00086 
00087     int NrVisible()
00088     {
00089         return mLastVisible-mFirstVisible+1;
00090     }
00091 
00092     virtual void DisplayFunc()
00093     {
00094         OGC oldOGC;
00095         OGCSave(&oldOGC);
00096         Window::DisplayFunc();
00097         if (NrVisible() != 0)
00098         {
00099             ShowHistogram();
00100             HandleViews();
00101             HandleDetailView();
00102         }
00103         OGCRestore(&oldOGC);
00104     }
00105 
00106     // Listener for the WindowView2D's and WeekSensorWnd
00107     virtual void
00108     WindowMouseEvent(OglGui::Window *src, int msg, int but, int state,
00109                      int x, int y, void *userData )
00110     {
00111         if (userData == (void*) WNDVIEW2D_IDX)
00112             WndView2DMouseEvent((WindowView2D*)src,msg);
00113         if (userData == (void*) WEEKWND_IDX)
00114             WeekWndMouseEvent(src,msg,x,y);
00115     }
00116 
00117 protected:
00118 
00119     // Show detail view if mouse in a view
00120     void WndView2DMouseEvent(WindowView2D* wndView2D, int msg)
00121     {
00122         if (msg == oglMouseEnter /* && wndView2D->W()<100 */)
00123         {
00124             mDetailRef = wndView2D;
00125             mDetailView->SetImage(wndView2D->GetOglView()->im);
00126             int topX = wndView2D->W()/2-50;
00127             int topY = -120;
00128             ToTopWindow(wndView2D,topX,topY);
00129             mDetailView->SetDimensions(topX,topY,100,100);
00130             mDetailView->SetVisible(true);
00131         }
00132         if (msg == oglMouseLeave)
00133             mDetailView->SetVisible(false);
00134     }
00135 
00136     // Show text representation of week nr in text balloon.
00137     void WeekWndMouseEvent(Window* wnd, int msg, int x, int y)
00138     {
00139         int   nrVis  = NrVisible();
00140 
00141         if (nrVis!=0 && (msg == oglMouseEnter || msg == oglMouseMove))
00142         {
00143             int topX = AXIS_X + x + 10;
00144             int topY = -30; // Fixed y position for text balloon
00145 
00146             ToTopWindow(this,topX,topY);
00147             mWeekText->SetDimensions(topX,topY,180,20);
00148             mWeekText->SetVisible(true);
00149 
00150             float slotSz = (W() - AXIS_X) / (float) nrVis;
00151             int   weekNr = mFirstVisible + x / slotSz;
00152 
00153             mWeekText->SetText(Tag::flickrWeekToString(weekNr));
00154         }
00155         if (msg == oglMouseLeave)
00156             mWeekText->SetVisible(false);
00157     }
00158 
00159     void HandleViews()
00160     {
00161         int   nrVis  = NrVisible();
00162         float slotSz = (W() - AXIS_X) / (float) nrVis;
00163 
00164         for (int i=0; i<mNrViews; i++)
00165         {
00166             mWndViews[i]->SetVisible(i<nrVis && slotSz>=mMinViewSize);
00167             if (slotSz < mMinViewSize)
00168                 continue;
00169             int x = AXIS_X + i * slotSz;
00170             mWndViews[i]->SetDimensions(x,AXIS_Y,slotSz,slotSz);
00171             mWndViews[i]->SetImage(i>=nrVis ? 0 : mOglImages[mFirstVisible+i]);
00172         }
00173     }
00174 
00175     void ShowWeekNr(int weekNr, int x, int slotSz)
00176     {
00177         if (slotSz < 24)
00178             return;
00179 
00180         int  txtX, txtY;
00181         char buf[10];
00182         sprintf(buf,"%d", weekNr);
00183         oglSys.AlignTextXY(mOglWnd,buf,oglCenterAlign,oglCenterAlign,
00184                            slotSz, 20, &txtX, &txtY);
00185         oglSys.PosColPrintf(mOglWnd,x+txtX,txtY+2,mBarBorderColor,buf);
00186     }
00187 
00188     void ShowLabel(int value, int y)
00189     {
00190         int  txtX, txtY;
00191         char buf[10];
00192         sprintf(buf,"%d", value);
00193         oglSys.AlignTextXY(mOglWnd,buf,oglRightAlign,oglBottomAlign,
00194                            AXIS_X-3, 0, &txtX, &txtY);
00195         oglSys.PosColPrintf(mOglWnd,txtX,y-4,mBarBorderColor,buf);
00196     }
00197 
00198     void ShowHistogram()
00199     {
00200         float slotSz = (W() - AXIS_X) / (float) NrVisible();
00201         float binSz  = (slotSz >= 2) ? slotSz / 2 : 1;
00202         float viewH  = (slotSz >= mMinViewSize) ? slotSz : 0;
00203         bool  oneCol = mBarBgColor == mBarFillColor &&
00204                        mBarBgColor == mBarBorderColor;
00205 
00206         int yHeight = H()-AXIS_Y-viewH-7;
00207 
00208         for (int i=mFirstVisible; i<=mLastVisible; i++)
00209         {
00210             int x    = AXIS_X + (i-mFirstVisible) * slotSz;
00211             int barH = (mHistogram[i]/(float) mMaxFreq) * yHeight;
00212 
00213             if (barH >= 1)
00214             {
00215                 SetSolidFillColor(mBarBgColor);
00216                 FillRectangle(x+slotSz/4,AXIS_Y+viewH,binSz,barH);
00217             }
00218             if (!oneCol && mFills[i] * barH >= 1)
00219             {
00220                 SetSolidFillColor(mBarFillColor);
00221                 FillRectangle(x+slotSz/4,AXIS_Y+viewH,binSz,mFills[i]*barH);
00222             }
00223             if (!oneCol && barH >= 1)
00224             {
00225                 SetSolidLineColor(mBarBorderColor);
00226                 DrawRectangle(x+slotSz/4,AXIS_Y+viewH,binSz,barH);
00227             }
00228             ShowWeekNr(i, x, slotSz);
00229         }
00230 
00231         SetSolidLineColor(mBarBorderColor);
00232         DrawRectangle(AXIS_X+1, AXIS_Y+viewH, 0, yHeight);
00233         for(long i=0; i <= mMaxFreq; i+= mStep) {
00234                 //ILOG_INFO("i=" << i << "; mMaxFreq=" << mMaxFreq);
00235                 int y = (i/(float) mMaxFreq) * yHeight+AXIS_Y+viewH;
00236             DrawRectangle(AXIS_X, y, -3, 0);
00237             ShowLabel(i, y);
00238         }
00239     }
00240 
00241     // Draw 2 lines from view to detail view
00242     void HandleDetailView()
00243     {
00244         if (!mDetailView->GetVisible())
00245             return;
00246 
00247         int x,y,w,h;
00248         mDetailRef->GetDimensions(x,y,w,h);
00249         SetSolidLineColor(oglRED);
00250         DrawLine(x,y,x+w/2-50,y-AXIS_Y);
00251         DrawLine(x+w,y,x+w/2+50,y-AXIS_Y);
00252     }
00253 
00254 private:
00255     void Init(int w, int h, int nrView)
00256     {
00257         mFirstVisible = 0;
00258         mLastVisible  = 10;
00259         mNrViews      = nrView;
00260         mMinViewSize  = 8;
00261         mMaxFreq      = 0;
00262 
00263         mBarBorderColor = oglRED;
00264         mBarBgColor     = oglRED;
00265         mBarFillColor   = oglRED;
00266 
00267         for (int i=0; i<mNrViews; i++)
00268         {
00269             WindowView2D* wndView = new WindowView2D(this,0,0,10,10,0);
00270             wndView->Texturing(false);
00271             wndView->SetVisible(false);
00272             // Set listener to react to mouse Enter/Leave
00273             wndView->SetWindowListener(this,WNDVIEW2D_IDX);
00274             mWndViews.push_back(wndView);
00275         }
00276 
00277         Window* topWnd = this;
00278         while(topWnd->GetParent())
00279             topWnd = topWnd->GetParent();
00280         mDetailView = new WindowView2D(topWnd,0,0,10,10,0);
00281         mDetailView->Texturing(false);
00282 
00283         mDetailView->SetVisible(false);
00284 
00285         mWeekSensorWnd = new Window(this,AXIS_X,0,w,AXIS_Y);
00286         mWeekSensorWnd->ConnectTo(this,OglGui::TOLEFTRIGHT);
00287         mWeekSensorWnd->SetWindowListener(this,WEEKWND_IDX);
00288         // Indicate that we want all mouse motion events
00289         mWeekSensorWnd->GetOGLWND()->allMouseMotion = 1;
00290 
00291         mWeekText = new StaticText(topWnd,0,0,100,20,"");
00292         mWeekText->SetRoundness(20,20,20,20);
00293         mWeekText->SetBorderType(BEV_LINE);
00294         mWeekText->SetBorderFillShaded(2);
00295         mWeekText->SetVisible(false);
00296     }
00297 
00298     double findStep(double min, double max, double& newMin, double& newMax) {
00299         double range = max - min;
00300         if(range < 0) range *= -1;
00301         double exponent = floor(log10(range));
00302         double coefficient = range/pow(10, exponent);
00303 
00304         double step = 1;
00305         if(coefficient <= 5) {
00306                 step = 0.5;
00307                 if(coefficient <= 2.5) {
00308                         step = 0.25;
00309                         if(coefficient == 1) step = 0.1;
00310                 }
00311         }
00312 
00313         step *= pow(10, exponent);
00314         if(step == 2.5) step = 2;
00315 
00316         newMin = floor(min/step)*step;
00317         newMax = ceil(max/step)*step;
00318 
00319         if(min > max) return -step;
00320         return step;
00321     }
00322     double findStep(double& min, double& max) {return findStep(min, max, min, max);}
00323 
00324 
00325     std::vector<int>                mHistogram;
00326     std::vector<float>              mFills;
00327     std::vector<OGLIMAGE*>          mOglImages;
00328     std::vector<WindowView2D*>      mWndViews;
00329 
00330     WindowView2D*                   mDetailView;
00331     WindowView2D*                   mDetailRef;
00332 
00333     Window*                         mWeekSensorWnd;
00334     StaticText*                     mWeekText;
00335 
00336     int                             mNrViews;
00337     int                             mFirstVisible;
00338     int                             mLastVisible;
00339     int                             mMinViewSize;
00340     long                            mMaxFreq;
00341     int                                                         mStep;
00342 
00343     ULONG                           mBarBorderColor;
00344     ULONG                           mBarBgColor;
00345     ULONG                           mBarFillColor;
00346 
00347     const static int AXIS_X        = 65;
00348     const static int AXIS_Y        = 20;
00349     const static int WNDVIEW2D_IDX = 1;
00350     const static int WEEKWND_IDX   = 2;
00351 };
00352 
00353 } // namespace TagsLife
00354 } // namespace Application
00355 } // namespace Impala
00356 
00357 #endif

Generated on Fri Mar 19 09:30:40 2010 for ImpalaSrc by  doxygen 1.5.1