File indexing completed on 2024-05-12 04:57:49
0001 /************************************************************************** 0002 ** 0003 ** This file is part of Qt Creator 0004 ** 0005 ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). 0006 ** 0007 ** Contact: Nokia Corporation (qt-info@nokia.com) 0008 ** 0009 ** Commercial Usage 0010 ** 0011 ** Licensees holding valid Qt Commercial licenses may use this file in 0012 ** accordance with the Qt Commercial License Agreement provided with the 0013 ** Software or, alternatively, in accordance with the terms contained in 0014 ** a written agreement between you and Nokia. 0015 ** 0016 ** GNU Lesser General Public License Usage 0017 ** 0018 ** Alternatively, this file may be used under the terms of the GNU Lesser 0019 ** General Public License version 2.1 as published by the Free Software 0020 ** Foundation and appearing in the file LICENSE.LGPL included in the 0021 ** packaging of this file. Please review the following information to 0022 ** ensure the GNU Lesser General Public License version 2.1 requirements 0023 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 0024 ** 0025 ** If you are unsure which license is appropriate for your use, please 0026 ** contact the sales department at http://qt.nokia.com/contact. 0027 ** 0028 **************************************************************************/ 0029 0030 #include "stylehelper.h" 0031 0032 #include <QPixmapCache> 0033 #include <QWidget> 0034 #include <QtCore/QRect> 0035 #include <QPainter> 0036 #include <QApplication> 0037 #include <QPalette> 0038 #include <QStyleOption> 0039 #include <QtCore/QObject> 0040 0041 // Clamps float color values within (0, 255) 0042 static int clamp(float x) 0043 { 0044 const int val = x > 255 ? 255 : static_cast<int>(x); 0045 return val < 0 ? 0 : val; 0046 } 0047 0048 namespace Utils 0049 { 0050 0051 qreal StyleHelper::sidebarFontSize() 0052 { 0053 #if defined(Q_OS_MACOS) 0054 return 10; 0055 #else 0056 return 7.5; 0057 #endif 0058 } 0059 0060 QColor StyleHelper::panelTextColor(bool lightColored) 0061 { 0062 if (!lightColored) { 0063 return Qt::white; 0064 } 0065 else { 0066 return Qt::black; 0067 } 0068 } 0069 0070 // Invalid by default, setBaseColor needs to be called at least once 0071 QColor StyleHelper::m_baseColor; 0072 QColor StyleHelper::m_requestedBaseColor; 0073 0074 QColor StyleHelper::baseColor(bool lightColored) 0075 { 0076 if (!lightColored) { 0077 return m_baseColor; 0078 } 0079 else { 0080 return m_baseColor.lighter(230); 0081 } 0082 } 0083 0084 QColor StyleHelper::highlightColor(bool lightColored) 0085 { 0086 QColor result = baseColor(lightColored); 0087 if (!lightColored) 0088 result.setHsv(result.hue(), 0089 clamp(result.saturation()), 0090 clamp(result.value() * 1.16)); 0091 else 0092 result.setHsv(result.hue(), 0093 clamp(result.saturation()), 0094 clamp(result.value() * 1.06)); 0095 return result; 0096 } 0097 0098 QColor StyleHelper::shadowColor(bool lightColored) 0099 { 0100 QColor result = baseColor(lightColored); 0101 result.setHsv(result.hue(), 0102 clamp(result.saturation() * 1.1), 0103 clamp(result.value() * 0.70)); 0104 return result; 0105 } 0106 0107 QColor StyleHelper::borderColor(bool lightColored) 0108 { 0109 QColor result = baseColor(lightColored); 0110 result.setHsv(result.hue(), 0111 result.saturation(), 0112 result.value() / 2); 0113 return result; 0114 } 0115 0116 // We try to ensure that the actual color used are within 0117 // reasonalbe bounds while generating the actual baseColor 0118 // from the users request. 0119 void StyleHelper::setBaseColor(const QColor &newcolor) 0120 { 0121 m_requestedBaseColor = newcolor; 0122 0123 QColor color; 0124 color.setHsv(newcolor.hue(), 0125 newcolor.saturation() * 0.7, 0126 64 + newcolor.value() / 3); 0127 0128 if (color.isValid() && color != m_baseColor) { 0129 m_baseColor = color; 0130 0131 auto const l_topLevelWidgets = QApplication::topLevelWidgets(); 0132 for (QWidget* w : l_topLevelWidgets) { 0133 w->update(); 0134 } 0135 } 0136 } 0137 0138 static void verticalGradientHelper(QPainter* p, const QRect &spanRect, const QRect &rect, bool lightColored) 0139 { 0140 QColor highlight = StyleHelper::highlightColor(lightColored); 0141 QColor shadow = StyleHelper::shadowColor(lightColored); 0142 QLinearGradient grad(spanRect.topRight(), spanRect.topLeft()); 0143 grad.setColorAt(0, highlight.lighter(117)); 0144 grad.setColorAt(1, shadow.darker(109)); 0145 p->fillRect(rect, grad); 0146 0147 QColor light(255, 255, 255, 80); 0148 p->setPen(light); 0149 p->drawLine(rect.topRight() - QPoint(1, 0), rect.bottomRight() - QPoint(1, 0)); 0150 QColor dark(0, 0, 0, 90); 0151 p->setPen(dark); 0152 p->drawLine(rect.topLeft(), rect.bottomLeft()); 0153 } 0154 0155 void StyleHelper::verticalGradient(QPainter* painter, const QRect &spanRect, const QRect &clipRect, bool lightColored) 0156 { 0157 if (StyleHelper::usePixmapCache()) { 0158 QString key; 0159 QColor keyColor = baseColor(lightColored); 0160 key.asprintf("mh_vertical %d %d %d %d %d", 0161 spanRect.width(), spanRect.height(), clipRect.width(), 0162 clipRect.height(), keyColor.rgb()); 0163 0164 QPixmap pixmap; 0165 if (!QPixmapCache::find(key, &pixmap)) { 0166 pixmap = QPixmap(clipRect.size()); 0167 QPainter p(&pixmap); 0168 QRect rect(0, 0, clipRect.width(), clipRect.height()); 0169 verticalGradientHelper(&p, spanRect, rect, lightColored); 0170 p.end(); 0171 QPixmapCache::insert(key, pixmap); 0172 } 0173 0174 painter->drawPixmap(clipRect.topLeft(), pixmap); 0175 } 0176 else { 0177 verticalGradientHelper(painter, spanRect, clipRect, lightColored); 0178 } 0179 } 0180 0181 // Draws a cached pixmap with shadow 0182 void StyleHelper::drawIconWithShadow(const QIcon &icon, const QRect &rect, 0183 QPainter* p, QIcon::Mode iconMode, int radius, const QColor &color, const QPoint &offset) 0184 { 0185 QPixmap cache; 0186 QString pixmapName = QSL("icon %0 %1 %2").arg(icon.cacheKey()).arg(iconMode).arg(rect.height()); 0187 0188 if (!QPixmapCache::find(pixmapName, &cache)) { 0189 QPixmap px = icon.pixmap(rect.size(), iconMode); 0190 px.setDevicePixelRatio(qApp->devicePixelRatio()); 0191 cache = QPixmap(px.size() + QSize(radius * 2, radius * 2)); 0192 cache.setDevicePixelRatio(px.devicePixelRatioF()); 0193 cache.fill(Qt::transparent); 0194 0195 QPainter cachePainter(&cache); 0196 0197 // Draw shadow 0198 QImage tmp(px.size() + QSize(radius * 2, radius * 2 + 1), QImage::Format_ARGB32_Premultiplied); 0199 tmp.setDevicePixelRatio(px.devicePixelRatioF()); 0200 tmp.fill(Qt::transparent); 0201 0202 QPainter tmpPainter(&tmp); 0203 tmpPainter.setCompositionMode(QPainter::CompositionMode_Source); 0204 tmpPainter.drawPixmap(QPoint(radius, radius), px); 0205 tmpPainter.end(); 0206 0207 // blur the alpha channel 0208 QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied); 0209 blurred.fill(Qt::transparent); 0210 QPainter blurPainter(&blurred); 0211 qt_blurImage(&blurPainter, tmp, radius, false, true); 0212 blurPainter.end(); 0213 0214 tmp = blurred; 0215 0216 // blacken the image... 0217 tmpPainter.begin(&tmp); 0218 tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); 0219 tmpPainter.fillRect(tmp.rect(), color); 0220 tmpPainter.end(); 0221 0222 tmpPainter.begin(&tmp); 0223 tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); 0224 tmpPainter.fillRect(tmp.rect(), color); 0225 tmpPainter.end(); 0226 0227 // draw the blurred drop shadow... 0228 cachePainter.drawImage(QRect(0, 0, cache.rect().width() / cache.devicePixelRatioF(), cache.rect().height() / cache.devicePixelRatioF()), tmp); 0229 0230 // Draw the actual pixmap... 0231 cachePainter.drawPixmap(QPoint(radius, radius) + offset, px); 0232 QPixmapCache::insert(pixmapName, cache); 0233 } 0234 0235 QRect targetRect = cache.rect(); 0236 targetRect.setWidth(cache.rect().width() / cache.devicePixelRatioF()); 0237 targetRect.setHeight(cache.rect().height() / cache.devicePixelRatioF()); 0238 targetRect.moveCenter(rect.center()); 0239 p->drawPixmap(targetRect.topLeft() - offset, cache); 0240 } 0241 0242 } // namespace Utils