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