* Saner resizing of the icon when pressed
* Nicer SVG, also fixed the corners, now are pixel perfect * Prepared the code for the upcoming blur of the wallpaper.... svn path=/trunk/KDE/kdebase/workspace/lib/plasma/; revision=672328
This commit is contained in:
parent
cd701724cb
commit
a043e502f3
260
widgets/icon.cpp
260
widgets/icon.cpp
@ -28,6 +28,244 @@
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>
|
||||
void fastbluralpha(QImage &img, int radius)
|
||||
{
|
||||
if (radius < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
QRgb *pix = (QRgb*)img.bits();
|
||||
int w = img.width();
|
||||
int h = img.height();
|
||||
int wm = w-1;
|
||||
int hm = h-1;
|
||||
int wh = w*h;
|
||||
int div = radius+radius+1;
|
||||
|
||||
int *r = new int[wh];
|
||||
int *g = new int[wh];
|
||||
int *b = new int[wh];
|
||||
int *a = new int[wh];
|
||||
int rsum, gsum, bsum, asum, x, y, i, yp, yi, yw;
|
||||
QRgb p;
|
||||
int *vmin = new int[qMax(w,h)];
|
||||
|
||||
int divsum = (div+1)>>1;
|
||||
divsum *= divsum;
|
||||
int *dv = new int[256*divsum];
|
||||
for (i=0; i < 256*divsum; ++i) {
|
||||
dv[i] = (i/divsum);
|
||||
}
|
||||
|
||||
yw = yi = 0;
|
||||
|
||||
int **stack = new int*[div];
|
||||
for(int i = 0; i < div; ++i) {
|
||||
stack[i] = new int[4];
|
||||
}
|
||||
|
||||
|
||||
int stackpointer;
|
||||
int stackstart;
|
||||
int *sir;
|
||||
int rbs;
|
||||
int r1 = radius+1;
|
||||
int routsum, goutsum, boutsum, aoutsum;
|
||||
int rinsum, ginsum, binsum, ainsum;
|
||||
|
||||
for (y = 0; y < h; ++y){
|
||||
rinsum = ginsum = binsum = ainsum
|
||||
= routsum = goutsum = boutsum = aoutsum
|
||||
= rsum = gsum = bsum = asum = 0;
|
||||
for(i =- radius; i <= radius; ++i) {
|
||||
p = pix[yi+qMin(wm,qMax(i,0))];
|
||||
sir = stack[i+radius];
|
||||
sir[0] = qRed(p);
|
||||
sir[1] = qGreen(p);
|
||||
sir[2] = qBlue(p);
|
||||
sir[3] = qAlpha(p);
|
||||
|
||||
rbs = r1-abs(i);
|
||||
rsum += sir[0]*rbs;
|
||||
gsum += sir[1]*rbs;
|
||||
bsum += sir[2]*rbs;
|
||||
asum += sir[3]*rbs;
|
||||
|
||||
if (i > 0){
|
||||
rinsum += sir[0];
|
||||
ginsum += sir[1];
|
||||
binsum += sir[2];
|
||||
ainsum += sir[3];
|
||||
} else {
|
||||
routsum += sir[0];
|
||||
goutsum += sir[1];
|
||||
boutsum += sir[2];
|
||||
aoutsum += sir[3];
|
||||
}
|
||||
}
|
||||
stackpointer = radius;
|
||||
|
||||
for (x=0; x < w; ++x) {
|
||||
|
||||
r[yi] = dv[rsum];
|
||||
g[yi] = dv[gsum];
|
||||
b[yi] = dv[bsum];
|
||||
a[yi] = dv[asum];
|
||||
|
||||
rsum -= routsum;
|
||||
gsum -= goutsum;
|
||||
bsum -= boutsum;
|
||||
asum -= aoutsum;
|
||||
|
||||
stackstart = stackpointer-radius+div;
|
||||
sir = stack[stackstart%div];
|
||||
|
||||
routsum -= sir[0];
|
||||
goutsum -= sir[1];
|
||||
boutsum -= sir[2];
|
||||
aoutsum -= sir[3];
|
||||
|
||||
if (y == 0) {
|
||||
vmin[x] = qMin(x+radius+1,wm);
|
||||
}
|
||||
p = pix[yw+vmin[x]];
|
||||
|
||||
sir[0] = qRed(p);
|
||||
sir[1] = qGreen(p);
|
||||
sir[2] = qBlue(p);
|
||||
sir[3] = qAlpha(p);
|
||||
|
||||
rinsum += sir[0];
|
||||
ginsum += sir[1];
|
||||
binsum += sir[2];
|
||||
ainsum += sir[3];
|
||||
|
||||
rsum += rinsum;
|
||||
gsum += ginsum;
|
||||
bsum += binsum;
|
||||
asum += ainsum;
|
||||
|
||||
stackpointer = (stackpointer+1)%div;
|
||||
sir = stack[(stackpointer)%div];
|
||||
|
||||
routsum += sir[0];
|
||||
goutsum += sir[1];
|
||||
boutsum += sir[2];
|
||||
aoutsum += sir[3];
|
||||
|
||||
rinsum -= sir[0];
|
||||
ginsum -= sir[1];
|
||||
binsum -= sir[2];
|
||||
ainsum -= sir[3];
|
||||
|
||||
++yi;
|
||||
}
|
||||
yw += w;
|
||||
}
|
||||
for (x=0; x < w; ++x){
|
||||
rinsum = ginsum = binsum = ainsum
|
||||
= routsum = goutsum = boutsum = aoutsum
|
||||
= rsum = gsum = bsum = asum = 0;
|
||||
|
||||
yp =- radius * w;
|
||||
|
||||
for(i=-radius; i <= radius; ++i) {
|
||||
yi=qMax(0,yp)+x;
|
||||
|
||||
sir = stack[i+radius];
|
||||
|
||||
sir[0] = r[yi];
|
||||
sir[1] = g[yi];
|
||||
sir[2] = b[yi];
|
||||
sir[3] = a[yi];
|
||||
|
||||
rbs = r1-abs(i);
|
||||
|
||||
rsum += r[yi]*rbs;
|
||||
gsum += g[yi]*rbs;
|
||||
bsum += b[yi]*rbs;
|
||||
asum += a[yi]*rbs;
|
||||
|
||||
if (i > 0) {
|
||||
rinsum += sir[0];
|
||||
ginsum += sir[1];
|
||||
binsum += sir[2];
|
||||
ainsum += sir[3];
|
||||
} else {
|
||||
routsum += sir[0];
|
||||
goutsum += sir[1];
|
||||
boutsum += sir[2];
|
||||
aoutsum += sir[3];
|
||||
}
|
||||
|
||||
if (i < hm){
|
||||
yp += w;
|
||||
}
|
||||
}
|
||||
|
||||
yi = x;
|
||||
stackpointer = radius;
|
||||
|
||||
for (y=0; y < h; ++y){
|
||||
pix[yi] = qRgba(dv[rsum], dv[gsum], dv[bsum], dv[asum]);
|
||||
|
||||
rsum -= routsum;
|
||||
gsum -= goutsum;
|
||||
bsum -= boutsum;
|
||||
asum -= aoutsum;
|
||||
|
||||
stackstart = stackpointer-radius+div;
|
||||
sir = stack[stackstart%div];
|
||||
|
||||
routsum -= sir[0];
|
||||
goutsum -= sir[1];
|
||||
boutsum -= sir[2];
|
||||
aoutsum -= sir[3];
|
||||
|
||||
if (x==0){
|
||||
vmin[y] = qMin(y+r1,hm)*w;
|
||||
}
|
||||
p = x+vmin[y];
|
||||
|
||||
sir[0] = r[p];
|
||||
sir[1] = g[p];
|
||||
sir[2] = b[p];
|
||||
sir[3] = a[p];
|
||||
|
||||
rinsum += sir[0];
|
||||
ginsum += sir[1];
|
||||
binsum += sir[2];
|
||||
ainsum += sir[3];
|
||||
|
||||
rsum += rinsum;
|
||||
gsum += ginsum;
|
||||
bsum += binsum;
|
||||
asum += ainsum;
|
||||
|
||||
stackpointer = (stackpointer+1)%div;
|
||||
sir = stack[stackpointer];
|
||||
|
||||
routsum += sir[0];
|
||||
goutsum += sir[1];
|
||||
boutsum += sir[2];
|
||||
aoutsum += sir[3];
|
||||
|
||||
rinsum -= sir[0];
|
||||
ginsum -= sir[1];
|
||||
binsum -= sir[2];
|
||||
ainsum -= sir[3];
|
||||
|
||||
yi += w;
|
||||
}
|
||||
}
|
||||
delete [] r;
|
||||
delete [] g;
|
||||
delete [] b;
|
||||
delete [] a;
|
||||
delete [] vmin;
|
||||
delete [] dv;
|
||||
}
|
||||
|
||||
class Icon::Private
|
||||
{
|
||||
@ -142,8 +380,18 @@ void Icon::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid
|
||||
}
|
||||
|
||||
if (!element.isEmpty()) {
|
||||
//kDebug() << "painting " << element << endl;
|
||||
d->svg.paint(painter, 0, 0, element);
|
||||
painter->save();
|
||||
if (element == "background-pressed") {
|
||||
QImage img(sizeHint().width(), sizeHint().height(), QImage::Format_ARGB32);
|
||||
img.fill(qRgba(0,0,0,0));
|
||||
QPainter p(&img);
|
||||
d->svg.paint(&p, 0, 0, element);
|
||||
fastbluralpha(img, 2);
|
||||
painter->drawImage(QPointF(0,0), img);
|
||||
} else {
|
||||
d->svg.paint(painter, 0, 0, element);
|
||||
}
|
||||
painter->restore();
|
||||
element = QString();
|
||||
}
|
||||
|
||||
@ -154,8 +402,14 @@ void Icon::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid
|
||||
qreal deltaY = (d->size.height() - ih) / 2 ;
|
||||
if(d->state == Private::PressedState)
|
||||
{
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->scale(0.95, 0.95);
|
||||
deltaY *= 0.95;
|
||||
deltaX *= 0.95;
|
||||
painter->drawPixmap(deltaX + (iw * .025), deltaY + (ih * .025),
|
||||
d->icon.pixmap(d->iconSize.toSize() * 0.95));
|
||||
d->icon.pixmap(d->iconSize.toSize()));
|
||||
painter->restore();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user