From e6d4be3e6d80d82ad9b25fa334080859d113cf71 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Mal=C3=BD?= Date: Wed, 2 Jul 2014 22:48:37 +0200 Subject: [PATCH] Draw axis labels with units --- gui/graphview.cpp | 12 ++--- signaldrawer.cpp | 123 +++++++++++++++++++++++++++++++++++++++------- signaldrawer.h | 23 ++++++--- 3 files changed, 128 insertions(+), 30 deletions(-) diff --git a/gui/graphview.cpp b/gui/graphview.cpp index 329e114..9f7c3fc 100644 --- a/gui/graphview.cpp +++ b/gui/graphview.cpp @@ -145,9 +145,9 @@ void GraphView::mousePressEvent(QMouseEvent* ev) PeakDrawData pdData = m_controller->integratePeak(xPixToRel(m_integrateStartXPix), yPixToRel(m_integrateStartYPix), xPixToRel(m_integrateStopXPix), yPixToRel(m_integrateStopYPix)); eraseIntegrationBaseline(true); - QRect rect = renderPeak(pdData, m_background); - copyPixmapRegion(rect, m_background, m_pixmap); - update(rect); + QRegion reg = renderPeak(pdData, m_background); + copyPixmapRegion(reg, m_background, m_pixmap); + update(reg); m_integrateStartXPix = -1; m_mouseMode = GraphView::MouseMode::CROSSHAIR; break; @@ -467,10 +467,10 @@ void GraphView::zoom(const int fromXPix, const int fromYPix, const int toXPix, c void GraphView::onCtxMenuDeletePeak(const QPoint pixPos) { const PeakDrawData pdData = m_controller->deletePeak(xPixToRel(pixPos.x())); - QRect rect = erasePeak(pdData); - if (rect.isEmpty()) + QRegion reg = erasePeak(pdData); + if (reg.isEmpty()) return; - refresh(rect); + refresh(reg); } void GraphView::onCtxMenuZoomOut() diff --git a/signaldrawer.cpp b/signaldrawer.cpp index aea8ed3..21eb97c 100644 --- a/signaldrawer.cpp +++ b/signaldrawer.cpp @@ -26,6 +26,8 @@ #include const QString SignalDrawer::ME_SENDER_STR("SignalDrawer"); +const int SignalDrawer::AXIS_LABEL_BORDER_OFFSET(2); +const int SignalDrawer::AXIS_LABEL_SCALE_OFFSET(2); const int SignalDrawer::SCALE_MARGIN_TIME(16); const int SignalDrawer::SCALE_MARGIN_VALUE(48); @@ -36,7 +38,11 @@ SignalDrawer::SignalDrawer(std::shared_ptr controller, const C m_relXMax(constraints.toX), m_relXMin(constraints.fromX), m_relYMax(constraints.toY), - m_relYMin(constraints.fromY) + m_relYMin(constraints.fromY), + m_axisLabelFont(QFont("arial", 10)), + m_axisLabelFM(QFontMetrics(m_axisLabelFont)), + m_xAxisLabelText("[" + QString::fromStdString(controller->signal()->xunitToString()) + "]"), + m_yAxisLabelText("[" + QString::fromStdString(controller->signal()->yunitToString()) + "]") { } @@ -53,6 +59,10 @@ bool SignalDrawer::draw(const double fromX, const double fromY, const double toX bool ret; setNewRelativeConstraints(fromX, fromY, toX, toY); + m_xAxisLabelRect = m_axisLabelFM.boundingRect(m_xAxisLabelText); + m_yAxisLabelRect = m_axisLabelFM.boundingRect(m_yAxisLabelText); + m_xAxisLabelRect.moveTo(m_width - m_axisLabelFM.width(m_xAxisLabelText) - AXIS_LABEL_BORDER_OFFSET, m_gHeight - AXIS_LABEL_SCALE_OFFSET); + m_yAxisLabelRect.moveTo(SCALE_MARGIN_VALUE + AXIS_LABEL_SCALE_OFFSET, m_axisLabelFM.height() - m_axisLabelFM.underlinePos()); fresh = createFreshPixmap(); if (fresh == nullptr) @@ -63,16 +73,22 @@ bool SignalDrawer::draw(const double fromX, const double fromY, const double toX ret = drawGraph(fresh); if (!ret) { Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw graph"); - restoreRelativeConstraints(); - delete fresh; - return ret; + goto error_out; } } /* Draw the scale */ if (flags(GraphLayers::SCALE & layers)) { - ret = renderScale(SignalController::Axis::VALUE, fresh); - ret = renderScale(SignalController::Axis::TIME, fresh); + ret = drawScale(SignalController::Axis::VALUE, fresh); + if (!ret) { + Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw scale for Y axis"); + goto error_out; + } + ret = drawScale(SignalController::Axis::TIME, fresh); + if (!ret) { + Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw scale for X axis"); + goto error_out; + } } /* Draw integrated peaks */ @@ -80,14 +96,30 @@ bool SignalDrawer::draw(const double fromX, const double fromY, const double toX ret = drawPeaks(fresh); if (!ret) { Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw integrated peaks"); - restoreRelativeConstraints(); - delete fresh; - return ret; + goto error_out; } } + + /* Draw axes labels */ + ret = drawAxisLabel(SignalController::Axis::TIME, fresh); + if (!ret) { + Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw X axis label"); + goto error_out; + } + ret = drawAxisLabel(SignalController::Axis::VALUE, fresh); + if (!ret) { + Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " cannot draw Y axis label"); + goto error_out; + } + renderFresh(fresh); return true; + +error_out: + restoreRelativeConstraints(); + delete fresh; + return ret; } bool SignalDrawer::setDimensions(const int width, const int height) @@ -109,11 +141,12 @@ bool SignalDrawer::setDimensions(const int width, const int height) /** Protected methods **/ -void SignalDrawer::copyPixmapRegion(const QRect& rect, QPixmap* const source, QPixmap* const target) +void SignalDrawer::copyPixmapRegion(const QRegion& reg, QPixmap* const source, QPixmap* const target) { QPainter p(target); - p.drawPixmap(rect, *source, rect); + for (const QRect& rect : reg.rects()) + p.drawPixmap(rect, *source, rect); } bool SignalDrawer::drawGraph(QPixmap* const target) @@ -127,6 +160,38 @@ bool SignalDrawer::drawGraph(QPixmap* const target) return renderGraph(target); } +bool SignalDrawer::drawAxisLabel(const SignalController::Axis axis, QPixmap* const target) +{ + QPainter p; + int xPix, yPix; + QString text; + + if (target == nullptr) { + Logger::log(Logger::Level::WARNING, ME_SENDER_STR, __QFUNC__ + " null pointer to pixmap"); + return false; + } + + switch (axis) { + case SignalController::Axis::TIME: + xPix = m_xAxisLabelRect.x(); + yPix = m_xAxisLabelRect.y(); + text = m_xAxisLabelText; + break; + case SignalController::Axis::VALUE: + xPix = m_yAxisLabelRect.x(); + yPix = m_yAxisLabelRect.y(); + text = m_yAxisLabelText; + break; + } + + p.begin(target); + p.setFont(m_axisLabelFont); + p.drawText(xPix, yPix, text); + p.end(); + + return true; +} + bool SignalDrawer::drawPeaks(QPixmap* const target) { std::vector pdData = m_controller->getPeaksDrawData(m_relXMin, m_relYMin, m_relXMax, m_relYMax); @@ -141,7 +206,7 @@ bool SignalDrawer::drawPeaks(QPixmap* const target) return true; } -bool SignalDrawer::renderScale(const SignalController::Axis axis, QPixmap* const target) +bool SignalDrawer::drawScale(const SignalController::Axis axis, QPixmap* const target) { QPainter p; double absVal; @@ -241,12 +306,13 @@ void SignalDrawer::renderValueScaleTick(QPainter* const p, const double rel, con } } -QRect SignalDrawer::erasePeak(const PeakDrawData& pd) +QRegion SignalDrawer::erasePeak(const PeakDrawData& pd) { - QPainter p; + //QPainter p; QFont font("arial", 10); QFontMetrics fm(font); QString aucText, timeText; + QRegion peakReg; int tTextHeight, tTextWidth, aTextWidth; int fromXPix, fromYPix; int toXPix, toYPix; @@ -281,7 +347,15 @@ QRect SignalDrawer::erasePeak(const PeakDrawData& pd) else endXPix = toXPix; - return QRect(beginXPix, 0, endXPix - beginXPix, m_height); + peakReg = QRect(beginXPix, 0, endXPix - beginXPix, m_height); + if (peakReg.intersects(m_xAxisLabelRect)) { + peakReg += m_xAxisLabelRect; + } + if (peakReg.intersects(m_yAxisLabelRect)) { + peakReg += m_yAxisLabelRect; + } + + return peakReg; } bool SignalDrawer::renderGraph(QPixmap* const target) @@ -327,12 +401,13 @@ void SignalDrawer::renderFresh(QPixmap* const fresh) } -QRect SignalDrawer::renderPeak(const PeakDrawData& pd, QPixmap* const target) +QRegion SignalDrawer::renderPeak(const PeakDrawData& pd, QPixmap* const target) { QPainter p; QFont font("arial", 10); QFontMetrics fm(font); QString aucText, timeText; + QRegion peakReg; int tTextHeight, tTextWidth, aTextWidth; int fromXPix, fromYPix; int toXPix, toYPix; @@ -399,8 +474,21 @@ QRect SignalDrawer::renderPeak(const PeakDrawData& pd, QPixmap* const target) else endXPix = toXPix; + peakReg = QRect(beginXPix, 0, endXPix - beginXPix, m_height); + p.end(); - return QRect(beginXPix, 0, endXPix - beginXPix, m_height); + if (peakReg.intersects(m_xAxisLabelRect)) { + qDebug() << "x inters"; + drawAxisLabel(SignalController::Axis::TIME, target); + peakReg += m_xAxisLabelRect; + } + if (peakReg.intersects(m_yAxisLabelRect)) { + qDebug() << "y inters"; + drawAxisLabel(SignalController::Axis::VALUE, target); + peakReg += m_yAxisLabelRect; + } + + return peakReg; } /** Private functions **/ @@ -449,7 +537,6 @@ double SignalDrawer::yPixToRel(const int pix) } /** Private methods **/ - void SignalDrawer::restoreRelativeConstraints() { m_relXMin = m_oldRelXMin; diff --git a/signaldrawer.h b/signaldrawer.h index 0140e4d..5789479 100644 --- a/signaldrawer.h +++ b/signaldrawer.h @@ -57,13 +57,14 @@ public: Constraints currentConstraints(); int dheight() const { return m_height; } bool draw(const double fromX, const double fromY, const double toX, const double toY, const GraphLayers layers = GraphLayers::ALL); + bool drawAxisLabel(const SignalController::Axis axis, QPixmap* const target); bool drawGraph(QPixmap* const target); bool drawPeaks(QPixmap* const target); - QRect erasePeak(const PeakDrawData& pd); + bool drawScale(const SignalController::Axis axis, QPixmap* const target); + QRegion erasePeak(const PeakDrawData& pd); int dwidth() const { return m_width; } bool renderGraph(QPixmap* const fresh); - QRect renderPeak(const PeakDrawData& pd, QPixmap* const target); - bool renderScale(const SignalController::Axis axis, QPixmap* const target); + QRegion renderPeak(const PeakDrawData& pd, QPixmap* const target); bool setDimensions(const int width, const int height); protected: @@ -80,7 +81,7 @@ protected: double m_relYMin; std::shared_ptr m_gdData; - void copyPixmapRegion(const QRect& region, QPixmap* const source, QPixmap* const target); + void copyPixmapRegion(const QRegion& region, QPixmap* const source, QPixmap* const target); QPixmap* createFreshPixmap() { return new QPixmap(m_width, m_height); } void renderFresh(QPixmap* const fresh); void renderTimeScaleText(QPainter*const p, const double rel, const double value); @@ -93,11 +94,16 @@ protected: double xPixToRel(const int pix); double yPixToRel(const int pix); + static const int AXIS_LABEL_BORDER_OFFSET; + static const int AXIS_LABEL_SCALE_OFFSET; static const int SCALE_MARGIN_TIME; static const int SCALE_MARGIN_VALUE; private: + QRect axisLabelBoundingRect(const SignalController::Axis axis); double linesIntersection(const double k1, const double q1, const double k2, const double q2); + void restoreRelativeConstraints(); + void setNewRelativeConstraints(const double fromX, const double fromY, const double toX, const double toY); int m_height; int m_width; @@ -109,8 +115,13 @@ private: double m_oldRelYMax; double m_oldRelYMin; - void setNewRelativeConstraints(const double fromX, const double fromY, const double toX, const double toY); - void restoreRelativeConstraints(); + const QFont m_axisLabelFont; + const QFontMetrics m_axisLabelFM; + QRect m_xAxisLabelRect; + QRect m_yAxisLabelRect; + const QString m_xAxisLabelText; + const QString m_yAxisLabelText; + static const QString ME_SENDER_STR; -- 2.43.5