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)
This commit is contained in:
Hugo Pereira Da Costa 2011-02-02 16:36:50 +01:00
parent c1ff9525e3
commit 488b3644d5
4 changed files with 135 additions and 131 deletions

View file

@ -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; }

View file

@ -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() )

View file

@ -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() );
}
}

View file

@ -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_;