mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
Add reveal controls for ScatterWindow
This commit is contained in:
159
qxt/src/qxtstringspinbox.cpp
Executable file
159
qxt/src/qxtstringspinbox.cpp
Executable file
@@ -0,0 +1,159 @@
|
||||
#include "qxtstringspinbox.h"
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
class QxtStringSpinBoxPrivate : public QxtPrivate<QxtStringSpinBox>
|
||||
{
|
||||
public:
|
||||
QXT_DECLARE_PUBLIC(QxtStringSpinBox)
|
||||
int startsWith(const QString& start, QString& string) const;
|
||||
QStringList strings;
|
||||
};
|
||||
|
||||
int QxtStringSpinBoxPrivate::startsWith(const QString& start, QString& string) const
|
||||
{
|
||||
const int size = strings.size();
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
if (strings.at(i).startsWith(start, Qt::CaseInsensitive))
|
||||
{
|
||||
// found
|
||||
string = strings.at(i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QxtStringSpinBox
|
||||
\inmodule QxtWidgets
|
||||
\brief The QxtStringSpinBox widget is a spin box with string items.
|
||||
|
||||
QxtStringSpinBox is spin box that takes strings. QxtStringSpinBox allows
|
||||
the user to choose a value by clicking the up and down buttons or by
|
||||
pressing Up or Down on the keyboard to increase or decrease the value
|
||||
currently displayed. The user can also type the value in manually.
|
||||
|
||||
\image qxtstringspinbox.png "QxtStringSpinBox in Cleanlooks style."
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs a new QxtStringSpinBox with \a pParent.
|
||||
*/
|
||||
QxtStringSpinBox::QxtStringSpinBox(QWidget* pParent) : QSpinBox(pParent)
|
||||
{
|
||||
setRange(0, 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
Destructs the spin box.
|
||||
*/
|
||||
QxtStringSpinBox::~QxtStringSpinBox()
|
||||
{}
|
||||
|
||||
/*!
|
||||
\property QxtStringSpinBox::strings
|
||||
\brief the string items of the spin box.
|
||||
*/
|
||||
const QStringList& QxtStringSpinBox::strings() const
|
||||
{
|
||||
return qxt_d().strings;
|
||||
}
|
||||
|
||||
void QxtStringSpinBox::setStrings(const QStringList& strings)
|
||||
{
|
||||
qxt_d().strings = strings;
|
||||
setRange(0, strings.size() - 1);
|
||||
if (!strings.isEmpty())
|
||||
setValue(0);
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
void QxtStringSpinBox::fixup(QString& input) const
|
||||
{
|
||||
// just attempt to change the input string to be valid according to the string list
|
||||
// no need to result in a valid string, callers of this function are responsible to
|
||||
// re-test the validity afterwards
|
||||
|
||||
// try finding a string from the list which starts with input
|
||||
input = input.simplified();
|
||||
if (!input.isEmpty())
|
||||
{
|
||||
qxt_d().startsWith(input, input);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QValidator::State QxtStringSpinBox::validate(QString& input, int& pos) const
|
||||
{
|
||||
// Invalid: input is invalid according to the string list
|
||||
// Intermediate: it is likely that a little more editing will make the input acceptable
|
||||
// (e.g. the user types "A" and stringlist contains "ABC")
|
||||
// Acceptable: the input is valid.
|
||||
Q_UNUSED(pos);
|
||||
QString temp;
|
||||
QValidator::State state = QValidator::Invalid;
|
||||
if (qxt_d().strings.contains(input))
|
||||
{
|
||||
// exact match
|
||||
state = QValidator::Acceptable;
|
||||
}
|
||||
else if (input.isEmpty() || qxt_d().startsWith(input, temp) != -1)
|
||||
{
|
||||
// still empty or some string in the list starts with input
|
||||
state = QValidator::Intermediate;
|
||||
}
|
||||
// else invalid
|
||||
return state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QString QxtStringSpinBox::textFromValue(int value) const
|
||||
{
|
||||
Q_ASSERT(qxt_d().strings.isEmpty() || (value >= 0 && value < qxt_d().strings.size()));
|
||||
return qxt_d().strings.isEmpty() ? QLatin1String("") : qxt_d().strings.at(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
int QxtStringSpinBox::valueFromText(const QString& text) const
|
||||
{
|
||||
return qxt_d().strings.indexOf(text);
|
||||
}
|
||||
60
qxt/src/qxtstringspinbox.h
Executable file
60
qxt/src/qxtstringspinbox.h
Executable file
@@ -0,0 +1,60 @@
|
||||
#ifndef QXTSTRINGSPINBOX_H
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#define QXTSTRINGSPINBOX_H
|
||||
|
||||
#include <QSpinBox>
|
||||
#include "qxtglobal.h"
|
||||
|
||||
class QxtStringSpinBoxPrivate;
|
||||
|
||||
class QXT_GUI_EXPORT QxtStringSpinBox : public QSpinBox
|
||||
{
|
||||
Q_OBJECT
|
||||
QXT_DECLARE_PRIVATE(QxtStringSpinBox)
|
||||
Q_PROPERTY(QStringList strings READ strings WRITE setStrings)
|
||||
|
||||
public:
|
||||
explicit QxtStringSpinBox(QWidget* pParent = 0);
|
||||
virtual ~QxtStringSpinBox();
|
||||
|
||||
const QStringList& strings() const;
|
||||
void setStrings(const QStringList& strings);
|
||||
|
||||
virtual void fixup(QString& input) const;
|
||||
virtual QValidator::State validate(QString& input, int& pos) const;
|
||||
|
||||
protected:
|
||||
virtual QString textFromValue(int value) const;
|
||||
virtual int valueFromText(const QString& text) const;
|
||||
};
|
||||
|
||||
#endif // QXTSTRINGSPINBOX_H
|
||||
@@ -45,19 +45,85 @@ ScatterWindow::addStandardChannels(QComboBox *box)
|
||||
//box->addItem(tr("Longitude"), MODEL_LONG); //XXX weird values make the plot ugly
|
||||
}
|
||||
|
||||
void
|
||||
ScatterWindow::addrStandardChannels(QxtStringSpinBox *box)
|
||||
{
|
||||
QStringList list;
|
||||
list.append(tr("Power"));
|
||||
list.append(tr("Cadence"));
|
||||
list.append(tr("Heartrate"));
|
||||
list.append(tr("Speed"));
|
||||
list.append(tr("Altitude"));
|
||||
list.append(tr("Torque"));
|
||||
list.append(tr("AEPF"));
|
||||
list.append(tr("CPV"));
|
||||
list.append(tr("Time"));
|
||||
list.append(tr("Distance"));
|
||||
box->setStrings(list);
|
||||
}
|
||||
|
||||
ScatterWindow::ScatterWindow(MainWindow *parent, const QDir &home) :
|
||||
GcWindow(parent), home(home), main(parent), ride(NULL), current(NULL)
|
||||
{
|
||||
setInstanceName("2D Window");
|
||||
|
||||
// Main layout
|
||||
QGridLayout *mainLayout = new QGridLayout(this);
|
||||
mainLayout->setContentsMargins(2,2,2,2);
|
||||
|
||||
//
|
||||
// reveal controls widget
|
||||
//
|
||||
|
||||
// reveal widget
|
||||
revealControls = new QWidget(this);
|
||||
revealControls->setFixedHeight(50);
|
||||
revealControls->setStyleSheet("background-color: rgba(100%, 100%, 100%, 80%)");
|
||||
revealControls->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
|
||||
// reveal controls
|
||||
QLabel *rxLabel = new QLabel(tr("X-Axis:"), this);
|
||||
rxSelector = new QxtStringSpinBox(revealControls);
|
||||
addrStandardChannels(rxSelector);
|
||||
|
||||
QLabel *ryLabel = new QLabel(tr("Y-Axis:"), this);
|
||||
rySelector = new QxtStringSpinBox(revealControls);
|
||||
addrStandardChannels(rySelector);
|
||||
|
||||
rIgnore = new QCheckBox(tr("Ignore Zero"));
|
||||
rIgnore->setChecked(true);
|
||||
rFrameInterval = new QCheckBox(tr("Frame intervals"));
|
||||
rFrameInterval->setChecked(true);
|
||||
|
||||
// layout reveal controls
|
||||
QHBoxLayout *r = new QHBoxLayout;
|
||||
r->setContentsMargins(0,0,0,0);
|
||||
r->addStretch();
|
||||
r->addWidget(rxLabel);
|
||||
r->addWidget(rxSelector);
|
||||
r->addWidget(ryLabel);
|
||||
r->addWidget(rySelector);
|
||||
r->addSpacing(5);
|
||||
r->addWidget(rIgnore);
|
||||
r->addWidget(rFrameInterval);
|
||||
r->addStretch();
|
||||
revealControls->setLayout(r);
|
||||
|
||||
// hide them initially
|
||||
revealControls->hide();
|
||||
|
||||
QWidget *c = new QWidget;
|
||||
QFormLayout *cl = new QFormLayout(c);
|
||||
setControls(c);
|
||||
|
||||
// the plot widget
|
||||
scatterPlot= new ScatterPlot(main);
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(scatterPlot);
|
||||
QVBoxLayout *vlayout = new QVBoxLayout;
|
||||
vlayout->addWidget(scatterPlot);
|
||||
|
||||
mainLayout->addLayout(vlayout,0,0);
|
||||
mainLayout->addWidget(revealControls,0,0, Qt::AlignTop);
|
||||
revealControls->raise();
|
||||
setLayout(mainLayout);
|
||||
|
||||
// labels
|
||||
@@ -65,12 +131,14 @@ ScatterWindow::ScatterWindow(MainWindow *parent, const QDir &home) :
|
||||
xSelector = new QComboBox;
|
||||
addStandardChannels(xSelector);
|
||||
xSelector->setCurrentIndex(0); // power
|
||||
rxSelector->setValue(0);
|
||||
cl->addRow(xLabel, xSelector);
|
||||
|
||||
yLabel = new QLabel(tr("Y-Axis:"), this);
|
||||
ySelector = new QComboBox;
|
||||
addStandardChannels(ySelector);
|
||||
ySelector->setCurrentIndex(2); // heartrate
|
||||
rySelector->setValue(2);
|
||||
cl->addRow(yLabel, ySelector);
|
||||
|
||||
timeLabel = new QLabel(tr("00:00:00"), this);
|
||||
@@ -104,11 +172,16 @@ ScatterWindow::ScatterWindow(MainWindow *parent, const QDir &home) :
|
||||
connect(main, SIGNAL(intervalsChanged()), this, SLOT(intervalSelected()));
|
||||
connect(xSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(setData()));
|
||||
connect(ySelector, SIGNAL(currentIndexChanged(int)), this, SLOT(setData()));
|
||||
connect(rxSelector, SIGNAL(valueChanged(int)), this, SLOT(rxSelectorChanged(int)));
|
||||
connect(rySelector, SIGNAL(valueChanged(int)), this, SLOT(rySelectorChanged(int)));
|
||||
connect(timeSlider, SIGNAL(valueChanged(int)), this, SLOT(setTime(int)));
|
||||
connect(grid, SIGNAL(stateChanged(int)), this, SLOT(setGrid()));
|
||||
//connect(legend, SIGNAL(stateChanged(int)), this, SLOT(setLegend()));
|
||||
connect(frame, SIGNAL(stateChanged(int)), this, SLOT(setFrame()));
|
||||
connect(ignore, SIGNAL(stateChanged(int)), this, SLOT(setIgnore()));
|
||||
connect(rFrameInterval, SIGNAL(stateChanged(int)), this, SLOT(setrFrame()));
|
||||
connect(rIgnore, SIGNAL(stateChanged(int)), this, SLOT(setrIgnore()));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -143,6 +216,15 @@ void
|
||||
ScatterWindow::setFrame()
|
||||
{
|
||||
settings.frame = frame->isChecked();
|
||||
rFrameInterval->setChecked(frame->isChecked());
|
||||
setData();
|
||||
}
|
||||
|
||||
void
|
||||
ScatterWindow::setrFrame()
|
||||
{
|
||||
settings.frame = rFrameInterval->isChecked();
|
||||
frame->setChecked(rFrameInterval->isChecked());
|
||||
setData();
|
||||
}
|
||||
|
||||
@@ -150,6 +232,15 @@ void
|
||||
ScatterWindow::setIgnore()
|
||||
{
|
||||
settings.ignore = ignore->isChecked();
|
||||
rIgnore->setChecked(ignore->isChecked());
|
||||
setData();
|
||||
}
|
||||
|
||||
void
|
||||
ScatterWindow::setrIgnore()
|
||||
{
|
||||
settings.ignore = rIgnore->isChecked();
|
||||
ignore->setChecked(rIgnore->isChecked());
|
||||
setData();
|
||||
}
|
||||
|
||||
@@ -172,6 +263,20 @@ ScatterWindow::setTime(int value)
|
||||
scatterPlot->showTime(&settings, value, 30);
|
||||
}
|
||||
|
||||
void
|
||||
ScatterWindow::rxSelectorChanged(int value)
|
||||
{
|
||||
xSelector->setCurrentIndex(value);
|
||||
setData();
|
||||
}
|
||||
|
||||
void
|
||||
ScatterWindow::rySelectorChanged(int value)
|
||||
{
|
||||
ySelector->setCurrentIndex(value);
|
||||
setData();
|
||||
}
|
||||
|
||||
void
|
||||
ScatterWindow::setData()
|
||||
{
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
|
||||
#include <QtGui>
|
||||
#include <QTimer>
|
||||
#include "qxtstringspinbox.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
|
||||
class ScatterPlot; // we don't include the header because it uses namespaces
|
||||
class ScatterDataColor;
|
||||
|
||||
@@ -58,11 +60,16 @@ class ScatterWindow : public GcWindow
|
||||
|
||||
ScatterWindow(MainWindow *, const QDir &);
|
||||
|
||||
// reveal
|
||||
bool hasReveal() { return true; }
|
||||
void reveal() { revealControls->show(); }
|
||||
void unreveal() { revealControls->hide(); }
|
||||
|
||||
// set/get properties
|
||||
int xseries() const { return xSelector->currentIndex(); }
|
||||
void setXSeries(int x) { xSelector->setCurrentIndex(x); }
|
||||
void setXSeries(int x) { xSelector->setCurrentIndex(x); rxSelector->setValue(x); }
|
||||
int yseries() const { return ySelector->currentIndex(); }
|
||||
void setYSeries(int x) { ySelector->setCurrentIndex(x); }
|
||||
void setYSeries(int x) { ySelector->setCurrentIndex(x); rySelector->setValue(x); }
|
||||
bool isGrid() const { return grid->isChecked(); }
|
||||
void set_Grid(bool x) { grid->setChecked(x); }
|
||||
bool isIgnore() const { return ignore->isChecked(); }
|
||||
@@ -77,10 +84,15 @@ class ScatterWindow : public GcWindow
|
||||
void intervalSelected();
|
||||
void setData();
|
||||
|
||||
void rxSelectorChanged(int);
|
||||
void rySelectorChanged(int);
|
||||
|
||||
// these set the plot when the properties change
|
||||
void setGrid();
|
||||
void setFrame();
|
||||
void setIgnore();
|
||||
void setrFrame();
|
||||
void setrIgnore();
|
||||
void setTime(int);
|
||||
|
||||
protected:
|
||||
@@ -116,8 +128,17 @@ class ScatterWindow : public GcWindow
|
||||
RideItem *current;
|
||||
|
||||
private:
|
||||
// reveal controls
|
||||
QWidget *revealControls;
|
||||
QxtStringSpinBox *rxSelector,
|
||||
*rySelector;
|
||||
QCheckBox *rFrameInterval,
|
||||
*rIgnore;
|
||||
|
||||
void addStandardChannels(QComboBox *);
|
||||
void addrStandardChannels(QxtStringSpinBox *box);
|
||||
|
||||
bool _lockReveal;
|
||||
};
|
||||
|
||||
#endif // _GC_ScatterWindow_h
|
||||
|
||||
@@ -215,6 +215,7 @@ SOURCES += ../qxt/src/qxtspanslider.cpp \
|
||||
../qxt/src/qxtscheduleviewheadermodel_p.cpp \
|
||||
../qxt/src/qxtscheduleitemdelegate.cpp \
|
||||
../qxt/src/qxtstyleoptionscheduleviewitem.cpp \
|
||||
../qxt/src/qxtstringspinbox.cpp \
|
||||
|
||||
isEmpty( QTSOAP_INSTALL ) {
|
||||
include( ../qtsolutions/soap/qtsoap.pri )
|
||||
@@ -232,7 +233,8 @@ HEADERS += ../qxt/src/qxtspanslider.h \
|
||||
../qxt/src/qxtscheduleheaderwidget.h \
|
||||
../qxt/src/qxtscheduleviewheadermodel_p.h \
|
||||
../qxt/src/qxtscheduleitemdelegate.h \
|
||||
../qxt/src/qxtstyleoptionscheduleviewitem.h
|
||||
../qxt/src/qxtstyleoptionscheduleviewitem.h \
|
||||
../qxt/src/qxtstringspinbox.h \
|
||||
|
||||
HEADERS += \
|
||||
AboutDialog.h \
|
||||
|
||||
Reference in New Issue
Block a user