diff --git a/clients/ozone/oxygen.cpp b/clients/ozone/oxygen.cpp index ae27f69400..8d4164e07d 100644 --- a/clients/ozone/oxygen.cpp +++ b/clients/ozone/oxygen.cpp @@ -24,6 +24,8 @@ // IN THE SOFTWARE. ////////////////////////////////////////////////////////////////////////////// +#include + #include "oxygen.h" #include "oxygenclient.h" #include @@ -150,6 +152,8 @@ bool OxygenFactory::supports( Ability ability ) const case AbilityButtonBelowOthers: case AbilityButtonSpacer: case AbilityButtonShade: + // compositing + case AbilityCompositingShadow: // TODO: UI option to use default shadows instead return true; // no colors supported at this time default: @@ -157,5 +161,129 @@ bool OxygenFactory::supports( Ability ability ) const }; } +////////////////////////////////////////////////////////////////////////////// +// Shadows + +QList< QList > OxygenFactory::shadowTextures() +{ + // 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 + + qreal size = 2 * ( shadowFuzzyness + shadowSize ) + 1; + QPixmap *shadow = new QPixmap( size, size ); + shadow->fill( Qt::transparent ); + size /= 2.0; + QRadialGradient rg( size, size, size ); + QColor c( 150, 234, 255, 255 ); + rg.setColorAt( 0, c ); + c.setAlpha( 0.3 * c.alpha() ); + if( shadowSize > 0 ) + rg.setColorAt( float( shadowSize ) / ( shadowFuzzyness + shadowSize ), c ); + c.setAlpha( 0 ); + rg.setColorAt( 0.8, c ); + QPainter p( shadow ); + p.setRenderHint( QPainter::Antialiasing ); + p.setPen( Qt::NoPen ); + p.setBrush( rg ); + p.drawRect( shadow->rect() ); + 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 ); + MAKE_TEX( 1, h, w, h ); + MAKE_TEX( w, h, w, h ); + MAKE_TEX( w, 1, 0, h ); + //MAKE_TEX( 1, 1, w, h ); + MAKE_TEX( w, 1, w, h ); + MAKE_TEX( w, h, 0, 0 ); + MAKE_TEX( 1, h, w, 0 ); + MAKE_TEX( w, h, w, 0 ); + delete shadow; + + textureLists.append( textures ); + + //--------------------------------------------------------------- + // Inactive shadow texture + + for( int i = 0; i < 8; i++ ) + { + QPainter pi( &textures[i] ); + pi.fillRect( textures[i].rect(), QColor( 0, 0, 0, 255 )); + pi.end(); + textures[i].setAlphaChannel( textureLists[0][i].alphaChannel() ); + } + + textureLists.append( textures ); + + return textureLists; +} + +int OxygenFactory::shadowTextureList( ShadowType type ) const +{ + switch( type ) { + case ShadowBorderedActive: + case ShadowBorderlessActive: + return 0; + case ShadowBorderedInactive: + case ShadowBorderlessInactive: + case ShadowOther: + return 1; + } + abort(); // Should never be reached +} + +QList OxygenFactory::shadowQuads( ShadowType type, QSize size ) const +{ +#define shadowFuzzyness 15 + + // These are slightly under the decoration so the corners look nicer + QList quads; + quads.append( QRect( -shadowFuzzyness+5, -shadowFuzzyness+5, shadowFuzzyness, shadowFuzzyness )); + quads.append( QRect( 0+5, -shadowFuzzyness+5, size.width()-10, shadowFuzzyness )); + quads.append( QRect( size.width()-5, -shadowFuzzyness+5, shadowFuzzyness, shadowFuzzyness )); + quads.append( QRect( -shadowFuzzyness+5, 0+5, shadowFuzzyness, size.height()-10 )); + //quads.append( QRect( 0+5, 0+5, size.width()-10, size.height()-10 )); + quads.append( QRect( size.width()-5, 0+5, shadowFuzzyness, size.height()-10 )); + quads.append( QRect( -shadowFuzzyness+5, size.height()-5, shadowFuzzyness, shadowFuzzyness )); + quads.append( QRect( 0+5, size.height()-5, size.width()-10, shadowFuzzyness )); + quads.append( QRect( size.width()-5, size.height()-5, shadowFuzzyness, shadowFuzzyness )); + + return quads; +} + +double OxygenFactory::shadowOpacity( ShadowType type, double dataOpacity ) const +{ + switch( type ) { + case ShadowBorderlessActive: + return dataOpacity; + case ShadowBorderlessInactive: + case ShadowOther: + return dataOpacity * 0.25; + } + abort(); // Should never be reached +} + } //namespace Oxygen } //namespace Ozone diff --git a/clients/ozone/oxygen.h b/clients/ozone/oxygen.h index 6cb4b4974b..e4f034100e 100644 --- a/clients/ozone/oxygen.h +++ b/clients/ozone/oxygen.h @@ -55,7 +55,7 @@ enum ButtonType { }; Q_DECLARE_FLAGS(ButtonTypes, ButtonType) -class OxygenFactory: public KDecorationFactory +class OxygenFactory: public KDecorationFactoryUnstable { public: OxygenFactory(); @@ -64,6 +64,11 @@ public: virtual bool reset(unsigned long changed); virtual bool supports( Ability ability ) const; + virtual QList< QList > shadowTextures(); + virtual int shadowTextureList( ShadowType type ) const; + virtual QList shadowQuads( ShadowType type, QSize size ) const; + virtual double shadowOpacity( ShadowType type, double dataOpacity ) const; + static bool initialized(); static Qt::Alignment titleAlignment(); static bool showStripes(); diff --git a/clients/ozone/oxygenclient.cpp b/clients/ozone/oxygenclient.cpp index 049e71f562..6996edc81a 100644 --- a/clients/ozone/oxygenclient.cpp +++ b/clients/ozone/oxygenclient.cpp @@ -72,7 +72,7 @@ void renderDot(QPainter *p, const QPointF &point, qreal diameter) OxygenClient::OxygenClient(KDecorationBridge *b, KDecorationFactory *f) - : KCommonDecoration(b, f) + : KCommonDecorationUnstable(b, f) , colorCacheInvalid_(true) , helper_(*globalHelper) { @@ -424,6 +424,41 @@ void OxygenClient::updateWindowShape() setMask(mask); } +QList OxygenClient::shadowQuads( ShadowType type ) const +{ + QSize size = widget()->size(); +#define shadowFuzzyness 15 + + // These are slightly under the decoration so the corners look nicer + QList quads; + quads.append( QRect( -shadowFuzzyness+5, -shadowFuzzyness+5, shadowFuzzyness, shadowFuzzyness )); + quads.append( QRect( 0+5, -shadowFuzzyness+5, size.width()-10, shadowFuzzyness )); + quads.append( QRect( size.width()-5, -shadowFuzzyness+5, shadowFuzzyness, shadowFuzzyness )); + quads.append( QRect( -shadowFuzzyness+5, 0+5, shadowFuzzyness, size.height()-10 )); + //quads.append( QRect( 0+5, 0+5, size.width()-10, size.height()-10 )); + quads.append( QRect( size.width()-5, 0+5, shadowFuzzyness, size.height()-10 )); + quads.append( QRect( -shadowFuzzyness+5, size.height()-5, shadowFuzzyness, shadowFuzzyness )); + quads.append( QRect( 0+5, size.height()-5, size.width()-10, shadowFuzzyness )); + quads.append( QRect( size.width()-5, size.height()-5, shadowFuzzyness, shadowFuzzyness )); + + return quads; +} + +double OxygenClient::shadowOpacity( ShadowType type, double dataOpacity ) const +{ + switch( type ) { + case ShadowBorderedActive: + if( isActive() ) + return dataOpacity; + return 0.0; + case ShadowBorderedInactive: + if( isActive() ) + return 0.0; + return dataOpacity * 0.25; + } + abort(); // Should never be reached +} + } //namespace Oxygen } //namespace Ozone diff --git a/clients/ozone/oxygenclient.h b/clients/ozone/oxygenclient.h index 916c8548db..76b8d75bac 100644 --- a/clients/ozone/oxygenclient.h +++ b/clients/ozone/oxygenclient.h @@ -39,7 +39,7 @@ namespace Ozone { namespace Oxygen { -class OxygenClient : public KCommonDecoration +class OxygenClient : public KCommonDecorationUnstable { Q_OBJECT public: @@ -53,6 +53,9 @@ public: virtual void updateWindowShape(); virtual void init(); + virtual QList shadowQuads( ShadowType type ) const; + virtual double shadowOpacity( ShadowType type, double dataOpacity ) const; + private: void paintEvent(QPaintEvent *e); void drawScratch(QPainter *p, QPalette &palette, const int start, const int end, const int topMargin);