From 368aeba04de86016de5f84db4f40ad286fc8948d Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Sat, 5 Nov 2011 13:06:31 +0000 Subject: [PATCH] Remove Globals from ErgFilePlot The original ErgFilePlot code used local static variables to bridge between the selected ErgFile and the Qwt data handlers. This was not an issue when we only allowed one chart of this type to be available at once. But now, with a more configurable layout it is possible to have multiple. The currently selected ErgFile can now be referenced from MainWindow in the same manner as the current RideFile can. This patch introduces no functional change for users. --- src/ErgFile.cpp | 8 +++++ src/ErgFile.h | 1 + src/ErgFilePlot.cpp | 65 ++++++++++++++++++++++----------------- src/ErgFilePlot.h | 15 +++++++-- src/MainWindow.h | 9 ++++-- src/WorkoutPlotWindow.cpp | 2 +- 6 files changed, 66 insertions(+), 34 deletions(-) diff --git a/src/ErgFile.cpp b/src/ErgFile.cpp index c42287d94..3208a36c8 100644 --- a/src/ErgFile.cpp +++ b/src/ErgFile.cpp @@ -361,12 +361,17 @@ ErgFile::calculateMetrics() XP = CP = AP = NP = IF = RI = TSS = BS = SVI = VI = 0; ELE = ELEDIST = GRADE = 0; + maxY = 0; // we need to reset it + if (format == CRS) { ErgFilePoint last; bool first = true; foreach (ErgFilePoint p, Points) { + // set the maximum Y value + if (p.y > maxY) maxY= p.y; + if (first == true) { first = false; } else if (p.y > last.y) { @@ -407,6 +412,9 @@ ErgFile::calculateMetrics() ErgFilePoint last; foreach (ErgFilePoint p, Points) { + // set the maximum Y value + if (p.y > maxY) maxY= p.y; + while (nextSecs < p.x) { // CALCULATE NP diff --git a/src/ErgFile.h b/src/ErgFile.h index b0aa5a823..336257f85 100644 --- a/src/ErgFile.h +++ b/src/ErgFile.h @@ -92,6 +92,7 @@ class ErgFile void calculateMetrics(); // calculate NP value for ErgFile // Metrics for this workout + double maxY; // maximum Y value double CP; double AP, NP, IF, TSS, VI; // Coggan for erg / mrc double XP, RI, BS, SVI; // Skiba for erg / mrc diff --git a/src/ErgFilePlot.cpp b/src/ErgFilePlot.cpp index 06d2704a5..bd2639db0 100644 --- a/src/ErgFilePlot.cpp +++ b/src/ErgFilePlot.cpp @@ -19,34 +19,45 @@ #include "ErgFilePlot.h" -// static locals for now -static ErgFile *ergFile; -static QList *courseData; -static long Now; -static double MaxWatts; +// Bridge between QwtPlot and ErgFile to avoid having to +// create a separate array for the ergfile data, we plot +// directly from the ErgFile points array +double ErgFileData::x(size_t i) const { + if (main->currentErgFile()) return main->currentErgFile()->Points.at(i).x; + else return 0; +} -// Load history -double ErgFileData::x(size_t i) const { return courseData ? courseData->at(i).x : 0; } -double ErgFileData::y(size_t i) const { return courseData ? courseData->at(i).y : 0; } -size_t ErgFileData::size() const { return courseData ? courseData->count() : 0; } -QwtData *ErgFileData::copy() const { return new ErgFileData(); } -//void ErgFileData::init() { } +double ErgFileData::y(size_t i) const { + if (main->currentErgFile()) return main->currentErgFile()->Points.at(i).y; + else return 0; +} + +size_t ErgFileData::size() const { + if (main->currentErgFile()) return main->currentErgFile()->Points.count(); + else return 0; +} + +QwtData *ErgFileData::copy() const { return new ErgFileData(main); } // Now bar -double NowData::x(size_t) const { return Now; } -double NowData::y(size_t i) const { return (i ? (MaxWatts ? MaxWatts : 500) : 0); } +double NowData::x(size_t) const { return main->getNow(); } +double NowData::y(size_t i) const { + if (i) { + if (main->currentErgFile()) return main->currentErgFile()->maxY; + else return 500; + } else return 0; +} size_t NowData::size() const { return 2; } -QwtData *NowData::copy() const { return new NowData(); } +QwtData *NowData::copy() const { return new NowData(main); } -ErgFilePlot::ErgFilePlot(QList *data) +ErgFilePlot::ErgFilePlot(MainWindow *main) : main(main) { setInstanceName("ErgFile Plot"); //insertLegend(new QwtLegend(), QwtPlot::BottomLegend); setCanvasBackground(GColor(CRIDEPLOTBACKGROUND)); canvas()->setFrameStyle(QFrame::NoFrame); - courseData = data; // what we plot - Now = 0; // where we are + //courseData = data; // what we plot // Setup the left axis (Power) setAxisTitle(yLeft, "Watts"); @@ -98,9 +109,11 @@ ErgFilePlot::ErgFilePlot(QList *data) setAxisScale(yRight2, 0, 60); // max speed of 60mph/60kmh seems ok to me! enableAxis(yRight2, false); + // data bridge to ergfile + lodData = new ErgFileData(main); // Load Curve LodCurve = new QwtPlotCurve("Course Load"); - LodCurve->setData(lodData); + LodCurve->setData(*lodData); LodCurve->attach(this); LodCurve->setYAxis(QwtPlot::yLeft); @@ -148,11 +161,14 @@ ErgFilePlot::ErgFilePlot(QList *data) speedData = new CurveData; speedCurve->setRawData(speedData->x(), speedData->y(), speedData->count()); + // Now data bridge + nowData = new NowData(main); + // Now pointer NowCurve = new QwtPlotCurve("Now"); QPen Nowpen = QPen(Qt::red, 2.0); NowCurve->setPen(Nowpen); - NowCurve->setData(nowData); + NowCurve->setData(*nowData); NowCurve->attach(this); NowCurve->setYAxis(QwtPlot::yLeft); @@ -204,10 +220,6 @@ ErgFilePlot::setData(ErgFile *ergfile) } // set up again - //setTitle(ergFile->Name); - courseData = &ergfile->Points; - MaxWatts = LodCurve->maxYValue(); - for(int i=0; i < ergFile->Laps.count(); i++) { // Show Lap Number @@ -228,8 +240,8 @@ ErgFilePlot::setData(ErgFile *ergfile) } // set the axis so we use all the screen estate - if ((*courseData).count()) { - double maxX = (double)(*courseData).last().x; + if (main->currentErgFile() && main->currentErgFile()->Points.count()) { + double maxX = (double)main->currentErgFile()->Points.last().x; if (bydist) { @@ -280,8 +292,6 @@ ErgFilePlot::setData(ErgFile *ergfile) // clear the plot we have nothing selected bydist = false; // do by time when no workout selected - MaxWatts = 0; - courseData = NULL; QwtText title; title.setFont(stGiles); @@ -303,7 +313,6 @@ ErgFilePlot::setData(ErgFile *ergfile) void ErgFilePlot::setNow(long msecs) { - Now = msecs; replot(); // and update } diff --git a/src/ErgFilePlot.h b/src/ErgFilePlot.h index 6e89c6dd7..c0a9cdc18 100644 --- a/src/ErgFilePlot.h +++ b/src/ErgFilePlot.h @@ -19,6 +19,7 @@ #ifndef _GC_ErgFilePlot_h #define _GC_ErgFilePlot_h 1 #include "GoldenCheetah.h" +#include "MainWindow.h" #include #include @@ -44,21 +45,27 @@ class ErgFileData : public QwtData { public: + ErgFileData (MainWindow *main) : main(main) {} double x(size_t i) const ; double y(size_t i) const ; size_t size() const ; virtual QwtData *copy() const ; void init() ; + private: + MainWindow *main; }; class NowData : public QwtData { public: + NowData (MainWindow *main) : main(main) {} double x(size_t i) const ; double y(size_t i) const ; size_t size() const ; virtual QwtData *copy() const ; void init() ; + private: + MainWindow *main; }; // incremental data, for each curve @@ -108,7 +115,7 @@ class ErgFilePlot : public QwtPlot public: - ErgFilePlot(QList * = 0); + ErgFilePlot(MainWindow *main); QList Marks; void setData(ErgFile *); // set the course @@ -122,7 +129,9 @@ class ErgFilePlot : public QwtPlot private: + MainWindow *main; bool bydist; + ErgFile *ergFile; QwtPlotGrid *grid; QwtPlotCurve *LodCurve; @@ -143,8 +152,8 @@ class ErgFilePlot : public QwtPlot cadsum, speedsum; - ErgFileData lodData; - NowData nowData; + ErgFileData *lodData; + NowData *nowData; DistScaleDraw *distdraw; TimeScaleDraw *timedraw; diff --git a/src/MainWindow.h b/src/MainWindow.h index f05cd2007..13fd5b90e 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -157,9 +157,11 @@ class MainWindow : public QMainWindow // realtime signals void notifyTelemetryUpdate(const RealtimeData &rtData) { telemetryUpdate(rtData); } - void notifyErgFileSelected(ErgFile *x) { ergFileSelected(x); } + void notifyErgFileSelected(ErgFile *x) { workout=x; ergFileSelected(x); } + ErgFile *currentErgFile() { return workout; } void notifyMediaSelected( QString x) { mediaSelected(x); } - void notifySetNow(long now) { setNow(now); } + void notifySetNow(long x) { now = x; setNow(x); } + long getNow() { return now; } void notifyNewLap() { emit newLap(); } void notifyStart() { emit start(); } void notifyUnPause() { emit unpause(); } @@ -291,6 +293,9 @@ class MainWindow : public QMainWindow RideItem *activeRide; // currently active for context menu popup RideItem *ride; // the currently selected ride + ErgFile *workout; // the currently selected workout file + long now; + QToolBox *toolBox; GcToolBar *toolbar; QDockWidget *dock; diff --git a/src/WorkoutPlotWindow.cpp b/src/WorkoutPlotWindow.cpp index 9fb66ab01..727507ce9 100644 --- a/src/WorkoutPlotWindow.cpp +++ b/src/WorkoutPlotWindow.cpp @@ -30,7 +30,7 @@ WorkoutPlotWindow::WorkoutPlotWindow(MainWindow *mainWindow) : QVBoxLayout *layout = new QVBoxLayout(this); layout->setSpacing(0); layout->setContentsMargins(2,2,2,2); - ergPlot = new ErgFilePlot(0); + ergPlot = new ErgFilePlot(mainWindow); layout->addWidget(ergPlot); connect(mainWindow, SIGNAL(setNow(long)), this, SLOT(setNow(long)));