Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

qwt_plot_zoomer.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** 00002 * Qwt Widget Library 00003 * Copyright (C) 1997 Josef Wilgen 00004 * Copyright (C) 2002 Uwe Rathmann 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the Qwt License, Version 1.0 00008 *****************************************************************************/ 00009 00010 // vim: expandtab 00011 00012 #include <math.h> 00013 #include "qwt_plot.h" 00014 #include "qwt_plot_canvas.h" 00015 #include "qwt_plot_zoomer.h" 00016 00040 QwtPlotZoomer::QwtPlotZoomer(QwtPlotCanvas *canvas, const char *name): 00041 QwtPlotPicker(canvas, name) 00042 { 00043 if ( canvas ) 00044 init(); 00045 } 00046 00068 QwtPlotZoomer::QwtPlotZoomer(int xAxis, int yAxis, 00069 QwtPlotCanvas *canvas, const char *name): 00070 QwtPlotPicker(xAxis, yAxis, canvas, name) 00071 { 00072 if ( canvas ) 00073 { 00074 init(); 00075 } 00076 } 00077 00102 QwtPlotZoomer::QwtPlotZoomer(int xAxis, int yAxis, int selectionFlags, 00103 DisplayMode cursorLabelMode, QwtPlotCanvas *canvas, const char *name): 00104 QwtPlotPicker(xAxis, yAxis,canvas, name) 00105 { 00106 if ( canvas ) 00107 { 00108 init(selectionFlags, cursorLabelMode); 00109 } 00110 } 00111 00113 void QwtPlotZoomer::init(int selectionFlags, DisplayMode cursorLabelMode) 00114 { 00115 d_maxStackDepth = -1; 00116 00117 setSelectionFlags(selectionFlags); 00118 setCursorLabelMode(cursorLabelMode); 00119 setRubberBand(RectRubberBand); 00120 00121 setZoomBase(scaleRect()); 00122 } 00123 00135 void QwtPlotZoomer::setMaxStackDepth(int depth) 00136 { 00137 d_maxStackDepth = depth; 00138 00139 if ( depth >= 0 ) 00140 { 00141 // unzoom if the current depth is below d_maxStackDepth 00142 00143 const int zoomOut = 00144 d_zoomStack.count() - 1 - depth; // -1 for the zoom base 00145 00146 if ( zoomOut > 0 ) 00147 { 00148 zoom(-zoomOut); 00149 for ( uint i = d_zoomStack.count() - 1; i > d_zoomRectIndex; i-- ) 00150 (void)d_zoomStack.pop(); // remove trailing rects 00151 } 00152 } 00153 } 00154 00159 int QwtPlotZoomer::maxStackDepth() const 00160 { 00161 return d_maxStackDepth; 00162 } 00163 00168 const QValueStack<QwtDoubleRect> &QwtPlotZoomer::zoomStack() const 00169 { 00170 return d_zoomStack; 00171 } 00172 00177 QValueStack<QwtDoubleRect> &QwtPlotZoomer::zoomStack() 00178 { 00179 return d_zoomStack; 00180 } 00181 00186 QwtDoubleRect QwtPlotZoomer::zoomBase() const 00187 { 00188 return d_zoomStack[0]; 00189 } 00190 00204 void QwtPlotZoomer::setZoomBase() 00205 { 00206 const QwtPlot *plt = plot(); 00207 if ( !plt ) 00208 return; 00209 00210 d_zoomStack.clear(); 00211 d_zoomStack.push(scaleRect()); 00212 d_zoomRectIndex = 0; 00213 00214 rescale(); 00215 } 00216 00227 void QwtPlotZoomer::setZoomBase(const QwtDoubleRect &base) 00228 { 00229 const QwtPlot *plt = plot(); 00230 if ( !plt ) 00231 return; 00232 00233 const QwtDoubleRect sRect = scaleRect(); 00234 const QwtDoubleRect bRect = base | sRect; 00235 00236 d_zoomStack.clear(); 00237 d_zoomStack.push(bRect); 00238 d_zoomRectIndex = 0; 00239 00240 if ( base != sRect ) 00241 { 00242 d_zoomStack.push(sRect); 00243 d_zoomRectIndex++; 00244 } 00245 00246 rescale(); 00247 } 00248 00254 QwtDoubleRect QwtPlotZoomer::zoomRect() const 00255 { 00256 return d_zoomStack[d_zoomRectIndex]; 00257 } 00258 00262 uint QwtPlotZoomer::zoomRectIndex() const 00263 { 00264 return d_zoomRectIndex; 00265 } 00266 00277 void QwtPlotZoomer::zoom(const QwtDoubleRect &rect) 00278 { 00279 if ( d_maxStackDepth >= 0 && int(d_zoomRectIndex) >= d_maxStackDepth ) 00280 return; 00281 00282 const QwtDoubleRect zoomRect = d_zoomStack[0] & rect.normalize(); 00283 if ( zoomRect != d_zoomStack[d_zoomRectIndex] ) 00284 { 00285 for ( uint i = d_zoomStack.count() - 1; i > d_zoomRectIndex; i-- ) 00286 (void)d_zoomStack.pop(); 00287 00288 d_zoomStack.push(zoomRect); 00289 d_zoomRectIndex++; 00290 00291 rescale(); 00292 } 00293 } 00294 00305 void QwtPlotZoomer::zoom(int offset) 00306 { 00307 if ( offset == 0 ) 00308 d_zoomRectIndex = 0; 00309 else 00310 { 00311 int newIndex = d_zoomRectIndex + offset; 00312 newIndex = QMAX(0, newIndex); 00313 newIndex = QMIN(int(d_zoomStack.count() - 1), newIndex); 00314 00315 d_zoomRectIndex = uint(newIndex); 00316 } 00317 00318 rescale(); 00319 } 00320 00327 void QwtPlotZoomer::rescale() 00328 { 00329 QwtPlot *plt = plot(); 00330 if ( !plt ) 00331 return; 00332 00333 const QwtDoubleRect &rect = d_zoomStack[d_zoomRectIndex]; 00334 if ( rect != scaleRect() ) 00335 { 00336 plt->setAxisScale(xAxis(), rect.x1(), rect.x2()); 00337 plt->setAxisScale(yAxis(), rect.y1(), rect.y2()); 00338 00339 plt->replot(); 00340 } 00341 } 00342 00350 void QwtPlotZoomer::setAxis(int xAxis, int yAxis) 00351 { 00352 if ( xAxis != QwtPlotPicker::xAxis() || yAxis != QwtPlotPicker::yAxis() ) 00353 { 00354 QwtPlotPicker::setAxis(xAxis, yAxis); 00355 setZoomBase(scaleRect()); 00356 } 00357 } 00358 00369 void QwtPlotZoomer::widgetMouseReleaseEvent(QMouseEvent *me) 00370 { 00371 if ( mouseMatch(MouseSelect2, me) ) 00372 zoom(0); 00373 else if ( mouseMatch(MouseSelect3, me) ) 00374 zoom(-1); 00375 else if ( mouseMatch(MouseSelect6, me) ) 00376 zoom(+1); 00377 else 00378 QwtPlotPicker::widgetMouseReleaseEvent(me); 00379 } 00380 00392 void QwtPlotZoomer::widgetKeyPressEvent(QKeyEvent *ke) 00393 { 00394 if ( !isActive() ) 00395 { 00396 if ( keyMatch(KeyUndo, ke) ) 00397 zoom(-1); 00398 else if ( keyMatch(KeyRedo, ke) ) 00399 zoom(+1); 00400 else if ( keyMatch(KeyHome, ke) ) 00401 zoom(0); 00402 } 00403 00404 QwtPlotPicker::widgetKeyPressEvent(ke); 00405 } 00406 00415 void QwtPlotZoomer::moveBy(double dx, double dy) 00416 { 00417 const QwtDoubleRect &rect = d_zoomStack[d_zoomRectIndex]; 00418 move(rect.x1() + dx, rect.y1() + dy); 00419 } 00420 00430 void QwtPlotZoomer::move(double x, double y) 00431 { 00432 x = QMAX(x, zoomBase().x1()); 00433 x = QMIN(x, zoomBase().x2() - zoomRect().width()); 00434 00435 y = QMAX(y, zoomBase().y1()); 00436 y = QMIN(y, zoomBase().y2() - zoomRect().height()); 00437 00438 if ( x != zoomRect().x1() || y != zoomRect().y1() ) 00439 { 00440 d_zoomStack[d_zoomRectIndex].move(x, y); 00441 rescale(); 00442 } 00443 } 00444 00456 bool QwtPlotZoomer::accept(QPointArray &pa) const 00457 { 00458 if ( pa.count() < 2 ) 00459 return FALSE; 00460 00461 QRect rect = QRect(pa[0], pa[int(pa.count() - 1)]).normalize(); 00462 00463 const int minSize = 2; 00464 if (rect.width() < minSize && rect.height() < minSize ) 00465 return FALSE; 00466 00467 const int minZoomSize = 11; 00468 00469 const QPoint center = rect.center(); 00470 rect.setSize(rect.size().expandedTo(QSize(minZoomSize, minZoomSize))); 00471 rect.moveCenter(center); 00472 00473 pa.resize(2); 00474 pa[0] = rect.topLeft(); 00475 pa[1] = rect.bottomRight(); 00476 00477 return TRUE; 00478 } 00479 00488 QwtDoubleSize QwtPlotZoomer::minZoomSize() const 00489 { 00490 char f; 00491 int fw, xprecision, yprecision; 00492 00493 plot()->axisLabelFormat(xAxis(), f, xprecision, fw); 00494 plot()->axisLabelFormat(yAxis(), f, yprecision, fw); 00495 00496 return QwtDoubleSize( 00497 d_zoomStack[0].width() / pow(10.0, xprecision - 1), 00498 d_zoomStack[0].height() / pow(10.0, yprecision - 1) 00499 ); 00500 } 00501 00508 void QwtPlotZoomer::begin() 00509 { 00510 if ( d_maxStackDepth >= 0 ) 00511 { 00512 if ( d_zoomRectIndex >= uint(d_maxStackDepth) ) 00513 return; 00514 } 00515 00516 const QwtDoubleSize minSize = minZoomSize(); 00517 if ( minSize.isValid() ) 00518 { 00519 const QwtDoubleSize sz = 00520 d_zoomStack[d_zoomRectIndex].size() * 0.9999; 00521 00522 if ( minSize.width() >= sz.width() && 00523 minSize.height() >= sz.height() ) 00524 { 00525 return; 00526 } 00527 } 00528 00529 QwtPlotPicker::begin(); 00530 } 00531 00539 bool QwtPlotZoomer::end(bool ok) 00540 { 00541 ok = QwtPlotPicker::end(ok); 00542 if (!ok) 00543 return FALSE; 00544 00545 QwtPlot *plot = QwtPlotZoomer::plot(); 00546 if ( !plot ) 00547 return FALSE; 00548 00549 const QPointArray &pa = selection(); 00550 if ( pa.count() < 2 ) 00551 return FALSE; 00552 00553 QRect rect = QRect(pa[0], pa[int(pa.count() - 1)]).normalize(); 00554 00555 QwtDoubleRect zoomRect = invTransform(rect).normalize(); 00556 00557 const QwtDoublePoint center = zoomRect.center(); 00558 zoomRect.setSize(zoomRect.size().expandedTo(minZoomSize())); 00559 zoomRect.moveCenter(center); 00560 00561 zoom(zoomRect); 00562 emit zoomed(zoomRect); 00563 00564 return TRUE; 00565 } 00566 00578 void QwtPlotZoomer::setSelectionFlags(int flags) 00579 { 00580 // we accept only rects 00581 flags &= ~(PointSelection | PolygonSelection); 00582 flags |= RectSelection; 00583 00584 QwtPlotPicker::setSelectionFlags(flags); 00585 } 00586 00587 // Local Variables: 00588 // mode: C++ 00589 // c-file-style: "stroustrup" 00590 // indent-tabs-mode: nil 00591 // End: 00592

Generated on Tue Nov 16 21:12:21 2004 for Qwt User's Guide by doxygen 1.3.8