From 77358fd3a379cd795f0fd665eb2b2da959faf481 Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Fri, 29 Apr 2011 14:14:20 +0100 Subject: [PATCH] Tooltip in CP chart A tooltip is now shown on the CP chart if you move the cursor over a point in the chart. The old picker ribbon is still shown when using left-click with the dates and values shown in the controls. --- src/CpintPlot.cpp | 34 ++++++++++++++++++++++++++++++++++ src/CpintPlot.h | 41 +++++++++++++++++++++++++++++++++++++++++ src/RideFile.cpp | 23 +++++++++++++++++++++++ src/RideFile.h | 1 + 4 files changed, 99 insertions(+) diff --git a/src/CpintPlot.cpp b/src/CpintPlot.cpp index f9e0ba630..b074f6053 100644 --- a/src/CpintPlot.cpp +++ b/src/CpintPlot.cpp @@ -35,6 +35,9 @@ #include "RideFile.h" #include "Season.h" #include "Settings.h" +#include "LTMCanvasPicker.h" +#include "TimeUtils.h" + #include #include // for std::lower_bound @@ -66,6 +69,13 @@ CpintPlot::CpintPlot(MainWindow *main, QString p, const Zones *zones) : grid->enableX(true); grid->attach(this); + zoomer = new penTooltip(this->canvas()); + zoomer->setMousePattern(QwtEventPattern::MouseSelect1, + Qt::LeftButton, Qt::ShiftModifier); + + canvasPicker = new LTMCanvasPicker(this); + connect(canvasPicker, SIGNAL(pointHover(QwtPlotCurve*, int)), this, SLOT(pointHover(QwtPlotCurve*, int))); + configChanged(); // apply colors } @@ -555,6 +565,7 @@ CpintPlot::calculate(RideItem *rideItem) case RideFile::hr: line.setColor(GColor(CHEARTRATE).darker(200)); fill = (GColor(CHEARTRATE)); + break; default: case RideFile::watts: // won't ever get here @@ -656,3 +667,26 @@ CpintPlot::showGrid(int state) grid->setVisible(state == Qt::Checked); replot(); } + +void +CpintPlot::pointHover(QwtPlotCurve *curve, int index) +{ + if (index >= 0) { + + double xvalue = curve->x(index); + double yvalue = curve->y(index); + QString text; + + // output the tooltip + text = QString("%1\n%3 %4") + .arg(interval_to_str(60.0*xvalue)) + .arg(yvalue, 0, 'f', RideFile::decimalsFor(series) ? 1 : 0) + .arg(RideFile::unitName(series)); + + // set that text up + zoomer->setText(text); + return; + } + // no point + zoomer->setText(""); +} diff --git a/src/CpintPlot.h b/src/CpintPlot.h index 12f1daf89..1a3ca1ac0 100644 --- a/src/CpintPlot.h +++ b/src/CpintPlot.h @@ -23,6 +23,7 @@ #include "RideFileCache.h" #include +#include #include class QwtPlotCurve; @@ -31,6 +32,43 @@ class QwtPlotMarker; class RideItem; class Zones; class MainWindow; +class LTMCanvasPicker; + +class penTooltip: public QwtPlotZoomer +{ + public: + penTooltip(QwtPlotCanvas *canvas): + QwtPlotZoomer(canvas), tip("") + { + // With some versions of Qt/Qwt, setting this to AlwaysOn + // causes an infinite recursion. + //setTrackerMode(AlwaysOn); + setTrackerMode(AlwaysOn); + } + + virtual QwtText trackerText(const QwtDoublePoint &/*pos*/) const + { + QColor bg = QColor(255,255, 170); // toolyip yellow +#if QT_VERSION >= 0x040300 + bg.setAlpha(200); +#endif + QwtText text; + QFont def; + //def.setPointSize(8); // too small on low res displays (Mac) + //double val = ceil(pos.y()*100) / 100; // round to 2 decimal place + //text.setText(QString("%1 %2").arg(val).arg(format), QwtText::PlainText); + text.setText(tip); + text.setFont(def); + text.setBackgroundBrush( QBrush( bg )); + text.setRenderFlags(Qt::AlignLeft | Qt::AlignTop); + return text; + } + void setFormat(QString fmt) { format = fmt; } + void setText(QString txt) { tip = txt; } + private: + QString format; + QString tip; +}; class CpintPlot : public QwtPlot { @@ -61,6 +99,7 @@ class CpintPlot : public QwtPlot void plot_CP_curve(CpintPlot *plot, double cp, double tau, double t0n); void plot_allCurve(CpintPlot *plot, int n_values, const double *power_values); void configChanged(); + void pointHover(QwtPlotCurve *curve, int index); protected: @@ -80,6 +119,8 @@ class CpintPlot : public QwtPlot MainWindow *mainWindow; RideFileCache *current, *bests; + LTMCanvasPicker *canvasPicker; + penTooltip *zoomer; }; #endif // _GC_CpintPlot_h diff --git a/src/RideFile.cpp b/src/RideFile.cpp index 0038d9713..158ab90bc 100644 --- a/src/RideFile.cpp +++ b/src/RideFile.cpp @@ -78,6 +78,29 @@ RideFile::seriesName(SeriesType series) } } +QString +RideFile::unitName(SeriesType series) +{ + bool useMetricUnits = (appsettings->value(NULL, GC_UNIT).toString() == "Metric"); + + switch (series) { + case RideFile::secs: return QString(tr("seconds")); + case RideFile::cad: return QString(tr("rpm")); + case RideFile::hr: return QString(tr("bpm")); + case RideFile::km: return QString(useMetricUnits ? tr("km") : tr("miles")); + case RideFile::kph: return QString(useMetricUnits ? tr("kph") : tr("mph")); + case RideFile::nm: return QString(tr("N")); + case RideFile::watts: return QString(tr("watts")); + case RideFile::xPower: return QString(tr("watts")); + case RideFile::NP: return QString(tr("watts")); + case RideFile::alt: return QString(useMetricUnits ? tr("metres") : tr("feet")); + case RideFile::lon: return QString(tr("lon")); + case RideFile::lat: return QString(tr("lat")); + case RideFile::headwind: return QString(tr("kph")); + case RideFile::interval: return QString(tr("Interval")); + default: return QString(tr("Unknown")); + } +} void RideFile::clearIntervals() diff --git a/src/RideFile.h b/src/RideFile.h index 4b5a9f12b..b011337cd 100644 --- a/src/RideFile.h +++ b/src/RideFile.h @@ -90,6 +90,7 @@ class RideFile : public QObject // QObject to emit signals enum seriestype { secs, cad, hr, km, kph, nm, watts, alt, lon, lat, headwind, interval, NP, xPower, none }; typedef enum seriestype SeriesType; static QString seriesName(SeriesType); + static QString unitName(SeriesType); static int decimalsFor(SeriesType series); static double maximumFor(SeriesType series); static double minimumFor(SeriesType series);