stylehelper.cpp 12.1 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2 3 4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11 12 13 14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18 19 20 21 22 23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** 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
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30 31 32 33
#include "stylehelper.h"

#include <QtGui/QPixmapCache>
#include <QtGui/QWidget>
34 35 36 37
#include <QtCore/QRect>
#include <QtGui/QPainter>
#include <QtGui/QApplication>
#include <QtGui/QPalette>
38 39
#include <QtGui/QStyleOption>
#include <QtCore/QObject>
con's avatar
con committed
40 41

// Clamps float color values within (0, 255)
hjk's avatar
hjk committed
42 43
static int clamp(float x)
{
con's avatar
con committed
44 45 46 47 48 49
    const int val = x > 255 ? 255 : static_cast<int>(x);
    return val < 0 ? 0 : val;
}

// Clamps float color values within (0, 255)
/*
hjk's avatar
hjk committed
50 51
static int range(float x, int min, int max)
{
con's avatar
con committed
52 53 54 55 56
    int val = x > max ? max : x;
    return val < min ? min : val;
}
*/

57 58
namespace Utils {

59 60 61 62 63 64 65 66 67 68
QColor StyleHelper::mergedColors(const QColor &colorA, const QColor &colorB, int factor)
{
    const int maxFactor = 100;
    QColor tmp = colorA;
    tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
    tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
    tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
    return tmp;
}

con's avatar
con committed
69 70
qreal StyleHelper::sidebarFontSize()
{
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
71
#if defined(Q_WS_MAC)
con's avatar
con committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
    return 9;
#else
    return 7.5;
#endif
}

QPalette StyleHelper::sidebarFontPalette(const QPalette &original)
{
    QPalette palette = original;
    palette.setColor(QPalette::Active, QPalette::Text, panelTextColor());
    palette.setColor(QPalette::Active, QPalette::WindowText, panelTextColor());
    palette.setColor(QPalette::Inactive, QPalette::Text, panelTextColor().darker());
    palette.setColor(QPalette::Inactive, QPalette::WindowText, panelTextColor().darker());
    return palette;
}

88
QColor StyleHelper::panelTextColor(bool lightColored)
con's avatar
con committed
89 90
{
    //qApp->palette().highlightedText().color();
91 92 93 94
    if (!lightColored)
        return Qt::white;
    else
        return Qt::black;
con's avatar
con committed
95 96 97 98
}

QColor StyleHelper::m_baseColor(0x666666);

99
QColor StyleHelper::baseColor(bool lightColored)
con's avatar
con committed
100
{
101 102 103 104
    if (!lightColored)
        return m_baseColor;
    else
        return m_baseColor.lighter(230);
con's avatar
con committed
105 106
}

107
QColor StyleHelper::highlightColor(bool lightColored)
con's avatar
con committed
108
{
109 110 111
    QColor result = baseColor(lightColored);
    if (!lightColored)
        result.setHsv(result.hue(),
con's avatar
con committed
112 113
                  clamp(result.saturation()),
                  clamp(result.value() * 1.16));
114 115 116 117
    else
        result.setHsv(result.hue(),
                  clamp(result.saturation()),
                  clamp(result.value() * 1.06));
con's avatar
con committed
118 119 120
    return result;
}

121
QColor StyleHelper::shadowColor(bool lightColored)
con's avatar
con committed
122
{
123
    QColor result = baseColor(lightColored);
con's avatar
con committed
124 125 126 127 128 129
    result.setHsv(result.hue(),
                  clamp(result.saturation() * 1.1),
                  clamp(result.value() * 0.70));
    return result;
}

130
QColor StyleHelper::borderColor(bool lightColored)
con's avatar
con committed
131
{
132
    QColor result = baseColor(lightColored);
con's avatar
con committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
    result.setHsv(result.hue(),
                  result.saturation(),
                  result.value() / 2);
    return result;
}

void StyleHelper::setBaseColor(const QColor &color)
{
    if (color.isValid() && color != m_baseColor) {
        m_baseColor = color;
        foreach (QWidget *w, QApplication::topLevelWidgets())
            w->update();
    }
}

148
static void verticalGradientHelper(QPainter *p, const QRect &spanRect, const QRect &rect, bool lightColored)
con's avatar
con committed
149
{
150 151 152
    QColor base = StyleHelper::baseColor(lightColored);
    QColor highlight = StyleHelper::highlightColor(lightColored);
    QColor shadow = StyleHelper::shadowColor(lightColored);
con's avatar
con committed
153
    QLinearGradient grad(spanRect.topRight(), spanRect.topLeft());
154
    grad.setColorAt(0, highlight);
con's avatar
con committed
155
    grad.setColorAt(0.301, base);
156
    grad.setColorAt(1, shadow);
con's avatar
con committed
157 158 159 160 161
    p->fillRect(rect, grad);

    QColor light(255, 255, 255, 80);
    p->setPen(light);
    p->drawLine(rect.topRight() - QPoint(1, 0), rect.bottomRight() - QPoint(1, 0));
162 163
}

164
void StyleHelper::verticalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored)
165 166 167
{
    if (StyleHelper::usePixmapCache()) {
        QString key;
168
        QColor keyColor = baseColor(lightColored);
169 170
        key.sprintf("mh_vertical %d %d %d %d %d",
            spanRect.width(), spanRect.height(), clipRect.width(),
171
            clipRect.height(), keyColor.rgb());;
172 173 174 175 176 177

        QPixmap pixmap;
        if (!QPixmapCache::find(key, pixmap)) {
            pixmap = QPixmap(clipRect.size());
            QPainter p(&pixmap);
            QRect rect(0, 0, clipRect.width(), clipRect.height());
178
            verticalGradientHelper(&p, spanRect, rect, lightColored);
179 180 181
            p.end();
            QPixmapCache::insert(key, pixmap);
        }
con's avatar
con committed
182 183

        painter->drawPixmap(clipRect.topLeft(), pixmap);
184
    } else {
185
        verticalGradientHelper(painter, spanRect, clipRect, lightColored);
con's avatar
con committed
186 187 188
    }
}

