Aurorae supports rendering previews directly, so we can drop the custom preview painting code.

svn path=/trunk/KDE/kdebase/workspace/; revision=1115567
This commit is contained in:
Martin Gräßlin 2010-04-16 21:03:34 +00:00
parent 6430ab6a36
commit c9d70cef70
5 changed files with 53 additions and 452 deletions

View file

@ -3,6 +3,8 @@ include_directories(
${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/clients/aurorae/src/lib
)
set(AURORAE_SOURCE_DIR ${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/clients/aurorae/src/lib/)
set(kcm_kwindecoration_PART_SRCS
kwindecoration.cpp
buttons.cpp
@ -11,8 +13,11 @@ set(kcm_kwindecoration_PART_SRCS
preview.cpp
decorationdelegate.cpp
decorationmodel.cpp
auroraepreview.cpp
${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/clients/aurorae/src/lib/themeconfig.cpp
${AURORAE_SOURCE_DIR}/auroraebutton.cpp
${AURORAE_SOURCE_DIR}/auroraescene.cpp
${AURORAE_SOURCE_DIR}/auroraetab.cpp
${AURORAE_SOURCE_DIR}/auroraetheme.cpp
${AURORAE_SOURCE_DIR}/themeconfig.cpp
)
kde4_add_ui_files(kcm_kwindecoration_PART_SRCS buttons.ui config.ui decoration.ui)

View file

@ -1,381 +0,0 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "auroraepreview.h"
#include "themeconfig.h"
// Qt
#include <QFile>
#include <QFont>
#include <QPainter>
// KDE
#include <KGlobalSettings>
#include <KIcon>
#include <KLocale>
#include <KStandardDirs>
// Plasma
#include <Plasma/FrameSvg>
#include <Plasma/PaintUtils>
namespace KWin
{
AuroraePreview::AuroraePreview( const QString& name, const QString& packageName,
const QString& themeRoot, QObject* parent )
: QObject( parent )
, m_title( name )
{
m_svg = new Plasma::FrameSvg( this );
QString svgFile = themeRoot + "/decoration.svg";
if( QFile::exists( svgFile ) )
{
m_svg->setImagePath( svgFile );
}
else
{
m_svg->setImagePath( svgFile + 'z' );
}
m_svg->setEnabledBorders( Plasma::FrameSvg::AllBorders );
m_themeConfig = new Aurorae::ThemeConfig();
KConfig conf( "aurorae/themes/" + packageName + '/' + packageName + "rc", KConfig::FullConfig, "data" );
m_themeConfig->load( conf );
initButtonFrame( "minimize", packageName );
initButtonFrame( "maximize", packageName );
initButtonFrame( "restore", packageName );
initButtonFrame( "close", packageName );
initButtonFrame( "alldesktops", packageName );
initButtonFrame( "keepabove", packageName );
initButtonFrame( "keepbelow", packageName );
initButtonFrame( "shade", packageName );
initButtonFrame( "help", packageName );
}
AuroraePreview::~AuroraePreview()
{
delete m_themeConfig;
}
void AuroraePreview::initButtonFrame( const QString &button, const QString &themeName )
{
QString file( "aurorae/themes/" + themeName + '/' + button + ".svg" );
QString path = KGlobal::dirs()->findResource( "data", file );
if( path.isEmpty() )
{
// let's look for svgz
file.append("z");
path = KGlobal::dirs()->findResource( "data", file );
}
if( !path.isEmpty() )
{
Plasma::FrameSvg *frame = new Plasma::FrameSvg( this );
frame->setImagePath( path );
frame->setCacheAllRenderedFrames( true );
frame->setEnabledBorders( Plasma::FrameSvg::NoBorder );
m_buttons.insert( button, frame );
}
}
QPixmap AuroraePreview::preview( const QSize& size, bool custom,
const QString& left, const QString& right ) const
{
QPixmap pixmap( size );
pixmap.fill( Qt::transparent );
QPainter painter( &pixmap );
painter.save();
paintDeco( &painter, false, pixmap.rect(), 5 + m_themeConfig->paddingLeft() + m_themeConfig->borderLeft(),
5, 5, 5 + m_themeConfig->paddingBottom() + m_themeConfig->borderBottom(),
custom, left, right );
painter.restore();
painter.save();
int activeLeft = 5;
int activeTop = 5 + m_themeConfig->paddingTop() + m_themeConfig->titleEdgeTop() +
m_themeConfig->titleEdgeBottom() + m_themeConfig->titleHeight();
int activeRight = 5 + m_themeConfig->paddingRight() + m_themeConfig->borderRight();
int activeBottom = 5;
paintDeco( &painter, true, pixmap.rect(), activeLeft, activeTop, activeRight, activeBottom,
custom, left, right );
painter.restore();
// paint title
painter.save();
QFont font = painter.font();
font.setWeight( QFont::Bold );
painter.setPen( m_themeConfig->activeTextColor() );
painter.setFont( font );
painter.drawText( QRect( pixmap.rect().topLeft() + QPoint( activeLeft, activeTop ),
pixmap.rect().bottomRight() - QPoint( activeRight, activeBottom ) ),
Qt::AlignCenter | Qt::TextWordWrap, m_title );
painter.restore();
return pixmap;
}
void AuroraePreview::paintDeco( QPainter *painter, bool active, const QRect &rect,
int leftMargin, int topMargin, int rightMargin, int bottomMargin,
bool custom, const QString& left, const QString& right ) const
{
m_svg->setElementPrefix( "decoration" );
if( !active && m_svg->hasElementPrefix("decoration-inactive") )
{
m_svg->setElementPrefix( "decoration-inactive" );
}
m_svg->resizeFrame( QSize( rect.width() - leftMargin - rightMargin, rect.height() - topMargin - bottomMargin ) );
m_svg->paintFrame( painter, rect.topLeft() + QPoint( leftMargin, topMargin ) );
int y = rect.top() + topMargin + m_themeConfig->paddingTop() + m_themeConfig->titleEdgeTop() + m_themeConfig->buttonMarginTop();
int x = rect.left() + leftMargin + m_themeConfig->paddingLeft() + m_themeConfig->titleEdgeLeft();
int buttonWidth = m_themeConfig->buttonWidth();
int buttonHeight = m_themeConfig->buttonHeight();
foreach( const QChar &character, custom ? left : m_themeConfig->defaultButtonsLeft() )
{
QString buttonName;
int width = buttonWidth;
if( character == '_' )
{
x += m_themeConfig->explicitButtonSpacer() + m_themeConfig->buttonSpacing();
continue;
}
else if( character == 'M' )
{
KIcon icon = KIcon( "xorg" );
int iconSize = qMin( m_themeConfig->buttonWidthMenu(), m_themeConfig->buttonHeight() );
QSize buttonSize( iconSize,iconSize );
painter->drawPixmap( QPoint( x, y ), icon.pixmap( buttonSize ) );
x += m_themeConfig->buttonWidthMenu();
}
else if( character == 'S' )
{
buttonName = "alldesktops";
width = m_themeConfig->buttonWidthAllDesktops();
}
else if( character == 'H' )
{
buttonName = "help";
width = m_themeConfig->buttonWidthHelp();
}
else if( character == 'I' )
{
buttonName = "minimize";
width = m_themeConfig->buttonWidthMinimize();
}
else if( character == 'A' )
{
buttonName = "restore";
if( !m_buttons.contains( buttonName ) )
{
buttonName = "maximize";
}
width = m_themeConfig->buttonWidthMaximizeRestore();
}
else if( character == 'X' )
{
buttonName = "close";
width = m_themeConfig->buttonWidthClose();
}
else if( character == 'F' )
{
buttonName = "keepabove";
width = m_themeConfig->buttonWidthKeepAbove();
}
else if( character == 'B' )
{
buttonName = "keepbelow";
width = m_themeConfig->buttonWidthKeepBelow();
}
else if( character == 'L' )
{
buttonName = "shade";
width = m_themeConfig->buttonWidthShade();
}
if( !buttonName.isEmpty() && m_buttons.contains( buttonName ) )
{
Plasma::FrameSvg *frame = m_buttons.value( buttonName );
frame->setElementPrefix( "active" );
if( !active && frame->hasElementPrefix( "inactive" ) )
{
frame->setElementPrefix( "inactive" );
}
frame->resizeFrame( QSize( width, buttonHeight ) );
frame->paintFrame( painter, QPoint( x, y ) );
x += width;
}
x += m_themeConfig->buttonSpacing();
}
if( !m_themeConfig->defaultButtonsLeft().isEmpty() )
{
x -= m_themeConfig->buttonSpacing();
}
int titleLeft = x;
x = rect.right() - rightMargin - m_themeConfig->paddingRight() - m_themeConfig->titleEdgeRight();
QString rightButtons;
foreach( const QChar &character, custom ? right : m_themeConfig->defaultButtonsRight() )
{
rightButtons.prepend(character);
}
foreach (const QChar &character, rightButtons)
{
QString buttonName;
int width = buttonWidth;
if( character == '_' )
{
x -= m_themeConfig->explicitButtonSpacer() + m_themeConfig->buttonSpacing();
continue;
}
else if( character == 'M' )
{
KIcon icon = KIcon( "xorg" );
QSize buttonSize( buttonWidth, buttonHeight );
x -= m_themeConfig->buttonWidthMenu();
painter->drawPixmap( QPoint( x, y ), icon.pixmap( buttonSize ) );
}
else if( character == 'S' )
{
buttonName = "alldesktops";
width = m_themeConfig->buttonWidthAllDesktops();
}
else if( character == 'H' )
{
buttonName = "help";
width = m_themeConfig->buttonWidthHelp();
}
else if( character == 'I' )
{
buttonName = "minimize";
width = m_themeConfig->buttonWidthMinimize();
}
else if( character == 'A' )
{
buttonName = "restore";
if( !m_buttons.contains( buttonName ) )
{
buttonName = "maximize";
}
width = m_themeConfig->buttonWidthMaximizeRestore();
}
else if( character == 'X' )
{
buttonName = "close";
width = m_themeConfig->buttonWidthClose();
}
else if( character == 'F' )
{
buttonName = "keepabove";
width = m_themeConfig->buttonWidthKeepAbove();
}
else if( character == 'B' )
{
buttonName = "keepbelow";
width = m_themeConfig->buttonWidthKeepBelow();
}
else if( character == 'L' )
{
buttonName = "shade";
width = m_themeConfig->buttonWidthShade();
}
if( !buttonName.isEmpty() && m_buttons.contains( buttonName ) )
{
Plasma::FrameSvg *frame = m_buttons.value( buttonName );
frame->setElementPrefix( "active" );
if( !active && frame->hasElementPrefix( "inactive" ) )
{
frame->setElementPrefix( "inactive" );
}
frame->resizeFrame( QSize( width, buttonHeight ) );
x -= width;
frame->paintFrame( painter, QPoint( x, y) );
}
x -= m_themeConfig->buttonSpacing();
}
if( !rightButtons.isEmpty() )
{
x += m_themeConfig->buttonSpacing();
}
int titleRight = x;
// draw text
y = rect.top() + topMargin + m_themeConfig->paddingTop() + m_themeConfig->titleEdgeTop();
QRectF titleRect( QPointF( titleLeft, y ), QPointF( titleRight, y + m_themeConfig->titleHeight() ) );
QString caption = i18n( "Active Window" );
if( !active )
{
caption = i18n( "Inactive Window" );
}
painter->setFont( KGlobalSettings::windowTitleFont() );
if( ( active && m_themeConfig->haloActive() ) || ( !active && m_themeConfig->haloInactive() ) )
{
QRectF haloRect = painter->fontMetrics().boundingRect(titleRect.toRect(),
m_themeConfig->alignment() | m_themeConfig->verticalAlignment() | Qt::TextSingleLine,
caption);
if( haloRect.width() > titleRect.width() )
haloRect.setWidth( titleRect.width() );
Plasma::PaintUtils::drawHalo(painter, haloRect);
}
if( m_themeConfig->useTextShadow() )
{
// shadow code is inspired by Qt FAQ: How can I draw shadows behind text?
// see http://www.qtsoftware.com/developer/faqs/faq.2007-07-27.3052836051
painter->save();
if( active )
{
painter->setPen( m_themeConfig->activeTextShadowColor() );
}
else
{
painter->setPen( m_themeConfig->inactiveTextShadowColor() );
}
int dx = m_themeConfig->textShadowOffsetX();
int dy = m_themeConfig->textShadowOffsetY();
painter->setOpacity( 0.5 );
painter->drawText( titleRect.translated( dx, dy ),
m_themeConfig->alignment() | m_themeConfig->verticalAlignment() | Qt::TextSingleLine,
caption );
painter->setOpacity( 0.2 );
painter->drawText( titleRect.translated( dx+1, dy ),
m_themeConfig->alignment() | m_themeConfig->verticalAlignment() | Qt::TextSingleLine,
caption );
painter->drawText( titleRect.translated( dx-1, dy ),
m_themeConfig->alignment() | m_themeConfig->verticalAlignment() | Qt::TextSingleLine,
caption );
painter->drawText( titleRect.translated( dx, dy+1 ),
m_themeConfig->alignment() | m_themeConfig->verticalAlignment() | Qt::TextSingleLine,
caption );
painter->drawText( titleRect.translated( dx, dy-1 ),
m_themeConfig->alignment() | m_themeConfig->verticalAlignment() | Qt::TextSingleLine,
caption );
painter->restore();
painter->save();
}
if( active )
{
painter->setPen( m_themeConfig->activeTextColor() );
}
else
{
painter->setPen( m_themeConfig->inactiveTextColor() );
}
painter->drawText( titleRect,
m_themeConfig->alignment() | m_themeConfig->verticalAlignment() | Qt::TextSingleLine,
caption );
painter->restore();
}
} // namespace KWin

View file

@ -1,62 +0,0 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_AURORAEPREVIEW_H
#define KWIN_AURORAEPREVIEW_H
#include <QObject>
#include <QPixmap>
#include <QHash>
namespace Aurorae
{
class ThemeConfig;
}
namespace Plasma
{
class FrameSvg;
}
namespace KWin
{
class AuroraePreview : public QObject
{
public:
AuroraePreview( const QString& name, const QString& packageName,
const QString& themeRoot, QObject* parent = NULL );
~AuroraePreview();
QPixmap preview( const QSize& size, bool custom, const QString& left, const QString& right ) const;
private:
void initButtonFrame( const QString &button, const QString &themeName );
void paintDeco( QPainter *painter, bool active, const QRect &rect,
int leftMargin, int topMargin, int rightMargin, int bottomMargin,
bool custom, const QString& left, const QString& right ) const;
Plasma::FrameSvg *m_svg;
Aurorae::ThemeConfig *m_themeConfig;
QHash<QString, Plasma::FrameSvg*> m_buttons;
QString m_title;
};
} // namespace KWin
#endif // KWIN_AURORAEPREVIEW_H

View file

@ -19,15 +19,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "decorationmodel.h"
#include "preview.h"
#include "auroraepreview.h"
#include "auroraetheme.h"
#include "auroraescene.h"
// kwin
#include <kdecorationfactory.h>
// Qt
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtGui/QApplication>
#include <QtGui/QPainter>
#include <QtGui/QStyle>
// KDE
#include <KConfigGroup>
#include <KDesktopFile>
#include <KIcon>
#include <KLocale>
#include <KStandardDirs>
namespace KWin
@ -40,7 +46,10 @@ DecorationModel::DecorationModel( KSharedConfigPtr config, QObject* parent )
, m_customButtons( false )
, m_leftButtons( QString() )
, m_rightButtons( QString() )
, m_theme( new Aurorae::AuroraeTheme( this ) )
, m_scene( new Aurorae::AuroraeScene( m_theme, QString(), QString(), true, this ) )
{
m_scene->setIcon( KIcon( "xorg" ) );
findDecorations();
}
@ -88,7 +97,6 @@ void DecorationModel::findDecorations()
data.name = desktopFile.readName();
data.libraryName = libName;
data.type = DecorationModelData::NativeDecoration;
data.aurorae = NULL;
data.borderSize = KDecorationDefines::BorderNormal;
metaData( data, desktopFile );
m_decorations.append(data);
@ -126,7 +134,6 @@ void DecorationModel::findAuroraeThemes()
data.libraryName = "kwin3_aurorae";
data.type = DecorationModelData::AuroraeDecoration;
data.auroraeName = packageName;
data.aurorae = new AuroraePreview( name, packageName, themeRoot, this );
data.borderSize = KDecorationDefines::BorderNormal;
metaData( data, df );
m_decorations.append(data);
@ -245,8 +252,35 @@ void DecorationModel::regeneratePreview( const QModelIndex& index, const QSize&
data.preview = m_preview->preview();
break;
case DecorationModelData::AuroraeDecoration:
data.preview = data.aurorae->preview( size, m_customButtons, m_leftButtons, m_rightButtons );
{
QPixmap pix( size );
pix.fill( Qt::transparent );
KConfig conf( "aurorae/themes/" + data.auroraeName + '/' + data.auroraeName + "rc", KConfig::FullConfig, "data" );
m_theme->loadTheme( data.auroraeName, conf );
m_theme->setBorderSize( data.borderSize );
int left, top, right, bottom;
m_theme->borders( left, top, right, bottom, false );
int padLeft, padRight, padTop, padBottom;
m_theme->padding( padLeft, padTop, padRight, padBottom );
top = qMin( int( top * .9 ), 30 );
int xoffset = qMin( qMax( 10, QApplication::isRightToLeft() ? left : right ), 30 );
m_scene->setSceneRect( 0, 0 ,
size.width() - xoffset - 20 + padLeft + padRight,
size.height() - top - 20 + padLeft + padRight );
m_scene->setActive( false, false );
m_scene->setCaption( data.name + " - " + i18n( "Inactive Window" ) );
m_scene->setButtons( m_customButtons ? m_leftButtons : m_theme->defaultButtonsLeft(),
m_customButtons ? m_rightButtons : m_theme->defaultButtonsRight());
QPainter painter( &pix );
QRect rect = QRectF( QPointF( 10 + xoffset - padLeft, 10 - padTop ), m_scene->sceneRect().size() ).toRect();
m_scene->render( &painter, QStyle::visualRect( QApplication::layoutDirection(), pix.rect(), rect ));
m_scene->setActive( true, false );
m_scene->setCaption( data.name + " - " + i18n( "Active Window" ) );
rect = QRectF( QPointF( 10 - padLeft, top + 10 - padTop ), m_scene->sceneRect().size() ).toRect();
m_scene->render( &painter, QStyle::visualRect( QApplication::layoutDirection(), pix.rect(), rect ));
data.preview = pix;
break;
}
default:
// nothing
break;

View file

@ -29,11 +29,15 @@ class KDesktopFile;
class KDecorationPlugins;
class KDecorationPreview;
namespace Aurorae
{
class AuroraeTheme;
class AuroraeScene;
}
namespace KWin
{
class AuroraePreview;
class DecorationModelData
{
public:
@ -53,7 +57,6 @@ class DecorationModelData
QString version;
QString license;
QString auroraeName;
AuroraePreview *aurorae;
KDecorationDefines::BorderSize borderSize;
static bool less( const DecorationModelData& a, const DecorationModelData& b )
@ -120,6 +123,8 @@ class DecorationModel : public QAbstractListModel
bool m_customButtons;
QString m_leftButtons;
QString m_rightButtons;
Aurorae::AuroraeTheme* m_theme;
Aurorae::AuroraeScene* m_scene;
};
} // namespace KWin