void Plot::drawItems (QPainter *painter, const QRect &rect, const QwtScaleMap map[axisCnt], const QwtPlotPrintFilter &pfilter) const { painter->save(); painter->setRenderHint(QPainter::Antialiasing); for (int i=0; i<QwtPlot::axisCnt; i++){ if (!axisEnabled(i)) continue; drawBreak(painter, rect, map[i], i); } painter->restore(); for (int i=0; i<QwtPlot::axisCnt; i++){ if (!axisEnabled(i)) continue; const ScaleEngine *sc_engine = (const ScaleEngine *)axisScaleEngine(i); /*const QwtScaleEngine *qwtsc_engine=axisScaleEngine(i); const ScaleEngine *sc_engine =dynamic_cast<const ScaleEngine*>(qwtsc_engine); if(sc_engine!=NULL) { */ if (!sc_engine->hasBreak()) continue; QwtScaleMap m = map[i]; int lb = m.transform(sc_engine->axisBreakLeft()); int rb = m.transform(sc_engine->axisBreakRight()); int start = lb, end = rb; if (sc_engine->testAttribute(QwtScaleEngine::Inverted)){ end = lb; start = rb; } QRegion cr(rect); if (i == QwtPlot::xBottom || i == QwtPlot::xTop) painter->setClipRegion(cr.subtracted(QRegion(start, rect.y(), abs(end - start), rect.height())), Qt::IntersectClip); else if (i == QwtPlot::yLeft || i == QwtPlot::yRight) painter->setClipRegion(cr.subtracted(QRegion(rect.x(), end, rect.width(), abs(end - start))), Qt::IntersectClip); //} } QwtPlot::drawItems(painter, rect, map, pfilter); for (int i=0; i<QwtPlot::axisCnt; i++){ if (!axisEnabled(i)) continue; const ScaleDraw *sd = (const ScaleDraw *) axisScaleDraw (i); int majorTicksType = sd->majorTicksStyle(); int minorTicksType = sd->minorTicksStyle(); bool min = (minorTicksType == ScaleDraw::In || minorTicksType == ScaleDraw::Both); bool maj = (majorTicksType == ScaleDraw::In || majorTicksType == ScaleDraw::Both); if (min || maj) drawInwardTicks(painter, rect, map[i], i, min, maj); } }
void PlotMatrix::updateLayout() { for ( int row = 0; row < numRows(); row++ ) { for ( int col = 0; col < numColumns(); col++ ) { QwtPlot *p = plot( row, col ); if ( p ) { bool showAxis[QwtPlot::axisCnt]; showAxis[QwtPlot::xBottom] = axisEnabled( QwtPlot::xBottom ) && row == numRows() - 1; showAxis[QwtPlot::xTop] = axisEnabled( QwtPlot::xTop ) && row == 0; showAxis[QwtPlot::yLeft] = axisEnabled( QwtPlot::yLeft ) && col == 0; showAxis[QwtPlot::yRight] = axisEnabled( QwtPlot::yRight ) && col == numColumns() - 1; for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) p->enableAxis( axis, showAxis[axis] ); else { p->enableAxis( axis, true ); QwtScaleDraw *sd = p->axisScaleDraw( axis ); sd->enableComponent( QwtScaleDraw::Backbone, showAxis[axis] ); sd->enableComponent( QwtScaleDraw::Ticks, showAxis[axis] ); sd->enableComponent( QwtScaleDraw::Labels, showAxis[axis] ); } } } } } for ( int col = 0; col < numColumns(); col++ ) { alignVAxes( col, QwtPlot::yLeft ); alignVAxes( col, QwtPlot::yRight ); } for ( int row = 0; row < numRows(); row++ ) { for ( int col = 0; col < numColumns(); col++ ) { QwtPlot *p = plot( row, col ); if ( p ) p->replot(); } } }
void PlotMatrix::updateLayout() { for ( int row = 0; row < numRows(); row++ ) { for ( int col = 0; col < numColumns(); col++ ) { QwtPlot *p = plotAt( row, col ); if ( p ) { bool showAxis[QwtPlot::axisCnt]; showAxis[QwtPlot::xBottom] = axisEnabled( QwtPlot::xBottom ) && row == numRows() - 1; showAxis[QwtPlot::xTop] = axisEnabled( QwtPlot::xTop ) && row == 0; showAxis[QwtPlot::yLeft] = axisEnabled( QwtPlot::yLeft ) && col == 0; showAxis[QwtPlot::yRight] = axisEnabled( QwtPlot::yRight ) && col == numColumns() - 1; for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) { enablePlotAxis( p, axis, showAxis[axis] ); } } } } for ( int row = 0; row < numRows(); row++ ) { alignAxes( row, QwtPlot::xTop ); alignAxes( row, QwtPlot::xBottom ); alignScaleBorder( row, QwtPlot::yLeft ); alignScaleBorder( row, QwtPlot::yRight ); } for ( int col = 0; col < numColumns(); col++ ) { alignAxes( col, QwtPlot::yLeft ); alignAxes( col, QwtPlot::yRight ); alignScaleBorder( col, QwtPlot::xBottom ); alignScaleBorder( col, QwtPlot::xTop ); } for ( int row = 0; row < numRows(); row++ ) { for ( int col = 0; col < numColumns(); col++ ) { QwtPlot *p = plotAt( row, col ); if ( p ) p->replot(); } } }
/*! \return Size hint for the plot widget \sa minimumSizeHint() */ QSize QwtPlot::sizeHint() const { int dw = 0; int dh = 0; for ( int axisId = 0; axisId < axisCnt; axisId++ ) { if ( axisEnabled( axisId ) ) { const int niceDist = 40; const QwtScaleWidget *scaleWidget = axisWidget( axisId ); const QwtScaleDiv &scaleDiv = scaleWidget->scaleDraw()->scaleDiv(); const int majCnt = scaleDiv.ticks( QwtScaleDiv::MajorTick ).count(); if ( axisId == yLeft || axisId == yRight ) { int hDiff = ( majCnt - 1 ) * niceDist - scaleWidget->minimumSizeHint().height(); if ( hDiff > dh ) dh = hDiff; } else { int wDiff = ( majCnt - 1 ) * niceDist - scaleWidget->minimumSizeHint().width(); if ( wDiff > dw ) dw = wDiff; } } } return minimumSizeHint() + QSize( dw, dh ); }
/*! \param axisId Axis \return Map for the axis on the canvas. With this map pixel coordinates can translated to plot coordinates and vice versa. \sa QwtScaleMap, transform(), invTransform() */ QwtScaleMap QwtPlot::canvasMap( int axisId ) const { QwtScaleMap map; if ( !d_data->canvas ) return map; map.setTransformation( axisScaleEngine( axisId )->transformation() ); const QwtScaleDiv &sd = axisScaleDiv( axisId ); map.setScaleInterval( sd.lowerBound(), sd.upperBound() ); if ( axisEnabled( axisId ) ) { const QwtScaleWidget *s = axisWidget( axisId ); if ( axisId == yLeft || axisId == yRight ) { double y = s->y() + s->startBorderDist() - d_data->canvas->y(); double h = s->height() - s->startBorderDist() - s->endBorderDist(); map.setPaintInterval( y + h, y ); } else { double x = s->x() + s->startBorderDist() - d_data->canvas->x(); double w = s->width() - s->startBorderDist() - s->endBorderDist(); map.setPaintInterval( x, x + w ); } } else { const QRect &canvasRect = d_data->canvas->contentsRect(); if ( axisId == yLeft || axisId == yRight ) { int top = 0; if ( !plotLayout()->alignCanvasToScale( xTop ) ) top = plotLayout()->canvasMargin( xTop ); int bottom = 0; if ( !plotLayout()->alignCanvasToScale( xBottom ) ) bottom = plotLayout()->canvasMargin( xBottom ); map.setPaintInterval( canvasRect.bottom() - bottom, canvasRect.top() + top ); } else { int left = 0; if ( !plotLayout()->alignCanvasToScale( yLeft ) ) left = plotLayout()->canvasMargin( yLeft ); int right = 0; if ( !plotLayout()->alignCanvasToScale( yRight ) ) right = plotLayout()->canvasMargin( yRight ); map.setPaintInterval( canvasRect.left() + left, canvasRect.right() - right ); } } return map; }
QValueList <int> Plot::getMinorTicksType() { QValueList <int> minorTicksType; for (int axis=0; axis<QwtPlot::axisCnt; axis++) { if (axisEnabled(axis)) { ScaleDraw *sd = (ScaleDraw *) axisScaleDraw (axis); minorTicksType << sd->minorTicksStyle(); } else minorTicksType << ScaleDraw::Out; } return minorTicksType; }
/*! \param axisId Axis \return Map for the axis on the canvas. With this map pixel coordinates can translated to plot coordinates and vice versa. \sa QwtScaleMap, transform(), invTransform() */ QwtScaleMap QwtPlot::canvasMap( int axisId ) const { QwtScaleMap map; if ( !d_data->canvas ) return map; map.setTransformation( axisScaleEngine( axisId )->transformation() ); const QwtScaleDiv *sd = axisScaleDiv( axisId ); map.setScaleInterval( sd->lowerBound(), sd->upperBound() ); if ( axisEnabled( axisId ) ) { const QwtScaleWidget *s = axisWidget( axisId ); if ( axisId == yLeft || axisId == yRight ) { double y = s->y() + s->startBorderDist() - d_data->canvas->y(); double h = s->height() - s->startBorderDist() - s->endBorderDist(); map.setPaintInterval( y + h, y ); } else { double x = s->x() + s->startBorderDist() - d_data->canvas->x(); double w = s->width() - s->startBorderDist() - s->endBorderDist(); map.setPaintInterval( x, x + w ); } } else { int margin = 0; if ( !plotLayout()->alignCanvasToScales() ) margin = plotLayout()->canvasMargin( axisId ); const QRect &canvasRect = d_data->canvas->contentsRect(); if ( axisId == yLeft || axisId == yRight ) { map.setPaintInterval( canvasRect.bottom() - margin, canvasRect.top() + margin ); } else { map.setPaintInterval( canvasRect.left() + margin, canvasRect.right() - margin ); } } return map; }
/*! \param axis Axis \return Map for the axis on the canvas. With this map pixel coordinates can translated to plot coordinates and vice versa. \sa QwtDiMap, QwtPlot::transform, QwtPlot::invTransform */ QwtDiMap QwtPlot::canvasMap(int axis) const { QwtDiMap map; if ( !d_canvas ) return map; const QwtScaleDiv &sd = d_as[axis].scaleDiv(); map.setDblRange(sd.lBound(), sd.hBound(), sd.logScale()); if ( axisEnabled(axis) ) { const QwtScale *s = d_scale[axis]; if ( axis == yLeft || axis == yRight ) { int y = s->y() + s->startBorderDist() - d_canvas->y(); int h = s->height() - s->startBorderDist() - s->endBorderDist(); map.setIntRange(y + h - 1, y); } else { int x = s->x() + s->startBorderDist() - d_canvas->x(); int w = s->width() - s->startBorderDist() - s->endBorderDist(); map.setIntRange(x, x + w - 1); } } else { const int margin = plotLayout()->canvasMargin(axis); const QRect &canvasRect = d_canvas->contentsRect(); if ( axis == yLeft || axis == yRight ) { map.setIntRange(canvasRect.bottom() - margin, canvasRect.top() + margin); } else { map.setIntRange(canvasRect.left() + margin, canvasRect.right() - margin); } } return map; }
//! Redraw grid, curves, and markers. The draw code // does not clear clipRegion prior to painting. // \param p painter used for drawing void QwtPlot::drawCanvas(QPainter *p) { QwtDiMap map[axisCnt]; for ( int axis = 0; axis < axisCnt; axis++ ) map[axis] = canvasMap(axis); QRect rect = d_canvas->contentsRect(); // // draw grid // if ( d_grid.enabled() && axisEnabled( d_grid.xAxis() ) && axisEnabled( d_grid.yAxis() ) ) { d_grid.draw(p, rect, map[d_grid.xAxis()], map[d_grid.yAxis()]); } // // draw curves // QIntDictIterator<QwtPlotCurve> itc(*d_curves); for (QwtPlotCurve *curve = itc.toFirst(); curve != 0; curve = ++itc ) { if ( curve->enabled() && axisEnabled( curve->xAxis() ) && axisEnabled( curve->yAxis() ) ) { curve->draw(p, map[curve->xAxis()], map[curve->yAxis()]); } } // // draw markers // QIntDictIterator<QwtPlotMarker> itm(*d_markers); for (QwtPlotMarker *marker = itm.toFirst(); marker != 0; marker = ++itm ) { if ( marker->enabled() && axisEnabled( marker->xAxis() ) && axisEnabled( marker->yAxis() ) ) { marker->draw(p, map[marker->xAxis()].transform(marker->xValue()), map[marker->yAxis()].transform(marker->yValue()), rect); } } }
void Plot::drawItems (QPainter *painter, const QRect &rect, const QwtArray< QwtScaleMap > &map, const QwtPlotPrintFilter &pfilter) const { QwtPlot::drawItems(painter, rect, map, pfilter); for (int i=0; i<QwtPlot::axisCnt; i++) { if (!axisEnabled(i)) continue; ScaleDraw *sd = (ScaleDraw *) axisScaleDraw (i); int majorTicksType = sd->majorTicksStyle(); int minorTicksType = sd->minorTicksStyle(); bool min = (minorTicksType == ScaleDraw::In || minorTicksType == ScaleDraw::Both); bool maj = (majorTicksType == ScaleDraw::In || majorTicksType == ScaleDraw::Both); if (min || maj) drawInwardTicks(painter, rect, map[i], i, min, maj); } }
/** \brief Adjust plot content to its current size. Must be reimplemented because the base implementation adds a mask causing an ugly drawing artefact. */ void Plot::updateLayout() { plotLayout()->activate(this, contentsRect()); // resize and show the visible widgets if (!titleLabel()->text().isEmpty()){ titleLabel()->setGeometry(plotLayout()->titleRect()); if (!titleLabel()->isVisible()) titleLabel()->show(); } else titleLabel()->hide(); for (int axisId = 0; axisId < axisCnt; axisId++ ){ if (axisEnabled(axisId) ){ axisWidget(axisId)->setGeometry(plotLayout()->scaleRect(axisId)); if (!axisWidget(axisId)->isVisible()) axisWidget(axisId)->show(); } else axisWidget(axisId)->hide(); } canvas()->setGeometry(plotLayout()->canvasRect()); }
/*! \brief Paint the plot into a given rectangle. Paint the contents of a QwtPlot instance into a given rectangle. \param painter Painter \param plotRect Bounding rectangle \param pfilter Print filter \sa QwtPlotPrintFilter */ void QwtPlot::print(QPainter *painter, const QRect &plotRect, const QwtPlotPrintFilter &pfilter) const { int axis; if ( painter == 0 || !painter->isActive() || !plotRect.isValid() || size().isNull() ) return; painter->save(); // All paint operations need to be scaled according to // the paint device metrics. QwtPainter::setMetricsMap(this, painter->device()); #if QT_VERSION < 300 if ( painter->device()->isExtDev() ) { QPaintDeviceMetrics metrics(painter->device()); if ( metrics.logicalDpiX() == 72 && metrics.logicalDpiY() == 72 ) { // In Qt 2.x QPrinter returns hardcoded wrong metrics. // So scaling won´t work: we reset to screen resolution QwtPainter::setMetricsMap(this, this); } } #endif const QwtMetricsMap &metricsMap = QwtPainter::metricsMap(); // It is almost impossible to integrate into the Qt layout // framework, when using different fonts for printing // and screen. To avoid writing different and Qt unconform // layout engines we change the widget attributes, print and // reset the widget attributes again. This way we produce a lot of // useless layout events ... pfilter.apply((QwtPlot *)this); int baseLineDists[QwtPlot::axisCnt]; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground) ) { // In case of no background we set the backbone of // the scale on the frame of the canvas. for (axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if ( d_scale[axis] ) { baseLineDists[axis] = d_scale[axis]->baseLineDist(); d_scale[axis]->setBaselineDist(0); } } } // Calculate the layout for the print. int layoutOptions = QwtPlotLayout::IgnoreScrollbars | QwtPlotLayout::IgnoreFrames; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintMargin) ) layoutOptions |= QwtPlotLayout::IgnoreMargin; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintLegend) ) layoutOptions |= QwtPlotLayout::IgnoreLegend; d_layout->activate(this, QwtPainter::metricsMap().deviceToLayout(plotRect), layoutOptions); if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle) && (!d_lblTitle->text().isEmpty())) { printTitle(painter, d_layout->titleRect()); } if ( (pfilter.options() & QwtPlotPrintFilter::PrintLegend) && !d_legend->isEmpty() ) { printLegend(painter, d_layout->legendRect()); } for ( axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if (d_scale[axis]) { int baseDist = d_scale[axis]->baseLineDist(); int startDist, endDist; d_scale[axis]->minBorderDist(startDist, endDist); printScale(painter, axis, startDist, endDist, baseDist, d_layout->scaleRect(axis)); } } const QRect canvasRect = metricsMap.layoutToDevice(d_layout->canvasRect()); // When using QwtPainter all sizes where computed in pixel // coordinates and scaled by QwtPainter later. This limits // the precision to screen resolution. A much better solution // is to scale the maps and print in unlimited resolution. QwtArray<QwtDiMap> map(axisCnt); for (axis = 0; axis < axisCnt; axis++) { const QwtScaleDiv &scaleDiv = d_as[axis].scaleDiv(); map[axis].setDblRange(scaleDiv.lBound(), scaleDiv.hBound(), scaleDiv.logScale()); double from, to; if ( axisEnabled(axis) ) { const int sDist = d_scale[axis]->startBorderDist(); const int eDist = d_scale[axis]->endBorderDist(); const QRect &scaleRect = d_layout->scaleRect(axis); if ( axis == xTop || axis == xBottom ) { from = metricsMap.layoutToDeviceX(scaleRect.left() + sDist); to = metricsMap.layoutToDeviceX(scaleRect.right() - eDist); } else { from = metricsMap.layoutToDeviceY(scaleRect.bottom() - sDist); to = metricsMap.layoutToDeviceY(scaleRect.top() + eDist); } } else { const int margin = plotLayout()->canvasMargin(axis); const QRect &canvasRect = plotLayout()->canvasRect(); if ( axis == yLeft || axis == yRight ) { from = metricsMap.layoutToDeviceX(canvasRect.bottom() - margin); to = metricsMap.layoutToDeviceX(canvasRect.top() + margin); } else { from = metricsMap.layoutToDeviceY(canvasRect.left() + margin); to = metricsMap.layoutToDeviceY(canvasRect.right() - margin); } } map[axis].setIntRange( qwtInt(from), qwtInt(to)); } // The maps are already scaled. QwtPainter::setMetricsMap(painter->device(), painter->device()); printCanvas(painter, canvasRect, map, pfilter); QwtPainter::resetMetricsMap(); d_layout->invalidate(); // reset all widgets with their original attributes. if ( !(pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground) ) { // restore the previous base line dists for (axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if ( d_scale[axis] ) d_scale[axis]->setBaselineDist(baseLineDists[axis]); } } pfilter.reset((QwtPlot *)this); painter->restore(); }
/*! \brief Paint the plot into a given rectangle. Paint the contents of a QwtPlot instance into a given rectangle. \param painter Painter \param plotRect Bounding rectangle \param pfilter Print filter \sa QwtPlotPrintFilter */ void QwtPlot::print(QPainter *painter, const QRect &plotRect, const QwtPlotPrintFilter &pfilter) const { int axisId; if ( painter == 0 || !painter->isActive() || !plotRect.isValid() || size().isNull() ) return; painter->save(); #if 1 /* PDF: In Qt4 ( <= 4.3.2 ) the scales are painted in gray instead of black. See http://trolltech.com/developer/task-tracker/index_html?id=184671&method=entry The dummy lines below work around the problem. */ const QPen pen = painter->pen(); painter->setPen(QPen(Qt::black, 1)); painter->setPen(pen); #endif // All paint operations need to be scaled according to // the paint device metrics. QwtPainter::setMetricsMap(this, painter->device()); const QwtMetricsMap &metricsMap = QwtPainter::metricsMap(); // It is almost impossible to integrate into the Qt layout // framework, when using different fonts for printing // and screen. To avoid writing different and Qt unconform // layout engines we change the widget attributes, print and // reset the widget attributes again. This way we produce a lot of // useless layout events ... pfilter.apply((QwtPlot *)this); int baseLineDists[QwtPlot::axisCnt]; if ( pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales ) { for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if ( scaleWidget ) { baseLineDists[axisId] = scaleWidget->margin(); scaleWidget->setMargin(0); } } } // Calculate the layout for the print. int layoutOptions = QwtPlotLayout::IgnoreScrollbars | QwtPlotLayout::IgnoreFrames; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintMargin) ) layoutOptions |= QwtPlotLayout::IgnoreMargin; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintLegend) ) layoutOptions |= QwtPlotLayout::IgnoreLegend; ((QwtPlot *)this)->plotLayout()->activate(this, QwtPainter::metricsMap().deviceToLayout(plotRect), layoutOptions); if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle) && (!titleLabel()->text().isEmpty())) { printTitle(painter, plotLayout()->titleRect()); } if ( (pfilter.options() & QwtPlotPrintFilter::PrintLegend) && legend() && !legend()->isEmpty() ) { printLegend(painter, plotLayout()->legendRect()); } for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if (scaleWidget) { int baseDist = scaleWidget->margin(); int startDist, endDist; scaleWidget->getBorderDistHint(startDist, endDist); printScale(painter, axisId, startDist, endDist, baseDist, plotLayout()->scaleRect(axisId)); } } QRect canvasRect = plotLayout()->canvasRect(); /* The border of the bounding rect needs to ba scaled to layout coordinates, so that it is aligned to the axes */ QRect boundingRect( canvasRect.left() - 1, canvasRect.top() - 1, canvasRect.width() + 2, canvasRect.height() + 2); boundingRect = metricsMap.layoutToDevice(boundingRect); boundingRect.setWidth(boundingRect.width() - 1); boundingRect.setHeight(boundingRect.height() - 1); canvasRect = metricsMap.layoutToDevice(canvasRect); // When using QwtPainter all sizes where computed in pixel // coordinates and scaled by QwtPainter later. This limits // the precision to screen resolution. A better solution // is to scale the maps and print in unlimited resolution. QwtScaleMap map[axisCnt]; for (axisId = 0; axisId < axisCnt; axisId++) { map[axisId].setTransformation(axisScaleEngine(axisId)->transformation()); const QwtScaleDiv &scaleDiv = *axisScaleDiv(axisId); map[axisId].setScaleInterval(scaleDiv.lBound(), scaleDiv.hBound()); double from, to; if ( axisEnabled(axisId) ) { const int sDist = axisWidget(axisId)->startBorderDist(); const int eDist = axisWidget(axisId)->endBorderDist(); const QRect &scaleRect = plotLayout()->scaleRect(axisId); if ( axisId == xTop || axisId == xBottom ) { from = metricsMap.layoutToDeviceX(scaleRect.left() + sDist); to = metricsMap.layoutToDeviceX(scaleRect.right() + 1 - eDist); } else { from = metricsMap.layoutToDeviceY(scaleRect.bottom() + 1 - eDist ); to = metricsMap.layoutToDeviceY(scaleRect.top() + sDist); } } else { int margin = plotLayout()->canvasMargin(axisId); if ( axisId == yLeft || axisId == yRight ) { margin = metricsMap.layoutToDeviceY(margin); from = canvasRect.bottom() - margin; to = canvasRect.top() + margin; } else { margin = metricsMap.layoutToDeviceX(margin); from = canvasRect.left() + margin; to = canvasRect.right() - margin; } } map[axisId].setPaintXInterval(from, to); } // The canvas maps are already scaled. QwtPainter::setMetricsMap(painter->device(), painter->device()); printCanvas(painter, boundingRect, canvasRect, map, pfilter); QwtPainter::resetMetricsMap(); ((QwtPlot *)this)->plotLayout()->invalidate(); // reset all widgets with their original attributes. if ( pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales ) { // restore the previous base line dists for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if ( scaleWidget ) scaleWidget->setMargin(baseLineDists[axisId]); } } pfilter.reset((QwtPlot *)this); painter->restore(); }
void QwtPlot::printLegend(QPainter *painter, const QRect &rect) const { if ( !legend() || legend()->isEmpty() ) return; QLayout *l = legend()->contentsWidget()->layout(); if ( l == 0 || !l->inherits("QwtDynGridLayout") ) return; QwtDynGridLayout *legendLayout = (QwtDynGridLayout *)l; uint numCols = legendLayout->columnsForWidth(rect.width()); #if QT_VERSION < 0x040000 QValueList<QRect> itemRects = legendLayout->layoutItems(rect, numCols); #else QList<QRect> itemRects = legendLayout->layoutItems(rect, numCols); #endif int index = 0; #if QT_VERSION < 0x040000 QLayoutIterator layoutIterator = legendLayout->iterator(); for ( QLayoutItem *item = layoutIterator.current(); item != 0; item = ++layoutIterator) { #else for ( int i = 0; i < legendLayout->count(); i++ ) { QLayoutItem *item = legendLayout->itemAt(i); #endif QWidget *w = item->widget(); if ( w ) { painter->save(); painter->setClipping(true); QwtPainter::setClipRect(painter, itemRects[index]); printLegendItem(painter, w, itemRects[index]); index++; painter->restore(); } } } /*! Print the legend item into a given rectangle. \param painter Painter \param w Widget representing a legend item \param rect Bounding rectangle */ void QwtPlot::printLegendItem(QPainter *painter, const QWidget *w, const QRect &rect) const { if ( w->inherits("QwtLegendItem") ) { QwtLegendItem *item = (QwtLegendItem *)w; painter->setFont(item->font()); item->drawItem(painter, rect); } } /*! \brief Paint a scale into a given rectangle. Paint the scale into a given rectangle. \param painter Painter \param axisId Axis \param startDist Start border distance \param endDist End border distance \param baseDist Base distance \param rect Bounding rectangle */ void QwtPlot::printScale(QPainter *painter, int axisId, int startDist, int endDist, int baseDist, const QRect &rect) const { if (!axisEnabled(axisId)) return; const QwtScaleWidget *scaleWidget = axisWidget(axisId); if ( scaleWidget->isColorBarEnabled() && scaleWidget->colorBarWidth() > 0) { const QwtMetricsMap map = QwtPainter::metricsMap(); QRect r = map.layoutToScreen(rect); r.setWidth(r.width() - 1); r.setHeight(r.height() - 1); scaleWidget->drawColorBar(painter, scaleWidget->colorBarRect(r)); const int off = scaleWidget->colorBarWidth() + scaleWidget->spacing(); if ( scaleWidget->scaleDraw()->orientation() == Qt::Horizontal ) baseDist += map.screenToLayoutY(off); else baseDist += map.screenToLayoutX(off); } QwtScaleDraw::Alignment align; int x, y, w; switch(axisId) { case yLeft: { x = rect.right() - baseDist; y = rect.y() + startDist; w = rect.height() - startDist - endDist; align = QwtScaleDraw::LeftScale; break; } case yRight: { x = rect.left() + baseDist; y = rect.y() + startDist; w = rect.height() - startDist - endDist; align = QwtScaleDraw::RightScale; break; } case xTop: { x = rect.left() + startDist; y = rect.bottom() - baseDist; w = rect.width() - startDist - endDist; align = QwtScaleDraw::TopScale; break; } case xBottom: { x = rect.left() + startDist; y = rect.top() + baseDist; w = rect.width() - startDist - endDist; align = QwtScaleDraw::BottomScale; break; } default: return; } scaleWidget->drawTitle(painter, align, rect); painter->save(); painter->setFont(scaleWidget->font()); QPen pen = painter->pen(); pen.setWidth(scaleWidget->penWidth()); painter->setPen(pen); QwtScaleDraw *sd = (QwtScaleDraw *)scaleWidget->scaleDraw(); const QPoint sdPos = sd->pos(); const int sdLength = sd->length(); sd->move(x, y); sd->setLength(w); #if QT_VERSION < 0x040000 sd->draw(painter, scaleWidget->palette().active()); #else QPalette palette = scaleWidget->palette(); palette.setCurrentColorGroup(QPalette::Active); sd->draw(painter, palette); #endif // reset previous values sd->move(sdPos); sd->setLength(sdLength); painter->restore(); } /*! Print the canvas into a given rectangle. \param painter Painter \param map Maps mapping between plot and paint device coordinates \param boundingRect Bounding rectangle \param canvasRect Canvas rectangle \param pfilter Print filter \sa QwtPlotPrintFilter */ void QwtPlot::printCanvas(QPainter *painter, const QRect &boundingRect, const QRect &canvasRect, const QwtScaleMap map[axisCnt], const QwtPlotPrintFilter &pfilter) const { if ( pfilter.options() & QwtPlotPrintFilter::PrintBackground ) { QBrush bgBrush; #if QT_VERSION >= 0x040000 bgBrush = canvas()->palette().brush(backgroundRole()); #else QColorGroup::ColorRole role = QPalette::backgroundRoleFromMode( backgroundMode() ); bgBrush = canvas()->colorGroup().brush( role ); #endif QRect r = boundingRect; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales) ) { r = canvasRect; #if QT_VERSION >= 0x040000 // Unfortunately the paint engines do no always the same const QPaintEngine *pe = painter->paintEngine(); if ( pe ) { switch(painter->paintEngine()->type() ) { case QPaintEngine::Raster: case QPaintEngine::X11: break; default: r.setWidth(r.width() - 1); r.setHeight(r.height() - 1); break; } } #else if ( painter->device()->isExtDev() ) { r.setWidth(r.width() - 1); r.setHeight(r.height() - 1); } #endif } QwtPainter::fillRect(painter, r, bgBrush); } if ( pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales ) { painter->save(); painter->setPen(QPen(Qt::black)); painter->setBrush(QBrush(Qt::NoBrush)); QwtPainter::drawRect(painter, boundingRect); painter->restore(); } painter->setClipping(true); QwtPainter::setClipRect(painter, canvasRect); drawItems(painter, canvasRect, map, pfilter); }
void Plot::printScale(QPainter *painter, int axisId, int startDist, int endDist, int baseDist, const QRect &rect) const { if (!axisEnabled(axisId)) return; const QwtScaleWidget *scaleWidget = axisWidget(axisId); if ( scaleWidget->isColorBarEnabled() && scaleWidget->colorBarWidth() > 0) { const QwtMetricsMap map = QwtPainter::metricsMap(); const QRect r = map.layoutToScreen(rect); scaleWidget->drawColorBar(painter, scaleWidget->colorBarRect(r)); const int off = scaleWidget->colorBarWidth() + scaleWidget->spacing(); if ( scaleWidget->scaleDraw()->orientation() == Qt::Horizontal ) baseDist += map.screenToLayoutY(off); else baseDist += map.screenToLayoutX(off); } QwtScaleDraw::Alignment align; int x, y, w; const int bw2 = scaleWidget->penWidth() / 2; switch(axisId) { case yLeft: { x = rect.right() - baseDist + 1 - bw2; y = rect.y() + startDist; w = rect.height() - startDist - endDist; align = QwtScaleDraw::LeftScale; break; } case yRight: { x = rect.left() + baseDist; if (scaleWidget->penWidth() % 2 == 0) x += 1; y = rect.y() + startDist; w = rect.height() - startDist - endDist + bw2; align = QwtScaleDraw::RightScale; break; } case xTop: { x = rect.left() + startDist; y = rect.bottom() - baseDist + 1; if (scaleWidget->penWidth() % 2 == 0) y -= bw2; w = rect.width() - startDist - endDist; align = QwtScaleDraw::TopScale; break; } case xBottom: { x = rect.left() + startDist; y = rect.top() + baseDist; if (scaleWidget->penWidth() % 2 == 1) y += bw2; w = rect.width() - startDist - endDist + bw2; align = QwtScaleDraw::BottomScale; break; } default: return; } scaleWidget->drawTitle(painter, align, rect); painter->save(); painter->setFont(scaleWidget->font()); QPen pen = painter->pen(); pen.setWidth(scaleWidget->penWidth()); painter->setPen(pen); QwtScaleDraw *sd = (QwtScaleDraw *)scaleWidget->scaleDraw(); const QPoint sdPos = sd->pos(); const int sdLength = sd->length(); sd->move(x, y); sd->setLength(w); #if QT_VERSION < 0x040000 sd->draw(painter, scaleWidget->palette().active()); #else QPalette palette = scaleWidget->palette(); palette.setCurrentColorGroup(QPalette::Active); sd->draw(painter, palette); #endif // reset previous values sd->move(sdPos); sd->setLength(sdLength); painter->restore(); }
bool SaxsviewImage::colorBarVisible() const { return axisEnabled(QwtPlot::yRight); }
void QwtPlot::printLegend(QPainter *painter, const QRect &rect) const { if ( !legend() || legend()->isEmpty() ) return; QLayout *l = legend()->contentsWidget()->layout(); if ( l == 0 || !l->inherits("QwtDynGridLayout") ) return; QwtDynGridLayout *legendLayout = (QwtDynGridLayout *)l; uint numCols = legendLayout->columnsForWidth(rect.width()); #if QT_VERSION < 0x040000 QValueList<QRect> itemRects = legendLayout->layoutItems(rect, numCols); #else QList<QRect> itemRects = legendLayout->layoutItems(rect, numCols); #endif int index = 0; #if QT_VERSION < 0x040000 QLayoutIterator layoutIterator = legendLayout->iterator(); for ( QLayoutItem *item = layoutIterator.current(); item != 0; item = ++layoutIterator) { #else for ( int i = 0; i < legendLayout->count(); i++ ) { QLayoutItem *item = legendLayout->itemAt(i); #endif QWidget *w = item->widget(); if ( w ) { painter->save(); painter->setClipping(true); QwtPainter::setClipRect(painter, itemRects[index]); printLegendItem(painter, w, itemRects[index]); index++; painter->restore(); } } } /*! Print the legend item into a given rectangle. \param painter Painter \param w Widget representing a legend item \param rect Bounding rectangle */ void QwtPlot::printLegendItem(QPainter *painter, const QWidget *w, const QRect &rect) const { if ( w->inherits("QwtLegendItem") ) { QwtLegendItem *item = (QwtLegendItem *)w; painter->setFont(item->font()); item->drawItem(painter, rect); } } /*! \brief Paint a scale into a given rectangle. Paint the scale into a given rectangle. \param painter Painter \param axisId Axis \param startDist Start border distance \param endDist End border distance \param baseDist Base distance \param rect Bounding rectangle */ void QwtPlot::printScale(QPainter *painter, int axisId, int startDist, int endDist, int baseDist, const QRect &rect) const { if (!axisEnabled(axisId)) return; QwtScaleDraw::Alignment align; int x, y, w; switch(axisId) { case yLeft: { x = rect.right() - baseDist + 1; y = rect.y() + startDist; w = rect.height() - startDist - endDist; align = QwtScaleDraw::LeftScale; break; } case yRight: { x = rect.left() + baseDist; y = rect.y() + startDist; w = rect.height() - startDist - endDist; align = QwtScaleDraw::RightScale; break; } case xTop: { x = rect.left() + startDist; y = rect.bottom() - baseDist + 1; w = rect.width() - startDist - endDist; align = QwtScaleDraw::TopScale; break; } case xBottom: { x = rect.left() + startDist; y = rect.top() + baseDist; w = rect.width() - startDist - endDist; align = QwtScaleDraw::BottomScale; break; } default: return; } const QwtScaleWidget *scaleWidget = axisWidget(axisId); scaleWidget->drawTitle(painter, align, rect); painter->save(); painter->setFont(scaleWidget->font()); QwtScaleDraw *sd = (QwtScaleDraw *)scaleWidget->scaleDraw(); const QPoint sdPos = sd->pos(); const int sdLength = sd->length(); sd->move(x, y); sd->setLength(w); #if QT_VERSION < 0x040000 sd->draw(painter, scaleWidget->palette().active()); #else QPalette palette = scaleWidget->palette(); palette.setCurrentColorGroup(QPalette::Active); sd->draw(painter, palette); #endif // reset previous values sd->move(sdPos); sd->setLength(sdLength); painter->restore(); } /*! Print the canvas into a given rectangle. \param painter Painter \param map Maps mapping between plot and paint device coordinates \param canvasRect Bounding rectangle \param pfilter Print filter \sa QwtPlotPrintFilter */ void QwtPlot::printCanvas(QPainter *painter, const QRect &canvasRect, const QwtArray<QwtScaleMap> &map, const QwtPlotPrintFilter &pfilter) const { if ( pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground ) { painter->setPen(Qt::NoPen); QBrush bgBrush; #if QT_VERSION >= 0x040000 bgBrush = canvas()->palette().brush(backgroundRole()); #else QColorGroup::ColorRole role = QPalette::backgroundRoleFromMode( backgroundMode() ); bgBrush = canvas()->colorGroup().brush( role ); #endif painter->setBrush(bgBrush); int x1 = 0; int x2 = 0; int y1 = 0; int y2 = 0; #if QT_VERSION >= 0x040000 switch(painter->device()->paintEngine()->type()) { case QPaintEngine::PostScript: x2 = 1; y2 = 1; break; default:; } #endif const QwtMetricsMap map = QwtPainter::metricsMap(); x1 = map.screenToLayoutX(x1); x2 = map.screenToLayoutX(x2); y1 = map.screenToLayoutY(y1); y2 = map.screenToLayoutY(y2); QwtPainter::drawRect(painter, canvasRect.x() + x1, canvasRect.y() + y1, canvasRect.width() - x2, canvasRect.height() - y2); } else { // Paint the canvas borders instead. painter->setPen(QPen(Qt::black)); painter->setBrush(QBrush(Qt::NoBrush)); QwtPainter::drawRect(painter, canvasRect); } painter->setClipping(true); QwtPainter::setClipRect(painter, canvasRect); drawItems(painter, canvasRect, map, pfilter); }
/*! \brief Paint the plot into a given rectangle. Paint the contents of a QwtPlot instance into a given rectangle. \param painter Painter \param plotRect Bounding rectangle \param pfilter Print filter \sa QwtPlotPrintFilter */ void QwtPlot::print(QPainter *painter, const QRect &plotRect, const QwtPlotPrintFilter &pfilter) const { int axisId; if ( painter == 0 || !painter->isActive() || !plotRect.isValid() || size().isNull() ) return; painter->save(); // All paint operations need to be scaled according to // the paint device metrics. QwtPainter::setMetricsMap(this, painter->device()); const QwtMetricsMap &metricsMap = QwtPainter::metricsMap(); // It is almost impossible to integrate into the Qt layout // framework, when using different fonts for printing // and screen. To avoid writing different and Qt unconform // layout engines we change the widget attributes, print and // reset the widget attributes again. This way we produce a lot of // useless layout events ... pfilter.apply((QwtPlot *)this); int baseLineDists[QwtPlot::axisCnt]; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground) ) { // In case of no background we set the backbone of // the scale on the frame of the canvas. for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if ( scaleWidget ) { baseLineDists[axisId] = scaleWidget->baseLineDist(); scaleWidget->setBaselineDist(0); } } } // Calculate the layout for the print. int layoutOptions = QwtPlotLayout::IgnoreScrollbars | QwtPlotLayout::IgnoreFrames; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintMargin) ) layoutOptions |= QwtPlotLayout::IgnoreMargin; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintLegend) ) layoutOptions |= QwtPlotLayout::IgnoreLegend; ((QwtPlot *)this)->plotLayout()->activate(this, QwtPainter::metricsMap().deviceToLayout(plotRect), layoutOptions); if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle) && (!titleLabel()->text().isEmpty())) { printTitle(painter, plotLayout()->titleRect()); } if ( (pfilter.options() & QwtPlotPrintFilter::PrintLegend) && legend() && !legend()->isEmpty() ) { printLegend(painter, plotLayout()->legendRect()); } for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if (scaleWidget) { int baseDist = scaleWidget->baseLineDist(); int startDist, endDist; scaleWidget->getBorderDistHint(startDist, endDist); printScale(painter, axisId, startDist, endDist, baseDist, plotLayout()->scaleRect(axisId)); } } const QRect canvasRect = metricsMap.layoutToDevice(plotLayout()->canvasRect()); // When using QwtPainter all sizes where computed in pixel // coordinates and scaled by QwtPainter later. This limits // the precision to screen resolution. A much better solution // is to scale the maps and print in unlimited resolution. QwtArray<QwtScaleMap> map(axisCnt); for (axisId = 0; axisId < axisCnt; axisId++) { map[axisId].setTransformation(axisScaleEngine(axisId)->transformation()); const QwtScaleDiv &scaleDiv = *axisScaleDiv(axisId); map[axisId].setScaleInterval(scaleDiv.lBound(), scaleDiv.hBound()); double from, to; if ( axisEnabled(axisId) ) { const int sDist = axisWidget(axisId)->startBorderDist(); const int eDist = axisWidget(axisId)->endBorderDist(); const QRect &scaleRect = plotLayout()->scaleRect(axisId); if ( axisId == xTop || axisId == xBottom ) { from = metricsMap.layoutToDeviceX(scaleRect.left() + sDist); to = metricsMap.layoutToDeviceX(scaleRect.right() - eDist); } else { from = metricsMap.layoutToDeviceY(scaleRect.bottom() - sDist); to = metricsMap.layoutToDeviceY(scaleRect.top() + eDist); } } else { const int margin = plotLayout()->canvasMargin(axisId); const QRect &canvasRect = plotLayout()->canvasRect(); if ( axisId == yLeft || axisId == yRight ) { from = metricsMap.layoutToDeviceX(canvasRect.bottom() - margin); to = metricsMap.layoutToDeviceX(canvasRect.top() + margin); } else { from = metricsMap.layoutToDeviceY(canvasRect.left() + margin); to = metricsMap.layoutToDeviceY(canvasRect.right() - margin); } } map[axisId].setPaintXInterval(from, to); } // The canvas maps are already scaled. QwtPainter::setMetricsMap(painter->device(), painter->device()); printCanvas(painter, canvasRect, map, pfilter); QwtPainter::resetMetricsMap(); ((QwtPlot *)this)->plotLayout()->invalidate(); // reset all widgets with their original attributes. if ( !(pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground) ) { // restore the previous base line dists for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if ( scaleWidget ) scaleWidget->setBaselineDist(baseLineDists[axisId]); } } pfilter.reset((QwtPlot *)this); painter->restore(); }
/*! \brief Adjust plot content to its current size. \sa resizeEvent() */ void QwtPlot::updateLayout() { d_data->layout->activate( this, contentsRect() ); QRect titleRect = d_data->layout->titleRect().toRect(); QRect footerRect = d_data->layout->footerRect().toRect(); QRect scaleRect[QwtPlot::axisCnt]; for ( int axisId = 0; axisId < axisCnt; axisId++ ) scaleRect[axisId] = d_data->layout->scaleRect( axisId ).toRect(); QRect legendRect = d_data->layout->legendRect().toRect(); QRect canvasRect = d_data->layout->canvasRect().toRect(); // resize and show the visible widgets if ( !d_data->titleLabel->text().isEmpty() ) { d_data->titleLabel->setGeometry( titleRect ); if ( !d_data->titleLabel->isVisibleTo( this ) ) d_data->titleLabel->show(); } else d_data->titleLabel->hide(); if ( !d_data->footerLabel->text().isEmpty() ) { d_data->footerLabel->setGeometry( footerRect ); if ( !d_data->footerLabel->isVisibleTo( this ) ) d_data->footerLabel->show(); } else d_data->footerLabel->hide(); for ( int axisId = 0; axisId < axisCnt; axisId++ ) { if ( axisEnabled( axisId ) ) { axisWidget( axisId )->setGeometry( scaleRect[axisId] ); #if 1 if ( axisId == xBottom || axisId == xTop ) { // do we need this code any longer ??? QRegion r( scaleRect[axisId] ); if ( axisEnabled( yLeft ) ) r = r.subtracted( QRegion( scaleRect[yLeft] ) ); if ( axisEnabled( yRight ) ) r = r.subtracted( QRegion( scaleRect[yRight] ) ); r.translate( -scaleRect[ axisId ].x(), -scaleRect[axisId].y() ); axisWidget( axisId )->setMask( r ); } #endif if ( !axisWidget( axisId )->isVisibleTo( this ) ) axisWidget( axisId )->show(); } else axisWidget( axisId )->hide(); } if ( d_data->legend ) { if ( d_data->legend->isEmpty() ) { d_data->legend->hide(); } else { d_data->legend->setGeometry( legendRect ); d_data->legend->show(); } } d_data->canvas->setGeometry( canvasRect ); }