00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "scrollbar.h"
00021
00022 #include <KColorUtils>
00023 #include <KColorScheme>
00024
00025 #include <QtGui/QPainter>
00026 #include <QtGui/QLinearGradient>
00027
00028 inline QColor alphaColor(QColor color, double alpha)
00029 {
00030 color.setAlphaF(alpha);
00031 return color;
00032 }
00033
00034 OxygenScrollbar::OxygenScrollbar(const QColor &c, double contrast) : color(c),
00035 light(KColorScheme::shade(c, KColorScheme::LightShade, contrast - 0.5)),
00036 mid(KColorScheme::shade(c, KColorScheme::MidShade, contrast)),
00037 dark(KColorScheme::shade(c, KColorScheme::DarkShade, contrast - 0.5)),
00038 shadow(KColorScheme::shade(c, KColorScheme::ShadowShade, contrast)),
00039 highlight(Qt::white)
00040 {
00041 double y = KColorUtils::luma(color);
00042 if (y > KColorUtils::luma(light)) {
00043 light = Qt::white;
00044 dark = KColorScheme::shade(c, KColorScheme::DarkShade, contrast);
00045 }
00046 }
00047
00048 void OxygenScrollbar::mask(QPainter &p, const QRectF &rect) const
00049 {
00050 double w = rect.width();
00051 double h = rect.height();
00052
00053
00054
00055
00056 p.setBrush(Qt::black);
00057 p.drawRect(rect.adjusted(7,0,-7,0));
00058 p.drawRect(rect.adjusted(0,7,0,-7));
00059 p.drawEllipse(QRectF(0,0,14,14));
00060 p.drawEllipse(QRectF(w-14,0,14,14));
00061 p.drawEllipse(QRectF(0,h-14,14,14));
00062 p.drawEllipse(QRectF(w-14,h-14,14,14));
00063
00064
00065 p.setCompositionMode(QPainter::CompositionMode_SourceAtop);
00066 }
00067
00068 QLinearGradient OxygenScrollbar::baseGradient(double width, Qt::Orientation orient) const
00069 {
00070 double x = 0.0, y1 = width, y2 = width;
00071 if (orient == Qt::Vertical)
00072 x = width * 0.6;
00073 else
00074 y2 = width * 0.4;
00075
00076 QLinearGradient gradient(0, y1, x, y2);
00077 gradient.setColorAt(0.0, color);
00078 gradient.setColorAt(1.0, mid);
00079
00080 return gradient;
00081 }
00082
00083 QLinearGradient OxygenScrollbar::shineGradient(double width, Qt::Orientation orient) const
00084 {
00085 double x = 0.0, y1 = -width, y2 = -width;
00086 if (orient == Qt::Vertical)
00087 x = width * 2.0;
00088 else
00089 y1 = width;
00090
00091 QLinearGradient gradient(0, y1, x, y2);
00092 gradient.setColorAt(0.0, light);
00093 gradient.setColorAt(0.5, alphaColor(color, 0.5));
00094 gradient.setColorAt(1.0, color);
00095
00096 return gradient;
00097 }
00098
00099 QLinearGradient OxygenScrollbar::shimmerGradient(double offset, Qt::Orientation orient) const
00100 {
00101 double x = 0.0, y = 0.0, xo = 0.0, yo = 0.0;
00102 if (orient == Qt::Vertical) {
00103 yo = offset;
00104 x = 14.4/2.0;
00105 y = 43.2/2.0;
00106 } else {
00107 xo = offset;
00108 x = 43.2/2.0;
00109 y = -14.4/2.0;
00110 }
00111
00112
00113 QLinearGradient gradient(xo, yo, x+xo, y+yo);
00114 gradient.setSpread(QGradient::ReflectSpread);
00115 gradient.setColorAt(0.0, alphaColor(dark, 0.40));
00116 gradient.setColorAt(0.6, alphaColor(dark, 0.10));
00117 gradient.setColorAt(1.0, alphaColor(dark, 0.00));
00118
00119 return gradient;
00120 }
00121
00122 QLinearGradient OxygenScrollbar::dimGradient(Qt::Orientation orient) const
00123 {
00124 int x = 0, y = 0;
00125 if (orient == Qt::Vertical)
00126 y = 3*22;
00127 else
00128 x = 3*22;
00129
00130 QLinearGradient gradient(0, 0, x, y);
00131 gradient.setSpread(QGradient::ReflectSpread);
00132 gradient.setColorAt(0.00, alphaColor(dark, 1.0));
00133 gradient.setColorAt(0.19, alphaColor(dark, 0.3));
00134 gradient.setColorAt(0.27, alphaColor(dark, 0.0));
00135
00136 return gradient;
00137 }
00138
00139 QPixmap OxygenScrollbar::bevel(int width, int height, double w, double h, int rx, int ry) const
00140 {
00141 QPixmap pixmap(width, height);
00142 pixmap.fill(Qt::transparent);
00143
00144 QPainter p(&pixmap);
00145 p.setRenderHint(QPainter::Antialiasing);
00146 p.setPen(Qt::NoPen);
00147 p.setWindow(0, 0, int(w), int(h));
00148
00149 QRectF rect(0, 0, w, h);
00150
00151
00152 QLinearGradient ahGradient(0, 0, 0, 8);
00153 ahGradient.setColorAt(0.0, dark);
00154 ahGradient.setColorAt(1.0, alphaColor(shadow,0.8));
00155 p.setBrush(ahGradient);
00156 p.drawRect(rect);
00157
00158
00159 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
00160 p.setBrush(Qt::black);
00161 p.drawRoundRect(rect.adjusted(1, 1, -1, -1.5), rx, ry);
00162
00163
00164 QLinearGradient bevelGradient(0, 0, 0, 8);
00165 bevelGradient.setColorAt(0.0, alphaColor(highlight, 0.5));
00166 bevelGradient.setColorAt(0.7, alphaColor(highlight, 0.3));
00167 bevelGradient.setColorAt(1.0, alphaColor(highlight, 0));
00168 p.setBrush(bevelGradient);
00169 p.setCompositionMode(QPainter::CompositionMode_DestinationOver);
00170 p.drawRect(rect.adjusted(1.5,0,-1.5,0));
00171
00172
00173 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
00174 p.setBrush(Qt::black);
00175 p.drawRoundRect(rect.adjusted(2, 2, -2, -2.5), rx, ry);
00176
00177 p.end();
00178 return pixmap;
00179 }
00180
00181 TileSet* OxygenScrollbar::vertical(int size, int width, int offset) const
00182 {
00183 int s = size/2;
00184 int length = s*22;
00185 double w = 12.0 * double(width)/double(s*2);
00186 double o = -12.0 * double(offset) / double(size);
00187 const int h = 6*22;
00188
00189 QPixmap pixmap(width, length);
00190 pixmap.fill(Qt::transparent);
00191
00192 QPainter p(&pixmap);
00193 p.setRenderHint(QPainter::Antialiasing);
00194 p.setPen(Qt::NoPen);
00195 p.setWindow(0, 0, int(w), h);
00196 QRectF rect(0, 0, w, h);
00197
00198
00199 mask(p, rect);
00200
00201
00202 p.setBrush(baseGradient(w, Qt::Vertical));
00203 p.drawRect(rect);
00204
00205
00206 p.setBrush(shineGradient(w, Qt::Vertical));
00207 p.drawRoundRect(QRectF(w- int(w*0.45)-0.5, 0, int(w*0.45), h), 2000.0 / w, 12);
00208 p.setClipping(false);
00209
00210
00211 p.setBrush(shimmerGradient(o, Qt::Vertical));
00212 p.drawRect(rect);
00213
00214
00215 p.setBrush(dimGradient(Qt::Vertical));
00216 p.drawRect(rect);
00217
00218
00219 p.setBrush(alphaColor(highlight, 0.2));
00220 p.drawRoundRect(QRectF(w-3, 5.5, 1.5, h-12), 100, 5);
00221 p.drawRoundRect(QRectF(1.5, 5.5, 1.5, h-12), 100, 5);
00222
00223
00224 p.setWindow(0, 0, width, length);
00225 p.drawPixmap(0, 0, bevel(width, length, w, h, int(1400.0/w), 9));
00226
00227 return new TileSet(pixmap, 1, s*3, width-2, s*16);
00228 }
00229
00230 TileSet* OxygenScrollbar::horizontal(int size, int width, int offset) const
00231 {
00232 int s = size/2;
00233 int length = s*22;
00234 double h = 12.0 * double(width)/double(s*2);
00235 double o = -12.0 * double(offset) / double(size);
00236 const int w = 6*22;
00237
00238 QPixmap pixmap(length, width);
00239 pixmap.fill(Qt::transparent);
00240
00241 QPainter p(&pixmap);
00242 p.setRenderHint(QPainter::Antialiasing);
00243 p.setPen(Qt::NoPen);
00244 p.setWindow(0, 0, w, int(h));
00245 QRectF rect(0, 0, w, h);
00246
00247
00248 mask(p, rect);
00249
00250
00251 p.setBrush(baseGradient(h, Qt::Horizontal));
00252 p.drawRect(rect);
00253
00254
00255 p.setBrush(shineGradient(h, Qt::Horizontal));
00256 p.drawRoundRect(QRectF(0, 0.5, w, int(h*0.45)), 12, 2000.0 / h);
00257 p.setClipping(false);
00258
00259
00260 p.setBrush(shimmerGradient(o, Qt::Horizontal));
00261 p.drawRect(rect);
00262
00263
00264 p.setBrush(dimGradient(Qt::Horizontal));
00265 p.drawRect(rect);
00266
00267
00268 p.setWindow(0, 0, length, width);
00269 p.drawPixmap(0, 0, bevel(length, width, w, h, 9, int(1400.0/h)));
00270
00271 return new TileSet(pixmap, s*3, 1, s*16, width-2);
00272 }