mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-14 16:39:57 +00:00
467 lines
12 KiB
C++
467 lines
12 KiB
C++
/*
|
|
* Copyright (c) 2011 Mark Liversedge (liversedge@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 "ChartBar.h"
|
|
#include "GcScopeBar.h"
|
|
#include "DiaryWindow.h"
|
|
#include "DiarySidebar.h"
|
|
#include "Context.h"
|
|
#include "QtMacButton.h"
|
|
|
|
#include <QFontMetrics>
|
|
|
|
#ifdef Q_OS_MAC
|
|
static int spacing_=7;
|
|
#else
|
|
static int spacing_=4;
|
|
#endif
|
|
ChartBar::ChartBar(Context *context) : QWidget(context->mainWindow), context(context)
|
|
{
|
|
// left / right scroller icon
|
|
static QIcon leftIcon = iconFromPNG(":images/mac/left.png");
|
|
static QIcon rightIcon = iconFromPNG(":images/mac/right.png");
|
|
|
|
setContentsMargins(0,0,0,0);
|
|
|
|
// main layout
|
|
QHBoxLayout *mlayout = new QHBoxLayout(this);
|
|
mlayout->setSpacing(0);
|
|
mlayout->setContentsMargins(0,0,0,0);
|
|
|
|
// buttonBar Widget
|
|
buttonBar = new ButtonBar(this);
|
|
buttonBar->setFixedHeight(23);
|
|
buttonBar->setContentsMargins(0,0,0,0);
|
|
|
|
QHBoxLayout *vlayout = new QHBoxLayout(buttonBar);
|
|
vlayout->setSpacing(0);
|
|
vlayout->setContentsMargins(0,0,0,0);
|
|
|
|
layout = new QHBoxLayout;
|
|
layout->setSpacing(2);
|
|
layout->setContentsMargins(0,0,0,0);
|
|
vlayout->addLayout(layout);
|
|
vlayout->addStretch();
|
|
|
|
// scrollarea
|
|
scrollArea = new QScrollArea(this);
|
|
scrollArea->setAutoFillBackground(false);
|
|
scrollArea->setWidgetResizable(true);
|
|
scrollArea->setFrameStyle(QFrame::NoFrame);
|
|
scrollArea->setContentsMargins(0,0,0,0);
|
|
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
scrollArea->setWidget(buttonBar);
|
|
// scroll area turns it on .. we turn it off!
|
|
buttonBar->setAutoFillBackground(false);
|
|
|
|
// scroller buttons
|
|
left = new QToolButton(this);
|
|
left->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
|
left->setAutoFillBackground(false);
|
|
left->setFixedSize(20,20);
|
|
left->setIcon(leftIcon);
|
|
left->setIconSize(QSize(20,20));
|
|
left->setFocusPolicy(Qt::NoFocus);
|
|
mlayout->addWidget(left);
|
|
connect(left, SIGNAL(clicked()), this, SLOT(scrollLeft()));
|
|
|
|
// menu bar in the middle of the buttons
|
|
mlayout->addWidget(scrollArea);
|
|
|
|
right = new QToolButton(this);
|
|
right->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
|
right->setAutoFillBackground(false);
|
|
right->setFixedSize(20,20);
|
|
right->setIcon(rightIcon);
|
|
right->setIconSize(QSize(20,20));
|
|
right->setFocusPolicy(Qt::NoFocus);
|
|
mlayout->addWidget(right);
|
|
connect(right, SIGNAL(clicked()), this, SLOT(scrollRight()));
|
|
|
|
// spacer to make the menuButton on the right
|
|
QLabel *spacer = new QLabel("", this);
|
|
spacer->setAutoFillBackground(false);
|
|
spacer->setFixedHeight(20);
|
|
spacer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
|
mlayout->addWidget(spacer);
|
|
|
|
menuButton = new QToolButton(this);
|
|
menuButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
|
|
menuButton->setAutoFillBackground(false);
|
|
menuButton->setFixedSize(20,20);
|
|
menuButton->setIcon(iconFromPNG(":images/sidebar/extra.png"));
|
|
menuButton->setIconSize(QSize(10,10));
|
|
menuButton->setFocusPolicy(Qt::NoFocus);
|
|
mlayout->addWidget(menuButton);
|
|
//connect(p, SIGNAL(clicked()), action, SLOT(trigger()));
|
|
|
|
QFontMetrics fs(buttonFont);
|
|
setFixedHeight(fs.height()+spacing_);
|
|
scrollArea->setFixedHeight(fs.height()+spacing_);
|
|
buttonBar->setFixedHeight(fs.height()+spacing_);
|
|
|
|
signalMapper = new QSignalMapper(this); // maps each option
|
|
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(clicked(int)));
|
|
|
|
barMenu = new QMenu("Add");
|
|
chartMenu = barMenu->addMenu(tr("Add Chart"));
|
|
|
|
// menu
|
|
connect(menuButton, SIGNAL(clicked()), this, SLOT(menuPopup()));
|
|
connect(chartMenu, SIGNAL(aboutToShow()), this, SLOT(setChartMenu()));
|
|
connect(chartMenu, SIGNAL(triggered(QAction*)), context->mainWindow, SLOT(addChart(QAction*)));
|
|
|
|
// trap resize / mouse events
|
|
installEventFilter(this);
|
|
|
|
// appearance update
|
|
connect(context, SIGNAL(configChanged(qint32)), this, SLOT(configChanged(qint32)));
|
|
}
|
|
|
|
void
|
|
ChartBar::configChanged(qint32)
|
|
{
|
|
buttonFont = QFont();
|
|
QFontMetrics fs(buttonFont);
|
|
setFixedHeight(fs.height()+spacing_);
|
|
scrollArea->setFixedHeight(fs.height()+spacing_);
|
|
buttonBar->setFixedHeight(fs.height()+spacing_);
|
|
foreach(GcScopeButton *b, buttons) {
|
|
int width = fs.width(b->text);
|
|
b->setFont(buttonFont);
|
|
b->setFixedWidth(width+20);
|
|
b->setFixedHeight(fs.height()+2);
|
|
}
|
|
}
|
|
|
|
void
|
|
ChartBar::addWidget(QString title)
|
|
{
|
|
GcScopeButton *newbutton = new GcScopeButton(this);
|
|
newbutton->setText(title);
|
|
newbutton->setFont(buttonFont);
|
|
|
|
// make the right size
|
|
QFontMetrics fontMetric(buttonFont);
|
|
int width = fontMetric.width(title);
|
|
newbutton->setFixedWidth(width+20);
|
|
newbutton->setFixedHeight(fontMetric.height()+2);
|
|
|
|
// add to layout
|
|
layout->addWidget(newbutton);
|
|
buttons << newbutton;
|
|
|
|
// map signals
|
|
connect(newbutton, SIGNAL(clicked(bool)), signalMapper, SLOT(map()));
|
|
signalMapper->setMapping(newbutton, buttons.count()-1);
|
|
|
|
newbutton->installEventFilter(this);
|
|
|
|
// tidy up scrollers etc
|
|
tidy();
|
|
}
|
|
|
|
void
|
|
ChartBar::setChartMenu()
|
|
{
|
|
context->mainWindow->setChartMenu(chartMenu);
|
|
}
|
|
|
|
void
|
|
ChartBar::menuPopup()
|
|
{
|
|
// set the point for the menu and call below
|
|
barMenu->exec(this->mapToGlobal(QPoint(menuButton->pos().x(), menuButton->pos().y()+20)));
|
|
}
|
|
|
|
void
|
|
ChartBar::setText(int index, QString text)
|
|
{
|
|
buttons[index]->setText(text);
|
|
QFontMetrics fontMetric(buttonFont);
|
|
int width = fontMetric.width(text);
|
|
buttons[index]->setWidth(width+20);
|
|
|
|
tidy(); // still fit ?
|
|
}
|
|
|
|
// tidy up the scrollers on first show...
|
|
void
|
|
ChartBar::tidy()
|
|
{
|
|
// resize to button widths + 2px spacing
|
|
int width = 2;
|
|
foreach (GcScopeButton *button, buttons) {
|
|
width += button->geometry().width() + 2;
|
|
}
|
|
buttonBar->setMinimumWidth(width);
|
|
|
|
if (buttonBar->width() > scrollArea->width()) {
|
|
left->show(); right->show();
|
|
} else {
|
|
left->hide(); right->hide();
|
|
}
|
|
}
|
|
|
|
bool
|
|
ChartBar::eventFilter(QObject *object, QEvent *e)
|
|
{
|
|
// show/hide scrollers on resize event
|
|
if (object == this && e->type() == QEvent::Resize) {
|
|
|
|
// we do NOT move the position, we just show/hide
|
|
// the left and right scrollers
|
|
tidy();
|
|
}
|
|
|
|
// showing us - tidy up
|
|
if (object == this && e->type() == QEvent::Show) {
|
|
tidy();
|
|
}
|
|
|
|
// enter/leave we can track approximate mouse position and decide
|
|
// if we want to 'autoscroll'
|
|
if (e->type() == QEvent::Leave || e->type() == QEvent::Enter) {
|
|
tidy(); // tidy up anyway
|
|
|
|
// XXX for later, perhaps when drag/dropping
|
|
// we should try and be a little more fluid / animate ...
|
|
// which will probably mean using QScrollArea::ScrollContentsBy
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void
|
|
ChartBar::scrollRight()
|
|
{
|
|
// scroll to the right...
|
|
int w = buttonBar->width();
|
|
scrollArea->ensureVisible(w-10,0,10,10);
|
|
}
|
|
|
|
void
|
|
ChartBar::scrollLeft()
|
|
{
|
|
// scroll to the left
|
|
scrollArea->ensureVisible(0,0,10,10);
|
|
}
|
|
|
|
void
|
|
ChartBar::clear()
|
|
{
|
|
foreach(GcScopeButton *button, buttons) {
|
|
layout->removeWidget(button);
|
|
delete button;
|
|
}
|
|
buttons.clear();
|
|
}
|
|
|
|
void
|
|
ChartBar::removeWidget(int index)
|
|
{
|
|
layout->removeWidget(buttons[index]);
|
|
delete buttons[index];
|
|
buttons.remove(index);
|
|
|
|
// reset mappings
|
|
for (int i=0; i<buttons.count(); i++)
|
|
signalMapper->setMapping(buttons[i], i);
|
|
|
|
}
|
|
|
|
void
|
|
ChartBar::setCurrentIndex(int index)
|
|
{
|
|
clicked(index);
|
|
}
|
|
|
|
void
|
|
ChartBar::clicked(int index)
|
|
{
|
|
setUpdatesEnabled(false);
|
|
// set selected
|
|
for(int i=0; i<buttons.count(); i++) {
|
|
buttons[i]->setChecked(i == index);
|
|
}
|
|
setUpdatesEnabled(true);
|
|
emit currentIndexChanged(index);
|
|
}
|
|
|
|
|
|
#if 0
|
|
ChartBar::setHighlighted()
|
|
{
|
|
if (context->isfiltered) {
|
|
searchLabel->setHighlighted(true);
|
|
searchLabel->show();
|
|
#ifndef Q_OS_MAC
|
|
home->setHighlighted(true);
|
|
anal->setHighlighted(true);
|
|
#ifdef GC_HAVE_ICAL
|
|
diary->setHighlighted(true);
|
|
#endif
|
|
#endif
|
|
} else {
|
|
searchLabel->setHighlighted(false);
|
|
searchLabel->hide();
|
|
#ifndef Q_OS_MAC
|
|
home->setHighlighted(false);
|
|
anal->setHighlighted(false);
|
|
#ifdef GC_HAVE_ICAL
|
|
diary->setHighlighted(false);
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
ChartBar::~ChartBar()
|
|
{
|
|
}
|
|
|
|
void
|
|
ChartBar::paintEvent (QPaintEvent *event)
|
|
{
|
|
// paint the darn thing!
|
|
paintBackground(event);
|
|
QWidget::paintEvent(event);
|
|
}
|
|
|
|
// paint is the same as sidebar
|
|
void
|
|
ChartBar::paintBackground(QPaintEvent *)
|
|
{
|
|
// setup a painter and the area to paint
|
|
QPainter painter(this);
|
|
|
|
painter.save();
|
|
QRect all(0,0,width(),height());
|
|
|
|
// linear gradients
|
|
QLinearGradient active = GCColor::linearGradient(23, true);
|
|
QLinearGradient inactive = GCColor::linearGradient(23, false);
|
|
|
|
// fill with a linear gradient
|
|
painter.setPen(Qt::NoPen);
|
|
painter.fillRect(all, QColor(Qt::white));
|
|
painter.fillRect(all, isActiveWindow() ? active : inactive);
|
|
|
|
if (!GCColor::isFlat()) {
|
|
QPen black(QColor(100,100,100,200));
|
|
painter.setPen(black);
|
|
painter.drawLine(0,height()-1, width()-1, height()-1);
|
|
|
|
QPen gray(QColor(230,230,230));
|
|
painter.setPen(gray);
|
|
painter.drawLine(0,0, width()-1, 0);
|
|
}
|
|
|
|
painter.restore();
|
|
}
|
|
|
|
void
|
|
ButtonBar::paintEvent(QPaintEvent *event)
|
|
{
|
|
// paint the darn thing!
|
|
paintBackground(event);
|
|
QWidget::paintEvent(event);
|
|
}
|
|
|
|
// paint is the same as sidebar
|
|
void
|
|
ButtonBar::paintBackground(QPaintEvent *)
|
|
{
|
|
// setup a painter and the area to paint
|
|
QPainter painter(this);
|
|
|
|
painter.save();
|
|
QRect all(0,0,width(),height());
|
|
|
|
// linear gradients
|
|
QLinearGradient active = GCColor::linearGradient(23, true);
|
|
QLinearGradient inactive = GCColor::linearGradient(23, false);
|
|
|
|
// fill with a linear gradient
|
|
painter.setPen(Qt::NoPen);
|
|
painter.fillRect(all, QColor(Qt::white));
|
|
painter.fillRect(all, isActiveWindow() ? active : inactive);
|
|
|
|
if (!GCColor::isFlat()) {
|
|
QPen black(QColor(100,100,100,200));
|
|
painter.setPen(black);
|
|
painter.drawLine(0,height()-1, width()-1, height()-1);
|
|
|
|
QPen gray(QColor(230,230,230));
|
|
painter.setPen(gray);
|
|
painter.drawLine(0,0, width()-1, 0);
|
|
}
|
|
|
|
painter.restore();
|
|
}
|
|
|
|
#if 0
|
|
int
|
|
ChartBar::selected()
|
|
{
|
|
if (home->isChecked()) return 0;
|
|
#ifdef GC_HAVE_ICAL
|
|
if (diary->isChecked()) return 1;
|
|
if (anal->isChecked()) return 2;
|
|
if (train->isChecked()) return 3;
|
|
#else
|
|
if (anal->isChecked()) return 1;
|
|
if (train->isChecked()) return 2;
|
|
#endif
|
|
|
|
// never gets here - shutup compiler
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
ChartBar::setSelected(int index)
|
|
{
|
|
// we're already there
|
|
if (index == selected()) return;
|
|
|
|
// mainwindow wants to tell us to switch to a selection
|
|
home->setChecked(false);
|
|
#ifdef GC_HAVE_ICAL
|
|
diary->setChecked(false);
|
|
#endif
|
|
anal->setChecked(false);
|
|
train->setChecked(false);
|
|
|
|
#ifdef GC_HAVE_ICAL
|
|
switch (index) {
|
|
case 0 : home->setChecked(true); break;
|
|
case 1 : diary->setChecked(true); break;
|
|
case 2 : anal->setChecked(true); break;
|
|
case 3 : train->setChecked(true); break;
|
|
}
|
|
#else
|
|
switch (index) {
|
|
case 0 : home->setChecked(true); break;
|
|
case 1 : anal->setChecked(true); break;
|
|
case 2 : train->setChecked(true); break;
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|