mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-14 08:38:45 +00:00
386 lines
15 KiB
C++
386 lines
15 KiB
C++
/*
|
|
* Copyright (c) 2015 Erik Botö (erik.boto@gmail.com)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "TrainBottom.h"
|
|
#include "TrainSidebar.h"
|
|
|
|
#include <QHBoxLayout>
|
|
#include <QPushButton>
|
|
#include <QSlider>
|
|
#include <QCheckBox>
|
|
#include <QPlainTextEdit>
|
|
#include <QTimer>
|
|
|
|
TrainBottom::TrainBottom(TrainSidebar *trainSidebar, QWidget *parent) :
|
|
QWidget(parent),
|
|
m_trainSidebar(trainSidebar)
|
|
{
|
|
// Control buttons
|
|
QHBoxLayout *toolbuttons = new QHBoxLayout;
|
|
toolbuttons->setSpacing(0);
|
|
toolbuttons->setContentsMargins(0,0,0,0);
|
|
|
|
QIcon connectButtonIcon(":images/oxygen/power-off.png");
|
|
m_connectButton = new QPushButton(connectButtonIcon, "", this);
|
|
m_connectButton->setFocusPolicy(Qt::NoFocus);
|
|
m_connectButton->setIconSize(QSize(64,64));
|
|
m_connectButton->setAutoFillBackground(false);
|
|
m_connectButton->setAutoDefault(false);
|
|
m_connectButton->setFlat(true);
|
|
m_connectButton->setStyleSheet("background-color: rgba( 255, 255, 255, 0% ); border: 0px;");
|
|
m_connectButton->setAutoRepeat(true);
|
|
m_connectButton->setAutoRepeatDelay(200);
|
|
#if QT_VERSION > 0x050400
|
|
m_connectButton->setShortcut(Qt::Key_MediaPrevious);
|
|
#endif
|
|
toolbuttons->addWidget(m_connectButton);
|
|
|
|
QIcon rewIcon(":images/oxygen/rewind.png");
|
|
m_rewindButton = new QPushButton(rewIcon, "", this);
|
|
m_rewindButton->setFocusPolicy(Qt::NoFocus);
|
|
m_rewindButton->setIconSize(QSize(64,64));
|
|
m_rewindButton->setAutoFillBackground(false);
|
|
m_rewindButton->setAutoDefault(false);
|
|
m_rewindButton->setFlat(true);
|
|
m_rewindButton->setStyleSheet("background-color: rgba( 255, 255, 255, 0% ); border: 0px;");
|
|
m_rewindButton->setAutoRepeat(true);
|
|
m_rewindButton->setAutoRepeatDelay(200);
|
|
#if QT_VERSION > 0x050400
|
|
m_rewindButton->setShortcut(Qt::Key_MediaPrevious);
|
|
#endif
|
|
toolbuttons->addWidget(m_rewindButton);
|
|
|
|
QIcon stopIcon(":images/oxygen/stop.png");
|
|
m_stopButton = new QPushButton(stopIcon, "", this);
|
|
m_stopButton->setFocusPolicy(Qt::NoFocus);
|
|
m_stopButton->setIconSize(QSize(64,64));
|
|
m_stopButton->setAutoFillBackground(false);
|
|
m_stopButton->setAutoDefault(false);
|
|
m_stopButton->setFlat(true);
|
|
m_stopButton->setStyleSheet("background-color: rgba( 255, 255, 255, 0% ); border: 0px;");
|
|
#if QT_VERSION > 0x050400
|
|
m_stopButton->setShortcut(Qt::Key_MediaStop);
|
|
#endif
|
|
toolbuttons->addWidget(m_stopButton);
|
|
|
|
QIcon playIcon(":images/oxygen/play.png");
|
|
m_playButton = new QPushButton(playIcon, "", this);
|
|
m_playButton->setFocusPolicy(Qt::NoFocus);
|
|
m_playButton->setIconSize(QSize(64,64));
|
|
m_playButton->setAutoFillBackground(false);
|
|
m_playButton->setAutoDefault(false);
|
|
m_playButton->setFlat(true);
|
|
m_playButton->setStyleSheet("background-color: rgba( 255, 255, 255, 0% ); border: 0px;");
|
|
m_playButton->setShortcut(Qt::Key_MediaTogglePlayPause);
|
|
toolbuttons->addWidget(m_playButton);
|
|
|
|
QIcon fwdIcon(":images/oxygen/ffwd.png");
|
|
m_forwardButton = new QPushButton(fwdIcon, "", this);
|
|
m_forwardButton->setFocusPolicy(Qt::NoFocus);
|
|
m_forwardButton->setIconSize(QSize(64,64));
|
|
m_forwardButton->setAutoFillBackground(false);
|
|
m_forwardButton->setAutoDefault(false);
|
|
m_forwardButton->setFlat(true);
|
|
m_forwardButton->setStyleSheet("background-color: rgba( 255, 255, 255, 0% ); border: 0px;");
|
|
m_forwardButton->setAutoRepeat(true);
|
|
m_forwardButton->setAutoRepeatDelay(200);
|
|
#if QT_VERSION > 0x050400
|
|
m_forwardButton->setShortcut(Qt::Key_MediaNext);
|
|
#endif
|
|
toolbuttons->addWidget(m_forwardButton);
|
|
|
|
QIcon lapIcon(":images/oxygen/lap.png");
|
|
m_lapButton = new QPushButton(lapIcon, "", this);
|
|
m_lapButton->setFocusPolicy(Qt::NoFocus);
|
|
m_lapButton->setIconSize(QSize(64,64));
|
|
m_lapButton->setAutoFillBackground(false);
|
|
m_lapButton->setAutoDefault(false);
|
|
m_lapButton->setFlat(true);
|
|
m_lapButton->setStyleSheet("background-color: rgba( 255, 255, 255, 0% ); border: 0px;");
|
|
#if QT_VERSION > 0x050400
|
|
m_lapButton->setShortcut(Qt::Key_0);
|
|
#endif
|
|
toolbuttons->addWidget(m_lapButton);
|
|
|
|
QIcon calIcon(":images/oxygen/cal.png");
|
|
cal = new QPushButton(calIcon, "", this);
|
|
cal->setFocusPolicy(Qt::NoFocus);
|
|
cal->setIconSize(QSize(64,64));
|
|
cal->setAutoFillBackground(false);
|
|
cal->setAutoDefault(false);
|
|
cal->setFlat(true);
|
|
cal->setStyleSheet("background-color: rgba( 255, 255, 255, 0% ); border: 0px;");
|
|
#if QT_VERSION > 0x050400
|
|
cal->setShortcut(Qt::Key_C);
|
|
#endif
|
|
toolbuttons->addWidget(cal);
|
|
|
|
QIcon upIcon(":images/oxygen/up.png");
|
|
loadUp = new QPushButton(upIcon, "", this);
|
|
loadUp->setFocusPolicy(Qt::NoFocus);
|
|
loadUp->setIconSize(QSize(64,64));
|
|
loadUp->setAutoFillBackground(false);
|
|
loadUp->setAutoDefault(false);
|
|
loadUp->setFlat(true);
|
|
loadUp->setAutoRepeat(true);
|
|
loadUp->setAutoRepeatInterval(50);
|
|
loadUp->setStyleSheet("background-color: rgba( 255, 255, 255, 0% ); border: 0px;");
|
|
#if QT_VERSION > 0x050400
|
|
loadUp->setShortcut(Qt::Key_Plus);
|
|
#endif
|
|
toolbuttons->addWidget(loadUp);
|
|
|
|
QIcon downIcon(":images/oxygen/down.png");
|
|
loadDown = new QPushButton(downIcon, "", this);
|
|
loadDown->setFocusPolicy(Qt::NoFocus);
|
|
loadDown->setIconSize(QSize(64,64));
|
|
loadDown->setAutoFillBackground(false);
|
|
loadDown->setAutoDefault(false);
|
|
loadDown->setFlat(true);
|
|
loadDown->setAutoRepeat(true);
|
|
loadDown->setAutoRepeatInterval(50);
|
|
loadDown->setStyleSheet("background-color: rgba( 255, 255, 255, 0% ); border: 0px;");
|
|
#if QT_VERSION > 0x050400
|
|
loadDown->setShortcut(Qt::Key_Minus);
|
|
#endif
|
|
toolbuttons->addWidget(loadDown);
|
|
|
|
intensitySlider = new QSlider(Qt::Vertical, this);
|
|
intensitySlider->setAutoFillBackground(false);
|
|
intensitySlider->setFocusPolicy(Qt::NoFocus);
|
|
intensitySlider->setMinimum(75);
|
|
intensitySlider->setMaximum(125);
|
|
intensitySlider->setValue(100);
|
|
toolbuttons->addWidget(intensitySlider);
|
|
|
|
// notification area
|
|
QHBoxLayout *notifications = new QHBoxLayout();
|
|
notifications->setSpacing(0);
|
|
notifications->setContentsMargins(0,0,0,0);
|
|
|
|
notificationText = new QPlainTextEdit();
|
|
notifications->addWidget(notificationText);
|
|
|
|
QFont font("Monospace");
|
|
font.setStyleHint(QFont::TypeWriter);
|
|
font.setBold(1);
|
|
font.setPointSize(14);
|
|
|
|
notificationText->setFont(font);
|
|
notificationText->setStyleSheet("QPlainTextEdit {background-color: black; color: red}");
|
|
notificationText->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
notificationText->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
notificationText->setTextInteractionFlags(Qt::NoTextInteraction);
|
|
notificationText->setLineWrapMode(QPlainTextEdit::NoWrap);
|
|
|
|
//QCheckBox *hideOnIdle = new QCheckBox(tr("Auto Hide"), this);
|
|
//intensityControlLayout->addWidget(hideOnIdle);
|
|
|
|
QHBoxLayout *allControlsLayout = new QHBoxLayout();
|
|
allControlsLayout->addLayout(toolbuttons);
|
|
allControlsLayout->addLayout(notifications);
|
|
|
|
connect(m_playButton, SIGNAL(clicked()), m_trainSidebar, SLOT(Start()));
|
|
connect(m_rewindButton, SIGNAL(clicked()), m_trainSidebar, SLOT(Rewind()));
|
|
connect(m_forwardButton, SIGNAL(clicked()), m_trainSidebar, SLOT(FFwd()));
|
|
connect(m_lapButton, SIGNAL(clicked()), m_trainSidebar, SLOT(newLap()));
|
|
connect(m_stopButton, SIGNAL(clicked()), m_trainSidebar, SLOT(Stop()));
|
|
connect(m_trainSidebar->context, SIGNAL(start()), this, SLOT(updatePlayButtonIcon()));
|
|
connect(m_trainSidebar->context, SIGNAL(pause()), this, SLOT(updatePlayButtonIcon()));
|
|
connect(m_trainSidebar->context, SIGNAL(unpause()), this, SLOT(updatePlayButtonIcon()));
|
|
connect(m_trainSidebar->context, SIGNAL(stop()), this, SLOT(updatePlayButtonIcon()));
|
|
//connect(hideOnIdle, SIGNAL(stateChanged(int)), this, SLOT(autoHideCheckboxChanged(int)));
|
|
connect(m_trainSidebar, SIGNAL(statusChanged(int)), this, SLOT(statusChanged(int)));
|
|
connect(m_connectButton, SIGNAL(released()), m_trainSidebar, SLOT(toggleConnect()));
|
|
connect(cal, SIGNAL(clicked()), m_trainSidebar, SLOT(Calibrate()));
|
|
|
|
connect(loadUp, SIGNAL(clicked()), m_trainSidebar, SLOT(Higher()));
|
|
connect(loadDown, SIGNAL(clicked()), m_trainSidebar, SLOT(Lower()));
|
|
connect(intensitySlider, SIGNAL(valueChanged(int)), m_trainSidebar, SLOT(adjustIntensity(int)));
|
|
connect(m_trainSidebar, SIGNAL(intensityChanged(int)), intensitySlider, SLOT(setValue(int)));
|
|
|
|
connect(m_trainSidebar, SIGNAL(setNotification(QString, int)), this, SLOT(setNotification(QString, int)));
|
|
connect(m_trainSidebar, SIGNAL(clearNotification(void)), this, SLOT(clearNotification(void)));
|
|
|
|
this->setContentsMargins(0,0,0,0);
|
|
this->setFocusPolicy(Qt::NoFocus);
|
|
this->setAutoFillBackground(false);
|
|
this->setStyleSheet("background-color: rgba( 255, 255, 255, 0% ); border: 0px;");
|
|
this->setLayout(allControlsLayout);
|
|
this->installEventFilter(trainSidebar);
|
|
|
|
// Ensure the bottom bar is sized to show 3 lines of notification text
|
|
// but don't allow it to crop the buttons if smaller font is used..
|
|
int buttonHeight = m_connectButton->sizeHint().height();
|
|
int notificationHeight = 3 * notificationText->fontMetrics().lineSpacing();
|
|
int contentHeight = qMax(buttonHeight, notificationHeight);
|
|
|
|
int layoutMargins = allControlsLayout->contentsMargins().top() +
|
|
allControlsLayout->contentsMargins().bottom();
|
|
|
|
// Adding an extra quarter line looks more symmetrical
|
|
int extra = notificationHeight / 12;
|
|
|
|
this->setFixedHeight(contentHeight + layoutMargins + extra);
|
|
|
|
//qDebug() << "Button height" << buttonHeight;
|
|
//qDebug() << "Notification line spacing" << notificationText->fontMetrics().lineSpacing();
|
|
//qDebug() << "bottombar margins:" << this->contentsMargins();
|
|
//qDebug() << "- allControlsLayout margins:" << allControlsLayout->contentsMargins();
|
|
//qDebug() << " - toolbuttons margins:" << toolbuttons->contentsMargins();
|
|
//qDebug() << " - notifications margins:" << notifications->contentsMargins();
|
|
//qDebug() << " - notificationText margins:" << notificationText->contentsMargins();
|
|
//notificationText->setPlainText("LINE1\nLINE2\nLINE3");
|
|
|
|
// Create a timer for notifications, but don't start yet
|
|
notificationTimer = new QTimer(this);
|
|
connect(notificationTimer, SIGNAL(timeout()), SLOT(clearNotification()));
|
|
}
|
|
|
|
void TrainBottom::updatePlayButtonIcon()
|
|
{
|
|
static QIcon playIcon(":images/oxygen/play.png");
|
|
static QIcon pauseIcon(":images/oxygen/pause.png");
|
|
|
|
if (m_trainSidebar->currentStatus() & RT_PAUSED)
|
|
{
|
|
m_playButton->setIcon(playIcon);
|
|
}
|
|
else if (m_trainSidebar->currentStatus() & RT_RUNNING)
|
|
{
|
|
m_playButton->setIcon(pauseIcon);
|
|
}
|
|
else // Not running or paused means stopped
|
|
{
|
|
m_playButton->setIcon(playIcon);
|
|
}
|
|
}
|
|
|
|
void TrainBottom::autoHideCheckboxChanged(int state)
|
|
{
|
|
emit autoHideChanged(state == Qt::Checked);
|
|
}
|
|
|
|
|
|
void TrainBottom::statusChanged(int status)
|
|
{
|
|
static QIcon connectedIcon(":images/oxygen/power-on.png");
|
|
static QIcon disconnectedIcon(":images/oxygen/power-off.png");
|
|
|
|
// not yet connected
|
|
if ((status&RT_CONNECTED) == 0) {
|
|
m_connectButton->setIcon(disconnectedIcon);
|
|
m_connectButton->setEnabled(true);
|
|
m_playButton->setEnabled(false);
|
|
m_stopButton->setEnabled(false);
|
|
m_forwardButton->setEnabled(false);
|
|
m_rewindButton->setEnabled(false);
|
|
m_lapButton->setEnabled(false);
|
|
cal->setEnabled(false);
|
|
loadUp->setEnabled(false);
|
|
loadDown->setEnabled(false);
|
|
intensitySlider->setEnabled(false);
|
|
return;
|
|
}
|
|
|
|
// connected, but not running
|
|
if ((status&RT_CONNECTED) && ((status&RT_RUNNING) == 0)) {
|
|
m_connectButton->setIcon(connectedIcon);
|
|
m_connectButton->setEnabled(true);
|
|
m_playButton->setEnabled(true);
|
|
m_stopButton->setEnabled(false);
|
|
m_forwardButton->setEnabled(false);
|
|
m_rewindButton->setEnabled(false);
|
|
m_lapButton->setEnabled(false);
|
|
cal->setEnabled(false);
|
|
loadUp->setEnabled(false);
|
|
loadDown->setEnabled(false);
|
|
intensitySlider->setEnabled(false);
|
|
return;
|
|
}
|
|
|
|
// paused - important to check for paused before running
|
|
if (status&RT_PAUSED) {
|
|
m_connectButton->setIcon(connectedIcon);
|
|
m_connectButton->setEnabled(false);
|
|
m_playButton->setEnabled(true);
|
|
m_stopButton->setEnabled(true);
|
|
m_forwardButton->setEnabled(false);
|
|
m_rewindButton->setEnabled(false);
|
|
m_lapButton->setEnabled(false);
|
|
cal->setEnabled(false);
|
|
loadUp->setEnabled(false);
|
|
loadDown->setEnabled(false);
|
|
intensitySlider->setEnabled(false);
|
|
return;
|
|
}
|
|
|
|
// running & calibrating
|
|
if ((status&RT_CALIBRATING) && (status&RT_RUNNING)) {
|
|
m_connectButton->setIcon(connectedIcon);
|
|
m_connectButton->setEnabled(false);
|
|
m_playButton->setEnabled(false);
|
|
m_stopButton->setEnabled(true);
|
|
m_forwardButton->setEnabled(false);
|
|
m_rewindButton->setEnabled(false);
|
|
m_lapButton->setEnabled(false);
|
|
cal->setEnabled(true);
|
|
loadUp->setEnabled(false);
|
|
loadDown->setEnabled(false);
|
|
intensitySlider->setEnabled(false);
|
|
return;
|
|
}
|
|
|
|
// running
|
|
if (status&RT_RUNNING) {
|
|
m_connectButton->setIcon(connectedIcon);
|
|
m_connectButton->setEnabled(false);
|
|
m_playButton->setEnabled(true);
|
|
m_stopButton->setEnabled(true);
|
|
m_forwardButton->setEnabled(true);
|
|
m_rewindButton->setEnabled(true);
|
|
m_lapButton->setEnabled(true);
|
|
cal->setEnabled(true);
|
|
loadUp->setEnabled(true);
|
|
loadDown->setEnabled(true);
|
|
intensitySlider->setEnabled(true);
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
void TrainBottom::setNotification(QString msg, int timeout)
|
|
{
|
|
if (timeout > 0) {
|
|
notificationTimer->setInterval(timeout * 1000);
|
|
notificationTimer->setSingleShot(true);
|
|
notificationTimer->start();
|
|
} else {
|
|
// stop any running timer
|
|
notificationTimer->stop();
|
|
}
|
|
|
|
notificationText->clear();
|
|
notificationText->setPlainText(msg);
|
|
}
|
|
|
|
void TrainBottom::clearNotification(void)
|
|
{
|
|
notificationText->clear();
|
|
}
|