]> git.sur5r.net Git - minitube/blob - src/iconutils.cpp
Upload 3.9.3-2 to unstable
[minitube] / src / iconutils.cpp
1 /* $BEGIN_LICENSE
2
3 This file is part of Minitube.
4 Copyright 2009, Flavio Tordini <flavio.tordini@gmail.com>
5
6 Minitube is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Minitube is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Minitube.  If not, see <http://www.gnu.org/licenses/>.
18
19 $END_LICENSE */
20
21 #include "iconutils.h"
22 #include "mainwindow.h"
23 #include <QAction>
24
25 namespace {
26
27 void addIconFile(QIcon &icon,
28                  const QString &filename,
29                  int size,
30                  QIcon::Mode mode = QIcon::Normal,
31                  QIcon::State state = QIcon::Off) {
32     if (QFile::exists(filename)) {
33         icon.addFile(filename, QSize(size, size), mode, state);
34     }
35 }
36
37 QVector<int> sizes;
38
39 } // namespace
40
41 void IconUtils::setSizes(const QVector<int> &value) {
42     sizes = value;
43 }
44
45 QIcon IconUtils::fromTheme(const QString &name) {
46     static const QLatin1String symbolic("-symbolic");
47     if (name.endsWith(symbolic)) return QIcon::fromTheme(name);
48     QIcon icon = QIcon::fromTheme(name + symbolic);
49     if (icon.isNull()) return QIcon::fromTheme(name);
50     return icon;
51 }
52
53 QIcon IconUtils::fromResources(const char *name) {
54     qDebug() << "Creating icon" << name;
55     static const QLatin1String normal("_normal");
56     static const QLatin1String active("_active");
57     static const QLatin1String selected("_selected");
58     static const QLatin1String disabled("_disabled");
59     static const QLatin1String checked("_checked");
60     static const QLatin1String ext(".png");
61
62     QString path = QStringLiteral(":/icons/");
63
64     if (MainWindow::instance()->palette().window().color().value() > 128)
65         path += QLatin1String("light/");
66     else
67         path += QLatin1String("dark/");
68
69     QIcon icon;
70
71     // WARN keep these sizes updated with what we really use
72     for (int size : qAsConst(sizes)) {
73         const QString pathAndName =
74                 path + QString::number(size) + QLatin1Char('/') + QLatin1String(name);
75         QString iconFilename = pathAndName + normal + ext;
76         if (QFile::exists(iconFilename)) {
77             addIconFile(icon, iconFilename, size);
78             addIconFile(icon, pathAndName + active + ext, size, QIcon::Active);
79             addIconFile(icon, pathAndName + selected + ext, size, QIcon::Selected);
80             addIconFile(icon, pathAndName + disabled + ext, size, QIcon::Disabled);
81             addIconFile(icon, pathAndName + checked + ext, size, QIcon::Normal, QIcon::On);
82         }
83     }
84     return icon;
85 }
86
87 QIcon IconUtils::icon(const char *name) {
88     static QMap<QByteArray, QIcon> cache = [] {
89         qDebug() << "Init icon cache";
90         QMap<QByteArray, QIcon> c;
91         QObject::connect(qApp, &QApplication::paletteChanged, qApp, [&c]() {
92             qDebug() << "Clearing icon cache";
93             c.clear();
94         });
95         return c;
96     }();
97
98     auto i = cache.constFind(QByteArray::fromRawData(name, strlen(name)));
99     if (i != cache.constEnd()) return i.value();
100
101     QIcon icon;
102 #ifdef APP_UBUNTU_NO
103     icon = fromTheme(name);
104     if (icon.isNull()) icon = fromResources(name);
105 #else
106     icon = fromResources(name);
107 #endif
108
109     cache.insert(QByteArray(name), icon);
110     return icon;
111 }
112
113 QIcon IconUtils::icon(const QVector<const char *> &names) {
114     QIcon icon;
115     for (auto name : names) {
116         icon = IconUtils::icon(name);
117         if (!icon.availableSizes().isEmpty()) break;
118     }
119     return icon;
120 }
121
122 QPixmap IconUtils::iconPixmap(const char *name,
123                               int size,
124                               const QColor &background,
125                               const qreal pixelRatio) {
126     QString path = QStringLiteral(":/icons/");
127     if (background.value() > 128)
128         path += QLatin1String("light/");
129     else
130         path += QLatin1String("dark/");
131     path += QString::number(size) + QLatin1Char('/') + QLatin1String(name) +
132             QLatin1String("_normal.png");
133     return IconUtils::pixmap(path, pixelRatio);
134 }
135
136 QIcon IconUtils::tintedIcon(const char *name, const QColor &color, const QVector<QSize> &sizes) {
137     QIcon i = IconUtils::icon(name);
138     QIcon t;
139     // if (sizes.isEmpty()) sizes = i.availableSizes();
140     for (const QSize &size : sizes) {
141         QPixmap pixmap = i.pixmap(size);
142         tint(pixmap, color);
143         t.addPixmap(pixmap);
144     }
145     return t;
146 }
147
148 QIcon IconUtils::tintedIcon(const char *name, const QColor &color, const QSize &size) {
149     return IconUtils::tintedIcon(name, color, QVector<QSize>() << size);
150 }
151
152 QImage IconUtils::grayscaled(const QImage &image) {
153     QImage img = image;
154     int pixels = img.width() * img.height();
155     unsigned int *data = (unsigned int *)img.bits();
156     for (int i = 0; i < pixels; ++i) {
157         int val = qGray(data[i]);
158         data[i] = qRgba(val, val, val, qAlpha(data[i]));
159     }
160     return img;
161 }
162
163 QImage IconUtils::tinted(const QImage &image, const QColor &color, QPainter::CompositionMode mode) {
164     QImage img(image.size(), QImage::Format_ARGB32_Premultiplied);
165     QPainter painter(&img);
166     painter.drawImage(0, 0, grayscaled(image));
167     painter.setCompositionMode(mode);
168     painter.fillRect(img.rect(), color);
169     painter.end();
170     img.setAlphaChannel(image.alphaChannel());
171     return img;
172 }
173
174 void IconUtils::tint(QPixmap &pixmap, const QColor &color, QPainter::CompositionMode mode) {
175     QPainter painter(&pixmap);
176     painter.setCompositionMode(mode);
177     painter.fillRect(pixmap.rect(), color);
178 }
179
180 QPixmap IconUtils::pixmap(const char *name, const qreal pixelRatio) {
181     return pixmap(QString::fromLatin1(name), pixelRatio);
182 }
183
184 QPixmap IconUtils::pixmap(const QString &filename, const qreal pixelRatio) {
185     // Check if a "@2x" file exists
186     if (pixelRatio > 1.0) {
187         int dotIndex = filename.lastIndexOf(QLatin1Char('.'));
188         if (dotIndex != -1) {
189             QString at2xfileName = filename;
190             at2xfileName.insert(dotIndex, QLatin1String("@2x"));
191             if (QFile::exists(at2xfileName)) {
192                 QPixmap pixmap(at2xfileName);
193                 pixmap.setDevicePixelRatio(pixelRatio);
194                 return pixmap;
195             }
196         }
197     }
198     return QPixmap(filename);
199 }