Utils: Changed crumblepath to use qpainter instead of stylesheets

This commit is contained in:
Lasse Holmstedt
2010-08-02 17:02:53 +02:00
parent 118f253a38
commit ef57d20a67
11 changed files with 156 additions and 44 deletions

View File

@@ -28,11 +28,14 @@
**************************************************************************/ **************************************************************************/
#include "crumblepath.h" #include "crumblepath.h"
#include "stylehelper.h"
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QPushButton> #include <QPushButton>
#include <QStyle> #include <QStyle>
#include <QResizeEvent> #include <QResizeEvent>
#include <QPainter>
#include <QImage>
namespace Utils { namespace Utils {
@@ -49,69 +52,126 @@ public:
explicit CrumblePathButton(const QString &title, QWidget *parent = 0); explicit CrumblePathButton(const QString &title, QWidget *parent = 0);
void setSegmentType(int type); void setSegmentType(int type);
protected:
void paintEvent(QPaintEvent *);
void mouseMoveEvent(QMouseEvent *e);
void leaveEvent(QEvent *);
void mousePressEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
private: private:
static QString middleSegmentSheet(bool useLeftPadding); void tintImages();
static QString lastSegmentSheet(bool useLeftPadding);
private:
bool m_isHovering;
bool m_isPressed;
bool m_isEnd;
QColor m_baseColor;
QImage m_segment;
QImage m_segmentEnd;
QImage m_segmentSelected;
QImage m_segmentSelectedEnd;
QImage m_segmentHover;
QImage m_segmentHoverEnd;
QPoint m_textPos;
}; };
CrumblePathButton::CrumblePathButton(const QString &title, QWidget *parent) CrumblePathButton::CrumblePathButton(const QString &title, QWidget *parent)
: QPushButton(title, parent) : QPushButton(title, parent), m_isHovering(false), m_isPressed(false), m_isEnd(true)
{ {
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
setToolTip(title); setToolTip(title);
setMinimumHeight(24); setMinimumHeight(24);
setMaximumHeight(24); setMaximumHeight(24);
setStyleSheet(lastSegmentSheet(true)); setMouseTracking(true);
m_textPos.setX(18);
m_textPos.setY(height());
m_baseColor = StyleHelper::baseColor();
m_segment = QImage(":/utils/images/crumblepath-segment.png");
m_segmentSelected = QImage(":/utils/images/crumblepath-segment-selected.png");
m_segmentHover = QImage(":/utils/images/crumblepath-segment-hover.png");
m_segmentEnd = QImage(":/utils/images/crumblepath-segment-end.png");
m_segmentSelectedEnd = QImage(":/utils/images/crumblepath-segment-selected-end.png");
m_segmentHoverEnd = QImage(":/utils/images/crumblepath-segment-hover-end.png");
tintImages();
} }
QString CrumblePathButton::middleSegmentSheet(bool useLeftPadding) void CrumblePathButton::paintEvent(QPaintEvent *)
{ {
QString sheet = QString( QPainter p(this);
"QPushButton {" QRect geom(0, 0, geometry().width(), geometry().height());
"text-align: left;"
"color: #eeeeee;" if (StyleHelper::baseColor() != m_baseColor) {
"border-image: url(:/qml/images/segment.png) 0 12 0 2;" m_baseColor = StyleHelper::baseColor();
"border-width: 0 12px 0 2px;" tintImages();
"padding-left:%1px;" }
"}"
"QPushButton:hover {" if (m_isEnd) {
" border-image: url(:/qml/images/segment-hover.png) 0 12 0 2;" if (m_isPressed) {
"}" Utils::StyleHelper::drawCornerImage(m_segmentSelectedEnd, &p, geom, 2, 0, 2, 0);
"QPushButton:pressed {" } else if (m_isHovering) {
" border-image: url(:/qml/images/segment-selected.png) 0 12 0 2;" Utils::StyleHelper::drawCornerImage(m_segmentHoverEnd, &p, geom, 2, 0, 2, 0);
"}" } else {
).arg(useLeftPadding ? "18" : "4"); Utils::StyleHelper::drawCornerImage(m_segmentEnd, &p, geom, 2, 0, 2, 0);
return sheet; }
} else {
if (m_isPressed) {
Utils::StyleHelper::drawCornerImage(m_segmentSelected, &p, geom, 2, 0, 12, 0);
} else if (m_isHovering) {
Utils::StyleHelper::drawCornerImage(m_segmentHover, &p, geom, 2, 0, 12, 0);
} else {
Utils::StyleHelper::drawCornerImage(m_segment, &p, geom, 2, 0, 12, 0);
}
}
p.setPen(StyleHelper::panelTextColor());
p.drawText(QRectF(m_textPos.x(), 4, geom.width(), geom.height()), text());
} }
QString CrumblePathButton::lastSegmentSheet(bool useLeftPadding) void CrumblePathButton::tintImages()
{ {
QString sheet = QString( StyleHelper::tintImage(m_segmentEnd, m_baseColor);
"QPushButton {" StyleHelper::tintImage(m_segmentSelectedEnd, m_baseColor);
"text-align: left;" StyleHelper::tintImage(m_segmentHoverEnd, m_baseColor);
"color: #eeeeee;" StyleHelper::tintImage(m_segmentSelected, m_baseColor);
"border-image: url(:/qml/images/segment-end.png) 0 2 0 2;" StyleHelper::tintImage(m_segmentHover, m_baseColor);
"border-width: 0 2px 0 2px;" StyleHelper::tintImage(m_segment, m_baseColor);
"padding-left:%1px;" }
"}"
"QPushButton:hover {" void CrumblePathButton::leaveEvent(QEvent *e)
" border-image: url(:/qml/images/segment-hover-end.png) 0 2 0 2;" {
"}" QPushButton::leaveEvent(e);
"QPushButton:pressed {" m_isHovering = false;
" border-image: url(:/qml/images/segment-selected-end.png) 0 2 0 2;" update();
"}" }
).arg(useLeftPadding ? "18" : "4");
return sheet; void CrumblePathButton::mouseMoveEvent(QMouseEvent *e)
{
QPushButton::mouseMoveEvent(e);
m_isHovering = true;
update();
}
void CrumblePathButton::mousePressEvent(QMouseEvent *e)
{
QPushButton::mousePressEvent(e);
m_isPressed = true;
update();
}
void CrumblePathButton::mouseReleaseEvent(QMouseEvent *e)
{
QPushButton::mouseReleaseEvent(e);
m_isPressed = false;
update();
} }
void CrumblePathButton::setSegmentType(int type) void CrumblePathButton::setSegmentType(int type)
{ {
bool useLeftPadding = !(type & FirstSegment); bool useLeftPadding = !(type & FirstSegment);
if (type & LastSegment) { m_isEnd = (type & LastSegment);
setStyleSheet(lastSegmentSheet(useLeftPadding)); m_textPos.setX(useLeftPadding ? 18 : 4);
} else if (type & MiddleSegment) {
setStyleSheet(middleSegmentSheet(useLeftPadding));
}
} }
// //
@@ -120,11 +180,13 @@ void CrumblePathButton::setSegmentType(int type)
CrumblePath::CrumblePath(QWidget *parent) : CrumblePath::CrumblePath(QWidget *parent) :
QWidget(parent), m_background(new QWidget(this)) QWidget(parent), m_background(new QWidget(this))
{ {
m_baseColor = StyleHelper::baseColor();
setMinimumHeight(25); setMinimumHeight(25);
setMaximumHeight(25); setMaximumHeight(25);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
m_background->setStyleSheet("QWidget { background-color:#2d2d2d;}"); setBackgroundStyle();
m_background->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); m_background->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
} }
@@ -134,6 +196,11 @@ CrumblePath::~CrumblePath()
m_buttons.clear(); m_buttons.clear();
} }
void CrumblePath::setBackgroundStyle()
{
m_background->setStyleSheet("QWidget { background-color:" + m_baseColor.name() + ";}");
}
void CrumblePath::pushElement(const QString &title) void CrumblePath::pushElement(const QString &title)
{ {
CrumblePathButton *newButton = new CrumblePathButton(title, this); CrumblePathButton *newButton = new CrumblePathButton(title, this);
@@ -248,4 +315,14 @@ void CrumblePath::mapContextMenuRequestToIndex()
} }
} }
void CrumblePath::paintEvent(QPaintEvent *event)
{
if (StyleHelper::baseColor() != m_baseColor) {
m_baseColor = StyleHelper::baseColor();
setBackgroundStyle();
}
QWidget::paintEvent(event);
}
} // namespace QmlViewer } // namespace QmlViewer

