File: scalableicon.cpp

package info (click to toggle)
openmw 0.50.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 37,076 kB
  • sloc: cpp: 380,958; xml: 2,192; sh: 1,449; python: 911; makefile: 26; javascript: 5
file content (110 lines) | stat: -rw-r--r-- 2,816 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "scalableicon.hpp"

#include <QApplication>
#include <QDataStream>
#include <QDebug>
#include <QDir>
#include <QFont>
#include <QIODevice>
#include <QIconEngine>
#include <QPainter>
#include <QPalette>
#include <QtSvg/QSvgRenderer>

namespace Misc
{
    Q_GLOBAL_STATIC(QSet<ScalableIcon*>, ScalableIconInstances)

    ScalableIcon::ScalableIcon(const QByteArray& svgContent)
        : mTemplate(svgContent)
    {
        update();
        ScalableIconInstances->insert(this);
    }

    ScalableIcon::~ScalableIcon()
    {
        if (!ScalableIconInstances.isDestroyed())
        {
            ScalableIconInstances->remove(this);
        }
    }

    QIcon Misc::ScalableIcon::load(const QString& fileName)
    {
        if (fileName.isEmpty())
            return QIcon();

        QFile iconFile(fileName);
        if (!iconFile.open(QIODevice::ReadOnly))
        {
            qDebug() << "Failed to open icon file:" << fileName;
            return QIcon();
        }

        auto content = iconFile.readAll();
        if (!content.startsWith("<?xml"))
            return QIcon(fileName);

        return QIcon(new ScalableIcon(content));
    }

    void ScalableIcon::update()
    {
        constexpr const char* templateColor = "#4d4d4d";
        mContent = mTemplate;

        auto themeColor = QApplication::palette().text().color().name().toLower().toLatin1();
        mContent.replace(templateColor, themeColor);
    }

    void ScalableIcon::updateAllIcons()
    {
        for (auto engine : *ScalableIconInstances)
        {
            engine->update();
        }
    }

    void ScalableIcon::paint(QPainter* painter, const QRect& rect, QIcon::Mode mode, QIcon::State state)
    {
        Q_UNUSED(mode);
        Q_UNUSED(state);

        QSvgRenderer renderer(mContent);
        renderer.render(painter, rect);
    }

    QIconEngine* ScalableIcon::clone() const
    {
        return new ScalableIcon(*this);
    }

    QPixmap ScalableIcon::pixmap(const QSize& size, QIcon::Mode mode, QIcon::State state)
    {
        QPixmap pix = QPixmap(size);
        pix.fill(Qt::transparent);

        QPainter painter(&pix);
        QRect r(QPoint(0.0, 0.0), size);
        this->paint(&painter, r, mode, state);

        if (mode != QIcon::Disabled)
            return pix;

        // For disabled icons use grayscale icons with 50% transparency
        QImage img = pix.toImage();

        for (int x = 0; x < img.width(); x++)
        {
            for (int y = 0; y < img.height(); y++)
            {
                QColor n = img.pixelColor(x, y);
                int gray = qGray(n.red(), n.green(), n.blue());
                img.setPixelColor(x, y, QColor(gray, gray, gray, n.alpha() / 2));
            }
        }

        return QPixmap::fromImage(img, Qt::NoFormatConversion);
    }
}