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