Modify Aerolab to add interval highlight and zoom + auto offset

Fixes #241
Fixes #147
This commit is contained in:
Damien
2011-08-12 15:39:38 +02:00
committed by Gareth Coco
parent 9ab5fb26e2
commit 0c7abe9755
5 changed files with 565 additions and 47 deletions

View File

@@ -17,6 +17,7 @@
*/
#include "Aerolab.h"
#include "AerolabWindow.h"
#include "MainWindow.h"
#include "RideFile.h"
#include "RideItem.h"
@@ -42,11 +43,193 @@ max(double a, double b) { if (a > b) return a; else return b; }
static inline double
min(double a, double b) { if (a < b) return a; else return b; }
Aerolab::Aerolab(QWidget *parent):
/*----------------------------------------------------------------------
* Interval plotting
*--------------------------------------------------------------------*/
class IntervalAerolabData : public QwtData
{
public:
Aerolab *aerolab;
MainWindow *mainWindow;
IntervalAerolabData
(
Aerolab *aerolab,
MainWindow *mainWindow
) : aerolab( aerolab ), mainWindow( mainWindow ) { }
double x( size_t ) const;
double y( size_t ) const;
size_t size() const;
virtual QwtData *copy() const;
void init();
IntervalItem *intervalNum( int ) const;
int intervalCount() const;
};
/*
* HELPER FUNCTIONS:
* intervalNum - returns a pointer to the nth selected interval
* intervalCount - returns the number of highlighted intervals
*/
// ------------------------------------------------------------------------------------------------------------
// note this is operating on the children of allIntervals and not the
// intervalWidget (QTreeWidget) -- this is why we do not use the
// selectedItems() member. N starts a one not zero.
// ------------------------------------------------------------------------------------------------------------
IntervalItem *IntervalAerolabData::intervalNum
(
int number
) const
{
int highlighted = 0;
const QTreeWidgetItem *allIntervals = mainWindow->allIntervalItems();
for ( int ii = 0; ii < allIntervals->childCount(); ii++)
{
IntervalItem *current = (IntervalItem *) allIntervals->child( ii );
if ( current == NULL)
{
return NULL;
}
if ( current->isSelected() == true )
{
++highlighted;
}
if ( highlighted == number )
{
return current;
}
}
return NULL;
}
// ------------------------------------------------------------------------------------------------------------
// how many intervals selected?
// ------------------------------------------------------------------------------------------------------------
int IntervalAerolabData::intervalCount() const
{
int highlighted = 0;
if ( mainWindow->allIntervalItems() != NULL )
{
const QTreeWidgetItem *allIntervals = mainWindow->allIntervalItems();
for ( int ii = 0; ii < allIntervals->childCount(); ii++)
{
IntervalItem *current = (IntervalItem *) allIntervals->child( ii );
if ( current != NULL )
{
if ( current->isSelected() == true )
{
++highlighted;
}
}
}
}
return highlighted;
}
/*
* INTERVAL HIGHLIGHTING CURVE
* IntervalAerolabData - implements the qwtdata interface where
* x,y return point co-ordinates and
* size returns the number of points
*/
// The interval curve data is derived from the intervals that have
// been selected in the MainWindow leftlayout for each selected
// interval we return 4 data points; bottomleft, topleft, topright
// and bottom right.
//
// the points correspond to:
// bottom left = interval start, 0 watts
// top left = interval start, maxwatts
// top right = interval stop, maxwatts
// bottom right = interval stop, 0 watts
//
double IntervalAerolabData::x
(
size_t number
) const
{
// for each interval there are four points, which interval is this for?
// interval numbers start at 1 not ZERO in the utility functions
double result = 0;
int interval_no = number ? 1 + number / 4 : 1;
// get the interval
IntervalItem *current = intervalNum( interval_no );
if ( current != NULL )
{
double multiplier = aerolab->useMetricUnits ? 1 : MILES_PER_KM;
// which point are we returning?
//qDebug() << "number = " << number << endl;
switch ( number % 4 )
{
case 0 : result = aerolab->bydist ? multiplier * current->startKM : current->start/60; // bottom left
break;
case 1 : result = aerolab->bydist ? multiplier * current->startKM : current->start/60; // top left
break;
case 2 : result = aerolab->bydist ? multiplier * current->stopKM : current->stop/60; // bottom right
break;
case 3 : result = aerolab->bydist ? multiplier * current->stopKM : current->stop/60; // top right
break;
}
}
return result;
}
double IntervalAerolabData::y
(
size_t number
) const
{
// which point are we returning?
double result = 0;
switch ( number % 4 )
{
case 0 : result = -5000; // bottom left
break;
case 1 : result = 5000; // top left - set to out of bound value
break;
case 2 : result = 5000; // top right - set to out of bound value
break;
case 3 : result = -5000; // bottom right
break;
}
return result;
}
size_t IntervalAerolabData::size() const
{
return intervalCount() * 4;
}
QwtData *IntervalAerolabData::copy() const
{
return new IntervalAerolabData( aerolab, mainWindow );
}
//**********************************************
//** END IntervalAerolabData **
//**********************************************
Aerolab::Aerolab(
AerolabWindow *parent,
MainWindow *mainWindow
):
QwtPlot(parent),
parent(parent),
unit(0),
rideItem(NULL),
smooth(1), bydist(false) {
smooth(1), bydist(true), autoEoffset(true) {
crr = 0.005;
cda = 0.500;
@@ -69,9 +252,19 @@ Aerolab::Aerolab(QWidget *parent):
setAxisScale(xBottom, 0, 60);
veCurve = new QwtPlotCurve(tr("V-Elevation"));
altCurve = new QwtPlotCurve(tr("Elevation"));
// get rid of nasty blank space on right of the plot
veCurve->setYAxis( yLeft );
altCurve->setYAxis( yLeft );
intervalHighlighterCurve = new QwtPlotCurve();
intervalHighlighterCurve->setBaseline(-5000);
intervalHighlighterCurve->setYAxis( yLeft );
intervalHighlighterCurve->setData( IntervalAerolabData( this, mainWindow ) );
intervalHighlighterCurve->attach( this );
this->legend()->remove( intervalHighlighterCurve ); // don't show in legend
grid = new QwtPlotGrid();
grid->enableX(false);
grid->attach(this);
@@ -79,6 +272,7 @@ Aerolab::Aerolab(QWidget *parent):
configChanged();
}
void
Aerolab::configChanged()
{
@@ -93,6 +287,16 @@ Aerolab::configChanged()
QPen gridPen(GColor(CPLOTGRID));
gridPen.setStyle(Qt::DotLine);
grid->setPen(gridPen);
QPen ihlPen = QPen( GColor( CINTERVALHIGHLIGHTER ) );
ihlPen.setWidth(1);
intervalHighlighterCurve->setPen( ihlPen );
QColor ihlbrush = QColor(GColor(CINTERVALHIGHLIGHTER));
ihlbrush.setAlpha(40);
intervalHighlighterCurve->setBrush(ihlbrush); // fill below the line
this->legend()->remove( intervalHighlighterCurve ); // don't show in legend
}
void
@@ -158,7 +362,7 @@ Aerolab::setData(RideItem *_rideItem, bool new_zoom) {
if ( arrayLength == 0 )
e = eoffset;
timeArray[arrayLength] = p1->secs;
timeArray[arrayLength] = p1->secs / 60.0;
if ( have_recorded_alt_curve )
altArray[arrayLength] = (useMetricUnits
? p1->alt
@@ -173,8 +377,13 @@ Aerolab::setData(RideItem *_rideItem, bool new_zoom) {
}
double f = 0.0;
double a = 0.0;
d += v * dt;
distanceArray[arrayLength] = d/1000;
// Use km data insteed of formula for file with a stop (gap).
//d += v * dt;
//distanceArray[arrayLength] = d/1000;
distanceArray[arrayLength] = p1->km;
if( v > small_number ) {
@@ -201,14 +410,34 @@ Aerolab::setData(RideItem *_rideItem, bool new_zoom) {
veCurve->setVisible(false);
altCurve->setVisible(false);
}
recalc(new_zoom);
adjustEoffset();
} else {
setTitle("no data");
}
}
void
Aerolab::adjustEoffset() {
if (autoEoffset && !altArray.empty()) {
double idx = axisScaleDiv( QwtPlot::xBottom )->lowerBound();
parent->eoffsetSlider->setEnabled(false);
if (bydist) {
int v = 100*(altArray.at(rideItem->ride()->distanceIndex(idx))-veArray.at(rideItem->ride()->distanceIndex(idx)));
parent->eoffsetSlider->setValue(intEoffset()+v);
}
else {
int v = 100*(altArray.at(rideItem->ride()->timeIndex(60*idx))-veArray.at(rideItem->ride()->timeIndex(60*idx)));
parent->eoffsetSlider->setValue(intEoffset()+v);
}
} else
parent->eoffsetSlider->setEnabled(true);
}
struct DataPoint {
double time, hr, watts, speed, cad, alt;
DataPoint(double t, double h, double w, double s, double c, double a) :
@@ -235,8 +464,7 @@ Aerolab::recalc( bool new_zoom ) {
return;
}
QVector<double> &xaxis = distanceArray;
QVector<double> &xaxis = (bydist?distanceArray:timeArray);
int startingIndex = 0;
int totalPoints = arrayLength - startingIndex;
@@ -251,9 +479,12 @@ Aerolab::recalc( bool new_zoom ) {
}
if( new_zoom )
setAxisScale(xBottom, 0.0, totalRideDistance);
setAxisScale(xBottom, 0.0, (bydist?totalRideDistance:rideTimeSecs));
setYMax();
setYMax(new_zoom );
refreshIntervalMarkers();
replot();
}
@@ -261,19 +492,75 @@ Aerolab::recalc( bool new_zoom ) {
void
Aerolab::setYMax() {
Aerolab::setYMax(bool new_zoom)
{
if (veCurve->isVisible())
{
if (veCurve->isVisible()) {
setAxisTitle(yLeft, tr("Elevation"));
if ( useMetricUnits )
{
setAxisTitle( yLeft, "Elevation (m)" );
}
else
{
setAxisTitle( yLeft, "Elevation (')" );
}
double minY = 0.0;
double maxY = 0.0;
//************
//if (veCurve->isVisible()) {
// setAxisTitle(yLeft, tr("Elevation"));
if ( !altArray.empty() ) {
setAxisScale(yLeft,
min( veCurve->minYValue(), altCurve->minYValue() ) - 10,
10.0 + max( veCurve->maxYValue(), altCurve->maxYValue() ) );
// setAxisScale(yLeft,
// min( veCurve->minYValue(), altCurve->minYValue() ) - 10,
// 10.0 + max( veCurve->maxYValue(), altCurve->maxYValue() ) );
minY = min( veCurve->minYValue(), altCurve->minYValue() ) - 10;
maxY = 10.0 + max( veCurve->maxYValue(), altCurve->maxYValue() );
} else {
setAxisScale(yLeft,
veCurve->minYValue() ,
1.05 * veCurve->maxYValue() );
//setAxisScale(yLeft,
// veCurve->minYValue() ,
// 1.05 * veCurve->maxYValue() );
if ( new_zoom )
{
minY = veCurve->minYValue();
maxY = veCurve->maxYValue();
}
else
{
minY = parent->getCanvasTop();
maxY = parent->getCanvasBottom();
}
//adjust eooffset
// TODO
}
setAxisScale( yLeft, minY, maxY );
setAxisLabelRotation(yLeft,270);
setAxisLabelAlignment(yLeft,Qt::AlignVCenter);
}
@@ -292,12 +579,18 @@ Aerolab::setXTitle() {
setAxisTitle(xBottom, tr("Time (minutes)"));
}
void
Aerolab::setAutoEoffset(int value)
{
autoEoffset = value;
adjustEoffset();
}
void
Aerolab::setByDistance() {
bydist = true;
Aerolab::setByDistance(int value) {
bydist = value;
setXTitle();
recalc(false);
recalc(true);
}
@@ -388,3 +681,72 @@ Aerolab::setIntEoffset(
eoffset = (double) value / 100.0;
recalc(false);
}
void Aerolab::pointHover (QwtPlotCurve *curve, int index)
{
if ( index >= 0 && curve != intervalHighlighterCurve )
{
double x_value = curve->x( index );
double y_value = curve->y( index );
// output the tooltip
QString text = QString( "%1 %2 %3 %4 %5" )
. arg( this->axisTitle( curve->xAxis() ).text() )
. arg( x_value, 0, 'f', 3 )
. arg( "\n" )
. arg( this->axisTitle( curve->yAxis() ).text() )
. arg( y_value, 0, 'f', 3 );
// set that text up
tooltip->setText( text );
}
else
{
// no point
tooltip->setText( "" );
}
}
void Aerolab::refreshIntervalMarkers()
{
foreach( QwtPlotMarker *mrk, d_mrk )
{
mrk->detach();
delete mrk;
}
d_mrk.clear();
QRegExp wkoAuto("^(Peak *[0-9]*(s|min)|Entire workout|Find #[0-9]*) *\\([^)]*\\)$");
if ( rideItem->ride() )
{
foreach(const RideFileInterval &interval, rideItem->ride()->intervals()) {
// skip WKO autogenerated peak intervals
if (wkoAuto.exactMatch(interval.name))
continue;
QwtPlotMarker *mrk = new QwtPlotMarker;
d_mrk.append(mrk);
mrk->attach(this);
mrk->setLineStyle(QwtPlotMarker::VLine);
mrk->setLabelAlignment(Qt::AlignRight | Qt::AlignTop);
mrk->setLinePen(QPen(GColor(CPLOTMARKER), 0, Qt::DashDotLine));
QwtText text(interval.name);
text.setFont(QFont("Helvetica", 10, QFont::Bold));
text.setColor(GColor(CPLOTMARKER));
if (!bydist)
mrk->setValue(interval.start / 60.0, 0.0);
else
mrk->setValue((useMetricUnits ? 1 : MILES_PER_KM) *
rideItem->ride()->timeToDistance(interval.start), 0.0);
mrk->setLabel(text);
}
}
}

View File

@@ -22,6 +22,7 @@
#include <qwt_plot.h>
#include <qwt_data.h>
#include <QtGui>
#include "LTMWindow.h" // for tooltip/canvaspicker
// forward references
class RideItem;
@@ -31,32 +32,56 @@ class QwtPlotGrid;
class QwtPlotMarker;
class AerolabWindow;
class MainWindow;
class IntervalAerolabData;
class LTMToolTip;
class LTMCanvasPicker;
class Aerolab : public QwtPlot {
Q_OBJECT
public:
Aerolab(QWidget *parent);
Aerolab( AerolabWindow *, MainWindow * );
bool byDistance() const { return bydist; }
bool useMetricUnits; // whether metric units are used (or imperial)
void setData(RideItem *_rideItem, bool new_zoom);
void refreshIntervalMarkers();
private:
AerolabWindow *parent;
LTMToolTip *tooltip;
LTMCanvasPicker *_canvasPicker; // allow point selection/hover
void adjustEoffset();
public slots:
void setByDistance();
void setAutoEoffset(int value);
void setByDistance(int value);
void configChanged();
void pointHover( QwtPlotCurve *, int );
signals:
protected:
friend class ::AerolabWindow;
friend class ::IntervalAerolabData;
QVariant unit;
QwtPlotGrid *grid;
QVector<QwtPlotMarker*> d_mrk;
// One curve to plot in the Course Profile:
QwtPlotCurve *veCurve; // virtual elevation curve
QwtPlotCurve *altCurve; // recorded elevation curve, if available
QwtPlotCurve *intervalHighlighterCurve; // highlight selected intervals on the Plot
RideItem *rideItem;
QVector<double> hrArray;
@@ -72,6 +97,7 @@ class Aerolab : public QwtPlot {
int smooth;
bool bydist;
bool autoEoffset;
int arrayLength;
int iCrr;
int iCda;
@@ -85,7 +111,7 @@ class Aerolab : public QwtPlot {
double slope(double, double, double, double, double, double, double);
void recalc(bool);
void setYMax();
void setYMax(bool);
void setXTitle();
void setIntCrr(int);
void setIntCda(int);
@@ -93,18 +119,20 @@ class Aerolab : public QwtPlot {
void setIntEta(int);
void setIntEoffset(int);
void setIntTotalMass(int);
double getCrr() const { return (double)crr; };
double getCda() const { return (double)cda; };
double getTotalMass() const { return (double)totalMass; };
double getRho() const { return (double)rho; };
double getEta() const { return (double)eta; };
double getEoffset() const { return (double)eoffset; };
int intCrr() const { return (int)( crr * 1000000 ); };
int intCda() const { return (int)( cda * 100000); };
int intTotalMass() const { return (int)( totalMass * 100); };
int intRho() const { return (int)( rho * 10000); };
int intEta() const { return (int)( eta * 10000); };
int intEoffset() const { return (int)( eoffset * 100); };
double getCrr() const { return (double)crr; }
double getCda() const { return (double)cda; }
double getTotalMass() const { return (double)totalMass; }
double getRho() const { return (double)rho; }
double getEta() const { return (double)eta; }
double getEoffset() const { return (double)eoffset; }
int intCrr() const { return (int)( crr * 1000000 ); }
int intCda() const { return (int)( cda * 10000); }
int intTotalMass() const { return (int)( totalMass * 100); }
int intRho() const { return (int)( rho * 10000); }
int intEta() const { return (int)( eta * 10000); }
int intEoffset() const { return (int)( eoffset * 100); }
};
#endif // _GC_Aerolab_h

View File

@@ -33,7 +33,7 @@ AerolabWindow::AerolabWindow(MainWindow *mainWindow) :
QHBoxLayout *cLayout = new QHBoxLayout;
// Plot:
aerolab = new Aerolab(this);
aerolab = new Aerolab(this, mainWindow);
// Left controls layout:
QVBoxLayout *leftControls = new QVBoxLayout;
@@ -63,11 +63,14 @@ AerolabWindow::AerolabWindow(MainWindow *mainWindow) :
QHBoxLayout *cdaLayout = new QHBoxLayout;
QLabel *cdaLabel = new QLabel(tr("CdA"), this);
cdaLabel->setFixedWidth(labelWidth1);
cdaQLCDNumber = new QLCDNumber(7);
cdaLineEdit = new QLineEdit();
cdaLineEdit->setFixedWidth(50);
cdaLineEdit->setText(QString("%1").arg(aerolab->getCda()) );
/*cdaQLCDNumber = new QLCDNumber(7);
cdaQLCDNumber->setMode(QLCDNumber::Dec);
cdaQLCDNumber->setSmallDecimalPoint(false);
cdaQLCDNumber->setSegmentStyle(QLCDNumber::Flat);
cdaQLCDNumber->display(QString("%1").arg(aerolab->getCda()) );
cdaQLCDNumber->display(QString("%1").arg(aerolab->getCda()) );*/
cdaSlider = new QSlider(Qt::Horizontal);
cdaSlider->setTickPosition(QSlider::TicksBelow);
cdaSlider->setTickInterval(100);
@@ -75,7 +78,8 @@ AerolabWindow::AerolabWindow(MainWindow *mainWindow) :
cdaSlider->setMaximum(6000);
cdaSlider->setValue(aerolab->intCda());
cdaLayout->addWidget( cdaLabel );
cdaLayout->addWidget( cdaQLCDNumber );
//cdaLayout->addWidget( cdaQLCDNumber );
cdaLayout->addWidget( cdaLineEdit );
cdaLayout->addWidget( cdaSlider );
// Eta:
@@ -157,16 +161,28 @@ AerolabWindow::AerolabWindow(MainWindow *mainWindow) :
eoffsetSlider->setTickPosition(QSlider::TicksBelow);
eoffsetSlider->setTickInterval(1000);
eoffsetSlider->setMinimum(-30000);
eoffsetSlider->setMaximum(30000);
eoffsetSlider->setMaximum(100000);
eoffsetSlider->setValue(aerolab->intEoffset());
eoffsetLayout->addWidget( eoffsetLabel );
eoffsetLayout->addWidget( eoffsetQLCDNumber );
eoffsetLayout->addWidget( eoffsetSlider );
QCheckBox *eoffsetAuto = new QCheckBox(tr("eoffset auto"), this);
eoffsetAuto->setCheckState(Qt::Checked);
eoffsetLayout->addWidget(eoffsetAuto);
QHBoxLayout *smoothLayout = new QHBoxLayout;
QComboBox *comboDistance = new QComboBox();
comboDistance->addItem(tr("X Axis Shows Time"));
comboDistance->addItem(tr("X Axis Shows Distance"));
comboDistance->setCurrentIndex(1);
smoothLayout->addWidget(comboDistance);
// Add to leftControls:
rightControls->addLayout( mLayout );
rightControls->addLayout( rhoLayout );
rightControls->addLayout( eoffsetLayout );
rightControls->addLayout( smoothLayout );
// Assemble controls layout:
@@ -180,26 +196,67 @@ AerolabWindow::AerolabWindow(MainWindow *mainWindow) :
| QwtPicker::CornerToCorner);
allZoomer->setTrackerMode(QwtPicker::AlwaysOff);
allZoomer->setEnabled(true);
allZoomer->setMousePattern( QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier );
allZoomer->setMousePattern( QwtEventPattern::MouseSelect3, Qt::RightButton );
// SIGNALs to SLOTs:
connect(mainWindow, SIGNAL(rideSelected()), this, SLOT(rideSelected()));
connect(crrSlider, SIGNAL(valueChanged(int)),this, SLOT(setCrrFromSlider()));
connect(cdaSlider, SIGNAL(valueChanged(int)), this, SLOT(setCdaFromSlider()));
connect(cdaLineEdit, SIGNAL(textChanged(const QString)), this, SLOT(setCdaFromText(const QString)));
connect(mSlider, SIGNAL(valueChanged(int)),this, SLOT(setTotalMassFromSlider()));
connect(rhoSlider, SIGNAL(valueChanged(int)), this, SLOT(setRhoFromSlider()));
connect(etaSlider, SIGNAL(valueChanged(int)), this, SLOT(setEtaFromSlider()));
connect(eoffsetSlider, SIGNAL(valueChanged(int)), this, SLOT(setEoffsetFromSlider()));
connect(eoffsetAuto, SIGNAL(stateChanged(int)), this, SLOT(setAutoEoffset(int)));
connect(comboDistance, SIGNAL(currentIndexChanged(int)), this, SLOT(setByDistance(int)));
connect(mainWindow, SIGNAL(configChanged()), aerolab, SLOT(configChanged()));
connect(mainWindow, SIGNAL(configChanged()), this, SLOT(configChanged()));
connect(mainWindow, SIGNAL( intervalSelected() ), this, SLOT(intervalSelected()));
connect(allZoomer, SIGNAL( zoomed(const QwtDoubleRect) ), this, SLOT(zoomChanged()));
// Build the tab layout:
vLayout->addWidget(aerolab);
vLayout->addLayout(cLayout);
setLayout(vLayout);
// tooltip on hover over point
//************************************
aerolab->tooltip = new LTMToolTip( QwtPlot::xBottom,
QwtPlot::yLeft,
QwtPicker::PointSelection,
QwtPicker::VLineRubberBand,
QwtPicker::AlwaysOn,
aerolab->canvas(),
""
);
aerolab->tooltip->setSelectionFlags( QwtPicker::PointSelection | QwtPicker::RectSelection | QwtPicker::DragSelection);
aerolab->tooltip->setRubberBand( QwtPicker::VLineRubberBand );
aerolab->tooltip->setMousePattern( QwtEventPattern::MouseSelect1, Qt::LeftButton, Qt::ShiftModifier );
aerolab->tooltip->setTrackerPen( QColor( Qt::black ) );
QColor inv( Qt::white );
inv.setAlpha( 0 );
aerolab->tooltip->setRubberBandPen( inv );
aerolab->tooltip->setEnabled( true );
aerolab->_canvasPicker = new LTMCanvasPicker( aerolab );
connect( aerolab->_canvasPicker, SIGNAL( pointHover( QwtPlotCurve*, int ) ),
aerolab, SLOT ( pointHover( QwtPlotCurve*, int ) ) );
configChanged(); // pickup colors etc
}
void
AerolabWindow::zoomChanged()
{
RideItem *ride = mainWindow->rideItem();
aerolab->setData(ride, false);
}
void
AerolabWindow::configChanged()
{
@@ -217,7 +274,10 @@ AerolabWindow::rideSelected() {
if (!ride)
return;
aerolab->setData(ride, true);
allZoomer->setZoomBase();
}
@@ -232,12 +292,25 @@ AerolabWindow::setCrrFromSlider() {
}
}
void
AerolabWindow::setCdaFromText(const QString text) {
int value = 10000 * text.toDouble();
if (aerolab->intCda() != value) {
aerolab->setIntCda(value);
//cdaQLCDNumber->display(QString("%1").arg(aerolab->getCda()));
cdaSlider->setValue(aerolab->intCda());
RideItem *ride = mainWindow->rideItem();
aerolab->setData(ride, false);
}
}
void
AerolabWindow::setCdaFromSlider() {
if (aerolab->intCda() != cdaSlider->value()) {
aerolab->setIntCda(cdaSlider->value());
cdaQLCDNumber->display(QString("%1").arg(aerolab->getCda()));
//cdaQLCDNumber->display(QString("%1").arg(aerolab->getCda()));
cdaLineEdit->setText(QString("%1").arg(aerolab->getCda()) );
RideItem *ride = mainWindow->rideItem();
aerolab->setData(ride, false);
}
@@ -287,6 +360,23 @@ AerolabWindow::setEoffsetFromSlider() {
}
}
void
AerolabWindow::setAutoEoffset(int value)
{
aerolab->setAutoEoffset(value);
}
void
AerolabWindow::setByDistance(int value)
{
aerolab->setByDistance(value);
// refresh
RideItem *ride = mainWindow->rideItem();
aerolab->setData(ride, false);
}
void
AerolabWindow::zoomInterval(IntervalItem *which) {
@@ -302,5 +392,35 @@ AerolabWindow::zoomInterval(IntervalItem *which) {
rect.setTop(aerolab->veCurve->maxYValue()*1.1);
rect.setBottom(aerolab->veCurve->minYValue()-10);
allZoomer->zoom(rect);
aerolab->recalc(false);
}
void AerolabWindow::intervalSelected()
{
if ( mainWindow->activeTab() != this )
{
return;
}
RideItem *ride = mainWindow->rideItem();
if ( !ride )
{
return;
}
// set the elevation data
aerolab->setData( ride, true );
}
double AerolabWindow::getCanvasTop() const
{
const QwtDoubleRect &canvasRect = allZoomer->zoomRect();
return canvasRect.top();
}
double AerolabWindow::getCanvasBottom() const
{
const QwtDoubleRect &canvasRect = allZoomer->zoomRect();
return canvasRect.bottom();
}

View File

@@ -38,18 +38,25 @@ class AerolabWindow : public QWidget {
AerolabWindow(MainWindow *mainWindow);
void setData(RideItem *ride);
void zoomInterval(IntervalItem *); // zoom into a specified interval
double getCanvasTop() const;
double getCanvasBottom() const;
QSlider *eoffsetSlider;
public slots:
void setCrrFromSlider();
void setCdaFromSlider();
void setCdaFromText(const QString text);
void setTotalMassFromSlider();
void setRhoFromSlider();
void setEtaFromSlider();
void setEoffsetFromSlider();
void setAutoEoffset(int value);
void setByDistance(int value);
void rideSelected();
void zoomChanged();
void configChanged();
void intervalSelected();
protected slots:
@@ -74,7 +81,7 @@ class AerolabWindow : public QWidget {
QSlider *etaSlider;
QLineEdit *etaLineEdit;
QLCDNumber *etaQLCDNumber;
QSlider *eoffsetSlider;
QLineEdit *eoffsetLineEdit;
QLCDNumber *eoffsetQLCDNumber;

View File

@@ -1004,7 +1004,7 @@ MainWindow::showContextMenuPopup(const QPoint &pos)
connect(actFrontInt, SIGNAL(triggered(void)), this, SLOT(frontInterval(void)));
connect(actBackInt, SIGNAL(triggered(void)), this, SLOT(backInterval(void)));
if (tabWidget->currentWidget() == allPlotWindow)
if (tabWidget->currentWidget() == allPlotWindow || tabWidget->currentWidget() == aerolabWindow)
menu.addAction(actZoomInt);
menu.addAction(actRenameInt);
menu.addAction(actDeleteInt);
@@ -1070,6 +1070,7 @@ void
MainWindow::zoomInterval() {
// zoom into this interval on allPlot
allPlotWindow->zoomInterval(activeInterval);
aerolabWindow->zoomInterval(activeInterval);
}
void