void SingleCellViewGraphPanelPlotWidget::mouseReleaseEvent(QMouseEvent *pEvent) { // Default handling of the event QwtPlot::mouseReleaseEvent(pEvent); // Check that interaction is allowed if (!mInteractive) return; // Check whether we need to carry out an action if (mAction == None) return; // Keep track of the action to carry out // Note: this is so that we can reset mAction while still being able to // finish carrying out the action... Action action = mAction; // We are done carrying out an action, so... mAction = None; // Finish carrying out the action switch (action) { case ShowCoordinates: // Remove the coordinates by replotting ourselves replotNow(); break; case ZoomRegion: { // Zoom our region QRectF zoomRegionRect = zoomRegion(); setLocalAxes(zoomRegionRect.left(), zoomRegionRect.right(), zoomRegionRect.bottom(), zoomRegionRect.top()); break; } default: // Another action which needs nothing more to be done ; } }
bool SingleCellViewGraphPanelPlotWidget::setAxes(double pMinX, double pMaxX, double pMinY,double pMaxY, const bool &pCanReplot) { // Keep track of our axes' old values double oldMinX = minX(); double oldMaxX = maxX(); double oldMinY = minY(); double oldMaxY = maxY(); // Make sure that the given axes' values are fine checkAxesValues(pMinX, pMaxX, pMinY, pMaxY); // Update our axes' values, if needed bool axesValuesChanged = false; if ((pMinX != oldMinX) || (pMaxX != oldMaxX)) { setAxis(QwtPlot::xBottom, pMinX, pMaxX); axesValuesChanged = true; } if ((pMinY != oldMinY) || (pMaxY != oldMaxY)) { setAxis(QwtPlot::yLeft, pMinY, pMaxY); axesValuesChanged = true; } // Update our actions in case the axes' values have changed if (axesValuesChanged) updateActions(); // Replot ourselves, if needed and allowed if (axesValuesChanged && pCanReplot) { replotNow(); return true; } else { return false; } }
void SingleCellViewGraphPanelPlotWidget::mousePressEvent(QMouseEvent *pEvent) { // Default handling of the event QwtPlot::mousePressEvent(pEvent); // Check that interaction is allowed if (!mInteractive) return; // Check that the position of the mouse is over our canvas if (!plotLayout()->canvasRect().contains(pEvent->pos())) return; // Check which action we can carry out if ( (pEvent->button() == Qt::LeftButton) && (pEvent->modifiers() == Qt::NoModifier)) { // We want to pan mAction = Pan; } else if ( (pEvent->button() == Qt::LeftButton) && (pEvent->modifiers() == Qt::ShiftModifier)) { // We want to show the coordinates mAction = ShowCoordinates; } else if ( (pEvent->button() == Qt::RightButton) && (pEvent->modifiers() == Qt::NoModifier)) { // We want to zoom in/out mAction = Zoom; } else if ( (pEvent->button() == Qt::RightButton) && (pEvent->modifiers() == Qt::ControlModifier)) { // We want to zoom a region, but we can only do this if we are not // already fully zoomed in if ((mZoomFactorX < MaxZoomFactor) || (mZoomFactorY < MaxZoomFactor)) { mAction = ZoomRegion; } else { // We are already fully zoomed in, so... mAction = None; return; } } else { // We cannot carry out any action, so check whether we need to replot // ourselves (in case we were in the middle of carrying out a visual // action), make sure that we have no action to carry out, replot // ourselves if needed, and then leave bool needReplotNow; switch (mAction) { case ShowCoordinates: case ZoomRegion: needReplotNow = true; break; default: needReplotNow = false; } mAction = None; if (needReplotNow) replotNow(); return; } // Retrieve a pixmap version of our canvas, if needed if ((mAction == ShowCoordinates) || (mAction == ZoomRegion)) mCanvasPixmap = grab(plotLayout()->canvasRect().toRect()); // Keep track of the mouse position mOriginPoint = mousePositionWithinCanvas(pEvent->pos()); }
void SingleCellViewGraphPanelPlotWidget::mouseMoveEvent(QMouseEvent *pEvent) { // Default handling of the event QwtPlot::mouseMoveEvent(pEvent); // Check that interaction is allowed if (!mInteractive) return; // Retrieve the current point QPointF currentPoint = mousePositionWithinCanvas(pEvent->pos()); // Carry out the action switch (mAction) { case Pan: { // Determine the X/Y shifts for the panning double shiftX = currentPoint.x()-mOriginPoint.x(); double shiftY = currentPoint.y()-mOriginPoint.y(); // Determine our new local minimum/maximum values for our axes double newLocalMinX = localMinX()-shiftX; double newLocalMaxX = localMaxX()-shiftX; double newLocalMinY = localMinY()-shiftY; double newLocalMaxY = localMaxY()-shiftY; // Make sure that our new local minimum/maximum values for our axes // are within our local minimum/maximum values if (newLocalMinX < minX()) { newLocalMinX = minX(); newLocalMaxX = newLocalMinX+localMaxX()-localMinX(); } else if (newLocalMaxX > maxX()) { newLocalMaxX = maxX(); newLocalMinX = newLocalMaxX-localMaxX()+localMinX(); } if (newLocalMinY < minY()) { newLocalMinY = minY(); newLocalMaxY = newLocalMinY+localMaxY()-localMinY(); } else if (newLocalMaxY > maxY()) { newLocalMaxY = maxY(); newLocalMinY = newLocalMaxY-localMaxY()+localMinY(); } // Set our new local minimum/maximum values for our local axes which // will replot ourselves as a result setLocalAxes(newLocalMinX, newLocalMaxX, newLocalMinY, newLocalMaxY); break; } case ShowCoordinates: // Show the coordinates by simply replotting ourselves replotNow(); break; case Zoom: { // Rescale ourselves (which will replot ourselves as a result) double deltaX = currentPoint.x()-mOriginPoint.x(); double deltaY = currentPoint.y()-mOriginPoint.y(); scaleLocalAxes(deltaX? (deltaX > 0)? ScalingInFactor: ScalingOutFactor: NoScalingFactor, deltaY? (deltaY < 0)? ScalingInFactor: ScalingOutFactor: NoScalingFactor); break; } case ZoomRegion: // Draw our zoom region by updating our end point and then replotting // ourselves mEndPoint = mousePositionWithinCanvas(pEvent->pos()); replotNow(); break; default: // None ; } // Reset our point of origin, but only if we are doing something and it's // not zooming a region if ((mAction != None) && (mAction != ZoomRegion)) mOriginPoint = mousePositionWithinCanvas(pEvent->pos()); }
void SingleCellViewGraphPanelPlotWidget::setLocalAxes(const double &pLocalMinX, const double &pLocalMaxX, const double &pLocalMinY, const double &pLocalMaxY, const bool &pCanReplot, const bool &pForceMinMaxValues, const bool &pUpdateMinMaxValues, const bool &pResetMinMaxValues) { // Update our axes double oldLocalMinX = localMinX(); double oldLocalMaxX = localMaxX(); double oldLocalMinY = localMinY(); double oldLocalMaxY = localMaxY(); double newLocalMinX = pLocalMinX; double newLocalMaxX = pLocalMaxX; double newLocalMinY = pLocalMinY; double newLocalMaxY = pLocalMaxY; // Retrieve the bounding rectangle for all our curves (but only for those // that have some data) QRectF boundingRect = QRectF(); foreach (SingleCellViewGraphPanelPlotCurve *curve, mCurves) if (curve->dataSize()) boundingRect |= curve->boundingRect(); // Update the minimum/maximum values of our axes, should we have retrieved a // valid bounding rectangle if (boundingRect != QRectF()) { // Optimise our bounding rectangle by first retrieving the // minimum/maximum values of our axes double xMin = boundingRect.left(); double xMax = boundingRect.right(); double yMin = boundingRect.top(); double yMax = boundingRect.bottom(); // Make sure that the minimum/maximum values of our axes have finite // values checkAnyAxesValues(xMin, xMax, yMin, yMax); // Optimise the minimum/maximum values of our axes by rounding them // down/up, respectively double powerX = qPow(10.0, qMax(xMin?qFloor(log10(qAbs(xMin))):0, xMax?qFloor(log10(qAbs(xMax))):0)); double powerY = qPow(10.0, qMax(yMin?qFloor(log10(qAbs(yMin))):0, yMax?qFloor(log10(qAbs(yMax))):0)); xMin = powerX*qFloor(xMin/powerX); xMax = powerX*qCeil(xMax/powerX); yMin = powerY*qFloor(yMin/powerY); yMax = powerY*qCeil(yMax/powerY); // Make sure that the optimised minimum/maximum values of our axes have // finite values checkAnyAxesValues(xMin, xMax, yMin, yMax); // Update the minimum/maximum values of our axes, if required if (!mFixedAxisX) { if (pResetMinMaxValues) setMinMaxX(xMin, xMax); else if (pUpdateMinMaxValues) setMinMaxX(qMin(mMinX, xMin), qMax(mMaxX, xMax)); } if (!mFixedAxisY) { if (pResetMinMaxValues) setMinMaxY(yMin, yMax); else if (pUpdateMinMaxValues) setMinMaxY(qMin(mMinY, yMin), qMax(mMaxY, yMax)); } } // Make sure that the new minimum/maximum values of our local axes fit // within the minimum/maximum values of our axes if (pForceMinMaxValues) { newLocalMinX = mMinX; newLocalMaxX = mMaxX; newLocalMinY = mMinY; newLocalMaxY = mMaxY; } else { newLocalMinX = qMax(newLocalMinX, mMinX); newLocalMaxX = qMin(newLocalMaxX, mMaxX); newLocalMinY = qMax(newLocalMinY, mMinY); newLocalMaxY = qMin(newLocalMaxY, mMaxY); } // Make sure that the new minimum/maximum values of our local axes have // finite values checkAnyAxesValues(newLocalMinX, newLocalMaxX, newLocalMinY, newLocalMaxY); // Make sure that the new minimum/maximum values of our local axes have a // valid zoom factor checkLocalAxisValues(QwtPlot::xBottom, newLocalMinX, newLocalMaxX); checkLocalAxisValues(QwtPlot::yLeft, newLocalMinY, newLocalMaxY); // Update the minimum/maximum values of our local axes, if needed bool needReplot = false; if ((newLocalMinX != oldLocalMinX) || (newLocalMaxX != oldLocalMaxX)) { setLocalMinMaxX(newLocalMinX, newLocalMaxX); needReplot = true; } if ((newLocalMinY != oldLocalMinY) || (newLocalMaxY != oldLocalMaxY)) { setLocalMinMaxY(newLocalMinY, newLocalMaxY); needReplot = true; } // Replot ourselves, if needed and allowed if (needReplot && pCanReplot) replotNow(); }
void SingleCellViewGraphPanelPlotWidget::drawCurveSegment ( QSharedPointer<SingleCellViewGraphPanelPlotCurve> pCurve, const qulonglong &pFrom, const qulonglong &pTo) { // Make sure that we have a curve segment to draw if (pFrom == pTo) return; // Reset our local axes and replot ourselves, if it is our first curve // segment, or carry on as normal if (!pFrom) { // It is our first curve segment, so check our local axes // Note: we always want to replot, hence our passing false as an // argument to resetLocalAxes()... resetLocalAxes(false); replotNow(); } else { // It's not our first curve segment, so determine the minimum/maximum // X/Y values of our new data double xMin = 0.0; double xMax = 0.0; double yMin = 0.0; double yMax = 0.0; for (qulonglong i = pFrom; i <= pTo; ++i) if (i == pFrom) { xMin = xMax = pCurve->data()->sample(i).x(); yMin = yMax = pCurve->data()->sample(i).y(); } else { double xVal = pCurve->data()->sample(i).x(); double yVal = pCurve->data()->sample(i).y(); xMin = qMin(xMin, xVal); xMax = qMax(xMax, xVal); yMin = qMin(yMin, yVal); yMax = qMax(yMax, yVal); } // Check whether our X/Y axis can handle the minimum/maximum X/Y values // of our new data if ( (xMin < minX()) || (xMax > maxX()) || (yMin < minY()) || (yMax > maxY())) // Our X/Y axis cannot handle the minimum/maximum X/Y values of our // new data, so check our local axes checkLocalAxes(true, true, true); else // Our X/Y axis can handle the X/Y min/max of our new data, so just // draw our new curve segment mDirectPainter->drawSeries(pCurve.data(), pFrom, pTo); } }