From 488b3644d5070fffd5a3ce5b8e2a5453db844893 Mon Sep 17 00:00:00 2001 From: Hugo Pereira Da Costa Date: Wed, 2 Feb 2011 16:36:50 +0100 Subject: [PATCH] Changed handling of shadow overlap with window content Oxygen::ShadowCache::shadowSize() now returns the shadow extend outside of the window body (the extend) Overlab between the actual shadow pixmap and the window body is dealt with internally (by creating larger pixmaps) This allows notably Oxygen::Client to not attempt to draw shadow when shadowSize == 0 (which was never the case before) --- .../oxygen/demo/oxygenshadowdemowidget.cpp | 4 +- clients/oxygen/oxygenclient.cpp | 14 +- clients/oxygen/oxygenshadowcache.cpp | 241 +++++++++--------- clients/oxygen/oxygenshadowcache.h | 7 +- 4 files changed, 135 insertions(+), 131 deletions(-) diff --git a/clients/oxygen/demo/oxygenshadowdemowidget.cpp b/clients/oxygen/demo/oxygenshadowdemowidget.cpp index 68f92a9810..f47acde71f 100644 --- a/clients/oxygen/demo/oxygenshadowdemowidget.cpp +++ b/clients/oxygen/demo/oxygenshadowdemowidget.cpp @@ -45,7 +45,7 @@ namespace Oxygen if( _drawBackground ) { updateBackgroundPixmap(); - painter.translate( _shadowSize - 4, _shadowSize - 4 ); + painter.translate( _shadowSize, _shadowSize ); painter.drawPixmap( QPoint(0,0), _backgroundPixmap ); } @@ -56,7 +56,7 @@ namespace Oxygen { // check if background pixmap needs update - QRect backgroundRect( QPoint( 0, 0 ), size() - QSize( 2*(_shadowSize-4), 2*(_shadowSize-4) ) ); + QRect backgroundRect( QPoint( 0, 0 ), size() - QSize( 2*_shadowSize, 2*_shadowSize ) ); if( !_backgroundPixmap.isNull() && _backgroundPixmap.size() == backgroundRect.size() ) { return; } diff --git a/clients/oxygen/oxygenclient.cpp b/clients/oxygen/oxygenclient.cpp index 5fe0b3cc75..84f7c0473d 100644 --- a/clients/oxygen/oxygenclient.cpp +++ b/clients/oxygen/oxygenclient.cpp @@ -1100,7 +1100,7 @@ namespace Oxygen // for shaded maximized windows adjust frame and draw the bottom part of it helper().drawFloatFrame( - painter, frame.adjusted( -4, 0, 4, 0 ), backgroundColor( widget(), palette ), + painter, frame, backgroundColor( widget(), palette ), !( compositingActive() || configuration().frameBorder() == Configuration::BorderNone ), isActive(), KDecoration::options()->color(ColorTitleBar), TileSet::Bottom @@ -1351,7 +1351,7 @@ namespace Oxygen QColor color = palette.window().color(); // draw shadows - if( compositingActive() ) + if( compositingActive() && shadowCache().shadowSize() > 0 ) { TileSet *tileSet( 0 ); @@ -1367,14 +1367,16 @@ namespace Oxygen } - if( !isMaximized() ) tileSet->render( frame.adjusted( 4, 4, -4, -4), &painter, TileSet::Ring); - else if( isShade() ) tileSet->render( frame.adjusted( 0, 4, 0, -4), &painter, TileSet::Bottom); + tileSet->render( frame, &painter, TileSet::Ring); } // adjust frame - qreal shadowSize( shadowCache().shadowSize() ); - frame.adjust( shadowSize, shadowSize, -shadowSize, -shadowSize ); + frame.adjust( + layoutMetric(LM_OuterPaddingLeft), + layoutMetric(LM_OuterPaddingTop), + -layoutMetric(LM_OuterPaddingRight), + -layoutMetric(LM_OuterPaddingBottom) ); // adjust mask if( compositingActive() || isPreview() ) diff --git a/clients/oxygen/oxygenshadowcache.cpp b/clients/oxygen/oxygenshadowcache.cpp index fe1805033f..68c5ca8b88 100644 --- a/clients/oxygen/oxygenshadowcache.cpp +++ b/clients/oxygen/oxygenshadowcache.cpp @@ -74,7 +74,7 @@ namespace Oxygen if( enabled_ && shadowCache_.contains(hash) ) return shadowCache_.object(hash); // create tileSet otherwise - qreal size( shadowSize() ); + qreal size( shadowSize() + overlap ); TileSet* tileSet = new TileSet( shadowPixmap( key, key.active ), size, size, size, size, size, size, 1, 1); shadowCache_.insert( hash, tileSet ); @@ -97,7 +97,7 @@ namespace Oxygen if( enabled_ && animatedShadowCache_.contains(hash) ) return animatedShadowCache_.object(hash); // create shadow and tileset otherwise - qreal size( shadowSize() ); + qreal size( shadowSize() + overlap ); QPixmap shadow( size*2, size*2 ); shadow.fill( Qt::transparent ); @@ -142,6 +142,12 @@ namespace Oxygen qreal size( shadowSize() ); qreal shadowSize( shadowConfiguration.isEnabled() ? shadowConfiguration.shadowSize():0 ); + if( !shadowSize ) return QPixmap(); + + // add overlap + size += overlap; + shadowSize += overlap; + QPixmap shadow = QPixmap( size*2, size*2 ); shadow.fill( Qt::transparent ); @@ -152,148 +158,143 @@ namespace Oxygen // some gradients rendering are different at bottom corners if client has no border bool hasBorder( key.hasBorder || key.isShade ); - if( shadowSize ) + if( active ) { - if( active ) { + // inner (sharp) gradient + const qreal gradientSize = qMin( shadowSize, (shadowSize+fixedSize)/2 ); + const qreal hoffset = shadowConfiguration.horizontalOffset()*gradientSize/fixedSize; + const qreal voffset = shadowConfiguration.verticalOffset()*gradientSize/fixedSize; + + QRadialGradient rg = QRadialGradient( size+12.0*hoffset, size+12.0*voffset, gradientSize ); + rg.setColorAt(1, Qt::transparent ); + + // gaussian shadow is used + int nPoints( (10*gradientSize)/fixedSize ); + Gaussian f( 0.85, 0.17 ); + QColor c = shadowConfiguration.innerColor(); + for( int i = 0; i < nPoints; i++ ) { - - // inner (shark) gradient - const qreal gradientSize = qMin( shadowSize, (shadowSize+fixedSize)/2 ); - const qreal hoffset = shadowConfiguration.horizontalOffset()*gradientSize/fixedSize; - const qreal voffset = shadowConfiguration.verticalOffset()*gradientSize/fixedSize; - - QRadialGradient rg = QRadialGradient( size+12.0*hoffset, size+12.0*voffset, gradientSize ); - rg.setColorAt(1, Qt::transparent ); - - // gaussian shadow is used - int nPoints( (10*gradientSize)/fixedSize ); - Gaussian f( 0.85, 0.17 ); - QColor c = shadowConfiguration.innerColor(); - for( int i = 0; i < nPoints; i++ ) - { - qreal x = qreal(i)/nPoints; - c.setAlphaF( f(x) ); - rg.setColorAt( x, c ); - - } - - p.setBrush( rg ); - renderGradient( p, shadow.rect(), rg, hasBorder ); + qreal x = qreal(i)/nPoints; + c.setAlphaF( f(x) ); + rg.setColorAt( x, c ); } + p.setBrush( rg ); + renderGradient( p, shadow.rect(), rg, hasBorder ); + + } + + { + + // outer (spread) gradient + const qreal gradientSize = shadowSize; + const qreal hoffset = shadowConfiguration.horizontalOffset()*gradientSize/fixedSize; + const qreal voffset = shadowConfiguration.verticalOffset()*gradientSize/fixedSize; + + QRadialGradient rg = QRadialGradient( size+12.0*hoffset, size+12.0*voffset, gradientSize ); + rg.setColorAt(1, Qt::transparent ); + + // gaussian shadow is used + int nPoints( (10*gradientSize)/fixedSize ); + Gaussian f( 0.46, 0.34 ); + QColor c = shadowConfiguration.outerColor(); + for( int i = 0; i < nPoints; i++ ) { - - // outer (spread) gradient - const qreal gradientSize = shadowSize; - const qreal hoffset = shadowConfiguration.horizontalOffset()*gradientSize/fixedSize; - const qreal voffset = shadowConfiguration.verticalOffset()*gradientSize/fixedSize; - - QRadialGradient rg = QRadialGradient( size+12.0*hoffset, size+12.0*voffset, gradientSize ); - rg.setColorAt(1, Qt::transparent ); - - // gaussian shadow is used - int nPoints( (10*gradientSize)/fixedSize ); - Gaussian f( 0.46, 0.34 ); - QColor c = shadowConfiguration.outerColor(); - for( int i = 0; i < nPoints; i++ ) - { - qreal x = qreal(i)/nPoints; - c.setAlphaF( f(x) ); - rg.setColorAt( x, c ); - - } - - p.setBrush( rg ); - p.drawRect( shadow.rect() ); + qreal x = qreal(i)/nPoints; + c.setAlphaF( f(x) ); + rg.setColorAt( x, c ); } - } else { + p.setBrush( rg ); + p.drawRect( shadow.rect() ); + } + + } else { + + { + // inner (sharp gradient) + const qreal gradientSize = qMin( shadowSize, fixedSize ); + const qreal hoffset = shadowConfiguration.horizontalOffset()*gradientSize/fixedSize; + const qreal voffset = shadowConfiguration.verticalOffset()*gradientSize/fixedSize; + + QRadialGradient rg = QRadialGradient( size+hoffset, size+voffset, gradientSize ); + rg.setColorAt(1, Qt::transparent ); + + // parabolic shadow is used + int nPoints( (10*gradientSize)/fixedSize ); + Parabolic f( 1.0, 0.22 ); + QColor c = shadowConfiguration.outerColor(); + for( int i = 0; i < nPoints; i++ ) { - // inner (sharp gradient) - const qreal gradientSize = qMin( shadowSize, fixedSize ); - const qreal hoffset = shadowConfiguration.horizontalOffset()*gradientSize/fixedSize; - const qreal voffset = shadowConfiguration.verticalOffset()*gradientSize/fixedSize; - - QRadialGradient rg = QRadialGradient( size+hoffset, size+voffset, gradientSize ); - rg.setColorAt(1, Qt::transparent ); - - // parabolic shadow is used - int nPoints( (10*gradientSize)/fixedSize ); - Parabolic f( 1.0, 0.22 ); - QColor c = shadowConfiguration.outerColor(); - for( int i = 0; i < nPoints; i++ ) - { - qreal x = qreal(i)/nPoints; - c.setAlphaF( f(x) ); - rg.setColorAt( x, c ); - - } - - - p.setBrush( rg ); - renderGradient( p, shadow.rect(), rg, hasBorder ); + qreal x = qreal(i)/nPoints; + c.setAlphaF( f(x) ); + rg.setColorAt( x, c ); } + + p.setBrush( rg ); + renderGradient( p, shadow.rect(), rg, hasBorder ); + + } + + { + + // mid gradient + const qreal gradientSize = qMin( shadowSize, (shadowSize+2*fixedSize)/3 ); + const qreal hoffset = shadowConfiguration.horizontalOffset()*gradientSize/fixedSize; + const qreal voffset = shadowConfiguration.verticalOffset()*gradientSize/fixedSize; + + // gaussian shadow is used + QRadialGradient rg = QRadialGradient( size+8.0*hoffset, size+8.0*voffset, gradientSize ); + rg.setColorAt(1, Qt::transparent ); + + int nPoints( (10*gradientSize)/fixedSize ); + Gaussian f( 0.54, 0.21); + QColor c = shadowConfiguration.outerColor(); + for( int i = 0; i < nPoints; i++ ) { - - // mid gradient - const qreal gradientSize = qMin( shadowSize, (shadowSize+2*fixedSize)/3 ); - const qreal hoffset = shadowConfiguration.horizontalOffset()*gradientSize/fixedSize; - const qreal voffset = shadowConfiguration.verticalOffset()*gradientSize/fixedSize; - - // gaussian shadow is used - QRadialGradient rg = QRadialGradient( size+8.0*hoffset, size+8.0*voffset, gradientSize ); - rg.setColorAt(1, Qt::transparent ); - - int nPoints( (10*gradientSize)/fixedSize ); - Gaussian f( 0.54, 0.21); - QColor c = shadowConfiguration.outerColor(); - for( int i = 0; i < nPoints; i++ ) - { - qreal x = qreal(i)/nPoints; - c.setAlphaF( f(x) ); - rg.setColorAt( x, c ); - - } - - p.setBrush( rg ); - p.drawRect( shadow.rect() ); + qreal x = qreal(i)/nPoints; + c.setAlphaF( f(x) ); + rg.setColorAt( x, c ); } + p.setBrush( rg ); + p.drawRect( shadow.rect() ); + + } + + { + + // outer (spread) gradient + const qreal gradientSize = shadowSize; + const qreal hoffset = shadowConfiguration.horizontalOffset()*gradientSize/fixedSize; + const qreal voffset = shadowConfiguration.verticalOffset()*gradientSize/fixedSize; + + // gaussian shadow is used + QRadialGradient rg = QRadialGradient( size+20.0*hoffset, size+20.0*voffset, gradientSize ); + rg.setColorAt(1, Qt::transparent ); + + int nPoints( (20*gradientSize)/fixedSize ); + Gaussian f( 0.155, 0.445); + QColor c = shadowConfiguration.outerColor(); + for( int i = 0; i < nPoints; i++ ) { - - // outer (spread) gradient - const qreal gradientSize = shadowSize; - const qreal hoffset = shadowConfiguration.horizontalOffset()*gradientSize/fixedSize; - const qreal voffset = shadowConfiguration.verticalOffset()*gradientSize/fixedSize; - - // gaussian shadow is used - QRadialGradient rg = QRadialGradient( size+20.0*hoffset, size+20.0*voffset, gradientSize ); - rg.setColorAt(1, Qt::transparent ); - - int nPoints( (20*gradientSize)/fixedSize ); - Gaussian f( 0.155, 0.445); - QColor c = shadowConfiguration.outerColor(); - for( int i = 0; i < nPoints; i++ ) - { - qreal x = qreal(i)/nPoints; - c.setAlphaF( f(x) ); - rg.setColorAt( x, c ); - } - - p.setBrush( rg ); - p.drawRect( shadow.rect() ); - + qreal x = qreal(i)/nPoints; + c.setAlphaF( f(x) ); + rg.setColorAt( x, c ); } + p.setBrush( rg ); + p.drawRect( shadow.rect() ); + } } diff --git a/clients/oxygen/oxygenshadowcache.h b/clients/oxygen/oxygenshadowcache.h index ab0c0757b8..b6a61e9d18 100644 --- a/clients/oxygen/oxygenshadowcache.h +++ b/clients/oxygen/oxygenshadowcache.h @@ -110,11 +110,9 @@ namespace Oxygen { qreal activeSize( activeShadowConfiguration_.isEnabled() ? activeShadowConfiguration_.shadowSize():0 ); qreal inactiveSize( inactiveShadowConfiguration_.isEnabled() ? inactiveShadowConfiguration_.shadowSize():0 ); - qreal size( qMax( activeSize, inactiveSize ) ); // even if shadows are disabled, - // you need a minimum size to allow corner rendering - return qMax( size, qreal(5.0) ); + return qMax( activeSize, inactiveSize ); } //! Key class to be used into QCache @@ -242,6 +240,9 @@ namespace Oxygen //! helper DecoHelper& helper_; + //! defines overlap between shadows and body + enum { overlap = 4 }; + //! caching enable state bool enabled_;