189
static void horizontalGradientHelper(QPainter *p, const QRect &spanRect, const
190
QRect &rect, bool lightColored)
con's avatar
con committed
191
{
192 193 194
    QColor base = StyleHelper::baseColor(lightColored);
    QColor highlight = StyleHelper::highlightColor(lightColored);
    QColor shadow = StyleHelper::shadowColor(lightColored);
con's avatar
con committed
195
    QLinearGradient grad(rect.topLeft(), rect.bottomLeft());
196
    grad.setColorAt(0, highlight.lighter(120));
197
    if (rect.height() == StyleHelper::navigationWidgetHeight()) {
198
        grad.setColorAt(0.4, highlight);
199 200
        grad.setColorAt(0.401, base);
    }
201
    grad.setColorAt(1, shadow);
con's avatar
con committed
202 203 204
    p->fillRect(rect, grad);

    QLinearGradient shadowGradient(spanRect.topLeft(), spanRect.topRight());
205 206 207 208 209 210 211 212 213
        shadowGradient.setColorAt(0, QColor(0, 0, 0, 30));
    QColor lighterHighlight;
    if (!lightColored)
        lighterHighlight = highlight.lighter(130);
    else
        lighterHighlight = highlight.lighter(90);
    lighterHighlight.setAlpha(100);
    shadowGradient.setColorAt(0.7, lighterHighlight);
        shadowGradient.setColorAt(1, QColor(0, 0, 0, 40));
con's avatar
con committed
214 215 216
    p->fillRect(rect, shadowGradient);
}

217
void StyleHelper::horizontalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored)
con's avatar
con committed
218
{
219 220
    if (StyleHelper::usePixmapCache()) {
        QString key;
221
        QColor keyColor = baseColor(lightColored);
222 223
        key.sprintf("mh_horizontal %d %d %d %d %d",
            spanRect.width(), spanRect.height(), clipRect.width(),
224
            clipRect.height(), keyColor.rgb());
225 226 227 228 229 230

        QPixmap pixmap;
        if (!QPixmapCache::find(key, pixmap)) {
            pixmap = QPixmap(clipRect.size());
            QPainter p(&pixmap);
            QRect rect = QRect(0, 0, clipRect.width(), clipRect.height());
231
            horizontalGradientHelper(&p, spanRect, rect, lightColored);
232 233 234 235 236 237 238
            p.end();
            QPixmapCache::insert(key, pixmap);
        }

        painter->drawPixmap(clipRect.topLeft(), pixmap);

    } else {
239
        horizontalGradientHelper(painter, spanRect, clipRect, lightColored);
con's avatar
con committed
240
    }
241
}
con's avatar
con committed
242

243 244
static void menuGradientHelper(QPainter *p, const QRect &spanRect, const QRect &rect)
{
con's avatar
con committed
245
    QLinearGradient grad(spanRect.topLeft(), spanRect.bottomLeft());
246
    QColor menuColor = StyleHelper::mergedColors(StyleHelper::baseColor(), QColor(244, 244, 244), 25);
con's avatar
con committed
247 248 249
    grad.setColorAt(0, menuColor.lighter(112));
    grad.setColorAt(1, menuColor);
    p->fillRect(rect, grad);
250 251
}

