00001 #ifndef Impala_Visualization_ImageSet_h
00002 #define Impala_Visualization_ImageSet_h
00003
00004 #include "Visualization/ImagesWindow.h"
00005 #include "OglGui/WindowScrollBar.h"
00006
00007 namespace Impala
00008 {
00009 namespace Visualization
00010 {
00011
00012
00013 class ImageSet : public ImagesWindow, public OglGui::RepeatTimer,
00014 public OglGui::ScrollBarListener
00015 {
00016 public:
00017 ImageSet(OglGui::Window* parent, int x, int y, int imW, int imH, double scale,
00018 int nrVisibleX, int nrVisibleY, int distance = 3) :
00019 ImagesWindow(parent, x, y, (imW*scale + distance) * nrVisibleX + 16,
00020 (imH*scale + distance) * nrVisibleY + 4, true)
00021 {
00022 Init(imW, imH, scale, nrVisibleX, nrVisibleY, distance);
00023 }
00024
00025 ImageSet(OglGui::Window* parent, int imW, int imH, double scale,
00026 int nrVisibleX, int nrVisibleY, int distance = 3) :
00027 ImagesWindow(parent, (imW*scale + distance) * nrVisibleX + 16,
00028 (imH*scale + distance) * nrVisibleY + 4, true)
00029 {
00030 Init(imW, imH, scale, nrVisibleX, nrVisibleY, distance);
00031 }
00032
00033 OglGui::ScrollBar*
00034 ScrollBar()
00035 {
00036 return mScrollBar;
00037 }
00038
00039 void
00040 SetImageSelected(int idx)
00041 {
00042 mImSelected = idx;
00043 SetViewSelected(mImSelected - (mFirstVisY * mNrVisibleX));
00044 }
00045
00046 void
00047 SetAllowDragging(bool mode)
00048 {
00049 if (!(mAllowDragging = mode))
00050 mDragImId = -1;
00051 }
00052
00053 int
00054 GetFirstVisY()
00055 {
00056 return mFirstVisY;
00057 }
00058
00059 void
00060 SetFirstVisY(int nr, bool signalScrollBar = false)
00061 {
00062 if (signalScrollBar)
00063 {
00064 mScrollBar->SetNewPos(nr*mImSteps);
00065 return;
00066 }
00067 if (nr == mFirstVisY)
00068 return;
00069 int nrLines = (mImages.size() == 0)
00070 ? 0 : (mImages.size()-1) / mNrVisibleX + 1;
00071 if ((nr < 0) || (nr > nrLines-(mNrVisibleY-mExtraLines)))
00072 return;
00073 mFirstVisY = nr;
00074 Redraw();
00075 }
00076
00077 int
00078 GetIndexForId(int id)
00079 {
00080 for (int i=0 ; i<mImages.size() ; i++) {
00081 if (mImages[i]->Idx() == id)
00082 return i;
00083 }
00084 return mImages.size();
00085 }
00086
00087 int
00088 GetIdForIndex(int idx)
00089 {
00090 if (idx >= 0 && idx < mImages.size())
00091 return mImages[idx]->Idx();
00092 return -1;
00093 }
00094
00095 void
00096 RemoveImageById(int id)
00097 {
00098 RemoveImageByIndex(GetIndexForId(id));
00099 }
00100
00101 void
00102 RemoveImageByIndex(int index)
00103 {
00104 if (index >= mImages.size())
00105 return;
00106 mImages.erase(mImages.begin() + index);
00107
00108
00109 if (mImages.size() <= (mLines-1)*mNrVisibleX)
00110 {
00111 mLines--;
00112 UpdateScrollBarRange();
00113 }
00114 if ((mImages.size()-1)/mNrVisibleX+1 < mFirstVisY+(mNrVisibleY-mExtraLines)
00115 && mFirstVisY > 0)
00116 {
00117 SetFirstVisY(mFirstVisY - 1);
00118 }
00119 else
00120 {
00121 Redraw();
00122 }
00123 if (index < mImSelected)
00124 mImSelected = -1;
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 }
00139
00140 void
00141 Redraw()
00142 {
00143 int nrV = mNrVisibleX * mNrVisibleY;
00144 int start = mFirstVisY * mNrVisibleX;
00145 for (int i=0 ; i<nrV ; i++)
00146 {
00147 if (ViewHasImage(i))
00148 {
00149 SetViewVisible(i, true);
00150 UpdateViewWithImage(i, start + i);
00151 }
00152 else
00153 {
00154 SetViewVisible(i, false);
00155 }
00156 }
00157 SetImageSelected(mImSelected);
00158 if (mDragImId != -1)
00159 UpdateViewWithImage(mDragViewNr, mDragImId);
00160 }
00161
00162
00163
00164 virtual void
00165 DisplayFunc()
00166 {
00167 int cnt = 0;
00168 OGC oldOGC;
00169 int offY = mScrollBar->GetValue() % mImSteps;
00170 int nrV = mNrVisibleX * mNrVisibleY;
00171 int start = mFirstVisY * mNrVisibleX;
00172
00173 OGCSave(&oldOGC);
00174 for (int i=0 ; i<mNrVisibleY ; i++)
00175 {
00176 int y = mOglWnd->height - (i+1) * (mViewHeight+mDistance) +
00177 offY * (mViewHeight/mImSteps);
00178 for (int j=0 ; j<mNrVisibleX ; j++)
00179 {
00180 int x = j * (mViewWidth+mDistance);
00181 if (ViewHasImage(cnt))
00182 {
00183 View* view = GetView(cnt);
00184 view->SetDimensions2D(x, y, mViewWidth, mViewHeight);
00185 bool vis = start + cnt != mDragImId;
00186 view->SetVisible(vis);
00187 if (vis)
00188 view->SetText(mImages[start+cnt]->Caption());
00189 }
00190 cnt++;
00191 }
00192 }
00193
00194 if (mDragImId != -1)
00195 {
00196 View* view = GetView(mDragViewNr);
00197 view->SetVisible(true);
00198 view->SetText(mImages[mDragImId]->Caption());
00199 view->SetDimensions2D(mDragX-mViewWidth/2, mDragY-mViewHeight/2,
00200 mViewWidth, mViewHeight);
00201 }
00202
00203
00204 Window::DisplayFunc();
00205
00206 if (mDragImId != -1 && mPropagateScrolling && RepeatTime())
00207 mScrollBar->ChangePos(mPropagateScrolling);
00208
00209 if (mDragImId != -1)
00210 {
00211 View* dragView = GetView(mDragViewNr);
00212 dragView->SetVisible(false);
00213 View* view = FindView(mDragX, mDragY);
00214 if (view)
00215 {
00216 mDragInsertId = mFirstVisY * mNrVisibleX + GetViewIdx(view);
00217 int x, y, w;
00218 view->GetDimensions2D(&x, &y, &w, 0);
00219 if (mDragX > x + w/2)
00220 {
00221 x += mViewWidth;
00222 mDragInsertId++;
00223 }
00224 SetLineWidth(3);
00225 SetSolidLineColor(0xffff00ff);
00226 DrawLine(x, y, x, y + mViewHeight);
00227 }
00228 else
00229 mDragInsertId = -1;
00230 dragView->SetVisible(true);
00231 }
00232 OGCRestore(&oldOGC);
00233 }
00234
00235
00236 virtual void
00237 ReshapeFunc(int w, int h)
00238 {
00239 OglGui::Window::ReshapeFunc(w, h);
00240
00241 int visIdx = mFirstVisY * mNrVisibleX;
00242 mNrVisibleX = w / (mViewWidth+mDistance);
00243 mNrVisibleX = Max(mNrVisibleX,1);
00244 mNrVisibleY = h / (mViewHeight+mDistance) + mExtraLines;
00245 mLines = (mImages.size() == 0)
00246 ? 0 : (mImages.size()-1) / mNrVisibleX + 1;
00247 Redraw();
00248 UpdateScrollBarRange();
00249 SetFirstVisY((mNrVisibleX == 0) ? 0 : visIdx / mNrVisibleX, false);
00250 }
00251
00252 virtual void
00253 MouseFunc(int msg, int but, int state, int x, int y)
00254 {
00255 Window::MouseFunc(msg, but, state, x, y);
00256
00257 if (msg == oglMouseWheelUp)
00258 mScrollBar->ChangePos((state&oglShift) ? -5 : -1);
00259 if (msg == oglMouseWheelDown)
00260 mScrollBar->ChangePos((state&oglShift) ? 5 : 1);
00261
00262
00263 if (mImagesListener && (msg==oglMouseDown) && (but==oglLeftButton))
00264 {
00265 View* view = FindView(x, y);
00266 if (view)
00267 {
00268 int imIdx = mFirstVisY * mNrVisibleX + GetViewIdx(view);
00269 SetImageSelected(imIdx);
00270 int orgIdx = mImages[imIdx]->Idx();
00271 mImagesListener->ImageSelectionEvent(this, orgIdx,
00272 mImagesListenerData);
00273 }
00274 }
00275
00276 if (mAllowDragging && msg==oglMouseDown && but==oglRightButton)
00277 {
00278 View* dragView = FindView(x, y);
00279 if (dragView)
00280 {
00281 mDragX = x;
00282 mDragY = y;
00283 mDragImId = mFirstVisY * mNrVisibleX + GetViewIdx(dragView);
00284 mDragViewNr = NrViewers();
00285 if (mDragViewNr > mNrVisibleX * mNrVisibleY)
00286 mDragViewNr = mNrVisibleX * mNrVisibleY;
00287 UpdateViewWithImage(mDragViewNr, mDragImId);
00288 StartRepeatTime();
00289 oglSys.SetAlwaysDraw(mOglWnd, 1);
00290 }
00291 }
00292 if (mAllowDragging && msg==oglMouseMove && (state & oglRightButton))
00293 {
00294 mDragX = x;
00295 mDragY = y;
00296
00297 if (mDragY >= mOglWnd->height - mViewHeight/4)
00298 {
00299 mDragY = mOglWnd->height - mViewHeight/4;
00300 mPropagateScrolling = y > mOglWnd->height ? -mImSteps : -1;
00301 }
00302 else if (mDragY <= mViewHeight/4)
00303 {
00304 mDragY = mViewHeight/4;
00305 mPropagateScrolling = y < 0 ? mImSteps : 1;
00306 }
00307 else
00308 mPropagateScrolling = 0;
00309
00310 }
00311 if (msg==oglMouseUp && but==oglRightButton && mDragImId != -1)
00312 {
00313 if (mDragInsertId != -1)
00314 {
00315 MoveImageTo(mDragImId, mDragInsertId);
00316 if (mDragImId == mImSelected)
00317 mImSelected = mDragImId < mDragInsertId ? mDragInsertId-1
00318 : mDragInsertId;
00319 }
00320 mDragImId = -1;
00321 SetViewVisible(mDragViewNr, false);
00322 mDragViewNr = -1;
00323 Redraw();
00324 oglSys.SetAlwaysDraw(mOglWnd, 0);
00325 }
00326
00327 }
00328
00329 virtual void
00330 KeyboardFunc(int c, int state)
00331 {
00332 Window::KeyboardFunc(c, state);
00333 if (mScrollBar)
00334 mScrollBar->ScrollKeys(c, state);
00335 }
00336
00337 virtual int
00338 SetState(int nState)
00339 {
00340 mScrollBar->SetState(nState);
00341 return Window::SetState(nState);
00342 }
00343
00344 void
00345 OnScroll(OglGui::ScrollBar *src, int position, void* data)
00346 {
00347 SetFirstVisY(position / mImSteps);
00348 }
00349
00350 protected:
00351
00352 virtual void
00353 ImageAdded(int idx, bool intelliScroll)
00354 {
00355 int dispPos = idx - mFirstVisY * mNrVisibleX;
00356 if (idx >= mLines*mNrVisibleX)
00357 {
00358 mLines++;
00359 UpdateScrollBarRange();
00360 }
00361 if (dispPos < mNrVisibleX * mNrVisibleY)
00362 {
00363 UpdateViewWithImage(dispPos, idx);
00364 return;
00365 }
00366 if (intelliScroll &&
00367 (mFirstVisY * mNrVisibleX ==
00368 idx - mNrVisibleX * (mNrVisibleY - mExtraLines)))
00369 {
00370 SetFirstVisY(mFirstVisY + 1);
00371 }
00372 }
00373
00374 virtual void
00375 ImagesRemoved()
00376 {
00377 mFirstVisY = 0;
00378 mLines = 0;
00379 mImSelected = -1;
00380 UpdateScrollBarRange();
00381 }
00382
00383 private:
00384
00385 void
00386 Init(int imW, int imH, double scale, int nrVisibleX, int nrVisibleY,
00387 int distance)
00388 {
00389 mImSteps = 10;
00390 mExtraLines = 2;
00391 mAllowDragging = true;
00392 mDragViewNr = -1;
00393 mDragImId = -1;
00394 mDragInsertId = -1;
00395 mPropagateScrolling = 0;
00396 SetRepeatDelays(400, 25);
00397
00398 mViewWidth = imW * scale;
00399 mViewHeight = imH * scale;
00400 mNrVisibleX = nrVisibleX;
00401 mNrVisibleY = nrVisibleY + mExtraLines;
00402 mFirstVisY = 0;
00403 mDistance = distance;
00404 mLines = 0;
00405 mImSelected = -1;
00406 mScrollBar = new OglGui::WindowScrollBar(this, false);
00407 mScrollBar->SetBackground(oglLIGHTGREY);
00408 mScrollBar->SetScrollBarListener(this, 0);
00409 UpdateScrollBarRange();
00410 SetBorderType(BEV_ETCHED);
00411
00412
00413 }
00414
00415 void
00416 UpdateScrollBarRange()
00417 {
00418 int pageSize = (mNrVisibleY - mExtraLines) * mImSteps;
00419 if (pageSize < 1)
00420 pageSize = 1;
00421 mScrollBar->SetRange(mLines * mImSteps, pageSize);
00422 }
00423
00424 bool
00425 ViewHasImage(int v)
00426 {
00427 if (v == mDragViewNr)
00428 return false;
00429 return mFirstVisY * mNrVisibleX + v < mImages.size();
00430 }
00431
00432
00433 int mNrVisibleX;
00434 int mNrVisibleY;
00435 int mExtraLines;
00436 int mFirstVisY;
00437 int mDistance;
00438 int mLines;
00439 int mImSelected;
00440
00441 int mImSteps;
00442
00443
00444 int mPropagateScrolling;
00445
00446 bool mAllowDragging;
00447 int mDragViewNr;
00448
00449 int mDragImId;
00450 int mDragInsertId;
00451 int mDragX, mDragY;
00452
00453 OglGui::WindowScrollBar* mScrollBar;
00454
00455 ILOG_VAR_DEC;
00456 };
00457 ILOG_VAR_INIT(ImageSet, Visualization);
00458
00459
00460 }
00461 }
00462
00463 #endif