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

GridWindow.h

Go to the documentation of this file.
00001 #ifndef VideoExcel_GridWindow_h
00002 #define VideoExcel_GridWindow_h
00003 
00004 #include "TableColumn.h"
00005 #include "OglGui/WindowScrollBar.h"
00006 
00007 #ifndef OglGui_StaticText_h
00008 #include "OglGui/StaticText.h"
00009 #endif
00010 
00011 namespace Impala {
00012 namespace Application {
00013 namespace VideoExcel {
00014 
00015 //using namespace OglGui;
00016 //class TableColumn;
00017 
00018 class GridWindow : public OglGui::Window,
00019                    OglGui::ScrollBarListener,
00020                    public TableUpdateListener
00021 {
00022 public:
00023     typedef OglGui::Window                      Window;
00024     typedef OglGui::ScrollBar                   ScrollBar;
00025     typedef OglGui::WindowScrollBar             WindowScrollBar;
00026 
00027     GridWindow(Window* parent, TableDataSource *source, int width, int height) :
00028         Window(parent, width, height)
00029     {
00030         Init(source, width, height);
00031     }
00032 
00033     GridWindow(Window* parent, TableDataSource *source, int x, int y,
00034                int width, int height) :
00035         Window(parent, x, y, width, height)
00036     {
00037         Init(source, width, height);
00038     }
00039 
00040     void AddColumnsFromDataSource()
00041     {
00042         std::vector<TableSourceColumnDescription> c = mSource->GetColumns();
00043         ILOG_DEBUG("Searching for image column...");
00044         for (int i=0; i<c.size(); i++)
00045         {
00046             TableSourceColumnDescription d = c[i];
00047             if (d.GetType() == TableDataSource::TYPE_IMAGE)
00048             {
00049                 ILOG_DEBUG("Found image column: " << d.GetName());
00050                 mImageColumn = d.GetName();
00051                 break;
00052             }
00053         }
00054         HandleLayoutChange();
00055     }
00056 
00057     void HandleLayoutChange()
00058     {
00059         UpdateNumberOfRowsEvent();
00060     }
00061 
00062 
00063     inline int GetGridRows()
00064     {
00065         int viewheight = H() - mGridHeaderHeight;
00066         return viewheight / mGridHeight;
00067     }
00068 
00069     inline int GetGridColumns()
00070     {
00071         // remove width of scrollbar too
00072         return (W() - 20) / mGridWidth;
00073     }
00074 
00075     void SetGridSize(int gx, int gy)
00076     {
00077         mGridHeight = gy;
00078         mGridWidth = gx;
00079 
00080         UpdateNumberOfRowsEvent();
00081         UpdateRowsEvent();
00082     }
00083 
00084     void UpdateGrid()
00085     {
00086         if (mImageColumn == "")
00087             return;
00088 
00089         mCache->HideViews();
00090 
00091         int startRow = mSource->GetStartRow();
00092         int nx       = GetGridColumns();
00093         int ny       = GetGridRows();
00094         int x        = 0;
00095         int y        = 0;
00096         for (int i=startRow; i<startRow+mSource->GetNumberOfRows(); i++)
00097         {
00098             int px = x * (mGridWidth + 4);
00099             int py = H() - mGridHeaderHeight-mGridHeight-(y * (mGridHeight+4));
00100 
00101             mCache->ShowView(mImageColumn, i, px+2, py+2, mGridWidth-4,
00102                              mGridHeight-4);
00103             if (++x>=nx)
00104             {
00105                 y++;
00106                 x = 0;
00107             }
00108         }
00109     }
00110 
00111     int GetRowForXY(int x, int y)
00112     {
00113         if (x == 0 || y == 0) return -1;
00114 
00115         y = H() - mGridHeaderHeight - y;
00116 
00117         int px = x / (mGridWidth+4);
00118         int py = y / (mGridHeight+4);
00119         //ILOG_DEBUG("GetRowForXY: " << px << ", " << py << " = " <<
00120         //           py*GetGridColumns()+px);
00121         return mSource->GetStartRow()+ py * GetGridColumns() + px;
00122     }
00123 
00124     void GetXYForRow(int row, int &px, int &py)
00125     {
00126         row-=mSource->GetStartRow();
00127         int y = row / GetGridColumns();
00128         int x = row % GetGridColumns();
00129 
00130         px = x * (mGridWidth + 4);
00131         py = H() - mGridHeaderHeight - mGridHeight - (y * (mGridHeight + 4));   
00132     }
00133 
00134 // Listeners
00135 
00136     virtual void UpdateRowsEvent()
00137     {
00138         mReady = false;
00139         if (mSource->GetFilteredRows() == mSource->GetNumberOfRows())
00140             mVertScrollBar->SetVisible(false);
00141         else
00142         {
00143             mVertScrollBar->SetVisible(true);
00144             mVertScrollBar->SetRange(mSource->GetFilteredRows(), mSource->GetNumberOfRows());
00145         }
00146         if (mVertScrollBar->GetValue() > mSource->GetFilteredRows())
00147         {
00148             ILOG_DEBUG("scrollbar out of range, resetting.");
00149             mReady = true;
00150             mVertScrollBar->SetValue(0);
00151             mSource->SetStartRow(0);
00152             UpdateScene();
00153         }
00154 //        mSource->MarkVisibleRows(2, true);
00155         UpdateGrid();
00156         mReady = true;
00157     }
00158 
00159     virtual void ReshapeFunc(int w, int h)
00160     {
00161         Window::ReshapeFunc(w,h);
00162         HandleLayoutChange();
00163     }
00164 
00165     virtual void UpdateNumberOfRowsEvent()
00166     {
00167         ILOG_DEBUG("UpdateNumberOfRowsEvent: " << GetGridRows() << " rows, " <<
00168                    GetGridColumns() << " columns.");
00169         mSource->SetNumberOfRows(GetGridRows() * GetGridColumns());
00170 
00171         mVertScrollBar->SetLineIncrement(GetGridColumns());
00172     }
00173 
00174     virtual void OnScroll(ScrollBar *src, int position, void *userData)
00175     {
00176         if (!mReady) return;
00177         // round down to nearest whole line of images:
00178         mSource->SetStartRow(position / GetGridColumns() * GetGridColumns());
00179 
00180     }
00181 
00182     virtual void UpdateScrollFromSourceEvent()
00183     {
00184         mVertScrollBar->SetValue(mSource->GetStartRow());
00185     }
00186 
00187     void ScrollRelative(int nr)
00188     {
00189         mSource->SetStartRow(mSource->GetStartRow() + nr);
00190         UpdateScrollFromSourceEvent();
00191     }
00192 
00193     virtual void
00194     MouseFunc(int msg, int but, int state, int x, int y)
00195     {
00196         int nLine = ((state&oglShift) ? 5 : 1);
00197         if (msg == oglMouseWheelUp)
00198             mVertScrollBar->ChangePos(-mVertScrollBar->LineIncrement() * nLine);
00199         if (msg == oglMouseWheelDown)
00200             mVertScrollBar->ChangePos(mVertScrollBar->LineIncrement() * nLine);
00201 
00202         int row = -1;
00203         if (mShowZoomView)
00204             UpdateZoomView(row, x,y);
00205         
00206         if (msg == oglMouseDown && but == oglLeftButton)
00207         {
00208             if (row == -1)
00209                 row = GetRowForXY(x, y);
00210             if (row >= 0)
00211             {
00212                 if (state & oglShift && mLastSelectedRow != -1)
00213                 {
00214                     ILOG_DEBUG("shift-select range " << mLastSelectedRow <<
00215                                " to " << row);
00216                     mSource->MarkRange(mLastSelectedRow, row, 1, true);
00217                     mLastSelectedRow = -1;
00218                 }
00219                 else
00220                 {
00221                     mSource->MarkRow(row, 1, true, true);
00222                     mLastSelectedRow = row;
00223                 }
00224             }
00225         }
00226 
00227         if (msg == oglMouseMove && (state & oglLeftButton))
00228         {
00229             mMouseXE = x;
00230             mMouseYE = y;
00231             if (!mSelecting)
00232             {
00233                 mMouseXS = x;
00234                 mMouseYS = y;
00235                 mSelecting = true;
00236             }
00237         }
00238         if (msg == oglMouseUp && but == oglLeftButton)
00239         {
00240             mSelecting = false;
00241             mSource->DoUpdateSelectionEvent();
00242         }
00243     }
00244 
00245 
00246     virtual void KeyboardFunc(int c, int state)
00247     {
00248         switch (c)
00249         {
00250             case oglPAGEDOWN:
00251                 ScrollRelative(mSource->GetNumberOfRows());
00252                 break;
00253             case oglPAGEUP:
00254                 ScrollRelative(-mSource->GetNumberOfRows());
00255                 break;
00256 
00257             case oglUP:
00258                 ScrollRelative(-GetGridColumns());
00259                 break;
00260 
00261             case oglDOWN:
00262                 ScrollRelative(+GetGridColumns());
00263                 break;
00264 
00265             // 1-6 colorize mouse-marked selection
00266             case '1': TransformMarkedSelectionTo(1, 4); break;
00267             case '2': TransformMarkedSelectionTo(1, 8); break;
00268             case '3': TransformMarkedSelectionTo(1, 16); break;
00269             case '4': TransformMarkedSelectionTo(1, 32); break;
00270             case '5': TransformMarkedSelectionTo(1, 64); break;
00271             case '6': TransformMarkedSelectionTo(1, 128); break;
00272 
00273             // shift 1-6 recall colored selection to mouse-marked
00274             case '!': TransformMarkedSelectionTo(4, 1); break;
00275             case '@': TransformMarkedSelectionTo(8, 1); break;
00276             case '#': TransformMarkedSelectionTo(16, 1); break;
00277             case '$': TransformMarkedSelectionTo(32, 1); break;
00278             case '%': TransformMarkedSelectionTo(64, 1); break;
00279             case '^': TransformMarkedSelectionTo(128, 1); break;
00280 
00281             case 138: // Escape: unmark selection
00282                 mSource->MarkAllRows(1, false);
00283                 break;
00284 
00285             case '`':
00286                 ShowZoomView(!mShowZoomView);
00287                 break;
00288             case '~':
00289                 ToggleZoomViewSize();
00290                 break;
00291 
00292             case 'x':
00293                    SetGridSize(96, 96); break;
00294             case 'c':
00295                    SetGridSize(128, 128); break;
00296             case 'v':
00297                    SetGridSize(256, 256); break;
00298             case 'b':
00299                    SetGridSize(384, 384); break;
00300 
00301 
00302         }
00303     }
00304 
00305     bool GetShowPreview()
00306     {
00307         return mShowZoomView;
00308     }
00309 
00310     bool SetShowPreview(bool zoom)
00311     {
00312         ShowZoomView(zoom);
00313     }
00314 
00315 
00316     void TransformMarkedSelectionTo(int sourcemask, int targetmask)
00317     {
00318         mSource->TransformMarkedTo(sourcemask, targetmask);
00319         mSource->DoUpdateRowsEvent();
00320     }
00321 
00322     /* zoom view */
00323     void ShowZoomView(bool show)
00324     {
00325         if (!mCache)
00326             ILOG_WARNING("Zoom view disabled: no cache set.");
00327         if (!mZoomView)
00328             ILOG_WARNING("Zoom view disabled: no target window set.");
00329 
00330         mShowZoomView = show;
00331         if (mShowZoomView)
00332             viewSys.SetTags(mZoomView, visibleTag);
00333         else
00334         {
00335             viewSys.ClearTags(mZoomView, visibleTag);
00336             mZoomView->UserData1 = (void *) -1;
00337         }
00338     }
00339 
00340     void UpdateZoomView(int row, int x, int y)
00341     {
00342         // Richard:
00343         //  what I want to do here is to translate/scale the coordinates from this WindowTable view
00344         // to the window I designated as an overlay window in mainVideoExcel, there ought to be a nice
00345         // OGL function which handles this coordinate translation somewhere.
00346 
00347         // translation is now set manually for this layout:
00348         int transX = 0, transY = 140;
00349 
00350         int zx=x + transX;
00351         int zy=y + transY;
00352         if (zy + mZoomViewSize > mZoomViewTargetWindow->H())
00353             zy = mZoomViewTargetWindow->H() - mZoomViewSize;
00354         
00355         if (row == -1)
00356             row = GetRowForXY(x, y);
00357         if (mZoomViewFollowMouse)
00358             viewSys.SetDimensions(mZoomView, zx, zy, mZoomViewSize, mZoomViewSize);
00359         if (mZoomView->UserData1 != (void *) row)
00360         {
00361             SetZoomView(row);
00362         }
00363     }
00364 
00365     void ToggleZoomViewSize()
00366     {
00367         int newsize;
00368         switch (mZoomViewSize)
00369         {
00370             case 128: newsize = 256; break;
00371             case 256: newsize = 384; break;
00372             case 384: newsize = 512; break;
00373             case 512: newsize = 768; break;
00374             case 768: newsize = 1024; break;
00375             case 1024: newsize = 128; break;
00376         }
00377         mZoomViewSize = newsize;
00378         if (mZoomViewFollowMouse)
00379         {
00380             int x,y,w,h;
00381             viewSys.GetDimensions(mZoomView, &x,&y,&w,&h);
00382             if (y + mZoomViewSize > mZoomViewTargetWindow->H())
00383                 y = mZoomViewTargetWindow->H() - mZoomViewSize;
00384             viewSys.SetDimensions(mZoomView, x,y,mZoomViewSize,mZoomViewSize);
00385             float zoom = (mZoomView->h)/(float)mZoomView->im->h;
00386             viewSys.SetZoom(mZoomView, zoom, zoom);
00387         }
00388     }
00389 
00390     void SetZoomView(int row)
00391     {
00392         if (!mCache || !mShowZoomView)
00393             return;
00394 
00395         OGLVIEW* v = mCache->GetViewFromCache(mSource->GetID(row));
00396         if (!v || v->UserData2 == (void*)2) // image not currently in cache?
00397             return;
00398         OGLIMAGE* im = v->im;
00399         viewSys.SetImage(mZoomView, im);
00400 
00401         float zoom = (mZoomView->h)/(float)im->h;
00402         viewSys.SetZoom(mZoomView, zoom, zoom);
00403     }
00404 
00405     void SetZoomViewTargetWindow(Window *t, bool followMouse=false)
00406     {
00407         mZoomViewTargetWindow = t;
00408         mZoomView = viewSys.View2D(t->GetOGLWND(), 0, 0, 0, mZoomViewSize,
00409                                    mZoomViewSize);
00410         viewSys.SetTags(mZoomView, FlexViewTags);
00411         int clearTags = visibleTag|showBorderTag|showBgTag|selectableTag;
00412         viewSys.ClearTags(mZoomView, clearTags);
00413         viewSys.SetColor(mZoomView, OGL_BG, oglTrLIGHTGREY);
00414         mZoomView->UserData1 = (void *) -1;
00415         mZoomViewFollowMouse = followMouse;
00416     }
00417 
00418 // Overloaded standard OGL functions
00419 
00420     virtual void
00421     DisplayFunc()
00422     {
00423         OGC     myOGC;
00424         OGCSave(&myOGC);
00425 
00426         UpdateGrid();
00427 
00428         if (mCache && mCache->ProcessDelayLoad())
00429             UpdateScene();
00430         
00431         int mcx, mcy, mcw, mch;
00432         if (mSelecting)
00433         {
00434             mcx = (mMouseXS < mMouseXE) ? mMouseXS : mMouseXE;
00435             mcw = (mMouseXS < mMouseXE) ? mMouseXE-mMouseXS : mMouseXS-mMouseXE;
00436             mcy = (mMouseYS < mMouseYE) ? mMouseYS : mMouseYE;
00437             mch = (mMouseYS < mMouseYE) ? mMouseYE-mMouseYS : mMouseYS-mMouseYE;
00438             mSource->MarkAllRows(1, false);
00439         }
00440 
00441         for (int row = mSource->GetStartRow(); row < mSource->GetEndRow(); row++)
00442         {
00443             int px=0, py=0;
00444             GetXYForRow(row, px, py);
00445 
00446             if (mSelecting && mcy < py && py+mGridHeight < mcy + mch &&
00447                 mcx < px && px+mGridWidth < mcx + mcw)
00448             {
00449                     mSource->MarkRow(row, 1);
00450             }
00451 
00452             int mark = mSource->GetMark(row);
00453             if (mark)
00454             {
00455                 SetSolidFillColor(MarkToColor(mark));
00456                 FillRectangle(px-1, py-1, mGridWidth+2, mGridHeight+2);
00457             }
00458         }
00459 
00460         if (mSelecting)
00461         {
00462             // draw the current mouse selection:
00463             SetStipple((short)oglSolid);
00464             SetLineWidth(2.0f);
00465             SetSolidLineColor(0xff444466);
00466             DrawRectangle(mcx,mcy,mcw,mch);
00467         }
00468 
00469         OGCRestore(&myOGC);
00470         Window::DisplayFunc();
00471     }
00472 
00473 private :
00474 
00475     int MarkToColor(int m)
00476     {
00477         int r=127,g=127,b=127;
00478         if (m == -1)
00479             return ARGB2COLOR(255, 200, 200, 200);
00480         if (m & 1)
00481             r = g = b = 255;
00482 //        if (m & 2)
00483 //            r = g = b = 150;
00484         if (m & 4)
00485             r += 64;
00486         if (m & 8)
00487             g += 64;
00488         if (m & 16)
00489             b += 64;
00490         if (m & 32)
00491             { r += 64; g += 64; }
00492         if (m & 64)
00493             { g += 64; b += 64; }
00494         if (m & 128)
00495             { r += 64; b += 64; }
00496         if (r>255) r = 255;
00497         if (g>255) g = 255;
00498         if (b>255) b = 255;
00499         return ARGB2COLOR(255, r,g,b);
00500     }
00501 
00502     void
00503     Init(TableDataSource *source, int w, int h)
00504     {
00505         mReady = false;
00506 
00507         mSource                 = source;
00508         mGridHeight             = 128;
00509         mGridWidth              = 128;
00510         mGridHeaderHeight       = 20;
00511         mImageColumn            = "";
00512         mSelecting              = false;
00513         mAutoZoom               = false;
00514         mZoomViewTargetWindow   = 0;
00515         mLastSelectedRow        = -1;
00516 
00517         // init zoom view:
00518         mZoomViewSize           = 384;
00519         mZoomView               = 0;
00520         mShowZoomView           = false;
00521         mZoomViewFollowMouse    = false;
00522 
00523         SetBackground(0xffffffff);
00524         SetBorderType(1);
00525         SetBorderFillShaded(-2);
00526 
00527         mSource->AddTableUpdateListener(this);
00528         mVertScrollBar = new WindowScrollBar(this, false);
00529         mVertScrollBar->SetRange(mSource->GetTotalRows(),
00530                                  mSource->GetNumberOfRows());
00531         mVertScrollBar->SetScrollBarListener(this, 0);
00532         oglSys.SetAllMouseMotion( mOglWnd, 1 );
00533 
00534         mCache = new TableViewCache(this, mSource);
00535 
00536         mReady = true;
00537     }
00538 
00539     bool                    mReady;
00540     bool                    mSelecting;
00541     bool                    mAutoZoom;
00542     bool                    mShowZoomView;
00543     bool                    mZoomViewFollowMouse;
00544 
00545     int                     mZoomViewSize;
00546     int                     mGridHeight;
00547     int                     mGridWidth;
00548     int                     mGridHeaderHeight;
00549     int                     mMouseXS, mMouseYS, mMouseXE, mMouseYE;
00550     int                     mLastSelectedRow;
00551 
00552     String                  mImageColumn;
00553 
00554     TableDataSource*        mSource;
00555     TableViewCache*         mCache;
00556 
00557     Window*                 mHeaderWindow;
00558     Window*                 mZoomViewTargetWindow;
00559     WindowScrollBar*        mVertScrollBar;
00560     OGLVIEW*                mZoomView;
00561 
00562     ILOG_VAR_DEC;
00563 };
00564 
00565 ILOG_VAR_INIT(GridWindow, Application.VideoExcel);
00566 
00567 } // namespace VideoExcel
00568 } // namespace Application
00569 } // namespace Impala
00570 
00571 #endif // GridWindow_h

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