comparison widgets/IconLoader.cpp @ 964:9b4771ba2e3e osx-retina

Merge from branch scalable-icons
author Chris Cannam
date Thu, 14 May 2015 15:40:37 +0100
parents 85b39667e9cf
children 5fdf5cd032ac
comparison
equal deleted inserted replaced
963:fa96108d552d 964:9b4771ba2e3e
17 17
18 #include <QPixmap> 18 #include <QPixmap>
19 #include <QApplication> 19 #include <QApplication>
20 #include <QPainter> 20 #include <QPainter>
21 #include <QPalette> 21 #include <QPalette>
22 22 #include <QFile>
23 static const char *autoInvertExceptions[] = { 23 #include <QSvgRenderer>
24
25 #include <vector>
26 #include <set>
27
28 #include "base/Debug.h"
29
30 using namespace std;
31
32 static set<QString> autoInvertExceptions {
24 // These are the icons that look OK in their default colours, even 33 // These are the icons that look OK in their default colours, even
25 // in a colour scheme with a black background. (They may also be 34 // in a colour scheme with a black background. (They may also be
26 // icons that would look worse if we tried to auto-invert them.) 35 // icons that would look worse if we tried to auto-invert them.)
27 // If we have icons that look bad when auto-inverted but that are 36 // If we have icons that look bad when auto-inverted but that are
28 // not suitable for use without being inverted, we'll need to 37 // not suitable for use without being inverted, we'll need to
29 // supply inverted versions -- the loader will load xx_inverse.png 38 // supply inverted versions -- the loader will load xx_inverse.png
30 // in preference to xx.png if a dark background is found.) 39 // in preference to xx.png if a dark background is found.)
31 "fileclose", 40 "fileclose",
32 "filenew-22",
33 "filenew", 41 "filenew",
34 "fileopen-22",
35 "fileopen", 42 "fileopen",
36 "fileopenaudio", 43 "fileopenaudio",
37 "fileopensession", 44 "fileopensession",
38 "filesave-22",
39 "filesave", 45 "filesave",
40 "filesaveas-22",
41 "filesaveas", 46 "filesaveas",
47 "filesaveas-sv",
42 "help", 48 "help",
43 "editcut", 49 "editcut",
44 "editcopy", 50 "editcopy",
45 "editpaste", 51 "editpaste",
46 "editdelete", 52 "editdelete",
49 "zoom-in", 55 "zoom-in",
50 "zoom-out", 56 "zoom-out",
51 "zoom" 57 "zoom"
52 }; 58 };
53 59
60 static vector<int> sizes { 0, 16, 22, 24, 32, 48, 64, 128 };
61
54 QIcon 62 QIcon
55 IconLoader::load(QString name) 63 IconLoader::load(QString name)
56 { 64 {
57 QPixmap pmap(loadPixmap(name)); 65 QIcon icon;
58 if (pmap.isNull()) return QIcon(); 66 for (int sz: sizes) {
59 else return QIcon(pmap); 67 QPixmap pmap(loadPixmap(name, sz));
68 if (!pmap.isNull()) icon.addPixmap(pmap);
69 }
70 return icon;
71 }
72
73 bool
74 IconLoader::shouldInvert() const
75 {
76 QColor bg = QApplication::palette().window().color();
77 bool darkBackground = (bg.red() + bg.green() + bg.blue() <= 384);
78 return darkBackground;
79 }
80
81 bool
82 IconLoader::shouldAutoInvert(QString name) const
83 {
84 if (shouldInvert()) {
85 return (autoInvertExceptions.find(name) == autoInvertExceptions.end());
86 } else {
87 return false;
88 }
60 } 89 }
61 90
62 QPixmap 91 QPixmap
63 IconLoader::loadPixmap(QString name) 92 IconLoader::loadPixmap(QString name, int size)
64 { 93 {
65 QColor bg = QApplication::palette().window().color(); 94 bool invert = shouldInvert();
66 if (bg.red() + bg.green() + bg.blue() > 384) { // light background 95
67 QPixmap pmap(QString(":icons/%1").arg(name)); 96 QString scalableName, nonScalableName;
68 if (pmap.isNull()) { 97 QPixmap pmap;
69 pmap = QPixmap(QString(":icons/%1.png").arg(name)); 98
70 } 99 nonScalableName = makeNonScalableFilename(name, size, invert);
71 return pmap; 100 pmap = QPixmap(nonScalableName);
72 } 101 if (!pmap.isNull()) return pmap;
73 102
74 QPixmap pmap(QString(":icons/%1").arg(name)); 103 if (size > 0) {
75 if (pmap.isNull()) { 104 scalableName = makeScalableFilename(name, invert);
76 pmap = QPixmap(QString(":icons/%1_inverse.png").arg(name)); 105 pmap = loadScalable(scalableName, size);
77 if (pmap.isNull()) { 106 if (!pmap.isNull()) return pmap;
78 pmap = QPixmap(QString(":icons/%1.png").arg(name)); 107 }
79 } 108
80 } 109 if (invert && shouldAutoInvert(name)) {
81 if (pmap.isNull()) return pmap; 110
82 111 nonScalableName = makeNonScalableFilename(name, size, false);
83 for (int i = 0; i < int(sizeof(autoInvertExceptions)/ 112 pmap = QPixmap(nonScalableName);
84 sizeof(autoInvertExceptions[0])); ++i) { 113 if (!pmap.isNull()) return invertPixmap(pmap);
85 if (autoInvertExceptions[i] == name) { 114
86 return pmap; 115 if (size > 0) {
87 } 116 scalableName = makeScalableFilename(name, false);
88 } 117 pmap = loadScalable(scalableName, size);
89 118 if (!pmap.isNull()) return invertPixmap(pmap);
119 }
120 }
121
122 return QPixmap();
123 }
124
125 QPixmap
126 IconLoader::loadScalable(QString name, int size)
127 {
128 if (!QFile(name).exists()) {
129 cerr << "loadScalable: no such file as: \"" << name << "\"" << endl;
130 return QPixmap();
131 }
132 QPixmap pmap(size, size);
133 pmap.fill(Qt::transparent);
134 QSvgRenderer renderer(name);
135 QPainter painter;
136 painter.begin(&pmap);
137 cerr << "calling renderer for " << name << " at size " << size << "..." << endl;
138 renderer.render(&painter);
139 cerr << "renderer completed" << endl;
140 painter.end();
141 return pmap;
142 }
143
144 QString
145 IconLoader::makeNonScalableFilename(QString name, int size, bool invert)
146 {
147 if (invert) {
148 if (size == 0) {
149 return QString(":icons/%1_inverse.png").arg(name);
150 } else {
151 return QString(":icons/%1-%2_inverse.png").arg(name).arg(size);
152 }
153 } else {
154 if (size == 0) {
155 return QString(":icons/%1.png").arg(name);
156 } else {
157 return QString(":icons/%1-%2.png").arg(name).arg(size);
158 }
159 }
160 }
161
162 QString
163 IconLoader::makeScalableFilename(QString name, bool invert)
164 {
165 if (invert) {
166 return QString(":icons/scalable/%1_inverse.svg").arg(name);
167 } else {
168 return QString(":icons/scalable/%1.svg").arg(name);
169 }
170 }
171
172 QPixmap
173 IconLoader::invertPixmap(QPixmap pmap)
174 {
90 // No suitable inverted icon found for black background; try to 175 // No suitable inverted icon found for black background; try to
91 // auto-invert the default one 176 // auto-invert the default one
92 177
93 QImage img = pmap.toImage().convertToFormat(QImage::Format_ARGB32); 178 QImage img = pmap.toImage().convertToFormat(QImage::Format_ARGB32);
94 179