mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-14 16:39:57 +00:00
Upgrade to QWT 6.0.1, but still uses a locally patched copy since support for 8 axes has not been included, despite it being a relatively simple patch. Fixes #634. Fixes #567.
294 lines
7.6 KiB
C++
294 lines
7.6 KiB
C++
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
|
|
* Qwt Widget Library
|
|
* Copyright (C) 1997 Josef Wilgen
|
|
* Copyright (C) 2002 Uwe Rathmann
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the Qwt License, Version 1.0
|
|
*****************************************************************************/
|
|
|
|
// vim: expandtab
|
|
|
|
#include <qlayout.h>
|
|
#include <qpen.h>
|
|
#include <qwt_plot.h>
|
|
#include <qwt_scale_widget.h>
|
|
#include <qwt_scale_draw.h>
|
|
#include "plotmatrix.h"
|
|
|
|
class PlotMatrix::PrivateData
|
|
{
|
|
public:
|
|
PrivateData():
|
|
inScaleSync(false)
|
|
{
|
|
isAxisEnabled[QwtPlot::xBottom] = true;
|
|
isAxisEnabled[QwtPlot::xTop] = false;
|
|
isAxisEnabled[QwtPlot::yLeft] = true;
|
|
isAxisEnabled[QwtPlot::yRight] = false;
|
|
}
|
|
|
|
bool isAxisEnabled[QwtPlot::axisCnt];
|
|
QVector<QwtPlot *> plotWidgets;
|
|
mutable bool inScaleSync;
|
|
};
|
|
|
|
PlotMatrix::PlotMatrix( int numRows, int numColumns, QWidget *parent):
|
|
QFrame(parent)
|
|
{
|
|
d_data = new PrivateData();
|
|
d_data->plotWidgets.resize(numRows * numColumns);
|
|
|
|
QGridLayout *layout = new QGridLayout(this);
|
|
for ( int row = 0; row < numRows; row++ )
|
|
{
|
|
for ( int col = 0; col < numColumns; col++ )
|
|
{
|
|
QwtPlot *plot = new QwtPlot(this);
|
|
layout->addWidget(plot, row, col);
|
|
|
|
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
|
|
{
|
|
connect(plot->axisWidget(axis),
|
|
SIGNAL(scaleDivChanged()), SLOT(scaleDivChanged()) );
|
|
}
|
|
d_data->plotWidgets[row * numColumns + col] = plot;
|
|
}
|
|
}
|
|
|
|
updateLayout();
|
|
}
|
|
|
|
PlotMatrix::~PlotMatrix()
|
|
{
|
|
delete d_data;
|
|
}
|
|
|
|
int PlotMatrix::numRows() const
|
|
{
|
|
const QGridLayout *l = qobject_cast<const QGridLayout *>(layout());
|
|
if ( l )
|
|
return l->rowCount();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int PlotMatrix::numColumns() const
|
|
{
|
|
const QGridLayout *l = qobject_cast<const QGridLayout *>(layout());
|
|
if ( l )
|
|
return l->columnCount();
|
|
return 0;
|
|
}
|
|
|
|
QwtPlot* PlotMatrix::plot(int row, int column)
|
|
{
|
|
const int index = row * numColumns() + column;
|
|
if ( index < (int)d_data->plotWidgets.size() )
|
|
return d_data->plotWidgets[index];
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const QwtPlot* PlotMatrix::plot(int row, int column) const
|
|
{
|
|
const int index = row * numColumns() + column;
|
|
if ( index < (int)d_data->plotWidgets.size() )
|
|
return d_data->plotWidgets[index];
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void PlotMatrix::enableAxis(int axis, bool tf)
|
|
{
|
|
if ( axis >= 0 && axis < QwtPlot::axisCnt )
|
|
{
|
|
if ( tf != d_data->isAxisEnabled[axis] )
|
|
{
|
|
d_data->isAxisEnabled[axis] = tf;
|
|
updateLayout();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool PlotMatrix::axisEnabled(int axis) const
|
|
{
|
|
if ( axis >= 0 && axis < QwtPlot::axisCnt )
|
|
return d_data->isAxisEnabled[axis];
|
|
|
|
return false;
|
|
}
|
|
|
|
void PlotMatrix::setAxisScale(int axis, int rowOrColumn,
|
|
double min, double max, double step)
|
|
{
|
|
int row = 0;
|
|
int col = 0;
|
|
|
|
if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
|
|
col = rowOrColumn;
|
|
else
|
|
row = rowOrColumn;
|
|
|
|
QwtPlot *plt = plot(row, col);
|
|
if ( plt )
|
|
{
|
|
plt->setAxisScale(axis, min, max, step);
|
|
plt->updateAxes();
|
|
}
|
|
}
|
|
|
|
void PlotMatrix::scaleDivChanged()
|
|
{
|
|
if ( d_data->inScaleSync )
|
|
return;
|
|
|
|
d_data->inScaleSync = true;
|
|
|
|
QwtPlot *plt = NULL;
|
|
int axisId = -1;
|
|
int rowOrColumn = -1;
|
|
|
|
// find the changed axis
|
|
for ( int row = 0; row < numRows(); row++ )
|
|
{
|
|
for ( int col = 0; col < numColumns(); col++ )
|
|
{
|
|
QwtPlot *p = plot(row, col);
|
|
if ( p )
|
|
{
|
|
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
|
|
{
|
|
if ( p->axisWidget(axis) == sender() )
|
|
{
|
|
plt = p;
|
|
axisId = axis;
|
|
if ( axisId == QwtPlot::xBottom || axisId == QwtPlot::xTop )
|
|
rowOrColumn = col;
|
|
else
|
|
rowOrColumn = row;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( plt )
|
|
{
|
|
|
|
// synchronize the axes
|
|
if ( axisId == QwtPlot::xBottom || axisId == QwtPlot::xTop )
|
|
{
|
|
for ( int row = 0; row < numRows(); row++ )
|
|
{
|
|
QwtPlot *p = plot(row, rowOrColumn);
|
|
if ( p != plt )
|
|
p->setAxisScaleDiv(axisId, *plt->axisScaleDiv(axisId));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ( int col = 0; col < numColumns(); col++ )
|
|
{
|
|
QwtPlot *p = plot(rowOrColumn, col);
|
|
if ( p != plt )
|
|
p->setAxisScaleDiv(axisId, *plt->axisScaleDiv(axisId));
|
|
}
|
|
}
|
|
|
|
updateLayout();
|
|
}
|
|
|
|
d_data->inScaleSync = false;
|
|
}
|
|
|
|
void PlotMatrix::updateLayout()
|
|
{
|
|
for ( int row = 0; row < numRows(); row++ )
|
|
{
|
|
for ( int col = 0; col < numColumns(); col++ )
|
|
{
|
|
QwtPlot *p = plot(row, col);
|
|
if ( p )
|
|
{
|
|
bool showAxis[QwtPlot::axisCnt];
|
|
showAxis[QwtPlot::xBottom] =
|
|
axisEnabled(QwtPlot::xBottom) && row == numRows() - 1;
|
|
showAxis[QwtPlot::xTop] =
|
|
axisEnabled(QwtPlot::xTop) && row == 0;
|
|
showAxis[QwtPlot::yLeft] =
|
|
axisEnabled(QwtPlot::yLeft) && col == 0;
|
|
showAxis[QwtPlot::yRight] =
|
|
axisEnabled(QwtPlot::yRight) && col == numColumns() - 1;
|
|
|
|
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
|
|
{
|
|
if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
|
|
p->enableAxis(axis, showAxis[axis]);
|
|
else
|
|
{
|
|
p->enableAxis(axis, true);
|
|
|
|
QwtScaleDraw *sd = p->axisScaleDraw(axis);
|
|
sd->enableComponent(
|
|
QwtScaleDraw::Backbone, showAxis[axis]);
|
|
sd->enableComponent(
|
|
QwtScaleDraw::Ticks, showAxis[axis]);
|
|
sd->enableComponent(
|
|
QwtScaleDraw::Labels, showAxis[axis]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for ( int col = 0; col < numColumns(); col++ )
|
|
{
|
|
alignVAxes(col, QwtPlot::yLeft);
|
|
alignVAxes(col, QwtPlot::yRight);
|
|
}
|
|
|
|
for ( int row = 0; row < numRows(); row++ )
|
|
{
|
|
for ( int col = 0; col < numColumns(); col++ )
|
|
{
|
|
QwtPlot *p = plot(row, col);
|
|
if ( p )
|
|
p->replot();
|
|
}
|
|
}
|
|
}
|
|
|
|
void PlotMatrix::alignVAxes(int col, int axis)
|
|
{
|
|
if ( axis != QwtPlot::yLeft && axis != QwtPlot::yRight )
|
|
return;
|
|
|
|
int maxExtent = 0;
|
|
for ( int row = 0; row < numRows(); row++ )
|
|
{
|
|
QwtPlot *p = plot(row, col);
|
|
if ( p )
|
|
{
|
|
QwtScaleWidget *scaleWidget = p->axisWidget(axis);
|
|
|
|
QwtScaleDraw *sd = scaleWidget->scaleDraw();
|
|
sd->setMinimumExtent(0);
|
|
|
|
const int extent = sd->extent( scaleWidget->font() );
|
|
if ( extent > maxExtent )
|
|
maxExtent = extent;
|
|
}
|
|
}
|
|
for ( int row = 0; row < numRows(); row++ )
|
|
{
|
|
QwtPlot *p = plot(row, col);
|
|
if ( p )
|
|
{
|
|
QwtScaleWidget *scaleWidget = p->axisWidget(axis);
|
|
scaleWidget->scaleDraw()->setMinimumExtent(maxExtent);
|
|
}
|
|
}
|
|
}
|