View File

@@ -58,6 +58,7 @@ signals:
protected: protected:
void resizeEvent(QResizeEvent *); void resizeEvent(QResizeEvent *);
void paintEvent(QPaintEvent *);
private slots: private slots:
void mapClickToIndex(); void mapClickToIndex();
@@ -65,8 +66,10 @@ private slots:
private: private:
void resizeButtons(); void resizeButtons();
void setBackgroundStyle();
private: private:
QColor m_baseColor;
QList<CrumblePathButton*> m_buttons; QList<CrumblePathButton*> m_buttons;
QWidget *m_background; QWidget *m_background;
}; };

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -479,4 +479,28 @@ void StyleHelper::drawCornerImage(const QImage &img, QPainter *painter, QRect re
} }
} }
// Tints an image with tintColor, while preserving alpha and lightness
void StyleHelper::tintImage(QImage &img, const QColor &tintColor)
{
QPainter p(&img);
p.setCompositionMode(QPainter::CompositionMode_Screen);
for (int x = 0; x < img.width(); ++x) {
for (int y = 0; y < img.height(); ++y) {
QRgb rgbColor = img.pixel(x, y);
int alpha = qAlpha(rgbColor);
QColor c = QColor(rgbColor);
if (alpha > 0) {
c.toHsl();
qreal l = c.lightnessF();
QColor newColor = QColor::fromHslF(tintColor.hslHueF(), tintColor.hslSaturationF(), l);
newColor.setAlpha(alpha);
img.setPixel(x, y, newColor.rgba());
}
}
}
}
} // namespace Utils } // namespace Utils

View File

@@ -88,6 +88,8 @@ public:
static void drawCornerImage(const QImage &img, QPainter *painter, QRect rect, static void drawCornerImage(const QImage &img, QPainter *painter, QRect rect,
int left = 0, int top = 0, int right = 0, int bottom = 0); int left = 0, int top = 0, int right = 0, int bottom = 0);
static void tintImage(QImage &img, const QColor &tintColor);
private: private:
static QColor m_baseColor; static QColor m_baseColor;
static QColor m_requestedBaseColor; static QColor m_requestedBaseColor;

View File

@@ -2,5 +2,11 @@
<qresource prefix="/utils"> <qresource prefix="/utils">
<file>images/removesubmitfield.png</file> <file>images/removesubmitfield.png</file>
<file>images/arrow.png</file> <file>images/arrow.png</file>
<file>images/crumblepath-segment.png</file>
<file>images/crumblepath-segment-end.png</file>
<file>images/crumblepath-segment-hover-end.png</file>
<file>images/crumblepath-segment-hover.png</file>
<file>images/crumblepath-segment-selected-end.png</file>
<file>images/crumblepath-segment-selected.png</file>
</qresource> </qresource>
</RCC> </RCC>