add more spacing
[personal-kdebase.git] / runtime / kstyles / oxygen / helper.cpp
blob89d843dc65e3eb0452ca2c5b931ddeb0141767d7
1 /*
2 * Copyright 2008 Long Huynh Huu <long.upcase@googlemail.com>
3 * Copyright 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
4 * Copyright 2007 Casper Boemann <cbr@boemann.dk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License version 2 as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
21 #include "helper.h"
23 #include <KColorUtils>
24 #include <KColorScheme>
26 #include <QtGui/QPainter>
27 #include <QtGui/QLinearGradient>
29 #include <math.h>
31 const double OxygenStyleHelper::_slabThickness = 0.45; //TODO: configurable?
33 OxygenStyleHelper::OxygenStyleHelper(const QByteArray &componentName)
34 : OxygenHelper(componentName)
36 // optimize for repainting of dock contents, which saves memory
37 m_dockFrameCache.setMaxCost(1);
38 // we won't store many tilesets, because one size fits all
39 m_scrollHoleCache.setMaxCost(10);
42 QColor OxygenStyleHelper::calcMidColor(const QColor &color) const
44 return KColorScheme::shade(color, KColorScheme::MidShade, _contrast - 1.0);
47 void OxygenStyleHelper::invalidateCaches()
49 m_slabCache.clear();
50 m_slabSunkenCache.clear();
51 m_slabInvertedCache.clear();
52 m_holeCache.clear();
53 m_holeFlatCache.clear();
54 m_slopeCache.clear();
55 m_slitCache.clear();
56 m_dockFrameCache.clear();
57 m_scrollHoleCache.clear();
58 OxygenHelper::invalidateCaches();
61 SlabCache* OxygenStyleHelper::slabCache(const QColor &color)
63 quint64 key = (quint64(color.rgba()) << 32);
64 SlabCache *cache = m_slabCache.object(key);
66 if (!cache)
68 cache = new SlabCache;
69 m_slabCache.insert(key, cache);
72 return cache;
75 QPixmap OxygenStyleHelper::roundSlab(const QColor &color, double shade, int size)
77 SlabCache *cache = slabCache(color);
78 quint64 key = (int)(256.0 * shade) << 24 | size;
79 QPixmap *pixmap = cache->m_roundSlabCache.object(key);
81 if (!pixmap)
83 pixmap = new QPixmap(size*3, size*3);
84 pixmap->fill(QColor(0,0,0,0));
86 QPainter p(pixmap);
87 p.setRenderHints(QPainter::Antialiasing);
88 p.setPen(Qt::NoPen);
89 p.setWindow(0,0,21,21);
91 QColor base = KColorUtils::shade(color, shade);
92 QColor light = KColorUtils::shade(calcLightColor(color), shade);
93 QColor dark = KColorUtils::shade(calcDarkColor(color), shade);
95 // shadow
96 drawShadow(p, calcShadowColor(color), 21);
98 // bevel, part 1
99 qreal y = KColorUtils::luma(base);
100 qreal yl = KColorUtils::luma(light);
101 qreal yd = KColorUtils::luma(dark);
102 QLinearGradient bevelGradient1(0, 10, 0, 18);
103 bevelGradient1.setColorAt(0.0, light);
104 bevelGradient1.setColorAt(0.9, dark);
105 if (y < yl && y > yd) // no middle when color is very light/dark
106 bevelGradient1.setColorAt(0.5, base);
107 p.setBrush(bevelGradient1);
108 p.drawEllipse(QRectF(3.0,3.0,15.0,15.0));
110 // bevel, part 2
111 if (_slabThickness > 0.0) {
112 QLinearGradient bevelGradient2(0, 7, 0, 28);
113 bevelGradient2.setColorAt(0.0, light);
114 bevelGradient2.setColorAt(0.9, base);
115 p.setBrush(bevelGradient2);
116 p.drawEllipse(QRectF(3.6,3.6,13.8,13.8));
119 // inside
120 QLinearGradient innerGradient(0, -17, 0, 20);
121 innerGradient.setColorAt(0.0, light);
122 innerGradient.setColorAt(1.0, base);
123 p.setBrush(innerGradient);
124 double ic = 3.6 + _slabThickness;
125 double is = 13.8 - (2.0*_slabThickness);
126 p.drawEllipse(QRectF(ic, ic, is, is));
128 p.end();
130 cache->m_roundSlabCache.insert(key, pixmap);
133 return *pixmap;
136 QPixmap OxygenStyleHelper::roundSlabFocused(const QColor &color, const QColor &glowColor, double shade, int size)
138 SlabCache *cache = slabCache(color);
139 quint64 key = (quint64(glowColor.rgba()) << 32) | (int)(256.0 * shade) << 24 | size;
140 QPixmap *pixmap = cache->m_roundSlabCache.object(key);
142 if (!pixmap)
144 pixmap = new QPixmap(size*3, size*3);
145 pixmap->fill(QColor(0,0,0,0));
147 QPainter p(pixmap);
148 p.setRenderHints(QPainter::Antialiasing);
149 p.setPen(Qt::NoPen);
150 p.setWindow(0,0,21,21);
152 // slab
153 QPixmap slabPixmap = roundSlab(color, shade, size);
154 p.drawPixmap(0, 0, slabPixmap);
156 // glow
157 QPixmap gp = glow(glowColor, 21, size*3);
158 p.drawPixmap(0, 0, gp);
160 p.end();
162 cache->m_roundSlabCache.insert(key, pixmap);
164 return *pixmap;
167 void OxygenStyleHelper::drawHole(QPainter &p, const QColor &color, double shade, int r) const
169 const int r2 = 2*r;
170 QColor base = KColorUtils::shade(color, shade);
171 QColor light = KColorUtils::shade(calcLightColor(color), shade);
172 QColor dark = KColorUtils::shade(calcDarkColor(color), shade);
173 QColor mid = KColorUtils::shade(calcMidColor(color), shade);
175 // bevel
176 qreal y = KColorUtils::luma(base);
177 qreal yl = KColorUtils::luma(light);
178 qreal yd = KColorUtils::luma(dark);
179 QLinearGradient bevelGradient1(0, 2, 0, r2-2);
180 bevelGradient1.setColorAt(0.2, dark);
181 bevelGradient1.setColorAt(0.5, mid);
182 bevelGradient1.setColorAt(1.0, light);
183 if (y < yl && y > yd) // no middle when color is very light/dark
184 bevelGradient1.setColorAt(0.6, base);
185 p.setBrush(bevelGradient1);
186 p.drawEllipse(3,3,r2-5,r2-5);
188 // mask
189 QRadialGradient maskGradient(r,r,r-2);
190 maskGradient.setColorAt(0.80, QColor(0,0,0,255));
191 maskGradient.setColorAt(0.90, QColor(0,0,0,140));
192 maskGradient.setColorAt(1.00, QColor(0,0,0,0));
193 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
194 p.setBrush(maskGradient);
195 p.drawRect(0,0,r2,r2);
196 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
199 void OxygenStyleHelper::drawSlab(QPainter &p, const QColor &color, double shade) const
201 QColor base = KColorUtils::shade(color, shade);
202 QColor light = KColorUtils::shade(calcLightColor(color), shade);
203 QColor dark = KColorUtils::shade(calcDarkColor(color), shade);
205 // bevel, part 1
206 qreal y = KColorUtils::luma(base);
207 qreal yl = KColorUtils::luma(light);
208 qreal yd = KColorUtils::luma(dark);
209 QLinearGradient bevelGradient1(0, 7, 0, 11);
210 bevelGradient1.setColorAt(0.0, light);
211 if (y < yl && y > yd) // no middle when color is very light/dark
212 bevelGradient1.setColorAt(0.5, base);
213 bevelGradient1.setColorAt(0.9, base);
214 p.setBrush(bevelGradient1);
215 p.drawEllipse(QRectF(3.0,3.0,8.0,8.0));
217 // bevel, part 2
218 if (_slabThickness > 0.0) {
219 QLinearGradient bevelGradient2(0, 6, 0, 19);
220 bevelGradient2.setColorAt(0.0, light);
221 bevelGradient2.setColorAt(0.9, base);
222 p.setBrush(bevelGradient2);
223 p.drawEllipse(QRectF(3.6,3.6,6.8,6.8));
226 // inside mask
227 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
228 p.setBrush(QBrush(Qt::black));
229 double ic = 3.6 + _slabThickness;
230 double is = 6.8 - (2.0*_slabThickness);
231 p.drawEllipse(QRectF(ic, ic, is, is));
234 void OxygenStyleHelper::drawInverseShadow(QPainter &p, const QColor &color,
235 int pad, int size, double fuzz) const
237 double m = double(size)*0.5;
239 const double offset = 0.8;
240 double k0 = (m-2.0) / double(m+2.0);
241 QRadialGradient shadowGradient(pad+m, pad+m+offset, m+2.0);
242 for (int i = 0; i < 8; i++) { // sinusoidal gradient
243 double k1 = (double(8 - i) + k0 * double(i)) * 0.125;
244 double a = (cos(3.14159 * i * 0.125) + 1.0) * 0.25;
245 shadowGradient.setColorAt(k1, alphaColor(color, a * _shadowGain));
247 shadowGradient.setColorAt(k0, alphaColor(color, 0.0));
248 p.setBrush(shadowGradient);
249 p.drawEllipse(QRectF(pad-fuzz, pad-fuzz, size+fuzz*2.0, size+fuzz*2.0));
252 void OxygenStyleHelper::drawInverseGlow(QPainter &p, const QColor &color,
253 int pad, int size, int rsize) const
255 QRectF r(pad, pad, size, size);
256 double m = double(size)*0.5;
258 const double width = 3.0;
259 const double bias = _glowBias * 7.0 / double(rsize);
260 double k0 = (m-width) / (m-bias);
261 QRadialGradient glowGradient(pad+m, pad+m, m-bias);
262 for (int i = 0; i < 8; i++) { // inverse parabolic gradient
263 double k1 = (k0 * double(i) + double(8 - i)) * 0.125;
264 double a = 1.0 - sqrt(i * 0.125);
265 glowGradient.setColorAt(k1, alphaColor(color, a));
267 glowGradient.setColorAt(k0, alphaColor(color, 0.0));
268 p.setBrush(glowGradient);
269 p.drawEllipse(r);
272 void OxygenStyleHelper::fillSlab(QPainter &p, const QRect &rect, int size)
274 const double s = double(size) * (3.6 + (0.5 * _slabThickness)) / 7.0;
275 QRectF r = rect;
276 r.adjust(s, s, -s, -s);
277 double w = r.width(), h = r.height();
278 if (w <= 0 || h <= 0)
279 return;
280 const double ra = 200.0 * (7.0 - (3.6 + (0.5 * _slabThickness))) / 7.0;
281 qreal rx = floor((ra*size) / w);
282 qreal ry = floor((ra*size) / h);
284 p.drawRoundRect(r, rx, ry);
287 void OxygenStyleHelper::fillHole(QPainter &p, const QRect &rect, int size)
289 const double s = double(size) * 3.0 / 7.0;
290 p.drawRoundedRect(rect.adjusted(s,s,-s,-s), 4, 4);
293 TileSet *OxygenStyleHelper::slab(const QColor &color, double shade, int size)
295 SlabCache *cache = slabCache(color);
296 quint64 key = (int)(256.0 * shade) << 24 | size;
297 TileSet *tileSet = cache->m_slabCache.object(key);
299 if (!tileSet)
301 QPixmap pixmap(size*2, size*2);
302 pixmap.fill(QColor(0,0,0,0));
304 QPainter p(&pixmap);
305 p.setRenderHints(QPainter::Antialiasing);
306 p.setPen(Qt::NoPen);
307 p.setWindow(0,0,14,14);
309 // shadow
310 drawShadow(p, calcShadowColor(color), 14);
312 // slab
313 drawSlab(p, color, shade);
315 p.end();
317 tileSet = new TileSet(pixmap, size, size, size, size, size-1, size, 2, 1);
319 cache->m_slabCache.insert(key, tileSet);
321 return tileSet;
324 TileSet *OxygenStyleHelper::slabFocused(const QColor &color, const QColor &glowColor, double shade, int size)
326 SlabCache *cache = slabCache(color);
327 quint64 key = (quint64(glowColor.rgba()) << 32) | (int)(256.0 * shade) << 24 | size;
328 TileSet *tileSet = cache->m_slabCache.object(key);
330 if (!tileSet)
332 QPixmap pixmap(size*2,size*2);
333 pixmap.fill(QColor(0,0,0,0));
335 QPainter p(&pixmap);
336 p.setRenderHints(QPainter::Antialiasing);
337 p.setPen(Qt::NoPen);
338 p.setWindow(0,0,14,14);
340 TileSet *slabTileSet = slab(color, shade, size);
342 // slab
343 slabTileSet->render(QRect(0,0,14,14), &p);
345 // glow
346 QPixmap gp = glow(glowColor, 14, size*2);
347 p.drawPixmap(0, 0, gp);
349 p.end();
351 tileSet = new TileSet(pixmap, size, size, size, size, size-1, size, 2, 1);
353 cache->m_slabCache.insert(key, tileSet);
355 return tileSet;
358 TileSet *OxygenStyleHelper::slabSunken(const QColor &color, double shade, int size)
360 quint64 key = (quint64(color.rgba()) << 32);
361 TileSet *tileSet = m_slabSunkenCache.object(key);
363 if (!tileSet)
365 QPixmap pixmap(size*2, size*2);
366 pixmap.fill(QColor(0,0,0,0));
368 QPainter p(&pixmap);
369 p.setRenderHints(QPainter::Antialiasing);
370 p.setPen(Qt::NoPen);
371 p.setWindow(0,0,14,14);
373 // slab
374 drawSlab(p, color, shade);
376 // shadow
377 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
378 drawInverseShadow(p, calcShadowColor(color), 3, 8, 0.0);
380 p.end();
382 tileSet = new TileSet(pixmap, size, size, size, size, size-1, size, 2, 1);
384 m_slabSunkenCache.insert(key, tileSet);
386 return tileSet;
389 TileSet *OxygenStyleHelper::slabInverted(const QColor &color, double shade, int size)
391 quint64 key = (quint64(color.rgba()) << 32);
392 TileSet *tileSet = m_slabInvertedCache.object(key);
394 if (!tileSet)
396 QPixmap pixmap(size*2, size*2);
397 pixmap.fill(QColor(0,0,0,0));
399 QPainter p(&pixmap);
400 p.setRenderHints(QPainter::Antialiasing);
401 p.setPen(Qt::NoPen);
402 p.setWindow(0,0,14,14);
404 QColor base = KColorUtils::shade(color, shade);
405 QColor light = KColorUtils::shade(calcLightColor(color), shade);
406 QColor dark = KColorUtils::shade(calcDarkColor(color), shade);
408 // bevel, part 2
409 QLinearGradient bevelGradient2(0, 8, 0, -8);
410 bevelGradient2.setColorAt(0.0, light);
411 bevelGradient2.setColorAt(0.9, base);
412 p.setBrush(bevelGradient2);
413 p.drawEllipse(QRectF(2.6,2.6,8.8,8.8));
415 // bevel, part 1
416 qreal y = KColorUtils::luma(base);
417 qreal yl = KColorUtils::luma(light);
418 qreal yd = KColorUtils::luma(dark);
419 QLinearGradient bevelGradient1(0, 7, 0, 4);
420 bevelGradient1.setColorAt(0.0, light);
421 bevelGradient1.setColorAt(0.9, dark);
422 if (y < yl && y > yd) // no middle when color is very light/dark
423 bevelGradient1.setColorAt(0.5, base);
424 p.setBrush(bevelGradient1);
425 p.drawEllipse(QRectF(3.4,3.4,7.2,7.2));
427 // inside mask
428 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
429 p.setBrush(QBrush(Qt::black));
430 p.drawEllipse(QRectF(4.0,4.0,6.0,6.0));
432 // shadow
433 p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
434 drawInverseShadow(p, calcShadowColor(color), 4, 6, 0.5);
436 p.end();
438 tileSet = new TileSet(pixmap, size, size, size, size, size-1, size, 2, 1);
440 m_slabInvertedCache.insert(key, tileSet);
442 return tileSet;
445 TileSet *OxygenStyleHelper::slope(const QColor &color, double shade, int size)
447 quint64 key = (quint64(color.rgba()) << 32);
448 TileSet *tileSet = m_slopeCache.object(key);
450 if (!tileSet)
452 // TODO - rebase??
453 QPixmap pixmap(size*4, size*4);
454 pixmap.fill(QColor(0,0,0,0));
456 QPainter p(&pixmap);
457 p.setPen(Qt::NoPen);
459 // edges
460 TileSet *slabTileSet = slab(color, shade, size);
461 slabTileSet->render(QRect(0, 0, size*4, size*5), &p,
462 TileSet::Left | TileSet::Right | TileSet::Top);
464 p.setWindow(0,0,28,28);
466 // bottom
467 QColor base = color;
468 QColor light = KColorUtils::shade(calcLightColor(color), shade);
469 QLinearGradient fillGradient(0, -28, 0, 28);
470 light.setAlphaF(0.4);
471 fillGradient.setColorAt(0.0, light);
472 base.setAlphaF(0.4);
473 fillGradient.setColorAt(1.0, base);
474 p.setBrush(fillGradient);
475 p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
476 p.drawRect(3, 9, 22, 17);
478 // fade bottom
479 QLinearGradient maskGradient(0, 7, 0, 28);
480 maskGradient.setColorAt(0.0, QColor(0, 0, 0, 255));
481 maskGradient.setColorAt(1.0, QColor(0, 0, 0, 0));
483 p.setBrush(maskGradient);
484 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
485 p.drawRect(0, 9, 28, 19);
487 tileSet = new TileSet(pixmap, size, size, size*2, 2);
488 m_slopeCache.insert(key, tileSet);
490 return tileSet;
493 TileSet *OxygenStyleHelper::hole(const QColor &color, double shade, int size)
495 quint64 key = (quint64(color.rgba()) << 32) | (int)(256.0 * shade) << 24 | size;
496 TileSet *tileSet = m_holeCache.object(key);
498 if (!tileSet)
500 int rsize = (int)ceil(double(size) * 5.0/7.0);
501 QPixmap pixmap(rsize*2, rsize*2);
502 pixmap.fill(QColor(0,0,0,0));
504 QPainter p(&pixmap);
505 p.setRenderHints(QPainter::Antialiasing);
506 p.setPen(Qt::NoPen);
507 p.setWindow(2,2,10,10);
509 // hole mask
510 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
511 p.setBrush(Qt::black);
512 p.drawEllipse(3,3,8,8);
514 // shadow
515 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
516 drawInverseShadow(p, calcShadowColor(color), 3, 8, 0.0);
518 p.end();
520 tileSet = new TileSet(pixmap, rsize, rsize, rsize, rsize, rsize-1, rsize, 2, 1);
522 m_holeCache.insert(key, tileSet);
524 return tileSet;
527 TileSet *OxygenStyleHelper::holeFlat(const QColor &color, double shade, int size)
529 quint64 key = (quint64(color.rgba()) << 32) | (int)(256.0 * shade) << 24 | size;
530 TileSet *tileSet = m_holeFlatCache.object(key);
532 if (!tileSet)
534 int rsize = (int)ceil(double(size) * 5.0/7.0);
535 QPixmap pixmap(rsize*2, rsize*2);
536 pixmap.fill(QColor(0,0,0,0));
538 QPainter p(&pixmap);
539 p.setRenderHints(QPainter::Antialiasing);
540 p.setPen(Qt::NoPen);
541 p.setWindow(2,2,10,10);
543 // hole
544 drawHole(p, color, shade, 7);
546 // hole inside
547 p.setBrush(color);
548 p.drawEllipse(QRectF(3.2,3.2,7.6,7.6));
550 p.end();
552 tileSet = new TileSet(pixmap, rsize, rsize, rsize, rsize, rsize-1, rsize, 2, 1);
554 m_holeFlatCache.insert(key, tileSet);
556 return tileSet;
559 TileSet *OxygenStyleHelper::holeFocused(const QColor &color, const QColor &glowColor, double shade, int size)
561 // FIXME must move to s/slabcache/cache/ b/c key is wrong
562 quint64 key = (quint64(color.rgba()) << 32) | quint64(glowColor.rgba());
563 TileSet *tileSet = m_holeCache.object(key);
565 if (!tileSet)
567 int rsize = (int)ceil(double(size) * 5.0/7.0);
568 QPixmap pixmap(rsize*2, rsize*2);
569 pixmap.fill(QColor(0,0,0,0));
571 QPainter p(&pixmap);
572 p.setRenderHints(QPainter::Antialiasing);
573 p.setPen(Qt::NoPen);
575 TileSet *holeTileSet = hole(color, shade, size);
577 // hole
578 holeTileSet->render(QRect(0,0,10,10), &p);
580 p.setWindow(2,2,10,10);
582 // glow
583 drawInverseGlow(p, glowColor, 3, 8, size);
585 p.end();
587 tileSet = new TileSet(pixmap, rsize, rsize, rsize, rsize, rsize-1, rsize, 2, 1);
589 m_holeCache.insert(key, tileSet);
591 return tileSet;
594 TileSet *OxygenStyleHelper::groove(const QColor &color, double shade, int size)
596 quint64 key = (quint64(color.rgba()) << 32) | (int)(256.0 * shade) << 24 | size;
597 TileSet *tileSet = m_grooveCache.object(key);
599 if (!tileSet)
601 int rsize = (int)ceil(double(size) * 3.0/7.0);
602 QPixmap pixmap(rsize*2, rsize*2);
603 pixmap.fill(QColor(0,0,0,0));
605 QPainter p(&pixmap);
606 p.setRenderHints(QPainter::Antialiasing);
607 p.setPen(Qt::NoPen);
608 p.setWindow(2,2,6,6);
610 // hole mask
611 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
612 p.setBrush(Qt::black);
613 p.drawEllipse(4,4,2,2);
615 // shadow
616 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
617 drawInverseShadow(p, calcShadowColor(color), 3, 4, 0.0);
619 p.end();
621 tileSet = new TileSet(pixmap, rsize, rsize, rsize, rsize, rsize-1, rsize, 2, 1);
623 m_grooveCache.insert(key, tileSet);
625 return tileSet;
628 TileSet *OxygenStyleHelper::slitFocused(const QColor &glowColor)
630 quint64 key = (quint64(glowColor.rgba()) << 32);
631 TileSet *tileSet = m_slitCache.object(key);
633 if (!tileSet)
635 QImage tmpImg(9, 9, QImage::Format_ARGB32);
636 QPainter p;
638 tmpImg.fill(0);
640 p.begin(&tmpImg);
641 p.setPen(Qt::NoPen);
642 p.setRenderHint(QPainter::Antialiasing);
643 QRadialGradient rg = QRadialGradient(4.5, 4.5, 4.5, 4.5, 4.5);
644 QColor tmpColor = glowColor;
645 tmpColor.setAlpha(180);
646 rg.setColorAt(0.75, tmpColor);
647 tmpColor.setAlpha(0);
648 rg.setColorAt(0.90, tmpColor);
649 rg.setColorAt(0.4, tmpColor);
650 p.setBrush(rg);
651 p.drawEllipse(QRectF(0, 0, 9, 9));
653 tileSet = new TileSet(QPixmap::fromImage(tmpImg), 4, 4, 1, 1);
655 m_slitCache.insert(key, tileSet);
657 return tileSet;
660 TileSet *OxygenStyleHelper::dockFrame(const QColor &color, int width)
662 quint64 key = quint64(color.rgba()) << 32 | width;
663 TileSet *tileSet = m_dockFrameCache.object(key);
664 if (!tileSet)
666 if (!width&1) // width should be uneven
667 --width;
669 int w = width;
670 int h = 9;
672 QPixmap pm(w, h);
673 pm.fill(Qt::transparent);
675 QPainter p(&pm);
676 p.setRenderHints(QPainter::Antialiasing);
677 p.setBrush(Qt::NoBrush);
678 p.translate(0.5, 0.5);
679 QRect rect(0.5,0.5,w-0.5,h-0.);
681 QColor light = calcLightColor(color);
682 QColor dark = calcDarkColor(color);
684 //dark.setAlpha(200);
685 light.setAlpha(150);
687 // left and right border
688 QLinearGradient lg(QPoint(0,0), QPoint(w,0));
689 lg.setColorAt(0.0, light);
690 lg.setColorAt(0.1, QColor(0,0,0,0));
691 lg.setColorAt(0.9, QColor(0,0,0,0));
692 lg.setColorAt(1.0, light);
693 p.setPen(QPen(lg,1));
694 p.drawRoundedRect(rect.adjusted(0,-1,0,-1),4,5);
695 p.drawRoundedRect(rect.adjusted(2,1,-2,-2),4,5);
697 lg.setColorAt(0.0, dark);
698 lg.setColorAt(0.1, QColor(0,0,0,0));
699 lg.setColorAt(0.9, QColor(0,0,0,0));
700 lg.setColorAt(1.0, dark);
701 p.setPen(QPen(lg, 1));
702 p.drawRoundedRect(rect.adjusted(1,0,-1,-2),4,5);
704 // top and bottom border
705 drawSeparator(&p, QRect(0,0,w,2), color, Qt::Horizontal);
706 drawSeparator(&p, QRect(0,h-2,w,2), color, Qt::Horizontal);
708 tileSet = new TileSet(pm, 4, 4, w-8, h-8);
709 m_dockFrameCache.insert(key, tileSet);
711 return tileSet;
714 TileSet *OxygenStyleHelper::scrollHole(const QColor &color, Qt::Orientation orientation)
716 quint64 key = quint64(color.rgba()) << 32 | (orientation == Qt::Horizontal);
717 TileSet *tileSet = m_scrollHoleCache.object(key);
718 if (!tileSet)
720 QPixmap pm(15, 15);
721 pm.fill(Qt::transparent);
723 QPainter p(&pm);
725 QColor dark = calcDarkColor(color);
726 QColor light = calcLightColor(color);
727 QColor shadow = calcShadowColor(color);
728 // use space for white border
729 QRect r = QRect(0,0,15,15);
730 QRect rect = r.adjusted(1, 0, -1, -1);
731 int shadowWidth = (orientation == Qt::Horizontal) ? 3 : 3;
733 p.setRenderHints(QPainter::Antialiasing);
734 p.setBrush(dark);
735 p.setPen(Qt::NoPen);
737 // base
738 p.drawRoundedRect(rect, 4.5, 4.5);
740 // slight shadow
741 // try only for horizontal bars
742 if (orientation == Qt::Horizontal)
744 QLinearGradient shadowGradient(rect.topLeft(), rect.bottomLeft());
745 shadowGradient.setColorAt(0.0, alphaColor(shadow, 0.1));
746 shadowGradient.setColorAt(0.6, Qt::transparent);
747 p.setBrush(shadowGradient);
748 p.drawRoundedRect(rect, 4.5, 4.5);
751 // strong shadow
752 // left
753 QLinearGradient l1 = QLinearGradient(rect.topLeft(), rect.topLeft()+QPoint(shadowWidth,0));
754 l1.setColorAt(0.0, alphaColor(shadow, orientation == Qt::Horizontal ? 0.2 : 0.1));
755 l1.setColorAt(1.0, Qt::transparent);
756 p.setBrush(l1);
757 p.drawRoundedRect(QRect(rect.topLeft(), rect.bottomLeft()+QPoint(shadowWidth,0)), 4.5, 4.5);
758 // right
759 l1 = QLinearGradient(rect.topRight(), rect.topRight()-QPoint(shadowWidth,0));
760 l1.setColorAt(0.0, alphaColor(shadow, orientation == Qt::Horizontal ? 0.2 : 0.1));
761 l1.setColorAt(1.0, Qt::transparent);
762 p.setBrush(l1);
763 p.drawRoundedRect(QRect(rect.topRight()-QPoint(shadowWidth,0), rect.bottomRight()), 4.5, 4.5);
764 //top
765 l1 = QLinearGradient(rect.topLeft(), rect.topLeft()+QPoint(0,3));
766 l1.setColorAt(0.0, alphaColor(shadow, 0.3));
767 l1.setColorAt(1.0, Qt::transparent);
768 p.setBrush(l1);
769 p.drawRoundedRect(QRect(rect.topLeft(),rect.topRight()+QPoint(0,3)), 4.5, 4.5);
771 // light border
772 QLinearGradient borderGradient(r.topLeft()+QPoint(0,r.height()/2-1), r.bottomLeft());
773 borderGradient.setColorAt(0.0, Qt::transparent);
774 borderGradient.setColorAt(1.0, alphaColor(light, 0.8));
775 p.setPen( QPen(borderGradient, 1.0) );
776 p.setBrush(Qt::NoBrush);
777 p.drawRoundedRect(r.adjusted(0.5,0,-0.5,0), 5.0, 5.0);
779 tileSet = new TileSet(pm, 7, 7, 1, 1);
780 m_scrollHoleCache.insert(key, tileSet);
782 return tileSet;