Falkon Develop
Cross-platform Qt-based web browser
stylehelper.cpp
Go to the documentation of this file.
1/**************************************************************************
2**
3** This file is part of Qt Creator
4**
5** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
6**
7** Contact: Nokia Corporation (qt-info@nokia.com)
8**
9** Commercial Usage
10**
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17**
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** If you are unsure which license is appropriate for your use, please
26** contact the sales department at http://qt.nokia.com/contact.
27**
28**************************************************************************/
29
30#include "stylehelper.h"
31
32#include <QPixmapCache>
33#include <QWidget>
34#include <QtCore/QRect>
35#include <QPainter>
36#include <QApplication>
37#include <QPalette>
38#include <QStyleOption>
39#include <QtCore/QObject>
40
41// Clamps float color values within (0, 255)
42static int clamp(float x)
43{
44 const int val = x > 255 ? 255 : static_cast<int>(x);
45 return val < 0 ? 0 : val;
46}
47
48namespace Utils
49{
50
52{
53#if defined(Q_OS_MACOS)
54 return 10;
55#else
56 return 7.5;
57#endif
58}
59
60QColor StyleHelper::panelTextColor(bool lightColored)
61{
62 if (!lightColored) {
63 return Qt::white;
64 }
65 else {
66 return Qt::black;
67 }
68}
69
70// Invalid by default, setBaseColor needs to be called at least once
71QColor StyleHelper::m_baseColor;
72QColor StyleHelper::m_requestedBaseColor;
73
74QColor StyleHelper::baseColor(bool lightColored)
75{
76 if (!lightColored) {
77 return m_baseColor;
78 }
79 else {
80 return m_baseColor.lighter(230);
81 }
82}
83
84QColor StyleHelper::highlightColor(bool lightColored)
85{
86 QColor result = baseColor(lightColored);
87 if (!lightColored)
88 result.setHsv(result.hue(),
89 clamp(result.saturation()),
90 clamp(result.value() * 1.16));
91 else
92 result.setHsv(result.hue(),
93 clamp(result.saturation()),
94 clamp(result.value() * 1.06));
95 return result;
96}
97
98QColor StyleHelper::shadowColor(bool lightColored)
99{
100 QColor result = baseColor(lightColored);
101 result.setHsv(result.hue(),
102 clamp(result.saturation() * 1.1),
103 clamp(result.value() * 0.70));
104 return result;
105}
106
107QColor StyleHelper::borderColor(bool lightColored)
108{
109 QColor result = baseColor(lightColored);
110 result.setHsv(result.hue(),
111 result.saturation(),
112 result.value() / 2);
113 return result;
114}
115
116// We try to ensure that the actual color used are within
117// reasonalbe bounds while generating the actual baseColor
118// from the users request.
119void StyleHelper::setBaseColor(const QColor &newcolor)
120{
121 m_requestedBaseColor = newcolor;
122
123 QColor color;
124 color.setHsv(newcolor.hue(),
125 newcolor.saturation() * 0.7,
126 64 + newcolor.value() / 3);
127
128 if (color.isValid() && color != m_baseColor) {
129 m_baseColor = color;
130
131 auto const l_topLevelWidgets = QApplication::topLevelWidgets();
132 for (QWidget* w : l_topLevelWidgets) {
133 w->update();
134 }
135 }
136}
137
138static void verticalGradientHelper(QPainter* p, const QRect &spanRect, const QRect &rect, bool lightColored)
139{
140 QColor highlight = StyleHelper::highlightColor(lightColored);
141 QColor shadow = StyleHelper::shadowColor(lightColored);
142 QLinearGradient grad(spanRect.topRight(), spanRect.topLeft());
143 grad.setColorAt(0, highlight.lighter(117));
144 grad.setColorAt(1, shadow.darker(109));
145 p->fillRect(rect, grad);
146
147 QColor light(255, 255, 255, 80);
148 p->setPen(light);
149 p->drawLine(rect.topRight() - QPoint(1, 0), rect.bottomRight() - QPoint(1, 0));
150 QColor dark(0, 0, 0, 90);
151 p->setPen(dark);
152 p->drawLine(rect.topLeft(), rect.bottomLeft());
153}
154
155void StyleHelper::verticalGradient(QPainter* painter, const QRect &spanRect, const QRect &clipRect, bool lightColored)
156{
158 QString key;
159 QColor keyColor = baseColor(lightColored);
160 key.asprintf("mh_vertical %d %d %d %d %d",
161 spanRect.width(), spanRect.height(), clipRect.width(),
162 clipRect.height(), keyColor.rgb());
163
164 QPixmap pixmap;
165 if (!QPixmapCache::find(key, &pixmap)) {
166 pixmap = QPixmap(clipRect.size());
167 QPainter p(&pixmap);
168 QRect rect(0, 0, clipRect.width(), clipRect.height());
169 verticalGradientHelper(&p, spanRect, rect, lightColored);
170 p.end();
171 QPixmapCache::insert(key, pixmap);
172 }
173
174 painter->drawPixmap(clipRect.topLeft(), pixmap);
175 }
176 else {
177 verticalGradientHelper(painter, spanRect, clipRect, lightColored);
178 }
179}
180
181// Draws a cached pixmap with shadow
182void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect,
183 QPainter* p, QIcon::Mode iconMode, int radius, const QColor &color, const QPoint &offset)
184{
185 QPixmap cache;
186 QString pixmapName = QSL("icon %0 %1 %2").arg(icon.cacheKey()).arg(iconMode).arg(rect.height());
187
188 if (!QPixmapCache::find(pixmapName, &cache)) {
189 QPixmap px = icon.pixmap(rect.size(), iconMode);
190 px.setDevicePixelRatio(qApp->devicePixelRatio());
191 cache = QPixmap(px.size() + QSize(radius * 2, radius * 2));
192 cache.setDevicePixelRatio(px.devicePixelRatioF());
193 cache.fill(Qt::transparent);
194
195 QPainter cachePainter(&cache);
196
197 // Draw shadow
198 QImage tmp(px.size() + QSize(radius * 2, radius * 2 + 1), QImage::Format_ARGB32_Premultiplied);
199 tmp.setDevicePixelRatio(px.devicePixelRatioF());
200 tmp.fill(Qt::transparent);
201
202 QPainter tmpPainter(&tmp);
203 tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
204 tmpPainter.drawPixmap(QPoint(radius, radius), px);
205 tmpPainter.end();
206
207 // blur the alpha channel
208 QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied);
209 blurred.fill(Qt::transparent);
210 QPainter blurPainter(&blurred);
211 qt_blurImage(&blurPainter, tmp, radius, false, true);
212 blurPainter.end();
213
214 tmp = blurred;
215
216 // blacken the image...
217 tmpPainter.begin(&tmp);
218 tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
219 tmpPainter.fillRect(tmp.rect(), color);
220 tmpPainter.end();
221
222 tmpPainter.begin(&tmp);
223 tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
224 tmpPainter.fillRect(tmp.rect(), color);
225 tmpPainter.end();
226
227 // draw the blurred drop shadow...
228 cachePainter.drawImage(QRect(0, 0, cache.rect().width() / cache.devicePixelRatioF(), cache.rect().height() / cache.devicePixelRatioF()), tmp);
229
230 // Draw the actual pixmap...
231 cachePainter.drawPixmap(QPoint(radius, radius) + offset, px);
232 QPixmapCache::insert(pixmapName, cache);
233 }
234
235 QRect targetRect = cache.rect();
236 targetRect.setWidth(cache.rect().width() / cache.devicePixelRatioF());
237 targetRect.setHeight(cache.rect().height() / cache.devicePixelRatioF());
238 targetRect.moveCenter(rect.center());
239 p->drawPixmap(targetRect.topLeft() - offset, cache);
240}
241
242} // namespace Utils
static void verticalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored=false)
static qreal sidebarFontSize()
Definition: stylehelper.cpp:51
static QColor baseColor(bool lightColored=false)
Definition: stylehelper.cpp:74
static QColor highlightColor(bool lightColored=false)
Definition: stylehelper.cpp:84
static QColor borderColor(bool lightColored=false)
static QColor shadowColor(bool lightColored=false)
Definition: stylehelper.cpp:98
static void setBaseColor(const QColor &color)
static bool usePixmapCache()
Definition: stylehelper.h:75
static QColor panelTextColor(bool lightColored=false)
Definition: stylehelper.cpp:60
static void drawIconWithShadow(const QIcon &icon, const QRect &rect, QPainter *p, QIcon::Mode iconMode, int radius=3, const QColor &color=QColor(0, 0, 0, 130), const QPoint &offset=QPoint(1, -2))
QColor light(const QColor &c, int value)
Definition: colors.cpp:184
#define QSL(x)
Definition: qzcommon.h:40
void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed=0)