252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
void StyleHelper::drawArrow(QStyle::PrimitiveElement element, QPainter *painter, const QStyleOption *option)
{
    // From windowsstyle but modified to enable AA
    if (option->rect.width() <= 1 || option->rect.height() <= 1)
        return;

    QRect r = option->rect;
    int size = qMin(r.height(), r.width());
    QPixmap pixmap;
    QString pixmapName;
    pixmapName.sprintf("arrow-%s-%d-%d-%d-%lld",
                       "$qt_ia",
                       uint(option->state), element,
                       size, option->palette.cacheKey());
    if (!QPixmapCache::find(pixmapName, pixmap)) {
        int border = size/5;
        int sqsize = 2*(size/2);
        QImage image(sqsize, sqsize, QImage::Format_ARGB32);
        image.fill(Qt::transparent);
        QPainter imagePainter(&image);
        imagePainter.setRenderHint(QPainter::Antialiasing, true);
        imagePainter.translate(0.5, 0.5);
        QPolygon a;
        switch (element) {
            case QStyle::PE_IndicatorArrowUp:
                a.setPoints(3, border, sqsize/2,  sqsize/2, border,  sqsize - border, sqsize/2);
                break;
            case QStyle::PE_IndicatorArrowDown:
                a.setPoints(3, border, sqsize/2,  sqsize/2, sqsize - border,  sqsize - border, sqsize/2);
                break;
            case QStyle::PE_IndicatorArrowRight:
                a.setPoints(3, sqsize - border, sqsize/2,  sqsize/2, border,  sqsize/2, sqsize - border);
                break;
            case QStyle::PE_IndicatorArrowLeft:
                a.setPoints(3, border, sqsize/2,  sqsize/2, border,  sqsize/2, sqsize - border);
                break;
            default:
                break;
        }

        int bsx = 0;
        int bsy = 0;

        if (option->state & QStyle::State_Sunken) {
            bsx = qApp->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal);
            bsy = qApp->style()->pixelMetric(QStyle::PM_ButtonShiftVertical);
        }

        QRect bounds = a.boundingRect();
        int sx = sqsize / 2 - bounds.center().x() - 1;
        int sy = sqsize / 2 - bounds.center().y() - 1;
        imagePainter.translate(sx + bsx, sy + bsy);

        if (!(option->state & QStyle::State_Enabled)) {
            QColor foreGround(150, 150, 150, 150);
            imagePainter.setBrush(option->palette.mid().color());
            imagePainter.setPen(option->palette.mid().color());
        } else {
            QColor shadow(0, 0, 0, 100);
            imagePainter.translate(0, 1);
            imagePainter.setPen(shadow);
            imagePainter.setBrush(shadow);
            QColor foreGround(255, 255, 255, 210);
            imagePainter.drawPolygon(a);
            imagePainter.translate(0, -1);
            imagePainter.setPen(foreGround);
            imagePainter.setBrush(foreGround);
        }
        imagePainter.drawPolygon(a);
        imagePainter.end();
        pixmap = QPixmap::fromImage(image);
        QPixmapCache::insert(pixmapName, pixmap);
    }
    int xOffset = r.x() + (r.width() - size)/2;
    int yOffset = r.y() + (r.height() - size)/2;
    painter->drawPixmap(xOffset, yOffset, pixmap);
}

330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
void StyleHelper::menuGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect)
{
    if (StyleHelper::usePixmapCache()) {
        QString key;
        key.sprintf("mh_menu %d %d %d %d %d",
            spanRect.width(), spanRect.height(), clipRect.width(),
            clipRect.height(), StyleHelper::baseColor().rgb());

        QPixmap pixmap;
        if (!QPixmapCache::find(key, pixmap)) {
            pixmap = QPixmap(clipRect.size());
            QPainter p(&pixmap);
            QRect rect = QRect(0, 0, clipRect.width(), clipRect.height());
            menuGradientHelper(&p, spanRect, rect);
            p.end();
            QPixmapCache::insert(key, pixmap);
        }
con's avatar
con committed
347 348

        painter->drawPixmap(clipRect.topLeft(), pixmap);
349 350
    } else {
        menuGradientHelper(painter, spanRect, clipRect);
con's avatar
con committed
351 352
    }
}
353 354

} // namespace Utils