mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
.. akin to the NSImage 'template' function we now pre-process the GcSplitter icons to get a shaded and embossed look. Its a bit clunky code, but its only run at startup.
435 lines
12 KiB
C++
435 lines
12 KiB
C++
/*
|
|
* Copyright (c) 2013 Damien Grauser (Damien.Grauser@pev-geneve.ch)
|
|
*
|
|
* 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 "GcSideBarItem.h"
|
|
#include "GcCalendar.h"
|
|
|
|
QIcon iconFromPNG(QString filename)
|
|
{
|
|
QImage pngImage;
|
|
pngImage.load(filename);
|
|
|
|
// use muted dark gray color
|
|
QImage gray8 = pngImage.convertToFormat(QImage::Format_Indexed8);
|
|
QImage white8 = pngImage.convertToFormat(QImage::Format_Indexed8);
|
|
gray8.setColor(0, QColor(80,80,80, 255).rgb());
|
|
white8.setColor(0, QColor(255,255,255, 100).rgb());
|
|
|
|
// now convert to a format we can paint with!
|
|
QImage white = white8.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
|
QImage gray = gray8.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
|
|
|
QPainter painter;
|
|
painter.begin(&white);
|
|
painter.setBackgroundMode(Qt::TransparentMode);
|
|
painter.drawImage(0,-1, gray);
|
|
painter.end();
|
|
|
|
QIcon icon(QPixmap::fromImage(white));
|
|
return icon;
|
|
}
|
|
|
|
GcSplitter::GcSplitter(Qt::Orientation orientation, QWidget *parent) : QWidget(parent)
|
|
{
|
|
|
|
setContentsMargins(0,0,0,0);
|
|
|
|
control = new GcSplitterControl(this);
|
|
|
|
splitter = new GcSubSplitter(orientation, control, this);
|
|
splitter->setHandleWidth(23);
|
|
splitter->setFrameStyle(QFrame::NoFrame);
|
|
splitter->setContentsMargins(0,0,0,0);
|
|
splitter->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
|
|
|
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
|
layout->setSpacing(0);
|
|
layout->setAlignment(Qt::AlignBottom);
|
|
layout->setContentsMargins(0,0,0,0);
|
|
layout->addWidget(splitter);
|
|
layout->addWidget(control);
|
|
|
|
connect(splitter,SIGNAL(splitterMoved(int,int)), this, SLOT(subSplitterMoved(int,int)));
|
|
}
|
|
|
|
void
|
|
GcSplitter::prepare(QString cyclist, QString name)
|
|
{
|
|
this->name = name;
|
|
this->cyclist = cyclist;
|
|
|
|
// get saved state
|
|
QString statesetting = QString("splitter/%1/sizes").arg(name);
|
|
QVariant sizes = appsettings->cvalue(cyclist, statesetting);
|
|
if (sizes != QVariant()) {
|
|
splitter->restoreState(sizes.toByteArray());
|
|
splitter->setOpaqueResize(true); // redraw when released, snappier UI
|
|
}
|
|
|
|
// should we hide / show each widget?
|
|
for(int i=0; i<splitter->count(); i++) {
|
|
QString hidesetting = QString("splitter/%1/hide/%2").arg(name).arg(i);
|
|
QVariant hidden = appsettings->cvalue(cyclist, hidesetting);
|
|
if (i && hidden != QVariant()) {
|
|
if (hidden.toBool() == true) {
|
|
splitter->widget(i)->hide();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
GcSplitter::saveSettings()
|
|
{
|
|
// get saved state
|
|
QString statesetting = QString("splitter/%1/sizes").arg(name);
|
|
appsettings->setCValue(cyclist, statesetting, splitter->saveState());
|
|
|
|
// should we hide / show each widget?
|
|
for(int i=0; i<splitter->count(); i++) {
|
|
QString hidesetting = QString("splitter/%1/hide/%2").arg(name).arg(i);
|
|
appsettings->setCValue(cyclist, hidesetting, QVariant(splitter->widget(i)->isHidden()));
|
|
}
|
|
}
|
|
|
|
void
|
|
GcSplitter::setOpaqueResize(bool opaque)
|
|
{
|
|
return splitter->setOpaqueResize(opaque);
|
|
}
|
|
|
|
QList<int>
|
|
GcSplitter::sizes() const
|
|
{
|
|
return splitter->sizes();
|
|
}
|
|
|
|
void
|
|
GcSplitter::setSizes(const QList<int> &list)
|
|
{
|
|
return splitter->setSizes(list);
|
|
}
|
|
|
|
QByteArray
|
|
GcSplitter::saveState() const
|
|
{
|
|
return splitter->saveState();
|
|
}
|
|
|
|
bool
|
|
GcSplitter::restoreState(const QByteArray &state)
|
|
{
|
|
return splitter->restoreState(state);
|
|
}
|
|
|
|
void
|
|
GcSplitter::subSplitterMoved(int pos, int index)
|
|
{
|
|
saveSettings();
|
|
emit splitterMoved(pos, index);
|
|
}
|
|
|
|
void
|
|
GcSplitter::addWidget(QWidget *widget)
|
|
{
|
|
splitter->addWidget(widget);
|
|
}
|
|
|
|
void
|
|
GcSplitter::insertWidget(int index, QWidget *widget)
|
|
{
|
|
splitter->insertWidget(index, widget);
|
|
}
|
|
|
|
GcSubSplitter::GcSubSplitter(Qt::Orientation orientation, GcSplitterControl *control, GcSplitter *parent) : QSplitter(orientation, parent), control(control), gcSplitter (parent)
|
|
{
|
|
_insertedWidget = NULL;
|
|
|
|
// we add a fake widget to ensure the first real widget
|
|
// that is added has a handle (even though it cannot be moved)
|
|
QLabel *fake = new QLabel("fake");
|
|
fake->setFixedHeight(0);
|
|
setHandleWidth(0);
|
|
QSplitter::addWidget(fake);
|
|
//setStretchFactor(0,0);
|
|
}
|
|
|
|
void
|
|
GcSubSplitter::addWidget(QWidget *widget)
|
|
{
|
|
_insertedWidget = widget;
|
|
QSplitter::addWidget(widget);
|
|
//setStretchFactor(indexOf(widget), 1);
|
|
}
|
|
|
|
void
|
|
GcSubSplitter::insertWidget(int index, QWidget *widget)
|
|
{
|
|
_insertedWidget = widget;
|
|
QSplitter::insertWidget(index, widget);
|
|
}
|
|
|
|
QSplitterHandle*
|
|
GcSubSplitter::createHandle()
|
|
{
|
|
if(_insertedWidget != 0) {
|
|
GcSplitterItem* _item = dynamic_cast<GcSplitterItem*>(_insertedWidget);
|
|
if(_item != 0) {
|
|
_item->splitterHandle = new GcSplitterHandle(_item->title, _item, orientation(), this);
|
|
_item->splitterHandle->addActions(_item->actions());
|
|
_item->controlAction = new QAction(_item->icon, _item->title, this);
|
|
_item->controlAction->setStatusTip(_item->title);
|
|
control->addAction(_item->controlAction);
|
|
|
|
connect(_item->controlAction, SIGNAL(triggered(void)), _item, SLOT(selectHandle(void)));
|
|
connect(_item->controlAction, SIGNAL(triggered(void)), gcSplitter, SLOT(saveSettings()));
|
|
return _item->splitterHandle;
|
|
}
|
|
}
|
|
|
|
return QSplitter::createHandle();
|
|
}
|
|
|
|
GcSplitterHandle::GcSplitterHandle(QString title, GcSplitterItem *widget, Qt::Orientation orientation, GcSubSplitter *parent) : QSplitterHandle(orientation, parent), widget(widget), title(title)
|
|
{
|
|
setContentsMargins(0,0,0,0);
|
|
setFixedHeight(23);
|
|
|
|
gcSplitter = parent;
|
|
|
|
titleLayout = new QHBoxLayout(this);
|
|
titleLayout->setContentsMargins(0,0,0,0);
|
|
titleLayout->setSpacing(2);
|
|
|
|
titleLabel = new GcLabel(title, this);
|
|
titleLabel->setXOff(1);
|
|
|
|
QFont font;
|
|
#ifdef Q_OS_MAC
|
|
titleLabel->setFixedHeight(16);
|
|
titleLabel->setYOff(2);
|
|
font.setFamily("Lucida Grande");
|
|
font.setPointSize(11);
|
|
#else
|
|
titleLabel->setYOff(2);
|
|
font.setFamily("Helvetica");
|
|
font.setPointSize(10);
|
|
#endif
|
|
font.setWeight(QFont::Black);
|
|
titleLabel->setFont(font);
|
|
|
|
showHide = new QPushButton(this);
|
|
showHide->setStyleSheet("QPushButton {color : blue;background: transparent}");
|
|
showHide->setFixedWidth(16);
|
|
state = true;
|
|
//showHideClicked();
|
|
//titleLayout->addWidget(showHide);
|
|
//connect(showHide, SIGNAL(clicked(bool)), this, SLOT(showHideClicked()));
|
|
|
|
titleLayout->addSpacing(10);
|
|
|
|
titleLayout->addWidget(titleLabel);
|
|
titleLayout->addStretch();
|
|
|
|
titleToolbar = new QToolBar(this);
|
|
#ifndef Q_OS_MAC
|
|
titleToolbar->setFixedHeight(23);
|
|
#else
|
|
titleToolbar->setFixedHeight(10);
|
|
#endif
|
|
titleToolbar->setIconSize(QSize(8,8));
|
|
titleToolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
|
|
|
titleLayout->addWidget(titleToolbar);
|
|
|
|
setCursor(Qt::ArrowCursor);
|
|
}
|
|
|
|
QSize
|
|
GcSplitterHandle::sizeHint() const
|
|
{
|
|
return QSize(200, 23);
|
|
}
|
|
|
|
GcSubSplitter*
|
|
GcSplitterHandle::splitter() const
|
|
{
|
|
return gcSplitter;
|
|
}
|
|
|
|
void
|
|
GcSplitterHandle::addAction(QAction *action)
|
|
{
|
|
titleToolbar->addAction(action);
|
|
}
|
|
|
|
void
|
|
GcSplitterHandle::addActions(QList<QAction*> actions)
|
|
{
|
|
titleToolbar->addActions(actions);
|
|
}
|
|
|
|
void
|
|
GcSplitterHandle::paintEvent(QPaintEvent *event)
|
|
{
|
|
// paint the darn thing!
|
|
paintBackground(event);
|
|
QWidget::paintEvent(event);
|
|
}
|
|
|
|
void
|
|
GcSplitterHandle::paintBackground(QPaintEvent *)
|
|
{
|
|
// setup a painter and the area to paint
|
|
QPainter painter(this);
|
|
|
|
painter.save();
|
|
QRect all(0,0,width(),height());
|
|
|
|
// fill with a linear gradient
|
|
#ifdef Q_OS_MAC
|
|
int shade = isActiveWindow() ? 178 : 225;
|
|
#else
|
|
int shade = isActiveWindow() ? 200 : 250;
|
|
#endif
|
|
QLinearGradient linearGradient(0, 0, 0, height());
|
|
linearGradient.setColorAt(0.0, QColor(shade,shade,shade, 100));
|
|
linearGradient.setColorAt(0.5, QColor(shade,shade,shade, 180));
|
|
linearGradient.setColorAt(1.0, QColor(shade,shade,shade, 255));
|
|
linearGradient.setSpread(QGradient::PadSpread);
|
|
painter.setPen(Qt::NoPen);
|
|
painter.fillRect(all, linearGradient);
|
|
|
|
QPen black(QColor(100,100,100,200));
|
|
painter.setPen(black);
|
|
painter.drawLine(0,height()-1, width()-1, height()-1);
|
|
painter.restore();
|
|
}
|
|
|
|
void
|
|
GcSplitterHandle::setExpanded(bool expanded)
|
|
{
|
|
|
|
state = expanded;
|
|
if (expanded == false) {
|
|
showHide->setIcon(widget->icon);//QIcon(*show));
|
|
titleLabel->setStyleSheet("QLabel { color: gray; }");
|
|
fullHeight = widget->height();
|
|
widget->setFixedHeight(0);
|
|
} else {
|
|
showHide->setIcon(widget->icon);//QIcon(*hide));
|
|
titleLabel->setStyleSheet("QLabel { color: black; }");
|
|
widget->setBaseSize(widget->width(), fullHeight);
|
|
widget->setMaximumSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX);
|
|
widget->setMinimumSize(0,0);
|
|
}
|
|
showHide->setChecked(false);
|
|
repaint();
|
|
}
|
|
|
|
void
|
|
GcSplitterHandle::showHideClicked()
|
|
{
|
|
state = !state;
|
|
setExpanded(state);
|
|
}
|
|
|
|
GcSplitterControl::GcSplitterControl(QWidget *parent) : QToolBar(parent)
|
|
{
|
|
setContentsMargins(0,0,0,0);
|
|
setFixedHeight(20);
|
|
setIconSize(QSize(14,14));
|
|
setToolButtonStyle(Qt::ToolButtonIconOnly);
|
|
setAutoFillBackground(false);
|
|
|
|
}
|
|
|
|
void
|
|
GcSplitterControl::paintEvent(QPaintEvent *event)
|
|
{
|
|
// paint the darn thing!
|
|
paintBackground(event);
|
|
//QToolBar::paintEvent(event);
|
|
}
|
|
|
|
void
|
|
GcSplitterControl::paintBackground(QPaintEvent *)
|
|
{
|
|
QRect all(0,0,width(),height());
|
|
|
|
// setup a painter and the area to paint
|
|
QPainter painter(this);
|
|
|
|
// fill with a linear gradient
|
|
#ifdef Q_OS_MAC
|
|
int shade = isActiveWindow() ? 178 : 225;
|
|
#else
|
|
int shade = isActiveWindow() ? 200 : 250;
|
|
#endif
|
|
QLinearGradient linearGradient(0, 0, 0, height());
|
|
linearGradient.setColorAt(0.0, QColor(shade,shade,shade, 100));
|
|
linearGradient.setColorAt(0.5, QColor(shade,shade,shade, 180));
|
|
linearGradient.setColorAt(1.0, QColor(shade,shade,shade, 255));
|
|
linearGradient.setSpread(QGradient::PadSpread);
|
|
painter.setPen(Qt::NoPen);
|
|
painter.fillRect(all, linearGradient);
|
|
}
|
|
|
|
void
|
|
GcSplitterControl::selectAction()
|
|
{
|
|
this->setVisible(!this->isVisible());
|
|
|
|
/*this->setBaseSize(width(), parentWidget()->height());
|
|
this->setMaximumSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX);*/
|
|
}
|
|
|
|
GcSplitterItem::GcSplitterItem(QString title, QIcon icon, QWidget *parent) : QWidget(parent), title(title), icon(icon)
|
|
{
|
|
setContentsMargins(0,0,0,0);
|
|
layout = new QVBoxLayout(this);
|
|
layout->setContentsMargins(0,0,0,0);
|
|
layout->setSpacing(0);
|
|
content = NULL;
|
|
//titleBar = new GcSideBarTitle(title, this);
|
|
//layout->addWidget(titleBar);
|
|
}
|
|
|
|
void
|
|
GcSplitterItem::addWidget(QWidget *p)
|
|
{
|
|
content = p;
|
|
//p->setContentsMargins(0,0,0,0);
|
|
layout->addWidget(p);
|
|
}
|
|
|
|
void
|
|
GcSplitterItem::selectHandle()
|
|
{
|
|
//splitterHandle->gcSplitter->setStretchFactor(splitterHandle->index, this->isVisible() ? 0 : 1);
|
|
this->setVisible(!this->isVisible());
|
|
controlAction->setChecked(this->isVisible());
|
|
/*this->setBaseSize(width(), parentWidget()->height());
|
|
this->setMaximumSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX);*/
|
|
}
|
|
|
|
GcSplitterItem::~GcSplitterItem()
|
|
{
|
|
}
|
|
|