Added oxygen-shadow-demo to demonstrate shadow painting, add the possibility to save pixmaps

into files, and for debugging.

svn path=/trunk/KDE/kdebase/workspace/; revision=1217934
This commit is contained in:
Hugo Pereira Da Costa 2011-01-29 18:12:23 +00:00
parent 025e7a5859
commit fdddfcf9ee
8 changed files with 599 additions and 1 deletions

View file

@ -1,6 +1,8 @@
########### add version number into compilation defines
add_definitions ( -DAPP_VERSION=\\\"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}\\\")
add_subdirectory( config )
add_subdirectory( demo )
include_directories(${KDEBASE_WORKSPACE_SOURCE_DIR}/libs/oxygen)
########### next target ###############
@ -13,8 +15,8 @@ set(kwin_oxygen_SRCS
oxygenexception.cpp
oxygenexceptionlist.cpp
oxygenfactory.cpp
oxygenshadowconfiguration.cpp
oxygenshadowcache.cpp
oxygenshadowconfiguration.cpp
oxygensizegrip.cpp
oxygentitleanimationdata.cpp
)

View file

@ -0,0 +1,28 @@
include_directories( ${KDE4_KDEUI_INCLUDES} )
########### next target ###############
set( oxygen_shadow_demo_SOURCES
../oxygendecohelper.cpp
../oxygenshadowcache.cpp
../oxygenshadowconfiguration.cpp
oxygenshadowdemodialog.cpp
oxygenshadowdemowidget.cpp
main.cpp)
kde4_add_ui_files(oxygen_shadow_demo_SOURCES
ui/oxygenshadowdemo.ui
)
kde4_add_executable( oxygen-shadow-demo ${oxygen_shadow_demo_SOURCES} )
target_link_libraries( oxygen-shadow-demo
${KDE4_KDEUI_LIBS}
${X11_X11_LIB}
${X11_Xrender_LIB}
${KDE4_KIO_LIBS}
oxygenstyle
)
########### install files ###############
install (TARGETS oxygen-shadow-demo ${INSTALL_TARGETS_DEFAULT_ARGS} )

View file

@ -0,0 +1,62 @@
//////////////////////////////////////////////////////////////////////////////
// main.cpp
// oxygen-demo main
// -------------------
//
// Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include "oxygenshadowdemodialog.h"
#include <KCmdLineArgs>
#include <KApplication>
#include <KIcon>
#include <KAboutData>
#include <kdeversion.h>
#include <cassert>
int main(int argc, char *argv[])
{
KAboutData aboutData(
"oxygen-shadow-demo",
"kstyle_config",
ki18n( "Oxygen Shadow Demo" ),
KDE_VERSION_STRING,
ki18n( "Oxygen decoration shadows demonstration" ),
KAboutData::License_GPL_V2,
ki18n( "(c) 2011, Hugo Pereira Da Costa" ));
aboutData.addAuthor( ki18n( "Hugo Pereira Da Costa" ),KLocalizedString(), "hugo@oxygen-icons.org" );
KCmdLineArgs::init( argc, argv, &aboutData );
KApplication app;
app.setWindowIcon( KIcon( "oxygen" ) );
// create dialog
Oxygen::ShadowDemoDialog dialog;
dialog.show();
bool result = app.exec();
return result;
}

View file

@ -0,0 +1,124 @@
//////////////////////////////////////////////////////////////////////////////
// oxygenshadowdemodialog.h
// oxygen shadow demo dialog
// -------------------
//
// Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include "oxygenshadowdemodialog.h"
#include "oxygenshadowdemodialog.moc"
#include "../oxygenshadowconfiguration.h"
#include "oxygenhelper.h"
#include <QtGui/QDialogButtonBox>
#include <KPushButton>
#include <KFileDialog>
namespace Oxygen
{
//_________________________________________________________
ShadowDemoDialog::ShadowDemoDialog( QWidget* parent ):
KDialog( parent ),
_helper( "oxygenDeco" ),
_cache( _helper )
{
setWindowTitle( i18n( "Oxygen Shadow Demo" ) );
setButtons( KDialog::Cancel|KDialog::Apply );
button( KDialog::Apply )->setText( i18n("Save") );
button( KDialog::Apply )->setIcon( KIcon("document-save-as") );
button( KDialog::Apply )->setToolTip( i18n( "Save shadows as pixmaps in provided directory" ) );
QWidget *mainWidget( new QWidget( this ) );
ui.setupUi( mainWidget );
setMainWidget( mainWidget );
// read shadow configurations
KConfig config( "oxygenrc" );
_cache.setEnabled( true );
_cache.setShadowConfiguration( ShadowConfiguration( QPalette::Inactive, KConfigGroup( &config, "InactiveShadow") ) );
_cache.setShadowConfiguration( ShadowConfiguration( QPalette::Active, KConfigGroup( &config, "ActiveShadow") ) );
// pass tileSets to UI
ShadowCache::Key key;
key.active = false;
key.hasBorder = true;
key.useOxygenShadows = true;
ui.inactiveRoundWidget->setHelper( _helper );
ui.inactiveRoundWidget->setTileSet( *_cache.tileSet( key ) );
ui.inactiveRoundWidget->setShadowSize( _cache.shadowSize() );
key.active = false;
key.hasBorder = false;
key.useOxygenShadows = true;
ui.inactiveSquareWidget->setHelper( _helper );
ui.inactiveSquareWidget->setTileSet( *_cache.tileSet( key ) );
ui.inactiveSquareWidget->setShadowSize( _cache.shadowSize() );
ui.inactiveSquareWidget->setSquare( true );
key.active = true;
key.hasBorder = true;
key.useOxygenShadows = true;
ui.activeRoundWidget->setHelper( _helper );
ui.activeRoundWidget->setTileSet( *_cache.tileSet( key ) );
ui.activeRoundWidget->setShadowSize( _cache.shadowSize() );
key.active = true;
key.hasBorder = false;
key.useOxygenShadows = true;
ui.activeSquareWidget->setHelper( _helper );
ui.activeSquareWidget->setTileSet( *_cache.tileSet( key ) );
ui.activeSquareWidget->setShadowSize( _cache.shadowSize() );
ui.activeSquareWidget->setSquare( true );
// customize button box
QList<QDialogButtonBox*> children( findChildren<QDialogButtonBox*>() );
if( !children.isEmpty() )
{
QDialogButtonBox* buttonBox( children.front() );
_backgroundCheckBox = new QCheckBox( i18n( "Draw window background" ) );
_backgroundCheckBox->setChecked( true );
buttonBox->addButton( _backgroundCheckBox, QDialogButtonBox::ResetRole );
connect( _backgroundCheckBox, SIGNAL( toggled( bool ) ), ui.inactiveRoundWidget, SLOT( toggleBackground( bool ) ) );
connect( _backgroundCheckBox, SIGNAL( toggled( bool ) ), ui.inactiveSquareWidget, SLOT( toggleBackground( bool ) ) );
connect( _backgroundCheckBox, SIGNAL( toggled( bool ) ), ui.activeRoundWidget, SLOT( toggleBackground( bool ) ) );
connect( _backgroundCheckBox, SIGNAL( toggled( bool ) ), ui.activeSquareWidget, SLOT( toggleBackground( bool ) ) );
}
// save
connect( button( KDialog::Apply ), SIGNAL( clicked() ), SLOT( save() ) );
}
//_________________________________________________________
void ShadowDemoDialog::save( void )
{
QString dir( KFileDialog::getExistingDirectory() );
ui.inactiveRoundWidget->tileSet().save( dir + "/shadow" );
}
}

View file

@ -0,0 +1,76 @@
#ifndef oxygenshadowdemodialog_h
#define oxygenshadowdemodialog_h
//////////////////////////////////////////////////////////////////////////////
// oxygenshadowdemodialog.h
// oxygen shadow demo dialog
// -------------------
//
// Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include "ui_oxygenshadowdemo.h"
#include "../oxygendecohelper.h"
#include "../oxygenshadowcache.h"
#include <KDialog>
#include <QtGui/QCheckBox>
namespace Oxygen
{
class ShadowDemoDialog: public KDialog
{
Q_OBJECT
public:
//! constructor
explicit ShadowDemoDialog( QWidget* = 0 );
//! destructor
virtual ~ShadowDemoDialog( void )
{}
protected slots:
//! save
void save( void );
private:
//! ui
Ui_ShadowDemo ui;
//! helper
DecoHelper _helper;
//! shadow cache
ShadowCache _cache;
//! enable state checkbox
QCheckBox* _backgroundCheckBox;
};
}
#endif

View file

@ -0,0 +1,105 @@
//////////////////////////////////////////////////////////////////////////////
// oxygenshadowdemowidget.h
// shadow demo widget
// -------------------
//
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include "oxygenshadowdemowidget.h"
#include "oxygenshadowdemowidget.moc"
#include <QtGui/QPainter>
namespace Oxygen
{
//______________________________________
void ShadowDemoWidget::paintEvent( QPaintEvent* event )
{
if( !_tileSet.isValid() ) return;
QPainter painter( this );
painter.setClipRegion( event->region() );
_tileSet.render( rect(), &painter );
// draw background
if( _drawBackground )
{
updateBackgroundPixmap();
painter.translate( _shadowSize - 4, _shadowSize - 4 );
painter.drawPixmap( QPoint(0,0), _backgroundPixmap );
}
}
//______________________________________
void ShadowDemoWidget::updateBackgroundPixmap( void )
{
// check if background pixmap needs update
QRect backgroundRect( QPoint( 0, 0 ), size() - QSize( 2*(_shadowSize-4), 2*(_shadowSize-4) ) );
if( !_backgroundPixmap.isNull() && _backgroundPixmap.size() == backgroundRect.size() )
{ return; }
_backgroundPixmap = QPixmap( backgroundRect.size() );
_backgroundPixmap.fill( Qt::transparent );
QPainter painter( &_backgroundPixmap );
painter.setRenderHint( QPainter::Antialiasing );
_dummy.resize( backgroundRect.size() );
helper().renderWindowBackground(
&painter, backgroundRect,
&_dummy, &_dummy, palette().color( QPalette::Window ), 0, 64 );
// float frame
helper().drawFloatFrame( &painter, backgroundRect.adjusted( -1, -1, 1, 1 ), palette().color( QPalette::Window ), false );
// add rounded mask
painter.save();
painter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
painter.setBrush( Qt::black );
painter.setPen( Qt::NoPen );
if( _square )
{
QRectF rectF( backgroundRect );
QPainterPath path;
// rotate counterclockwise, cause that makes angles easier
path.moveTo( rectF.topLeft() + QPointF( 3.5, 0 ) );
path.arcTo( QRectF( rectF.topLeft(), QSize( 7, 7 ) ), 90, 90 );
path.lineTo( rectF.bottomLeft() );
path.lineTo( rectF.bottomRight() );
path.lineTo( rectF.topRight() + QPointF( 0, 3.5 ) );
path.arcTo( QRectF( rectF.topRight() + QPointF( -7, 0 ), QSize( 7, 7 ) ), 0, 90 );
path.lineTo( rectF.topLeft() + QPointF( 3.5, 0 ) );
painter.drawPath( path );
} else {
painter.drawRoundedRect( QRectF( backgroundRect ), 3.5, 3.5 );
}
painter.restore();
}
}

View file

@ -0,0 +1,140 @@
#ifndef oxygenshadowdemowidget_h
#define oxygenshadowdemowidget_h
//////////////////////////////////////////////////////////////////////////////
// oxygenshadowdemowidget.h
// shadow demo widget
// -------------------
//
// Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//////////////////////////////////////////////////////////////////////////////
#include "oxygentileset.h"
#include "oxygenhelper.h"
#include <QtGui/QWidget>
#include <QtGui/QPaintEvent>
#include <QtGui/QPixmap>
#include <cassert>
namespace Oxygen
{
//! shadow demo widget
class ShadowDemoWidget: public QWidget
{
Q_OBJECT
public:
//! constructor
explicit ShadowDemoWidget( QWidget* parent = 0 ):
QWidget( parent ),
_drawBackground( true ),
_square( false ),
_helper( 0L )
{}
//! destructor
virtual ~ShadowDemoWidget( void )
{}
//! helper
void setHelper( Helper& helper )
{ _helper = &helper; }
//! set tileSet
void setTileSet( const TileSet& tileSet )
{
_tileSet = tileSet;
if( isVisible() ) update();
}
//! tileset
const TileSet& tileSet( void ) const
{ return _tileSet; }
//! set shadow size
void setShadowSize( int size )
{
_shadowSize = size;
setMinimumSize( _shadowSize*2 + 100, _shadowSize*2 + 60 );
}
//! square
void setSquare( bool value )
{
_square = value;
if( isVisible() ) update();
}
protected slots:
//! toggle background drawing
void toggleBackground( bool value )
{
if( value == _drawBackground ) return;
_drawBackground = value;
update();
}
protected:
//! paint event
virtual void paintEvent( QPaintEvent* );
//! render window to pixmap
void updateBackgroundPixmap( void );
Helper& helper( void ) const
{
assert( _helper );
return *_helper;
}
private:
//! shadow size
int _shadowSize;
//! draw window background
bool _drawBackground;
//! true if (bottom) corners are square
bool _square;
//! helper
Helper* _helper;
//! dummy widget
QWidget _dummy;
//! window pixmap
QPixmap _backgroundPixmap;
//! tileSet
TileSet _tileSet;
};
}
#endif

View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ShadowDemo</class>
<widget class="QWidget" name="ShadowDemo">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>492</width>
<height>378</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,1,1">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Inactive Windows</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Active Windows</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="Oxygen::ShadowDemoWidget" name="inactiveRoundWidget" native="true"/>
</item>
<item row="1" column="1">
<widget class="Oxygen::ShadowDemoWidget" name="activeRoundWidget" native="true"/>
</item>
<item row="2" column="0">
<widget class="Oxygen::ShadowDemoWidget" name="inactiveSquareWidget" native="true"/>
</item>
<item row="2" column="1">
<widget class="Oxygen::ShadowDemoWidget" name="activeSquareWidget" native="true"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Oxygen::ShadowDemoWidget</class>
<extends>QWidget</extends>
<header>oxygenshadowdemowidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>