00001 #ifndef VideoExcel_TableWindow_h
00002 #define VideoExcel_TableWindow_h
00003
00004 #include "TableColumn.h"
00005 #include "OglGui/WindowScrollBar.h"
00006
00007 namespace Impala {
00008 namespace Application {
00009 namespace VideoExcel {
00010
00011 class TableWindow : public OglGui::Window,
00012 OglGui::ScrollBarListener,
00013 public TableUpdateListener
00014 {
00015 public:
00016 typedef OglGui::Window Window;
00017 typedef OglGui::ScrollBar ScrollBar;
00018 typedef OglGui::ScrollBarListener ScrollBarListener;
00019 typedef OglGui::WindowScrollBar WindowScrollBar;
00020 typedef Impala::Core::Array::Array2dVec3UInt8 Array2dVec3UInt8;
00021 typedef OglGui::MenuTopPane MenuTopPane;
00022 typedef OglGui::Menu Menu;
00023
00024 TableWindow(Window* parent, TableDataSource *source, int width, int height):
00025 Window(parent, width, height)
00026 {
00027 Init(source, width, height);
00028 }
00029
00030 TableWindow(Window* parent, TableDataSource *source, int x, int y,
00031 int width, int height) :
00032 Window(parent, x, y, width, height)
00033 {
00034 Init(source, width, height);
00035 }
00036
00037 private:
00038 void AddColumnFromDescription(TableSourceColumnDescription d,
00039 bool dynamicWidth=false)
00040 {
00041 TableColumn *p = new TableColumn(this,mSource,d.GetName(),d.GetWidth());
00042 if (dynamicWidth)
00043 p->SetColumnWidthDynamic(true);
00044 switch (d.GetType())
00045 {
00046 case TableDataSource::TYPE_TEXT:
00047 p->SetDisplayMode(TableCell::DISPLAY_TEXT);
00048 break;
00049 case TableDataSource::TYPE_INT:
00050 p->SetSortType(TableDataSource::TYPE_INT);
00051 break;
00052 case TableDataSource::TYPE_DOUBLE:
00053 p->SetSortType(TableDataSource::TYPE_DOUBLE);
00054 break;
00055 case TableDataSource::TYPE_IMAGE:
00056 p->SetDisplayMode(TableCell::DISPLAY_IMAGE);
00057 if (mZoomViewCache == 0)
00058 SetZoomViewCache(p->GetViewCache());
00059 break;
00060 case TableDataSource::TYPE_NORMALIZEDVALUE:
00061 if (dynamicWidth)
00062 p->SetDisplayMode(TableCell::DISPLAY_FILLED,d.GetVisParam());
00063 else
00064 p->SetDisplayMode(TableCell::DISPLAY_DOT, d.GetVisParam());
00065 break;
00066 }
00067 AddColumn(p);
00068 }
00069
00070 void AddColumn(TableColumn* col, int insertAt=-1)
00071 {
00072 if (insertAt==-1 || insertAt>mColumns.size()-1)
00073 mColumns.push_back(col);
00074 else
00075 mColumns.insert(mColumns.begin()+insertAt+1,col);
00076 col->SetAllowReposition(false);
00077 }
00078
00079 public:
00080 void AddColumnsFromDataSource()
00081 {
00082 std::vector<TableSourceColumnDescription> c = mSource->GetColumns();
00083 ILOG_DEBUG("Adding " << c.size() << " fixed columns from datasource");
00084 int swidth = 0;
00085 for (int i=0; i<c.size();i++)
00086 {
00087 AddColumnFromDescription(c[i]);
00088 swidth += c[i].GetWidth();
00089 }
00090
00091 mStaticColumnWidth = swidth;
00092 mStaticColumnCount = c.size();
00093
00094 std::vector<TableSourceColumnDescription> d=mSource->GetExtraColumns();
00095 ILOG_DEBUG("Adding " << d.size() << " dynamic columns from datasource");
00096 for (int i=0; i<d.size();i++)
00097 {
00098 AddColumnFromDescription(d[i], true);
00099 }
00100
00101 HandleColumnPositions();
00102 HandleLayoutChange();
00103 }
00104
00105 void HandleColumnPositions()
00106 {
00107 int x,y,w,h;
00108 int mx = 0;
00109 int maxw = W() - 60;
00110 int wpc = 0;
00111 if (mColumns.size() - mStaticColumnCount > 0)
00112 wpc = (maxw-mStaticColumnWidth)/(mColumns.size()-mStaticColumnCount);
00113
00114 for (int i=0; i<mColumns.size(); i++)
00115 {
00116 mColumns[i]->GetDimensions(x,y,w,h);
00117 x = mx;
00118 if (mColumns[i]->GetColumnWidthDynamic())
00119 w = wpc;
00120
00121 mx += w + 2;
00122 mColumns[i]->SetDimensions(x,y,w,h);
00123
00124
00125
00126
00127
00128 }
00129 }
00130
00131 void HandleLayoutChange()
00132 {
00133 UpdateNumberOfRowsEvent();
00134 }
00135
00136 void ResetFilters()
00137 {
00138 ILOG_DEBUG("Reset filters");
00139 for (int x = 0; x < mColumns.size(); x++)
00140 mColumns[x]->ResetFilter(false);
00141 mSource->ApplyFilters();
00142 }
00143
00144
00145
00146 virtual void UpdateRowsEvent()
00147 {
00148 mReady = false;
00149 if (mSource->GetFilteredRows() == mSource->GetNumberOfRows())
00150 mVertScrollBar->SetVisible(false);
00151 else
00152 {
00153 mVertScrollBar->SetVisible(true);
00154 mVertScrollBar->SetRange(mSource->GetFilteredRows(),
00155 mSource->GetNumberOfRows());
00156 }
00157 if (mVertScrollBar->GetValue() > mSource->GetFilteredRows())
00158 {
00159 ILOG_DEBUG("scrollbar out of range, resetting.");
00160 mReady = true;
00161 mVertScrollBar->SetValue(0);
00162 mSource->SetStartRow(0);
00163 UpdateScene();
00164 }
00165 mReady = true;
00166 }
00167
00168 virtual void UpdateNumberOfRowsEvent()
00169 {
00170 mSource->SetNumberOfRowsInPixels(H() - TableColumn::GetHeaderHeight());
00171 }
00172
00173 virtual void OnScroll(ScrollBar *src, int position, void *userData)
00174 {
00175 if (!mReady) return;
00176 mSource->SetStartRow(position);
00177
00178 }
00179
00180 virtual void UpdateScrollFromSourceEvent()
00181 {
00182 mVertScrollBar->SetValue(mSource->GetStartRow());
00183 }
00184
00185 void ScrollRelative(int nr)
00186 {
00187 mSource->SetStartRow(mSource->GetStartRow() + nr);
00188 UpdateScrollFromSourceEvent();
00189 }
00190
00191 virtual void MouseFunc(int msg, int but, int state, int x, int y)
00192 {
00193 mMouseX = x; mMouseY = y;
00194
00195 int nLine = ((state&oglShift) ? 5 : 1);
00196 if (msg == oglMouseWheelUp)
00197 mVertScrollBar->ChangePos(-mVertScrollBar->LineIncrement() * nLine);
00198 if (msg == oglMouseWheelDown)
00199 mVertScrollBar->ChangePos(mVertScrollBar->LineIncrement() * nLine);
00200
00201 if (!mAutoZoom)
00202 UnZoomRows();
00203 else if (!mSelecting)
00204 ZoomRow(GetRowForY(y));
00205
00206 if (msg == oglMouseEnter && mShowZoomView && mZoomView)
00207 viewSys.SetTags(mZoomView, visibleTag);
00208 if (msg == oglMouseLeave && mShowZoomView && mZoomView)
00209 viewSys.ClearTags(mZoomView, visibleTag);
00210
00211 if (msg == oglMouseDown && but == oglLeftButton)
00212 {
00213 int row = GetRowForY(y);
00214 if (row >= 0)
00215 {
00216 if (state & oglShift && mLastSelectedRow != -1)
00217 {
00218 ILOG_DEBUG("shift-select range " << mLastSelectedRow <<
00219 " to " << row);
00220 mSource->MarkRange(mLastSelectedRow, row, 1, true);
00221 mLastSelectedRow = -1;
00222 }
00223 else
00224 {
00225 mSource->MarkRow(row, 1, true, true);
00226 mLastSelectedRow = row;
00227 }
00228 }
00229 }
00230 if (msg == oglMouseMove && (state & oglLeftButton))
00231 {
00232 mMouseXE = x;
00233 mMouseYE = y;
00234 if (!mSelecting)
00235 {
00236 mMouseXS = x;
00237 mMouseYS = y;
00238 mSelecting = true;
00239 }
00240 }
00241 if (msg == oglMouseUp && but == oglLeftButton)
00242 {
00243 mSelecting = false;
00244 mSource->DoUpdateSelectionEvent();
00245 }
00246
00247 if (msg == oglMouseDown && but == oglRightButton)
00248 {
00249 int rx=0, ry=0;
00250 ToTopWindow(this, rx, ry);
00251 mContext->Open(rx+x,ry+y);
00252 }
00253
00254 }
00255
00256 virtual void KeyboardFunc(int c, int state)
00257 {
00258 switch (c)
00259 {
00260 case oglPAGEDOWN:
00261 ScrollRelative(mSource->GetNumberOfRows());
00262 break;
00263 case oglPAGEUP:
00264 ScrollRelative(-mSource->GetNumberOfRows());
00265 break;
00266
00267 case oglUP:
00268 ScrollRelative(-1);
00269 break;
00270
00271 case oglDOWN:
00272 ScrollRelative(+1);
00273 break;
00274
00275
00276 case '1': TransformMarkedSelectionTo(1, 4); break;
00277 case '2': TransformMarkedSelectionTo(1, 8); break;
00278 case '3': TransformMarkedSelectionTo(1, 16); break;
00279 case '4': TransformMarkedSelectionTo(1, 32); break;
00280 case '5': TransformMarkedSelectionTo(1, 64); break;
00281 case '6': TransformMarkedSelectionTo(1, 128); break;
00282
00283
00284 case '!': TransformMarkedSelectionTo(4, 1); break;
00285 case '@': TransformMarkedSelectionTo(8, 1); break;
00286 case '#': TransformMarkedSelectionTo(16, 1); break;
00287 case '$': TransformMarkedSelectionTo(32, 1); break;
00288 case '%': TransformMarkedSelectionTo(64, 1); break;
00289 case '^': TransformMarkedSelectionTo(128, 1); break;
00290
00291 case 138:
00292 mSource->MarkAllRows(1, false);
00293 break;
00294
00295
00296 case 'z':
00297 mAutoZoom = !mAutoZoom;
00298 break;
00299
00300 case 'x':
00301 mSource->SetDefaultRowSizes(20, 80); break;
00302 case 'c':
00303 mSource->SetDefaultRowSizes(15, 40); break;
00304 case 'v':
00305 mSource->SetDefaultRowSizes(10, 80); break;
00306 case 'b':
00307 mSource->SetDefaultRowSizes(10, 120); break;
00308
00309 case '`':
00310 ShowZoomView(!mShowZoomView);
00311 break;
00312 case '~':
00313 ToggleZoomViewSize();
00314 break;
00315 }
00316 }
00317
00318 bool GetAutoZoom()
00319 {
00320 return mAutoZoom;
00321 }
00322
00323 void SetAutoZoom(bool zoom)
00324 {
00325 mAutoZoom = zoom;
00326 }
00327
00328 bool GetShowPreview()
00329 {
00330 return mShowZoomView;
00331 }
00332
00333 void SetShowPreview(bool zoom)
00334 {
00335 ShowZoomView(zoom);
00336 }
00337
00338 void TransformMarkedSelectionTo(int sourcemask, int targetmask)
00339 {
00340 mSource->TransformMarkedTo(sourcemask, targetmask);
00341 mSource->DoUpdateSelectionEvent();
00342 }
00343
00344 int GetRowForY(int sy)
00345 {
00346 int my = 0, h=H();
00347 for (int y = mSource->GetStartRow(); y < mSource->GetEndRow(); y++)
00348 {
00349 my += mSource->GetRowHeight(y);
00350 if ((h - TableColumn::GetHeaderHeight() - my) < sy)
00351 return y;
00352 }
00353 return -1;
00354 }
00355
00356 void ZoomRow(int row)
00357 {
00358 mSource->SetZoomRow(row);
00359 }
00360
00361 void UnZoomRows()
00362 {
00363 mSource->UnsetZoom();
00364 }
00365
00366
00367 void ShowZoomView(bool show)
00368 {
00369 if (!mZoomViewCache)
00370 ILOG_WARNING("Zoom view disabled: no cache set.");
00371 if (!mZoomView)
00372 ILOG_WARNING("Zoom view disabled: no target window set.");
00373
00374 if (mShowZoomView = show)
00375 {
00376 oglSys.SetAlwaysDraw(mZoomViewTargetWindow->GetOGLWND(), true);
00377 viewSys.SetTags(mZoomView, visibleTag);
00378 }
00379 else
00380 {
00381 viewSys.ClearTags(mZoomView, visibleTag);
00382 mZoomView->UserData1 = (void *) -1;
00383 oglSys.SetAlwaysDraw(mZoomViewTargetWindow->GetOGLWND(), false);
00384 }
00385 }
00386
00387 void UpdateZoomView(int row, int x, int y)
00388 {
00389 int zx = x;
00390 int zy = y;
00391
00392 oglSys.VPToTopWndI(mOglWnd,&zx,&zy);
00393 oglSys.TopWndToVPI(mZoomViewTargetWindow->GetOGLWND(),&zx,&zy);
00394 if (zy + mZoomViewSize > mZoomViewTargetWindow->H())
00395 zy = mZoomViewTargetWindow->H() - mZoomViewSize;
00396
00397 if (row == -1)
00398 row = GetRowForY(y);
00399 if (mZoomViewFollowMouse)
00400 viewSys.SetDimensions(mZoomView,zx,zy,mZoomViewSize,mZoomViewSize);
00401 if (mZoomView->UserData1 != (void *) row)
00402 SetZoomView(row);
00403 }
00404
00405 void ToggleZoomViewSize()
00406 {
00407 int newsize;
00408 switch (mZoomViewSize)
00409 {
00410 case 128: newsize = 256; break;
00411 case 256: newsize = 384; break;
00412 case 384: newsize = 512; break;
00413 case 512: newsize = 768; break;
00414 case 768: newsize = 1024; break;
00415 case 1024: newsize = 128; break;
00416 }
00417 mZoomViewSize = newsize;
00418 int x,y,w,h;
00419 viewSys.GetDimensions(mZoomView,&x,&y,&w,&h);
00420 viewSys.SetDimensions(mZoomView,x,y,mZoomViewSize,mZoomViewSize);
00421
00422
00423
00424
00425
00426 }
00427
00428 void UpdateVideoFrame()
00429 {
00430 if (!mZoomViewVideoEnabled || !mZoomImage || !mShowZoomView) return;
00431
00432 Array2dVec3UInt8 *v = mSource->GetSortedVideoData("", mZoomViewRow);
00433 if (!v)
00434 return;
00435
00436 Array2dVec3UInt8* old = (Array2dVec3UInt8*)mZoomImage->imageHandle;
00437 if (old)
00438 delete old;
00439 if (mZoomImage->imageHandle = v)
00440 {
00441 mZoomImage->w = v->CW();
00442 mZoomImage->h = v->CH();
00443 }
00444 }
00445
00446 void SetZoomView(int row)
00447 {
00448 if (!mZoomViewCache || !mShowZoomView || mZoomViewRow == row)
00449 return;
00450
00451 mZoomViewRow = row;
00452
00453 Array2dVec3UInt8 *frame = mSource->GetSortedVideoData("", row);
00454 if (frame)
00455 {
00456 ILOG_DEBUG("SetZoomView: showing video preview for row " << row);
00457 mZoomViewVideoEnabled = true;
00458 if (!mZoomImage)
00459 mZoomImage = Visualization::RgbOglImage::OglImage(frame);
00460 else
00461 {
00462 if (mZoomImage->imageHandle)
00463 delete mZoomImage->imageHandle;
00464 mZoomImage->imageHandle = frame;
00465 mZoomImage->w = frame->CW();
00466 mZoomImage->h = frame->CH();
00467 }
00468 viewSys.SetImage(mZoomView, mZoomImage);
00469 return;
00470 }
00471
00472
00473 mZoomViewVideoEnabled = false;
00474 OGLVIEW* v = mZoomViewCache->GetViewFromCache(mSource->GetID(row));
00475 if (!v || v->UserData2 == (void*)2)
00476 return;
00477 OGLIMAGE* im = v->im;
00478 viewSys.SetImage(mZoomView, im);
00479 }
00480
00481 void SetZoomViewCache(TableViewCache *c)
00482 {
00483 mZoomViewCache = c;
00484 }
00485
00486 void SetZoomViewTargetWindow(Window *t, bool followMouse=false)
00487 {
00488 mZoomViewTargetWindow = t;
00489 mZoomView =
00490 viewSys.View2D(t->GetOGLWND(),0,0,0,mZoomViewSize, mZoomViewSize);
00491 viewSys.SetTags(mZoomView, FlexViewTags);
00492 int clearTags = visibleTag|showBorderTag|showBgTag|selectableTag;
00493 viewSys.ClearTags(mZoomView, clearTags);
00494 viewSys.SetColor(mZoomView, OGL_BG, oglTrLIGHTGREY);
00495 mZoomView->UserData1 = (void *) -1;
00496 mZoomViewFollowMouse = followMouse;
00497 }
00498
00499
00500
00501 virtual void ReshapeFunc(int w, int h)
00502 {
00503 Window::ReshapeFunc(w,h);
00504 HandleColumnPositions();
00505 HandleLayoutChange();
00506 }
00507
00508 virtual void DisplayFunc()
00509 {
00510 OGC myOGC;
00511 OGCSave(&myOGC);
00512
00513 int h = H(), w = W();
00514 int mx = 0, my = 0;
00515 int cx, cy, cw, ch;
00516 int mcx, mcy, mcw, mch;
00517
00518 if (mSelecting)
00519 {
00520 mcx = (mMouseXS < mMouseXE) ? mMouseXS : mMouseXE;
00521 mcw = (mMouseXS < mMouseXE) ? mMouseXE-mMouseXS : mMouseXS-mMouseXE;
00522 mcy = (mMouseYS < mMouseYE) ? mMouseYS : mMouseYE;
00523 mch = (mMouseYS < mMouseYE) ? mMouseYE-mMouseYS : mMouseYS-mMouseYE;
00524 mSource->MarkAllRows(1, false);
00525 }
00526
00527 SetStipple((short)oglDot);
00528 SetSolidLineColor(0xff777777);
00529 for (int x = 0; x < mColumns.size(); x++)
00530 {
00531 mColumns[x]->GetDimensions(cx,cy,cw,ch);
00532 mx += cw + 2;
00533 DrawLine(mx, 0, mx, h);
00534 }
00535 int hheight = TableColumn::GetHeaderHeight();
00536 my = hheight;
00537 for (int y = mSource->GetStartRow(); y < mSource->GetEndRow(); y++)
00538 {
00539 my += mSource->GetRowHeight(y);
00540
00541 if (mSelecting && (mcy < (h-my) && (h-my) < mcy + mch))
00542 mSource->MarkRow(y, 1);
00543
00544 int mark = mSource->GetMark(y);
00545 if (mark)
00546 {
00547 int markCol = MarkToColor(mark);
00548 SetSolidFillColor(markCol);
00549 FillRectangle(0, h - my, w - 20, mSource->GetRowHeight(y));
00550 }
00551
00552 DrawLine(0, h - my, w - 20, h - my);
00553 }
00554
00555 SetStipple((short)oglSolid);
00556 DrawLine(0, h - hheight, w - 20, h - hheight);
00557 DrawLine(w - 20, 0, w - 20, h - hheight);
00558
00559 if (mSelecting)
00560 {
00561
00562 SetStipple((short)oglSolid);
00563 SetLineWidth(2.0f);
00564 SetSolidLineColor(0xff444466);
00565 DrawRectangle(mcx,mcy,mcw,mch);
00566 }
00567
00568 OGCRestore(&myOGC);
00569 HandleZoomView();
00570 Window::DisplayFunc();
00571 }
00572
00573 private :
00574
00575 void FitImageToZoomView()
00576 {
00577 if (mZoomView && mZoomView->im)
00578 {
00579 float zoom = (mZoomView->h)/(float)mZoomView->im->h;
00580 viewSys.SetZoom(mZoomView, zoom, zoom);
00581 }
00582 }
00583
00584 void HandleZoomView()
00585 {
00586 if (mShowZoomView && mZoomView && viewSys.HasTags(mZoomView,visibleTag))
00587 {
00588 UpdateZoomView(-1, mMouseX, mMouseY);
00589 UpdateVideoFrame();
00590 FitImageToZoomView();
00591 }
00592 }
00593
00594 int MarkToColor(int m)
00595 {
00596 int r=127,g=127,b=127;
00597 if (m == -1)
00598 return ARGB2COLOR(255, 200, 200, 200);
00599 if (m & 1)
00600 r = g = b = 255;
00601 if (m & 2)
00602 r = g = b = 160;
00603 if (m & 4)
00604 r += 64;
00605 if (m & 8)
00606 g += 64;
00607 if (m & 16)
00608 b += 64;
00609 if (m & 32)
00610 { r += 64; g += 64; }
00611 if (m & 64)
00612 { g += 64; b += 64; }
00613 if (m & 128)
00614 { r += 64; b += 64; }
00615 if (r>255) r = 255;
00616 if (g>255) g = 255;
00617 if (b>255) b = 255;
00618 return ARGB2COLOR(255, r,g,b);
00619 }
00620
00621 void Init(TableDataSource *source, int w, int h)
00622 {
00623 mSource = source;
00624 mReady = false;
00625 mSelecting = false;
00626 mAutoZoom = false;
00627 mZoomViewTargetWindow = 0;
00628 mStaticColumnWidth = 0;
00629 mStaticColumnCount = 0;
00630 mLastSelectedRow = -1;
00631
00632
00633 mZoomViewSize = 384;
00634 mZoomView = 0;
00635 mZoomImage = 0;
00636 mZoomViewVideoEnabled = false;
00637 mZoomViewCache = 0;
00638 mShowZoomView = false;
00639 mZoomViewFollowMouse = false;
00640
00641 SetBackground(0xffffffff);
00642 SetBorderType(1);
00643 SetBorderFillShaded(-2);
00644
00645 mSource->AddTableUpdateListener(this);
00646
00647 mVertScrollBar = new WindowScrollBar(this, false);
00648 mVertScrollBar->SetRange(mSource->GetTotalRows(),
00649 mSource->GetNumberOfRows());
00650 mVertScrollBar->SetScrollBarListener(this, 0);
00651 oglSys.SetAllMouseMotion( mOglWnd, 1 );
00652 mReady = true;
00653
00654 MenuTopPane* top = new MenuTopPane(this);
00655 mContext = new Menu(top, 1, 180);
00656 mContext->AddItem("Show more results like this", 1);
00657 mContext->AddItem("Add selection to bucket:", 2);
00658 mContext->AddItem("red", 3);
00659 mContext->AddItem("green", 4);
00660 mContext->AddItem("blue", 5);
00661 mContext->AddItem("yellow", 6);
00662 mContext->AddItem("cyan", 7);
00663 mContext->AddItem("orange", 8);
00664 mContext->SetOptions(2, Menu::SEPARATOR, true);
00665
00666
00667 }
00668
00669 bool mReady;
00670 bool mSelecting;
00671 bool mAutoZoom;
00672 bool mShowZoomView;
00673 bool mZoomViewFollowMouse;
00674 bool mZoomViewVideoEnabled;
00675
00676 int mMouseX;
00677 int mMouseY;
00678 int mStaticColumnWidth;
00679 int mStaticColumnCount;
00680 int mZoomViewRow;
00681 int mZoomViewSize;
00682 int mLastSelectedRow;
00683 int mMouseXS, mMouseYS, mMouseXE, mMouseYE;
00684
00685 TableDataSource* mSource;
00686 std::vector<TableColumn*> mColumns;
00687 TableViewCache* mZoomViewCache;
00688 OGLVIEW* mZoomView;
00689 OGLIMAGE* mZoomImage;
00690
00691 Window* mHeaderWindow;
00692 Window* mZoomViewTargetWindow;
00693 WindowScrollBar* mVertScrollBar;
00694
00695 Menu* mContext;
00696
00697 ILOG_VAR_DEC;
00698 };
00699
00700 ILOG_VAR_INIT(TableWindow, Application.VideoExcel);
00701
00702 }
00703 }
00704 }
00705
00706 #endif // TableWindow_h