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
00016
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
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
00120
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
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
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
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
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
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:
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
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
00343
00344
00345
00346
00347
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)
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
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
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
00483
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
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 }
00568 }
00569 }
00570
00571 #endif // GridWindow_h