mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00
274 lines
9.9 KiB
C++
274 lines
9.9 KiB
C++
/***************************************************************************
|
|
* Copyright (C) 2009 by Rafael Fernández López <ereslibre@kde.org> *
|
|
* *
|
|
* 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 "CategoryDrawer.h"
|
|
|
|
#include "MenuProxyModel.h"
|
|
|
|
#include <QPainter>
|
|
#include <QApplication>
|
|
#include <QStyleOption>
|
|
|
|
CategoryDrawer::CategoryDrawer()
|
|
{
|
|
setLeftMargin( 7 );
|
|
setRightMargin( 7 );
|
|
}
|
|
|
|
void CategoryDrawer::drawCategory(const QModelIndex &index,
|
|
int sortRole,
|
|
const QStyleOption &option,
|
|
QPainter *painter) const
|
|
{
|
|
Q_UNUSED( option )
|
|
Q_UNUSED( painter )
|
|
Q_UNUSED( sortRole )
|
|
|
|
painter->setRenderHint(QPainter::Antialiasing);
|
|
|
|
const QRect optRect = option.rect;
|
|
QFont font(QApplication::font());
|
|
font.setBold(true);
|
|
const QFontMetrics fontMetrics = QFontMetrics(font);
|
|
const int height = categoryHeight(index, option);
|
|
const bool leftToRight = painter->layoutDirection() == Qt::LeftToRight;
|
|
|
|
//BEGIN: decoration gradient
|
|
{
|
|
QPainterPath path(optRect.bottomLeft());
|
|
|
|
path.lineTo(QPoint(optRect.topLeft().x(), optRect.topLeft().y() - 3));
|
|
const QPointF topLeft(optRect.topLeft());
|
|
QRectF arc(topLeft, QSizeF(4, 4));
|
|
path.arcTo(arc, 180, -90);
|
|
path.lineTo(optRect.topRight());
|
|
path.lineTo(optRect.bottomRight());
|
|
path.lineTo(optRect.bottomLeft());
|
|
|
|
QColor window(option.palette.window().color());
|
|
const QColor base(option.palette.base().color());
|
|
|
|
window.setAlphaF(0.4);
|
|
|
|
QLinearGradient decoGradient1;
|
|
if (leftToRight) {
|
|
decoGradient1.setStart(optRect.topLeft());
|
|
decoGradient1.setFinalStop(optRect.bottomLeft());
|
|
} else {
|
|
decoGradient1.setStart(optRect.topRight());
|
|
decoGradient1.setFinalStop(optRect.bottomRight());
|
|
}
|
|
decoGradient1.setColorAt(0, window);
|
|
decoGradient1.setColorAt(1, Qt::transparent);
|
|
|
|
QLinearGradient decoGradient2;
|
|
if (leftToRight) {
|
|
decoGradient2.setStart(optRect.topLeft());
|
|
decoGradient2.setFinalStop(optRect.topRight());
|
|
} else {
|
|
decoGradient2.setStart(optRect.topRight());
|
|
decoGradient2.setFinalStop(optRect.topLeft());
|
|
}
|
|
decoGradient2.setColorAt(0, Qt::transparent);
|
|
decoGradient2.setColorAt(1, base);
|
|
|
|
painter->fillPath(path, decoGradient1);
|
|
painter->fillPath(path, decoGradient2);
|
|
}
|
|
//END: decoration gradient
|
|
|
|
{
|
|
QRect newOptRect(optRect);
|
|
|
|
if (leftToRight) {
|
|
newOptRect.translate(1, 1);
|
|
} else {
|
|
newOptRect.translate(-1, 1);
|
|
}
|
|
|
|
//BEGIN: inner top left corner
|
|
{
|
|
painter->save();
|
|
painter->setPen(option.palette.base().color());
|
|
QRectF arc;
|
|
if (leftToRight) {
|
|
const QPointF topLeft(newOptRect.topLeft());
|
|
arc = QRectF(topLeft, QSizeF(4, 4));
|
|
arc.translate(0.5, 0.5);
|
|
painter->drawArc(arc, 1440, 1440);
|
|
} else {
|
|
QPointF topRight(newOptRect.topRight());
|
|
topRight.rx() -= 4;
|
|
arc = QRectF(topRight, QSizeF(4, 4));
|
|
arc.translate(-0.5, 0.5);
|
|
painter->drawArc(arc, 0, 1440);
|
|
}
|
|
painter->restore();
|
|
}
|
|
//END: inner top left corner
|
|
|
|
//BEGIN: inner left vertical line
|
|
{
|
|
QPoint start;
|
|
QPoint verticalGradBottom;
|
|
if (leftToRight) {
|
|
start = newOptRect.topLeft();
|
|
verticalGradBottom = newOptRect.topLeft();
|
|
} else {
|
|
start = newOptRect.topRight();
|
|
verticalGradBottom = newOptRect.topRight();
|
|
}
|
|
start.ry() += 3;
|
|
verticalGradBottom.ry() += newOptRect.height() - 3;
|
|
QLinearGradient gradient(start, verticalGradBottom);
|
|
gradient.setColorAt(0, option.palette.base().color());
|
|
gradient.setColorAt(1, Qt::transparent);
|
|
painter->fillRect(QRect(start, QSize(1, newOptRect.height() - 3)), gradient);
|
|
}
|
|
//END: inner left vertical line
|
|
|
|
//BEGIN: inner horizontal line
|
|
{
|
|
QPoint start;
|
|
QPoint horizontalGradTop;
|
|
if (leftToRight) {
|
|
start = newOptRect.topLeft();
|
|
horizontalGradTop = newOptRect.topLeft();
|
|
start.rx() += 3;
|
|
horizontalGradTop.rx() += newOptRect.width() - 3;
|
|
} else {
|
|
start = newOptRect.topRight();
|
|
horizontalGradTop = newOptRect.topRight();
|
|
start.rx() -= 3;
|
|
horizontalGradTop.rx() -= newOptRect.width() - 3;
|
|
}
|
|
QLinearGradient gradient(start, horizontalGradTop);
|
|
gradient.setColorAt(0, option.palette.base().color());
|
|
gradient.setColorAt(1, Qt::transparent);
|
|
QSize rectSize;
|
|
if (leftToRight) {
|
|
rectSize = QSize(newOptRect.width() - 3, 1);
|
|
} else {
|
|
rectSize = QSize(-newOptRect.width() + 3, 1);
|
|
}
|
|
painter->fillRect(QRect(start, rectSize), gradient);
|
|
}
|
|
//END: inner horizontal line
|
|
}
|
|
|
|
QColor outlineColor = option.palette.text().color();
|
|
outlineColor.setAlphaF(0.35);
|
|
|
|
//BEGIN: top left corner
|
|
{
|
|
painter->save();
|
|
painter->setPen(outlineColor);
|
|
QRectF arc;
|
|
if (leftToRight) {
|
|
const QPointF topLeft(optRect.topLeft());
|
|
arc = QRectF(topLeft, QSizeF(4, 4));
|
|
arc.translate(0.5, 0.5);
|
|
painter->drawArc(arc, 1440, 1440);
|
|
} else {
|
|
QPointF topRight(optRect.topRight());
|
|
topRight.rx() -= 4;
|
|
arc = QRectF(topRight, QSizeF(4, 4));
|
|
arc.translate(-0.5, 0.5);
|
|
painter->drawArc(arc, 0, 1440);
|
|
}
|
|
painter->restore();
|
|
}
|
|
//END: top left corner
|
|
|
|
//BEGIN: left vertical line
|
|
{
|
|
QPoint start;
|
|
QPoint verticalGradBottom;
|
|
if (leftToRight) {
|
|
start = optRect.topLeft();
|
|
verticalGradBottom = optRect.topLeft();
|
|
} else {
|
|
start = optRect.topRight();
|
|
verticalGradBottom = optRect.topRight();
|
|
}
|
|
start.ry() += 3;
|
|
verticalGradBottom.ry() += optRect.height() - 3;
|
|
QLinearGradient gradient(start, verticalGradBottom);
|
|
gradient.setColorAt(0, outlineColor);
|
|
gradient.setColorAt(1, option.palette.base().color());
|
|
painter->fillRect(QRect(start, QSize(1, optRect.height() - 3)), gradient);
|
|
}
|
|
//END: left vertical line
|
|
|
|
//BEGIN: horizontal line
|
|
{
|
|
QPoint start;
|
|
QPoint horizontalGradTop;
|
|
if (leftToRight) {
|
|
start = optRect.topLeft();
|
|
horizontalGradTop = optRect.topLeft();
|
|
start.rx() += 3;
|
|
horizontalGradTop.rx() += optRect.width() - 3;
|
|
} else {
|
|
start = optRect.topRight();
|
|
horizontalGradTop = optRect.topRight();
|
|
start.rx() -= 3;
|
|
horizontalGradTop.rx() -= optRect.width() - 3;
|
|
}
|
|
QLinearGradient gradient(start, horizontalGradTop);
|
|
gradient.setColorAt(0, outlineColor);
|
|
gradient.setColorAt(1, option.palette.base().color());
|
|
QSize rectSize;
|
|
if (leftToRight) {
|
|
rectSize = QSize(optRect.width() - 3, 1);
|
|
} else {
|
|
rectSize = QSize(-optRect.width() + 3, 1);
|
|
}
|
|
painter->fillRect(QRect(start, rectSize), gradient);
|
|
}
|
|
//END: horizontal line
|
|
|
|
//BEGIN: draw text
|
|
{
|
|
const QString category = index.model()->data(index, KCategorizedSortFilterProxyModel::CategoryDisplayRole).toString();
|
|
QRect textRect = QRect(option.rect.topLeft(), QSize(option.rect.width() - 2 - 3 - 3, height));
|
|
textRect.setTop(textRect.top() + 2 + 3 /* corner */);
|
|
textRect.setLeft(textRect.left() + 2 + 3 /* corner */ + 3 /* a bit of margin */);
|
|
painter->save();
|
|
painter->setFont(font);
|
|
QColor penColor(option.palette.text().color());
|
|
penColor.setAlphaF(0.6);
|
|
painter->setPen(penColor);
|
|
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignTop, category);
|
|
painter->restore();
|
|
}
|
|
//END: draw text
|
|
}
|
|
|
|
int CategoryDrawer::categoryHeight(const QModelIndex &index, const QStyleOption &option) const
|
|
{
|
|
Q_UNUSED( index );
|
|
Q_UNUSED( option );
|
|
|
|
QFont font(QApplication::font());
|
|
font.setBold(true);
|
|
const QFontMetrics fontMetrics = QFontMetrics(font);
|
|
|
|
return fontMetrics.height() + 2 + 12 /* vertical spacing */;
|
|
}
|