-rw-r--r-- | noncore/styles/theme/ogfxeffect.cpp | 249 | ||||
-rw-r--r-- | noncore/styles/theme/ogfxeffect.h | 3 | ||||
-rw-r--r-- | noncore/styles/theme/othemestyle.cpp | 7 |
3 files changed, 223 insertions, 36 deletions
diff --git a/noncore/styles/theme/ogfxeffect.cpp b/noncore/styles/theme/ogfxeffect.cpp index 55f3c1f..cc5bbcd 100644 --- a/noncore/styles/theme/ogfxeffect.cpp +++ b/noncore/styles/theme/ogfxeffect.cpp | |||
@@ -18,74 +18,257 @@ | |||
18 | //====================================================================== | 18 | //====================================================================== |
19 | // | 19 | // |
20 | // Gradient effects | 20 | // Gradient effects |
21 | // | 21 | // |
22 | //====================================================================== | 22 | //====================================================================== |
23 | 23 | ||
24 | 24 | ||
25 | QPixmap& OGfxEffect::gradient(QPixmap &pixmap, const QColor &ca, | 25 | QPixmap& OGfxEffect::gradient(QPixmap &pixmap, const QColor &ca, |
26 | const QColor &cb, GradientType eff, int /*ncols*/) | 26 | const QColor &cb, GradientType eff, int ncols) |
27 | { | 27 | { |
28 | if(pixmap.depth() > 8 && | 28 | QImage image = gradient(pixmap.size(), ca, cb, eff, ncols); |
29 | (eff == VerticalGradient || eff == HorizontalGradient)) { | 29 | pixmap.convertFromImage(image); |
30 | 30 | ||
31 | int rDiff, gDiff, bDiff; | 31 | return pixmap; |
32 | int rca, gca, bca /*, rcb, gcb, bcb*/; | 32 | } |
33 | |||
34 | QImage OGfxEffect::gradient(const QSize &size, const QColor &ca, | ||
35 | const QColor &cb, GradientType eff, int /*ncols*/) | ||
36 | { | ||
37 | int rDiff, gDiff, bDiff; | ||
38 | int rca, gca, bca, rcb, gcb, bcb; | ||
39 | |||
40 | QImage image(size, 32); | ||
41 | |||
42 | if (size.width() == 0 || size.height() == 0) { | ||
43 | qDebug ( "WARNING: OGfxEffect::gradient: invalid image" ); | ||
44 | return image; | ||
45 | } | ||
46 | |||
47 | register int x, y; | ||
33 | 48 | ||
34 | register int x, y; | 49 | rDiff = (rcb = cb.red()) - (rca = ca.red()); |
50 | gDiff = (gcb = cb.green()) - (gca = ca.green()); | ||
51 | bDiff = (bcb = cb.blue()) - (bca = ca.blue()); | ||
35 | 52 | ||
36 | rDiff = (/*rcb = */ cb.red()) - (rca = ca.red()); | 53 | if( eff == VerticalGradient || eff == HorizontalGradient ){ |
37 | gDiff = (/*gcb = */ cb.green()) - (gca = ca.green()); | 54 | |
38 | bDiff = (/*bcb = */ cb.blue()) - (bca = ca.blue()); | 55 | uint *p; |
56 | uint rgb; | ||
39 | 57 | ||
40 | register int rl = rca << 16; | 58 | register int rl = rca << 16; |
41 | register int gl = gca << 16; | 59 | register int gl = gca << 16; |
42 | register int bl = bca << 16; | 60 | register int bl = bca << 16; |
43 | 61 | ||
44 | int rcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * rDiff; | 62 | if( eff == VerticalGradient ) { |
45 | int gcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * gDiff; | 63 | |
46 | int bcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * bDiff; | 64 | int rcdelta = ((1<<16) / size.height()) * rDiff; |
65 | int gcdelta = ((1<<16) / size.height()) * gDiff; | ||
66 | int bcdelta = ((1<<16) / size.height()) * bDiff; | ||
47 | 67 | ||
48 | QPainter p(&pixmap); | 68 | for ( y = 0; y < size.height(); y++ ) { |
69 | p = (uint *) image.scanLine(y); | ||
49 | 70 | ||
50 | // these for-loops could be merged, but the if's in the inner loop | ||
51 | // would make it slow | ||
52 | switch(eff) { | ||
53 | case VerticalGradient: | ||
54 | for ( y = 0; y < pixmap.height(); y++ ) { | ||
55 | rl += rcdelta; | 71 | rl += rcdelta; |
56 | gl += gcdelta; | 72 | gl += gcdelta; |
57 | bl += bcdelta; | 73 | bl += bcdelta; |
58 | 74 | ||
59 | p.setPen(QColor(rl>>16, gl>>16, bl>>16)); | 75 | rgb = qRgb( (rl>>16), (gl>>16), (bl>>16) ); |
60 | p.drawLine(0, y, pixmap.width()-1, y); | 76 | |
77 | for( x = 0; x < size.width(); x++ ) { | ||
78 | *p = rgb; | ||
79 | p++; | ||
80 | } | ||
61 | } | 81 | } |
62 | break; | 82 | |
63 | case HorizontalGradient: | 83 | } |
64 | for( x = 0; x < pixmap.width(); x++) { | 84 | else { // must be HorizontalGradient |
85 | |||
86 | unsigned int *o_src = (unsigned int *)image.scanLine(0); | ||
87 | unsigned int *src = o_src; | ||
88 | |||
89 | int rcdelta = ((1<<16) / size.width()) * rDiff; | ||
90 | int gcdelta = ((1<<16) / size.width()) * gDiff; | ||
91 | int bcdelta = ((1<<16) / size.width()) * bDiff; | ||
92 | |||
93 | for( x = 0; x < size.width(); x++) { | ||
94 | |||
65 | rl += rcdelta; | 95 | rl += rcdelta; |
66 | gl += gcdelta; | 96 | gl += gcdelta; |
67 | bl += bcdelta; | 97 | bl += bcdelta; |
68 | 98 | ||
69 | p.setPen(QColor(rl>>16, gl>>16, bl>>16)); | 99 | *src++ = qRgb( (rl>>16), (gl>>16), (bl>>16)); |
70 | p.drawLine(x, 0, x, pixmap.height()-1); | 100 | } |
101 | |||
102 | src = o_src; | ||
103 | |||
104 | // Believe it or not, manually copying in a for loop is faster | ||
105 | // than calling memcpy for each scanline (on the order of ms...). | ||
106 | // I think this is due to the function call overhead (mosfet). | ||
107 | |||
108 | for (y = 1; y < size.height(); ++y) { | ||
109 | |||
110 | p = (unsigned int *)image.scanLine(y); | ||
111 | src = o_src; | ||
112 | for(x=0; x < size.width(); ++x) | ||
113 | *p++ = *src++; | ||
71 | } | 114 | } |
72 | break; | ||
73 | default: | ||
74 | ; | ||
75 | } | 115 | } |
76 | } | 116 | } |
117 | |||
77 | else { | 118 | else { |
78 | // QImage image = OGfxEffect::gradient(pixmap.size(), ca, cb, | ||
79 | // (OGfxEffect::GradientType) eff, ncols); | ||
80 | // pixmap.convertFromImage(image); | ||
81 | } | ||
82 | 119 | ||
83 | return pixmap; | 120 | float rfd, gfd, bfd; |
121 | float rd = rca, gd = gca, bd = bca; | ||
122 | |||
123 | unsigned char *xtable[3]; | ||
124 | unsigned char *ytable[3]; | ||
125 | |||
126 | unsigned int w = size.width(), h = size.height(); | ||
127 | xtable[0] = new unsigned char[w]; | ||
128 | xtable[1] = new unsigned char[w]; | ||
129 | xtable[2] = new unsigned char[w]; | ||
130 | ytable[0] = new unsigned char[h]; | ||
131 | ytable[1] = new unsigned char[h]; | ||
132 | ytable[2] = new unsigned char[h]; | ||
133 | w*=2, h*=2; | ||
134 | |||
135 | if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) { | ||
136 | // Diagonal dgradient code inspired by BlackBox (mosfet) | ||
137 | // BlackBox dgradient is (C) Brad Hughes, <bhughes@tcac.net> and | ||
138 | // Mike Cole <mike@mydot.com>. | ||
139 | |||
140 | rfd = (float)rDiff/w; | ||
141 | gfd = (float)gDiff/w; | ||
142 | bfd = (float)bDiff/w; | ||
143 | |||
144 | int dir; | ||
145 | for (x = 0; x < size.width(); x++, rd+=rfd, gd+=gfd, bd+=bfd) { | ||
146 | dir = eff == DiagonalGradient? x : size.width() - x - 1; | ||
147 | xtable[0][dir] = (unsigned char) rd; | ||
148 | xtable[1][dir] = (unsigned char) gd; | ||
149 | xtable[2][dir] = (unsigned char) bd; | ||
150 | } | ||
151 | rfd = (float)rDiff/h; | ||
152 | gfd = (float)gDiff/h; | ||
153 | bfd = (float)bDiff/h; | ||
154 | rd = gd = bd = 0; | ||
155 | for (y = 0; y < size.height(); y++, rd+=rfd, gd+=gfd, bd+=bfd) { | ||
156 | ytable[0][y] = (unsigned char) rd; | ||
157 | ytable[1][y] = (unsigned char) gd; | ||
158 | ytable[2][y] = (unsigned char) bd; | ||
159 | } | ||
160 | |||
161 | for (y = 0; y < size.height(); y++) { | ||
162 | unsigned int *scanline = (unsigned int *)image.scanLine(y); | ||
163 | for (x = 0; x < size.width(); x++) { | ||
164 | scanline[x] = qRgb(xtable[0][x] + ytable[0][y], | ||
165 | xtable[1][x] + ytable[1][y], | ||
166 | xtable[2][x] + ytable[2][y]); | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | else if (eff == RectangleGradient || | ||
172 | eff == PyramidGradient || | ||
173 | eff == PipeCrossGradient || | ||
174 | eff == EllipticGradient) | ||
175 | { | ||
176 | int rSign = rDiff>0? 1: -1; | ||
177 | int gSign = gDiff>0? 1: -1; | ||
178 | int bSign = bDiff>0? 1: -1; | ||
179 | |||
180 | rfd = (float)rDiff / size.width(); | ||
181 | gfd = (float)gDiff / size.width(); | ||
182 | bfd = (float)bDiff / size.width(); | ||
183 | |||
184 | rd = (float)rDiff/2; | ||
185 | gd = (float)gDiff/2; | ||
186 | bd = (float)bDiff/2; | ||
187 | |||
188 | for (x = 0; x < size.width(); x++, rd-=rfd, gd-=gfd, bd-=bfd) | ||
189 | { | ||
190 | xtable[0][x] = (unsigned char) abs((int)rd); | ||
191 | xtable[1][x] = (unsigned char) abs((int)gd); | ||
192 | xtable[2][x] = (unsigned char) abs((int)bd); | ||
193 | } | ||
194 | |||
195 | rfd = (float)rDiff/size.height(); | ||
196 | gfd = (float)gDiff/size.height(); | ||
197 | bfd = (float)bDiff/size.height(); | ||
198 | |||
199 | rd = (float)rDiff/2; | ||
200 | gd = (float)gDiff/2; | ||
201 | bd = (float)bDiff/2; | ||
202 | |||
203 | for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd) | ||
204 | { | ||
205 | ytable[0][y] = (unsigned char) abs((int)rd); | ||
206 | ytable[1][y] = (unsigned char) abs((int)gd); | ||
207 | ytable[2][y] = (unsigned char) abs((int)bd); | ||
208 | } | ||
209 | unsigned int rgb; | ||
210 | int h = (size.height()+1)>>1; | ||
211 | for (y = 0; y < h; y++) { | ||
212 | unsigned int *sl1 = (unsigned int *)image.scanLine(y); | ||
213 | unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y)); | ||
214 | |||
215 | int w = (size.width()+1)>>1; | ||
216 | int x2 = size.width()-1; | ||
217 | |||
218 | for (x = 0; x < w; x++, x2--) { | ||
219 | rgb = 0; | ||
220 | if (eff == PyramidGradient) { | ||
221 | rgb = qRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), | ||
222 | gcb-gSign*(xtable[1][x]+ytable[1][y]), | ||
223 | bcb-bSign*(xtable[2][x]+ytable[2][y])); | ||
224 | } | ||
225 | if (eff == RectangleGradient) { | ||
226 | rgb = qRgb(rcb - rSign * | ||
227 | QMAX(xtable[0][x], ytable[0][y]) * 2, | ||
228 | gcb - gSign * | ||
229 | QMAX(xtable[1][x], ytable[1][y]) * 2, | ||
230 | bcb - bSign * | ||
231 | QMAX(xtable[2][x], ytable[2][y]) * 2); | ||
232 | } | ||
233 | if (eff == PipeCrossGradient) { | ||
234 | rgb = qRgb(rcb - rSign * | ||
235 | QMIN(xtable[0][x], ytable[0][y]) * 2, | ||
236 | gcb - gSign * | ||
237 | QMIN(xtable[1][x], ytable[1][y]) * 2, | ||
238 | bcb - bSign * | ||
239 | QMIN(xtable[2][x], ytable[2][y]) * 2); | ||
240 | } | ||
241 | if (eff == EllipticGradient) { | ||
242 | rgb = qRgb(rcb - rSign * | ||
243 | (int)sqrt((xtable[0][x]*xtable[0][x] + | ||
244 | ytable[0][y]*ytable[0][y])*2.0), | ||
245 | gcb - gSign * | ||
246 | (int)sqrt((xtable[1][x]*xtable[1][x] + | ||
247 | ytable[1][y]*ytable[1][y])*2.0), | ||
248 | bcb - bSign * | ||
249 | (int)sqrt((xtable[2][x]*xtable[2][x] + | ||
250 | ytable[2][y]*ytable[2][y])*2.0)); | ||
251 | } | ||
252 | |||
253 | sl1[x] = sl2[x] = rgb; | ||
254 | sl1[x2] = sl2[x2] = rgb; | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | |||
259 | delete [] xtable[0]; | ||
260 | delete [] xtable[1]; | ||
261 | delete [] xtable[2]; | ||
262 | delete [] ytable[0]; | ||
263 | delete [] ytable[1]; | ||
264 | delete [] ytable[2]; | ||
265 | } | ||
266 | return image; | ||
84 | } | 267 | } |
85 | 268 | ||
86 | 269 | ||
87 | //====================================================================== | 270 | //====================================================================== |
88 | // | 271 | // |
89 | // Blend effects | 272 | // Blend effects |
90 | // | 273 | // |
91 | //====================================================================== | 274 | //====================================================================== |
diff --git a/noncore/styles/theme/ogfxeffect.h b/noncore/styles/theme/ogfxeffect.h index 45a8482..755537f 100644 --- a/noncore/styles/theme/ogfxeffect.h +++ b/noncore/styles/theme/ogfxeffect.h | |||
@@ -43,16 +43,19 @@ public: | |||
43 | * @param ncols The number of colors to use when not running on a | 43 | * @param ncols The number of colors to use when not running on a |
44 | * truecolor display. The gradient will be dithered to this number of | 44 | * truecolor display. The gradient will be dithered to this number of |
45 | * colors. Pass 0 to prevent dithering. | 45 | * colors. Pass 0 to prevent dithering. |
46 | * @return Returns the generated pixmap, for convenience. | 46 | * @return Returns the generated pixmap, for convenience. |
47 | */ | 47 | */ |
48 | static QPixmap& gradient(QPixmap& pixmap, const QColor &ca, const QColor &cb, | 48 | static QPixmap& gradient(QPixmap& pixmap, const QColor &ca, const QColor &cb, |
49 | GradientType type, int ncols=3); | 49 | GradientType type, int ncols=3); |
50 | 50 | ||
51 | static QImage gradient (const QSize &size, const QColor &ca, const QColor &cb, | ||
52 | GradientType type, int ncols=3); | ||
53 | |||
51 | 54 | ||
52 | /** | 55 | /** |
53 | * Blend the provided pixmap into a background of the indicated color | 56 | * Blend the provided pixmap into a background of the indicated color |
54 | * | 57 | * |
55 | * @param pixmap The pixmap to process. | 58 | * @param pixmap The pixmap to process. |
56 | * @param initial_intensity this parameter takes values from -1 to 1: | 59 | * @param initial_intensity this parameter takes values from -1 to 1: |
57 | * @li If positive, it tells how much to fade the image in its | 60 | * @li If positive, it tells how much to fade the image in its |
58 | * less affected spot. | 61 | * less affected spot. |
diff --git a/noncore/styles/theme/othemestyle.cpp b/noncore/styles/theme/othemestyle.cpp index d97b026..8c7a71b 100644 --- a/noncore/styles/theme/othemestyle.cpp +++ b/noncore/styles/theme/othemestyle.cpp | |||
@@ -1205,25 +1205,26 @@ void OThemeStyle::drawPopupMenuItem( QPainter* p, bool checkable, int maxpmw, | |||
1205 | if ( act ) { | 1205 | if ( act ) { |
1206 | drawBaseButton( p, x, y, w, h, g, true, false, MenuItemDown ); | 1206 | drawBaseButton( p, x, y, w, h, g, true, false, MenuItemDown ); |
1207 | } | 1207 | } |
1208 | else { | 1208 | else { |
1209 | drawShade( p, x, y, w, h, *colorGroup( g, MenuItem ), false, false, | 1209 | drawShade( p, x, y, w, h, *colorGroup( g, MenuItem ), false, false, |
1210 | highlightWidth( MenuItem ), borderWidth( MenuItem ), | 1210 | highlightWidth( MenuItem ), borderWidth( MenuItem ), |
1211 | shade() ); | 1211 | shade() ); |
1212 | int dw = decoWidth( MenuItem ); | 1212 | int dw = decoWidth( MenuItem ); |
1213 | if ( !isPixmap( MenuItem ) ) | 1213 | if ( !isPixmap( MenuItem ) ) { |
1214 | p->fillRect( x + dw, y + dw, w - dw * 2, h - dw * 2, | 1214 | p->fillRect( x + dw, y + dw, w - dw * 2, h - dw * 2, |
1215 | colorGroup( g, MenuItem ) -> | 1215 | colorGroup( g, MenuItem ) -> |
1216 | brush( QColorGroup::Background ) ); | 1216 | brush( QColorGroup::Background ) ); |
1217 | } | ||
1217 | else { | 1218 | else { |
1218 | // process inactive item pixmaps as one large item | 1219 | // process inactive item pixmaps as one large item |
1219 | p->drawTiledPixmap( x + dw, y + dw, w - dw * 2, h - dw * 2, *scalePixmap | 1220 | p->drawTiledPixmap( x + dw, y + dw, w - dw * 2, h - dw * 2, *scalePixmap |
1220 | // (w, p->window().height(), MenuItem), | 1221 | (w, ((QWidget *)p->device())->height(), MenuItem), |
1221 | ( w, p->clipRegion().boundingRect().height(), MenuItem ), | 1222 | //( w, p->clipRegion().boundingRect().height(), MenuItem ), // cliping does not work in Qt/E |
1222 | x, y ); | 1223 | x, y ); |
1223 | } | 1224 | } |
1224 | 1225 | ||
1225 | if ( checkable && mi && mi->isChecked() ) { | 1226 | if ( checkable && mi && mi->isChecked() ) { |
1226 | // draw 'pressed' border around checkable items | 1227 | // draw 'pressed' border around checkable items |
1227 | // This is extremely important for items that have an iconset | 1228 | // This is extremely important for items that have an iconset |
1228 | // because the checkmark isn't drawn in that case | 1229 | // because the checkmark isn't drawn in that case |
1229 | // An alternative would be superimposing the checkmark over | 1230 | // An alternative would be superimposing the checkmark over |