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.
This commit is contained in:
Mark Liversedge
2011-11-05 13:06:31 +00:00
parent cd6e9df377
commit 368aeba04d
6 changed files with 66 additions and 34 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -19,34 +19,45 @@
#include "ErgFilePlot.h"
// static locals for now
static ErgFile *ergFile;
static QList<ErgFilePoint> *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<ErgFilePoint> *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<ErgFilePoint> *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<ErgFilePoint> *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
}

View File

@@ -19,6 +19,7 @@
#ifndef _GC_ErgFilePlot_h
#define _GC_ErgFilePlot_h 1
#include "GoldenCheetah.h"
#include "MainWindow.h"
#include <QDebug>
#include <QtGui>
@@ -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<ErgFilePoint> * = 0);
ErgFilePlot(MainWindow *main);
QList<QwtPlotMarker *> 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;

View File

@@ -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;

View File

@@ -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)));