00001
00002
00003
00004 #ifndef Impala_Visualization_ImageSetIdxGrid_h
00005 #define Impala_Visualization_ImageSetIdxGrid_h
00006
00007 #include "OglGui/DocDimensions.h"
00008 #include "OglGui/DocFlowDrag.h"
00009 #include "Visualization/RgbOglImage.h"
00010 #include "Visualization/ImageSetIdxGridListener.h"
00011 #include "Core/ImageSet/ImageSet.h"
00012
00013 namespace Impala {
00014 namespace Visualization {
00015
00016 class ImageSetIdxGrid : public OglGui::Window,
00017 public OglGui::DocDimensions
00018 {
00019 public:
00020 typedef OglGui::Window Window;
00021 typedef Core::Array::Array2dVec3UInt8 Array2dVec3UInt8;
00022 typedef Core::ImageSet::ImageSet ImageSet;
00023
00024 ImageSetIdxGrid(int x, int y, int w, int h, int nOnRow=5) :
00025 Window(x,y,w,h)
00026 {
00027 Init(w,h,nOnRow);
00028 }
00029
00030 ImageSetIdxGrid(Window* parent, int w, int h, int nOnRow=5) :
00031 Window(parent,w,h)
00032 {
00033 Init(w,h,nOnRow);
00034 }
00035
00036 ImageSetIdxGrid(Window* parent, int x, int y, int w, int h, int nOnRow=5) :
00037 Window(parent,x,y,w,h)
00038 {
00039 Init(w,h,nOnRow);
00040 }
00041
00042 ~ImageSetIdxGrid()
00043 {
00044 Clear();
00045 }
00046
00047 void SetImageSetIdxGridListener(ImageSetIdxGridListener* l,void* userData=0)
00048 {
00049 mListener = l;
00050 mListenerData = userData;
00051 }
00052 void
00053 SetImageSetIdxGridListener(ImageSetIdxGridListener* l, int userData)
00054 {
00055 SetImageSetIdxGridListener(l, (void*) (long long) userData);
00056 }
00057
00058 void AddImageSetIdxs(ImageSet* imSet, int startIdx=0, int endIdx=-1)
00059 {
00060 if (!imSet || imSet->NrFiles()<=0)
00061 return;
00062 if (startIdx<0)
00063 startIdx = 0;
00064 if (endIdx == -1)
00065 endIdx = imSet->NrFiles()-1;
00066 if (endIdx < startIdx)
00067 endIdx = startIdx;
00068 for (int i = 0; i<endIdx; i++)
00069 AddImageSetIdx(imSet, i);
00070 HandleDocDimensions(true,true);
00071 }
00072
00073 void AddImageSetIdx(ImageSet* imSet, int idx)
00074 {
00075 mImSets.push_back(imSet);
00076 mIdxs.push_back(idx);
00077 }
00078
00079
00080 int ImageSetIdx(int imIdx)
00081 {
00082 if (imIdx<0 || imIdx >= mIdxs.size())
00083 return -1;
00084 return mIdxs[imIdx];
00085 }
00086
00087 ImageSet* GetImageSet(int imIdx)
00088 {
00089 if (imIdx<0 || imIdx >= mIdxs.size())
00090 return 0;
00091 return mImSets[imIdx];
00092 }
00093
00094 std::vector<OGLVIEW*>* OglViews()
00095 {
00096 return &mViews;
00097 }
00098
00099 void UpdateLayout(bool reset=false)
00100 {
00101 HandleDocDimensions(false,reset);
00102 }
00103
00104 void Clear()
00105 {
00106 SetSelected(-1);
00107 ClearViews();
00108 mImSets.clear();
00109 mIdxs.clear();
00110 UpdateLayout(true);
00111 }
00112
00113 void NrOfImOnRow(int n) { mFixedCellDims = !(mNrOfImOnRow = n); }
00114 int NrOfImOnRow() { return mNrOfImOnRow; }
00115 void ShowNames(bool mode) { mExtH = (mShowNames = mode) ? 6 : 0; }
00116 bool ShowNames() { return mShowNames; }
00117 void ShowDims(bool mode) { mShowDims = mode; }
00118 bool ShowDims() { return mShowDims; }
00119 int CellWidth() { return mCellW; }
00120 int CellHeight() { return mCellH; }
00121 int NrOfFiles() { return mIdxs.size(); }
00122
00123 int X2Column(int x) { return x / mCellW; }
00124 int Column2X(int col) { return col * mCellW; }
00125 int Y2Row(int y)
00126 {
00127 int res = (mDocY + mDocH - y) / mCellH;
00128 return (mDocY + mDocH - y) / mCellH;
00129 }
00130 int Row2Y(int row) { return (mDocY+mDocH-(row+1)*mCellH); }
00131 int NrRows() { return NrOfFiles() / mNrOfImOnRow; }
00132
00133 void FixedCellWidth(int w)
00134 {
00135 if (mFixedCellDims = (w > 20))
00136 mCellH = mExtH + (mCellW = w);
00137 else
00138 mCellH = mExtH + (mCellW = 128);
00139 }
00140
00141 int ClampImIdx(int& idx)
00142 {
00143 if (idx < 0)
00144 idx = 0;
00145 if (idx > NrOfFiles()-1)
00146 idx = NrOfFiles()-1;
00147 return idx;
00148 }
00149
00150 int ClampViewIdx(int& idx)
00151 {
00152 if (idx < 0)
00153 idx = 0;
00154 if (idx > mViews.size()-1)
00155 idx = mViews.size()-1;
00156 return idx;
00157 }
00158
00159 void ClearViews(int start=0, int end=10000)
00160 {
00161 ClampViewIdx(start);
00162 ClampViewIdx(end);
00163 for (int i=start; i<end; i++)
00164 {
00165 viewSys.SetImage(mViews[i], 0);
00166 viewSys.ClearTags(mViews[i], visibleTag);
00167 mViews[i]->UserData1 = (void*)-1;
00168 }
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 void SetFirstVisRow(int idx)
00185 {
00186 int row = idx / mNrOfImOnRow;
00187 int yDiff = (H()-mCellH) - Row2Y(row);
00188 mDocY += yDiff;
00189 }
00190
00191 int FindFirstVisible()
00192 {
00193 int first = Y2Row(H()) * mNrOfImOnRow;
00194 return ClampImIdx(first);
00195 }
00196 int FindLastVisible()
00197 {
00198 int last = Y2Row(-mCellH) * mNrOfImOnRow;
00199 return ClampImIdx(last);
00200 }
00201
00202 int FindIndexFwd(int imIdx, int start=0)
00203 {
00204 ClampViewIdx(start);
00205 for (int i=start; i<mViews.size(); i++)
00206 {
00207 if (imIdx == (int)(long long) mViews[i]->UserData1)
00208 return i;
00209 }
00210 return -1;
00211 }
00212
00213 int FindIndexBwd(int imIdx, int start=10000)
00214 {
00215 ClampViewIdx(start);
00216 for (int i=start; i>=0; i--)
00217 {
00218 if (imIdx == (int) (long long) mViews[i]->UserData1)
00219 return i;
00220 }
00221 return -1;
00222 }
00223
00224 int FindIndex(int imIdx, int start, bool backward=false)
00225 {
00226 if (backward)
00227 return FindIndexBwd(imIdx, start);
00228 else
00229 return FindIndexFwd(imIdx, start);
00230 }
00231
00232 void HandleDocDimensions(bool resizing=false, bool reset=false)
00233 {
00234 if (!mFixedCellDims)
00235 {
00236 mCellW = W() / mNrOfImOnRow;
00237 mCellH = mCellW + (mShowNames ? mExtH : 0);
00238 }
00239 else if ((mNrOfImOnRow = W() / mCellW)<1)
00240 mNrOfImOnRow = 1;
00241
00242 int docH = (NrOfFiles() / mNrOfImOnRow + 1) * mCellH;
00243
00244 if (resizing && mOldStartIm != -1)
00245 {
00246 int row = mOldStartIm / mNrOfImOnRow;
00247 mDocY = H() - (NrRows() - row + 1) * mCellH;
00248 }
00249 if (mDocY < (-docH+H()))
00250 mDocY = -docH+H();
00251 if (reset)
00252 SetDocDimensions(0,-docH+H(),W(), docH);
00253 else
00254 SetDocDimensions(mDocX, mDocY, W(), docH);
00255 }
00256
00257 void HandleViewText(OGLVIEW* oglView)
00258 {
00259 if (!(mShowNames || mShowDims))
00260 return;
00261
00262 OGLIMAGE* oglIm = oglView->im;
00263 int idx = (int)(long long)oglView->UserData1;
00264 int txtX = oglView->x;
00265 int txtY = oglView->y-14;
00266 std::string txt = "";
00267
00268 if (mShowNames)
00269 txt = mImSets[idx]->GetFile(mIdxs[idx]) + " ";
00270 if (mShowDims)
00271 {
00272 char buf[20];
00273 sprintf(buf, "[%dx%d]", oglIm->w, oglIm->h);
00274 txt += buf;
00275 }
00276 oglSys.StartScissor(mOglWnd,txtX,txtY-4,oglView->w,20);
00277 oglSys.PosColPrintf(mOglWnd,txtX,txtY,GetForeground(),"%s",txt.c_str());
00278 oglSys.EndScissor();
00279 }
00280
00281 void HandleViewZoom(OGLVIEW* oglView)
00282 {
00283 OGLIMAGE* oglIm = oglView->im;
00284 float zoomX = 1, zoomY = 1;
00285
00286 if (oglIm->w >= oglIm->h)
00287 zoomY = zoomX = (mCellW-8)/(float)oglIm->w;
00288 else if (oglIm->w<oglIm->h)
00289 zoomX = zoomY = (mCellH-(8+mExtH))/(float)oglIm->h;
00290 if (zoomX > 2)
00291 zoomX = zoomY = 2;
00292 viewSys.SetZoom(oglView, zoomX, zoomY);
00293 }
00294
00295 virtual void HandleViewDecoration(OGLVIEW* view)
00296 {
00297 SetSolidLineColor(oglLIGHTGREY);
00298 DrawRectangle(view->x-2, view->y-2, view->w+4, view->h+4);
00299 }
00300
00301 void HandleViewSettings(int vIdx)
00302 {
00303 OGLVIEW* oglView;
00304 if (vIdx<0 || vIdx>=mViews.size() || !(oglView=mViews[vIdx]))
00305 return;
00306 if (!mViews[vIdx]->im)
00307 return;
00308 HandleViewZoom(oglView);
00309 HandleViewText(oglView);
00310 HandleViewDecoration(oglView);
00311 }
00312
00313 void ViewCreateImage(int dstIdx, int imIdx)
00314 {
00315 Array2dVec3UInt8* ar = mImSets[imIdx]->GetImage(mIdxs[imIdx]);
00316 if (ar != 0)
00317 {
00318 OGLIMAGE* oglIm = RgbOglImage::OglImage(ar);
00319 viewSys.SetImage(mViews[dstIdx],oglIm);
00320 ReleaseOglImage(oglIm);
00321 } else {
00322 ILOG_WARN("array = 0, image not loaded.");
00323 viewSys.SetImage(mViews[dstIdx], 0);
00324 }
00325 mViews[dstIdx]->UserData1 = (void *) imIdx;
00326 }
00327
00328 void CopyImageFromView(int dstIdx, int srcIdx, int imIdx)
00329 {
00330 viewSys.SetImage(mViews[dstIdx], mViews[srcIdx]->im);
00331 mViews[dstIdx]->UserData1 = (void *) imIdx;
00332 }
00333
00334 bool ViewNewPositionNeedsIm(int vIdx, int imIdx)
00335 {
00336 int row = imIdx / mNrOfImOnRow;
00337 int x = (imIdx%mNrOfImOnRow) * mCellW + 4;
00338 int y = Row2Y(row) + 12 + mExtH;
00339 int w = mCellW - 8;
00340 int h = mCellH - (18+mExtH);
00341 viewSys.SetDimensions(mViews[vIdx], x, y, w, h);
00342 viewSys.SetTags(mViews[vIdx], visibleTag);
00343 return ((int)(long long) mViews[vIdx]->UserData1) != imIdx;
00344 }
00345
00346 virtual void ReshapeFunc(int w, int h)
00347 {
00348 Window::ReshapeFunc(w,h);
00349 HandleDocDimensions(true,false);
00350 }
00351
00352 void HandleView(int vIdx, int imIdx, bool bwd)
00353 {
00354 if (vIdx < 0 || vIdx > mViews.size()-1)
00355 return;
00356 if (ViewNewPositionNeedsIm(vIdx,imIdx))
00357 {
00358 int foundIdx;
00359 if ((foundIdx = FindIndex(imIdx,vIdx,bwd))!=-1)
00360 CopyImageFromView(vIdx,foundIdx,imIdx);
00361 else
00362 ViewCreateImage(vIdx,imIdx);
00363 }
00364 HandleViewSettings(vIdx);
00365 }
00366
00367 void SetSelected(int idx)
00368 {
00369 SetSelectedMode(mLastSelected, false);
00370 SetSelectedMode(mLastSelected=idx,true);
00371 }
00372
00373 void SetSelectedMode(int idx, bool mode)
00374 {
00375 if (idx < 0 || idx >= mIdxs.size())
00376 return;
00377 int vIdx = FindIndexFwd(idx);
00378 if (vIdx >=0 && vIdx < mViews.size())
00379 {
00380 if (mode)
00381 {
00382 ULONG col = oglSys.GetSelectColor(mViews[0]->oglWnd);
00383 viewSys.SetTags(mViews[vIdx],selectedTag);
00384 viewSys.SetColor(mViews[vIdx],OGL_BG,col);
00385 }
00386 else
00387 {
00388 viewSys.ClearTags(mViews[vIdx],selectedTag);
00389 viewSys.SetColor(mViews[vIdx],OGL_BG,0);
00390 }
00391 }
00392 }
00393
00394 virtual void DisplayFunc()
00395 {
00396 int dif = H() % CellHeight();
00397 mFlowDragger.SetFlowPageExtra(dif-1);
00398 mFlowDragger.FlowDragDisplay();
00399
00400 OGC myOGC;
00401 OGCSave(&myOGC);
00402 int first = FindFirstVisible();
00403 int last = FindLastVisible();
00404 int range = last - first + 1;
00405 int i, vIdx;
00406
00407 int oldLastSelected = mLastSelected;
00408 SetSelected(-1);
00409 if (mOldStartIm <= first)
00410 {
00411 for (i=first, vIdx=-1; i<=last; i++)
00412 HandleView(++vIdx,i,false);
00413 ClearViews(vIdx+1);
00414 }
00415 else
00416 {
00417 for (i=last, vIdx=range; i>=first; i--)
00418 HandleView(--vIdx, i, true);
00419 ClearViews(range);
00420 }
00421 SetSelected(oldLastSelected);
00422
00423 mOldStartIm = first;
00424 OGCRestore(&myOGC);
00425 Window::DisplayFunc();
00426 }
00427
00428 virtual void
00429 MouseFunc(int msg, int but, int state, int x, int y)
00430 {
00431 if (!GetState()) return;
00432
00433 mFlowDragger.MouseFunc(msg,but,state,x,y);
00434 Window::MouseFunc( msg, but, state, x, y );
00435
00436 if (state & (oglAlt|oglShift|oglControl))
00437 return;
00438
00439 if (msg == oglMouseDown && but == oglLeftButton)
00440 {
00441 int idx = Y2Row(y) * mNrOfImOnRow + X2Column(x);
00442 if (idx >= 0 && idx < NrOfFiles())
00443 {
00444 SetSelected(idx);
00445 if (mListener!=0)
00446 mListener->ImageSelectionEvent(this,idx,mListenerData);
00447 }
00448 }
00449 }
00450
00451 virtual void KeyboardFunc(int c, int state)
00452 {
00453 int oldDocY = mDocY;
00454 Window::KeyboardFunc(c, state);
00455 mFlowDragger.KeyboardFunc(c,state);
00456
00457 if (c == '~')
00458 mFixedCellDims = !mFixedCellDims;
00459
00460 if (oldDocY != mDocY)
00461 return;
00462 if (c==oglPAGEDOWN)
00463 mDocY += H();
00464 if (c==oglPAGEUP)
00465 mDocY -= H();
00466 if (c==oglUP)
00467 mDocY += 10;
00468 if (c==oglDOWN)
00469 mDocY -= 10;
00470 }
00471
00472 private:
00473
00474 void Init(int w, int h, int nOnRow)
00475 {
00476 mListener = 0;
00477 mFlowDragger.SetDocWnd(this,this);
00478 SetDocDimensions(0,0,w,h);
00479 FixedCellWidth(132);
00480 NrOfImOnRow(nOnRow);
00481 ShowNames(true);
00482 ShowDims(true);
00483 mLastSelected = -1;
00484 mOldStartIm = -1;
00485 for (int i=0; i<1000; i++)
00486 {
00487 OGLVIEW* view = viewSys.View2D(mOglWnd,0,0,0,128,128);
00488 viewSys.SetTags(view, FlexViewTags);
00489 viewSys.ClearTags(view, visibleTag|showBorderTag|selectableTag|panableTag|zoomableTag);
00490 viewSys.SetColor(view, OGL_BG, 0);
00491 view->UserData1 = (void *) -1;
00492 mViews.push_back(view);
00493 }
00494 }
00495
00496 ImageSetIdxGridListener* mListener;
00497 void* mListenerData;
00498
00499 std::vector<int> mIdxs;
00500 std::vector<ImageSet*> mImSets;
00501 std::vector<OGLVIEW*> mViews;
00502
00503 bool mFixedCellDims;
00504 bool mShowNames;
00505 bool mShowDims;
00506 int mNrOfImOnRow;
00507 int mCellW;
00508 int mCellH;
00509 int mExtH;
00510 int mLastSelected;
00511
00512 int mOldStartIm;
00513
00514 OglGui::DocFlowDrag mFlowDragger;
00515
00516 ILOG_VAR_DEC;
00517 };
00518
00519 ILOG_VAR_INIT(ImageSetIdxGrid, Visualization);
00520
00521 }
00522 }
00523 #endif