Mercurial > hg > svgui
comparison widgets/IconLoader.cpp @ 1216:dc2af6616c83
Merge from branch 3.0-integration
author | Chris Cannam |
---|---|
date | Fri, 13 Jan 2017 10:29:50 +0000 |
parents | 5fdf5cd032ac |
children | a9c2e791ab8d |
comparison
equal
deleted
inserted
replaced
1048:e8102ff5573b | 1216:dc2af6616c83 |
---|---|
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 |