From b52b5c0ffbe23520590cfe85642492eb89e63bbe Mon Sep 17 00:00:00 2001 From: Lucas Murray Date: Thu, 11 Jun 2009 05:53:19 +0000 Subject: [PATCH] Sync r979988 from Oxygen. svn path=/trunk/KDE/kdebase/workspace/; revision=980083 --- clients/ozone/CMakeLists.txt | 1 + clients/ozone/oxygen.cpp | 228 +-------------------------------- clients/ozone/oxygen.h | 6 +- clients/ozone/oxygenbutton.cpp | 2 +- clients/ozone/oxygenclient.cpp | 220 ++++++++++++++++++++++++------- clients/ozone/oxygenclient.h | 8 +- 6 files changed, 183 insertions(+), 282 deletions(-) diff --git a/clients/ozone/CMakeLists.txt b/clients/ozone/CMakeLists.txt index 396a097ce7..a8565afbde 100644 --- a/clients/ozone/CMakeLists.txt +++ b/clients/ozone/CMakeLists.txt @@ -4,6 +4,7 @@ add_subdirectory( config ) set(kwin_ozone_SRCS lib/helper.cpp + lib/tileset.cpp oxygenclient.cpp oxygenbutton.cpp oxygen.cpp diff --git a/clients/ozone/oxygen.cpp b/clients/ozone/oxygen.cpp index c69f0b1b65..673b1f6878 100644 --- a/clients/ozone/oxygen.cpp +++ b/clients/ozone/oxygen.cpp @@ -209,6 +209,7 @@ bool OxygenFactory::supports( Ability ability ) const case AbilityButtonShade: // compositing case AbilityCompositingShadow: // TODO: UI option to use default shadows instead + case AbilityUsesAlphaChannel: return true; // no colors supported at this time default: @@ -225,232 +226,5 @@ OxygenFactory::borderSizes() const BorderVeryHuge << BorderOversized; } -////////////////////////////////////////////////////////////////////////////// -// Shadows - -QList< QList > OxygenFactory::shadowTextures() -{ - QPalette palette = qApp->palette(); - - // Set palette to the right group. Which is active right now while drawing the glow - palette.setCurrentColorGroup(QPalette::Active); - - // TODO: THIS IS ALL VERY UGLY! Not recommended to do it this way. - // Copied from the shadow effect's XRender picture generator - - // TODO: You can add fake anti-aliasing here :) - - QList< QList > textureLists; - QList textures; - -#define shadowFuzzyness 10 -#define shadowSize 10 - - //--------------------------------------------------------------- - // Active shadow texture - - QColor color = palette.window().color(); - QColor light = oxygenHelper()->calcLightColor(oxygenHelper()->backgroundTopColor(color)); - QColor dark = oxygenHelper()->calcDarkColor(oxygenHelper()->backgroundBottomColor(color)); - QColor glow = KDecoration::options()->color(ColorFrame); - QColor glow2 = KDecoration::options()->color(ColorTitleBar); - - qreal size = 25.5; - QPixmap *shadow = new QPixmap( size*2, size*2 ); - shadow->fill( Qt::transparent ); - QRadialGradient rg( size, size, size ); - QColor c = color; - c.setAlpha( 255 ); rg.setColorAt( 4.4/size, c ); - c = glow; - c.setAlpha( 220 ); rg.setColorAt( 4.5/size, c ); - c.setAlpha( 180 ); rg.setColorAt( 5/size, c ); - c.setAlpha( 25 ); rg.setColorAt( 5.5/size, c ); - c.setAlpha( 0 ); rg.setColorAt( 6.5/size, c ); - QPainter p( shadow ); - p.setRenderHint( QPainter::Antialiasing ); - p.setPen( Qt::NoPen ); - p.setBrush( rg ); - p.drawRect( shadow->rect() ); - - rg = QRadialGradient( size, size, size ); - c = color; - c.setAlpha( 255 ); rg.setColorAt( 4.4/size, c ); - c = glow2; - c.setAlpha( 0.58*255 ); rg.setColorAt( 4.5/size, c ); - c.setAlpha( 0.43*255 ); rg.setColorAt( 5.5/size, c ); - c.setAlpha( 0.30*255 ); rg.setColorAt( 6.5/size, c ); - c.setAlpha( 0.22*255 ); rg.setColorAt( 7.5/size, c ); - c.setAlpha( 0.15*255 ); rg.setColorAt( 8.5/size, c ); - c.setAlpha( 0.08*255 ); rg.setColorAt( 11.5/size, c ); - c.setAlpha( 0); rg.setColorAt( 14.5/size, c ); - p.setRenderHint( QPainter::Antialiasing ); - p.setPen( Qt::NoPen ); - p.setBrush( rg ); - p.drawRect( shadow->rect() ); - - // draw the corner of the window - actually all 4 corners as one circle - p.setBrush( Qt::NoBrush ); - QLinearGradient lg = QLinearGradient(0.0, size-4.5, 0.0, size+4.5); - lg.setColorAt(0.52, light); - lg.setColorAt(1.0, dark); - p.setPen(QPen(lg, 0.8)); - p.drawEllipse(QRectF(size-4, size-4, 8, 8)); - - // cut out the part of the texture that is under the window - p.setCompositionMode( QPainter::CompositionMode_DestinationOut ); - p.setBrush( QColor( 0, 0, 0, 255 )); - p.setPen( Qt::NoPen ); - p.drawEllipse(QRectF(size-3, size-3, 6, 6)); - p.drawRect(QRectF(size-3, size-1, 6, 2)); - p.drawRect(QRectF(size-1, size-3, 2, 6)); - - p.end(); - - int w = shadow->width() / 2; - int h = shadow->height() / 2; - QPixmap dump; - -#define MAKE_TEX( _W_, _H_, _XOFF_, _YOFF_ ) \ - dump = QPixmap( _W_, _H_ ); \ - dump.fill( Qt::transparent ); \ - p.begin( &dump ); \ - p.drawPixmap( 0, 0, *shadow, _XOFF_, _YOFF_, _W_, _H_ ); \ - p.end(); \ - textures.append( dump.toImage() ); - - MAKE_TEX( w, h, 0, h+1 ); // corner - MAKE_TEX( 1, h, w, h+1 ); - MAKE_TEX( w, h, w+1, h+1 );// corner - MAKE_TEX( w, 1, 0, h ); - MAKE_TEX( w, 1, w+1, h ); - MAKE_TEX( w, h, 0, 0);// corner - MAKE_TEX( 1, h, w, 0); - MAKE_TEX( w, h, w+1, 0);// corner - - textureLists.append( textures ); - - //--------------------------------------------------------------- - // Inactive shadow texture - - textures.clear(); - - shadow->fill( Qt::transparent ); - p.begin(shadow); - p.setRenderHint( QPainter::Antialiasing ); - p.setPen( Qt::NoPen ); - - rg = QRadialGradient( size, size+4, size ); - c = QColor( Qt::black ); - c.setAlpha( 0.12*255 ); rg.setColorAt( 4.5/size, c ); - c.setAlpha( 0.11*255 ); rg.setColorAt( 6.6/size, c ); - c.setAlpha( 0.075*255 ); rg.setColorAt( 8.5/size, c ); - c.setAlpha( 0.06*255 ); rg.setColorAt( 11.5/size, c ); - c.setAlpha( 0.035*255 ); rg.setColorAt( 14.5/size, c ); - c.setAlpha( 0.025*255 ); rg.setColorAt( 17.5/size, c ); - c.setAlpha( 0.01*255 ); rg.setColorAt( 21.5/size, c ); - c.setAlpha( 0.0*255 ); rg.setColorAt( 25.5/size, c ); - p.setRenderHint( QPainter::Antialiasing ); - p.setPen( Qt::NoPen ); - p.setBrush( rg ); - p.drawRect( shadow->rect() ); - - rg = QRadialGradient( size, size+2, size ); - c = QColor( Qt::black ); - c.setAlpha( 0.25*255 ); rg.setColorAt( 4.5/size, c ); - c.setAlpha( 0.20*255 ); rg.setColorAt( 5.5/size, c ); - c.setAlpha( 0.13*255 ); rg.setColorAt( 7.5/size, c ); - c.setAlpha( 0.06*255 ); rg.setColorAt( 8.5/size, c ); - c.setAlpha( 0.015*255 ); rg.setColorAt( 11.5/size, c ); - c.setAlpha( 0.0*255 ); rg.setColorAt( 14.5/size, c ); - p.setRenderHint( QPainter::Antialiasing ); - p.setPen( Qt::NoPen ); - p.setBrush( rg ); - p.drawRect( shadow->rect() ); - - rg = QRadialGradient( size, size+0.2, size ); - c = color; - c = QColor( Qt::black ); - c.setAlpha( 0.35*255 ); rg.setColorAt( 0/size, c ); - c.setAlpha( 0.32*255 ); rg.setColorAt( 4.5/size, c ); - c.setAlpha( 0.22*255 ); rg.setColorAt( 5.0/size, c ); - c.setAlpha( 0.03*255 ); rg.setColorAt( 5.5/size, c ); - c.setAlpha( 0.0*255 ); rg.setColorAt( 6.5/size, c ); - p.setRenderHint( QPainter::Antialiasing ); - p.setPen( Qt::NoPen ); - p.setBrush( rg ); - p.drawRect( shadow->rect() ); - - rg = QRadialGradient( size, size, size ); - c = color; - c.setAlpha( 255 ); rg.setColorAt( 4.0/size, c ); - c.setAlpha( 0 ); rg.setColorAt( 4.01/size, c ); - p.setRenderHint( QPainter::Antialiasing ); - p.setPen( Qt::NoPen ); - p.setBrush( rg ); - p.drawRect( shadow->rect() ); - - // draw the corner of the window - actually all 4 corners as one circle - p.setBrush( Qt::NoBrush ); - p.setPen(QPen(lg, 0.8)); - p.drawEllipse(QRectF(size-4, size-4, 8, 8)); - - // cut out the part of the texture that is under the window - p.setCompositionMode( QPainter::CompositionMode_DestinationOut ); - p.setBrush( QColor( 0, 0, 0, 255 )); - p.setPen( Qt::NoPen ); - p.drawEllipse(QRectF(size-3, size-3, 6, 6)); - p.drawRect(QRectF(size-3, size-1, 6, 2)); - p.drawRect(QRectF(size-1, size-3, 2, 6)); - - p.end(); - - MAKE_TEX( w, h, 0, h+1 ); // corner - MAKE_TEX( 1, h, w, h+1 ); - MAKE_TEX( w, h, w+1, h+1 );// corner - MAKE_TEX( w, 1, 0, h ); - MAKE_TEX( w, 1, w+1, h ); - MAKE_TEX( w, h, 0, 0);// corner - MAKE_TEX( 1, h, w, 0); - MAKE_TEX( w, h, w+1, 0);// corner - - textureLists.append( textures ); - - delete shadow; - - return textureLists; -} - -int OxygenFactory::shadowTextureList( ShadowType type ) const -{ - switch( type ) { - case ShadowBorderedActive: - return 0; - case ShadowBorderedInactive: - return 1; - } - abort(); // Should never be reached -} - -QList OxygenFactory::shadowQuads( ShadowType type, QSize size ) const -{ - int outside=20, underlap=5, cornersize=25; - // These are underlap under the decoration so the corners look nicer 10px on the outside - QList quads; - /*quads.append(QRect(-outside, size.height()-underlap, cornersize, cornersize)); - quads.append(QRect(underlap, size.height()-underlap, size.width()-2*underlap, cornersize)); - quads.append(QRect(size.width()-underlap, size.height()-underlap, cornersize, cornersize)); - quads.append(QRect(-outside, underlap, cornersize, size.height()-2*underlap)); - quads.append(QRect(size.width()-underlap, underlap, cornersize, size.height()-2*underlap)); - quads.append(QRect(-outside, -outside, cornersize, cornersize)); - quads.append(QRect(underlap, -outside, size.width()-2*underlap, cornersize)); - quads.append(QRect(size.width()-underlap, -outside, cornersize, cornersize));*/ - return quads; -} - -double OxygenFactory::shadowOpacity( ShadowType type ) const -{ - return 1.0; -} - } //namespace Oxygen } //namespace Ozone diff --git a/clients/ozone/oxygen.h b/clients/ozone/oxygen.h index c6eb0f4ef0..a6a5963cae 100644 --- a/clients/ozone/oxygen.h +++ b/clients/ozone/oxygen.h @@ -36,6 +36,7 @@ namespace Oxygen // OxygenFactory ///////////////////////////////////////////////////////////// static const int OXYGEN_BUTTONSIZE = 22; +static const qreal SHADOW_WIDTH = 25.5; #define TFRAMESIZE 3 enum ButtonType { @@ -62,11 +63,6 @@ public: virtual bool supports( Ability ability ) const; QList< BorderSize > borderSizes() const; - virtual QList< QList > shadowTextures(); - virtual int shadowTextureList( ShadowType type ) const; - virtual QList shadowQuads( ShadowType type, QSize size ) const; - virtual double shadowOpacity( ShadowType type ) const; - static bool initialized(); static Qt::Alignment titleAlignment(); static bool showStripes(); diff --git a/clients/ozone/oxygenbutton.cpp b/clients/ozone/oxygenbutton.cpp index c0ccbfa1a7..1c586b92cd 100644 --- a/clients/ozone/oxygenbutton.cpp +++ b/clients/ozone/oxygenbutton.cpp @@ -190,7 +190,7 @@ void OxygenButton::paintEvent(QPaintEvent *) KDecorationDefines::ColorTitleBar, client_.isActive())); } // fill the grey square - helper_.renderWindowBackground(&painter, this->rect(), this, pal2, 0); + helper_.renderWindowBackground(&painter, this->rect(), this, pal, 23 /*TODO: calculate this from layout metrics*/); painter.setClipRect(this->rect()); // draw dividing line diff --git a/clients/ozone/oxygenclient.cpp b/clients/ozone/oxygenclient.cpp index 16d958a2b7..4b46d50652 100644 --- a/clients/ozone/oxygenclient.cpp +++ b/clients/ozone/oxygenclient.cpp @@ -77,6 +77,11 @@ static void oxkwincleanupBefore() h->invalidateCaches(); } +void OxygenClient::invalidateCaches() +{ + shadowCache_.clear(); +} + void renderDot(QPainter *p, const QPointF &point, qreal diameter) { p->drawEllipse(QRectF(point.x()-diameter/2, point.y()-diameter/2, diameter, diameter)); @@ -89,6 +94,9 @@ OxygenClient::OxygenClient(KDecorationBridge *b, KDecorationFactory *f) , helper_(*globalHelper) { qAddPostRoutine(oxkwincleanupBefore); + + // cache active and inactive states + shadowCache_.setMaxCost(2); } OxygenClient::~OxygenClient() @@ -189,6 +197,13 @@ int OxygenClient::layoutMetric(LayoutMetric lm, bool respectWindowState, const K case LM_ButtonMarginTop: return 0; + // outer margin for shadow/glow + case LM_OuterPaddingLeft: + case LM_OuterPaddingRight: + case LM_OuterPaddingTop: + case LM_OuterPaddingBottom: + return SHADOW_WIDTH; + default: return KCommonDecoration::layoutMetric(lm, respectWindowState, btn); } @@ -278,7 +293,6 @@ QColor OxygenClient::titlebarTextColor(const QPalette &palette) } } - void OxygenClient::paintEvent(QPaintEvent *e) { Q_UNUSED(e) @@ -295,7 +309,9 @@ void OxygenClient::paintEvent(QPaintEvent *e) palette.setCurrentColorGroup(QPalette::Inactive); int x,y,w,h; - QRect frame = widget()->frameGeometry(); + QRect frame = widget()->rect(); + frame.adjust(SHADOW_WIDTH, SHADOW_WIDTH, -SHADOW_WIDTH, -SHADOW_WIDTH); + QColor color = OxygenFactory::blendTitlebarColors() ? palette.window().color() : options()->color( ColorTitleBar, isActive()); QColor light = helper_.calcLightColor( color ); QColor dark = helper_.calcDarkColor( color ); @@ -317,8 +333,34 @@ void OxygenClient::paintEvent(QPaintEvent *e) pal2.setColor( QPalette::Window, options()->color( KDecorationDefines::ColorTitleBar, isActive())); } + + // draw shadow + + if (compositingActive()) + shadowTiles(color, SHADOW_WIDTH)->render( + frame.adjusted(-SHADOW_WIDTH+4, -SHADOW_WIDTH+4, SHADOW_WIDTH-4, SHADOW_WIDTH-4), + &painter, TileSet::Ring); + // draw window background - helper_.renderWindowBackground(&painter, frame, this->widget(), pal2, 0); + bool isCompositingActive = compositingActive(); + + if (isCompositingActive) { + frame.getRect(&x, &y, &w, &h); + + QRegion mask(x+5, y+0, w-10, h-0); + mask += QRegion(x+0, y+5, w-0, h-10); + mask += QRegion(x+1, y+3, w-2, h-6); + mask += QRegion(x+2, y+2, w-4, h-4); + mask += QRegion(x+3, y+1, w-6, h-2); + + painter.setClipRegion(mask); + } + + helper_.renderWindowBackground(&painter, frame, this->widget(), palette, SHADOW_WIDTH); + + if (isCompositingActive) { + painter.setClipping(false); + } // draw title text painter.setFont(options()->font(isActive(), false)); @@ -329,8 +371,7 @@ void OxygenClient::paintEvent(QPaintEvent *e) painter.setRenderHint(QPainter::Antialiasing); // Draw dividing line - frame = widget()->rect(); - if (shadowsActive()) { + if (compositingActive()) { frame.adjust(-1,-1,1,1); } frame.getRect(&x, &y, &w, &h); @@ -381,7 +422,7 @@ void OxygenClient::paintEvent(QPaintEvent *e) if(maximized) return; - helper_.drawFloatFrame(&painter, frame, color, !shadowsActive(), isActive(), + helper_.drawFloatFrame(&painter, frame, color, !compositingActive(), isActive(), KDecoration::options()->color(ColorTitleBar)); if(!isResizable()) @@ -441,59 +482,146 @@ void OxygenClient::updateWindowShape() return; } - if (!shadowsActive()) { + if (!compositingActive()) { QRegion mask(4, 0, w-8, h); mask += QRegion(0, 4, w, h-8); mask += QRegion(2, 1, w-4, h-2); mask += QRegion(1, 2, w-2, h-4); - setMask(mask); - } - else { - QRegion mask(5, 0, w-10, h-0); - mask += QRegion(0, 5, w-0, h-10); - mask += QRegion(2, 2, w-4, h-4); - mask += QRegion(3, 1, w-6, h-2); - mask += QRegion(1, 3, w-2, h-6); - setMask(mask); } } -QList OxygenClient::shadowQuads( ShadowType type ) const +TileSet *OxygenClient::shadowTiles(const QColor &color, qreal size) { - Q_UNUSED(type) + quint64 key = (quint64(color.rgba()) << 32) | quint64(size*10); + TileSet *tileSet = shadowCache_.object(key); - QSize size = widget()->size(); - int outside=21, underlap=4, cornersize=25; - // These are underlap under the decoration so the corners look nicer 10px on the outside - QList quads; - quads.append(QRect(-outside, size.height()-underlap, cornersize, cornersize)); - quads.append(QRect(underlap, size.height()-underlap, size.width()-2*underlap, cornersize)); - quads.append(QRect(size.width()-underlap, size.height()-underlap, cornersize, cornersize)); - quads.append(QRect(-outside, underlap, cornersize, size.height()-2*underlap)); - quads.append(QRect(size.width()-underlap, underlap, cornersize, size.height()-2*underlap)); - quads.append(QRect(-outside, -outside, cornersize, cornersize)); - quads.append(QRect(underlap, -outside, size.width()-2*underlap, cornersize)); - quads.append(QRect(size.width()-underlap, -outside, cornersize, cornersize)); - return quads; -} + if (!tileSet) + { + QColor light = oxygenHelper()->calcLightColor(oxygenHelper()->backgroundTopColor(color)); + QColor dark = oxygenHelper()->calcDarkColor(oxygenHelper()->backgroundBottomColor(color)); + QColor glow = KDecoration::options()->color(ColorFrame); + QColor glow2 = KDecoration::options()->color(ColorTitleBar); -double OxygenClient::shadowOpacity( ShadowType type ) const -{ - switch( type ) { - case ShadowBorderedActive: - if( isActive() ) - return 1.0; - return 0.0; - case ShadowBorderedInactive: - if( isActive() ) - return 0.0; - return 1.0; - default: - abort(); // Should never be reached + QPixmap shadow = QPixmap( size*2, size*2 ); + shadow.fill( Qt::transparent ); + + // draw the corner of the window - actually all 4 corners as one circle + QLinearGradient lg = QLinearGradient(0.0, size-4.5, 0.0, size+4.5); + lg.setColorAt(0.52, light); + lg.setColorAt(1.0, dark); + + QPainter p( &shadow ); + p.setRenderHint( QPainter::Antialiasing ); + p.setPen( Qt::NoPen ); + + if (isActive()) + { + //--------------------------------------------------------------- + // Active shadow texture + + QRadialGradient rg( size, size, size ); + QColor c = color; + c.setAlpha( 255 ); rg.setColorAt( 4.4/size, c ); + c = glow; + c.setAlpha( 220 ); rg.setColorAt( 4.5/size, c ); + c.setAlpha( 180 ); rg.setColorAt( 5/size, c ); + c.setAlpha( 25 ); rg.setColorAt( 5.5/size, c ); + c.setAlpha( 0 ); rg.setColorAt( 6.5/size, c ); + + p.setBrush( rg ); + p.drawRect( shadow.rect() ); + + rg = QRadialGradient( size, size, size ); + c = color; + c.setAlpha( 255 ); rg.setColorAt( 4.4/size, c ); + c = glow2; + c.setAlpha( 0.58*255 ); rg.setColorAt( 4.5/size, c ); + c.setAlpha( 0.43*255 ); rg.setColorAt( 5.5/size, c ); + c.setAlpha( 0.30*255 ); rg.setColorAt( 6.5/size, c ); + c.setAlpha( 0.22*255 ); rg.setColorAt( 7.5/size, c ); + c.setAlpha( 0.15*255 ); rg.setColorAt( 8.5/size, c ); + c.setAlpha( 0.08*255 ); rg.setColorAt( 11.5/size, c ); + c.setAlpha( 0); rg.setColorAt( 14.5/size, c ); + p.setRenderHint( QPainter::Antialiasing ); + p.setBrush( rg ); + p.drawRect( shadow.rect() ); + + p.setBrush( Qt::NoBrush ); + p.setPen(QPen(lg, 0.8)); + p.drawEllipse(QRectF(size-4, size-4, 8, 8)); + + p.end(); + + tileSet = new TileSet(shadow, size, size, 1, 1); + shadowCache_.insert(key, tileSet); + } else { + //--------------------------------------------------------------- + // Inactive shadow texture + + QRadialGradient rg = QRadialGradient( size, size+4, size ); + QColor c = QColor( Qt::black ); + c.setAlpha( 0.12*255 ); rg.setColorAt( 4.5/size, c ); + c.setAlpha( 0.11*255 ); rg.setColorAt( 6.6/size, c ); + c.setAlpha( 0.075*255 ); rg.setColorAt( 8.5/size, c ); + c.setAlpha( 0.06*255 ); rg.setColorAt( 11.5/size, c ); + c.setAlpha( 0.035*255 ); rg.setColorAt( 14.5/size, c ); + c.setAlpha( 0.025*255 ); rg.setColorAt( 17.5/size, c ); + c.setAlpha( 0.01*255 ); rg.setColorAt( 21.5/size, c ); + c.setAlpha( 0.0*255 ); rg.setColorAt( 25.5/size, c ); + p.setRenderHint( QPainter::Antialiasing ); + p.setPen( Qt::NoPen ); + p.setBrush( rg ); + p.drawRect( shadow.rect() ); + + rg = QRadialGradient( size, size+2, size ); + c = QColor( Qt::black ); + c.setAlpha( 0.25*255 ); rg.setColorAt( 4.5/size, c ); + c.setAlpha( 0.20*255 ); rg.setColorAt( 5.5/size, c ); + c.setAlpha( 0.13*255 ); rg.setColorAt( 7.5/size, c ); + c.setAlpha( 0.06*255 ); rg.setColorAt( 8.5/size, c ); + c.setAlpha( 0.015*255 ); rg.setColorAt( 11.5/size, c ); + c.setAlpha( 0.0*255 ); rg.setColorAt( 14.5/size, c ); + p.setRenderHint( QPainter::Antialiasing ); + p.setPen( Qt::NoPen ); + p.setBrush( rg ); + p.drawRect( shadow.rect() ); + + rg = QRadialGradient( size, size+0.2, size ); + c = color; + c = QColor( Qt::black ); + c.setAlpha( 0.35*255 ); rg.setColorAt( 0/size, c ); + c.setAlpha( 0.32*255 ); rg.setColorAt( 4.5/size, c ); + c.setAlpha( 0.22*255 ); rg.setColorAt( 5.0/size, c ); + c.setAlpha( 0.03*255 ); rg.setColorAt( 5.5/size, c ); + c.setAlpha( 0.0*255 ); rg.setColorAt( 6.5/size, c ); + p.setRenderHint( QPainter::Antialiasing ); + p.setPen( Qt::NoPen ); + p.setBrush( rg ); + p.drawRect( shadow.rect() ); + + rg = QRadialGradient( size, size, size ); + c = color; + c.setAlpha( 255 ); rg.setColorAt( 4.0/size, c ); + c.setAlpha( 0 ); rg.setColorAt( 4.01/size, c ); + p.setRenderHint( QPainter::Antialiasing ); + p.setPen( Qt::NoPen ); + p.setBrush( rg ); + p.drawRect( shadow.rect() ); + + // draw the corner of the window - actually all 4 corners as one circle + p.setBrush( Qt::NoBrush ); + p.setPen(QPen(lg, 0.8)); + p.drawEllipse(QRectF(size-4, size-4, 8, 8)); + + p.end(); + + tileSet = new TileSet(shadow, size, size, 1, 1); + shadowCache_.insert(key, tileSet); + } } - return 0; + return tileSet; } } //namespace Oxygen diff --git a/clients/ozone/oxygenclient.h b/clients/ozone/oxygenclient.h index b945501901..0893ac3b73 100644 --- a/clients/ozone/oxygenclient.h +++ b/clients/ozone/oxygenclient.h @@ -32,6 +32,7 @@ #include #include "lib/helper.h" +#include "lib/tileset.h" class QPoint; @@ -45,6 +46,7 @@ class OxygenClient : public KCommonDecorationUnstable public: OxygenClient(KDecorationBridge *b, KDecorationFactory *f); virtual ~OxygenClient(); + virtual void invalidateCaches(); virtual QString visibleName() const; virtual KCommonDecorationButton *createButton(::ButtonType type); @@ -53,9 +55,6 @@ public: virtual void updateWindowShape(); virtual void init(); - virtual QList shadowQuads( ShadowType type ) const; - virtual double shadowOpacity( ShadowType type ) const; - private: void paintEvent(QPaintEvent *e); void drawStripes(QPainter *p, QPalette &palette, const int start, const int end, const int topMargin); @@ -63,6 +62,9 @@ private: bool colorCacheInvalid_; QColor cachedTitlebarTextColor_; + TileSet *shadowTiles(const QColor&, qreal size); + QCache shadowCache_; + protected: friend class OxygenButton; OxygenHelper &helper_;