2008-11-04 00:08:39 +01:00
|
|
|
/*
|
|
|
|
* Copyright 2006-2007 Aaron Seigo <aseigo@kde.org>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Library General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2, 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 Library General Public
|
|
|
|
* License along with this program; if not, write to the
|
|
|
|
* Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "theme.h"
|
|
|
|
|
|
|
|
#include <QApplication>
|
|
|
|
#include <QFile>
|
2008-11-09 21:41:27 +01:00
|
|
|
#include <QFileInfo>
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
#include <QtGui/QPainter>
|
2008-11-04 00:08:39 +01:00
|
|
|
#ifdef Q_WS_X11
|
|
|
|
#include <QX11Info>
|
|
|
|
#endif
|
|
|
|
|
2008-11-04 03:04:34 +01:00
|
|
|
#include <kcolorscheme.h>
|
|
|
|
#include <kcomponentdata.h>
|
|
|
|
#include <kconfiggroup.h>
|
|
|
|
#include <kdebug.h>
|
2009-01-26 07:22:44 +01:00
|
|
|
#include <kdirwatch.h>
|
2008-11-04 03:04:34 +01:00
|
|
|
#include <kglobal.h>
|
|
|
|
#include <kglobalsettings.h>
|
2008-11-04 03:55:37 +01:00
|
|
|
#include <kmanagerselection.h>
|
2008-11-04 03:04:34 +01:00
|
|
|
#include <kpixmapcache.h>
|
|
|
|
#include <ksharedconfig.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kwindowsystem.h>
|
2008-11-04 00:08:39 +01:00
|
|
|
|
|
|
|
#include "private/packages_p.h"
|
2009-05-01 14:17:04 +02:00
|
|
|
#include "private/framebackgroundprovider.h"
|
2008-11-04 00:08:39 +01:00
|
|
|
|
|
|
|
namespace Plasma
|
|
|
|
{
|
|
|
|
|
2008-12-16 18:28:25 +01:00
|
|
|
#define DEFAULT_WALLPAPER_THEME "Air"
|
2008-11-04 00:08:39 +01:00
|
|
|
#define DEFAULT_WALLPAPER_SUFFIX ".jpg"
|
|
|
|
static const int DEFAULT_WALLPAPER_WIDTH = 1920;
|
|
|
|
static const int DEFAULT_WALLPAPER_HEIGHT = 1200;
|
|
|
|
|
2009-05-01 14:17:04 +02:00
|
|
|
QMap<QString, StandardThemeBackgroundProvider::PatternAlphaPair> StandardThemeBackgroundProvider::m_cachedPatterns;
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
|
2008-11-04 00:08:39 +01:00
|
|
|
class ThemePrivate
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ThemePrivate(Theme *theme)
|
|
|
|
: q(theme),
|
|
|
|
colorScheme(QPalette::Active, KColorScheme::Window, KSharedConfigPtr(0)),
|
|
|
|
buttonColorScheme(QPalette::Active, KColorScheme::Button, KSharedConfigPtr(0)),
|
|
|
|
defaultWallpaperTheme(DEFAULT_WALLPAPER_THEME),
|
|
|
|
defaultWallpaperSuffix(DEFAULT_WALLPAPER_SUFFIX),
|
|
|
|
defaultWallpaperWidth(DEFAULT_WALLPAPER_WIDTH),
|
|
|
|
defaultWallpaperHeight(DEFAULT_WALLPAPER_HEIGHT),
|
|
|
|
pixmapCache(0),
|
|
|
|
locolor(false),
|
|
|
|
compositingActive(KWindowSystem::compositingActive()),
|
|
|
|
isDefault(false),
|
|
|
|
useGlobal(true),
|
2009-02-24 23:42:06 +01:00
|
|
|
hasWallpapers(false),
|
|
|
|
useNativeWidgetStyle(false)
|
2008-11-04 00:08:39 +01:00
|
|
|
{
|
|
|
|
generalFont = QApplication::font();
|
2009-01-26 05:41:39 +01:00
|
|
|
cacheTheme = cacheConfig().readEntry("CacheTheme", true);
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
~ThemePrivate()
|
|
|
|
{
|
|
|
|
delete pixmapCache;
|
|
|
|
}
|
|
|
|
|
2009-01-26 05:41:39 +01:00
|
|
|
KConfigGroup cacheConfig()
|
|
|
|
{
|
2009-01-26 07:22:44 +01:00
|
|
|
return KConfigGroup(KSharedConfig::openConfig(themeRcFile), "CachePolicies");
|
2009-01-26 05:41:39 +01:00
|
|
|
}
|
|
|
|
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
const KConfigGroup& config() const {
|
|
|
|
return const_cast<ThemePrivate*>(this)->config();
|
|
|
|
}
|
|
|
|
|
2008-11-04 00:08:39 +01:00
|
|
|
KConfigGroup &config()
|
|
|
|
{
|
|
|
|
if (!cfg.isValid()) {
|
|
|
|
QString groupName = "Theme";
|
|
|
|
|
|
|
|
if (!useGlobal) {
|
|
|
|
QString app = KGlobal::mainComponent().componentName();
|
|
|
|
|
|
|
|
if (!app.isEmpty() && app != "plasma") {
|
|
|
|
kDebug() << "using theme for app" << app;
|
|
|
|
groupName.append("-").append(app);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-26 07:22:44 +01:00
|
|
|
cfg = KConfigGroup(KSharedConfig::openConfig(themeRcFile), groupName);
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return cfg;
|
|
|
|
}
|
|
|
|
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
/**
|
|
|
|
* Reads optional configuration, that is specific to the current composite mode:
|
|
|
|
* When composition is active, the configuration entry is prefixed with "composite_".
|
|
|
|
* Optionally, the configuration can also be specific to the specified image path:
|
|
|
|
* Then the image path has to be appended to the configuration name
|
|
|
|
*/
|
|
|
|
template<class T>
|
|
|
|
T readOptionalConfig(QString configName, T _default, QString imagePath) {
|
|
|
|
if(compositingActive)
|
|
|
|
configName = "composite_" + configName;
|
|
|
|
|
|
|
|
T ret = config().readEntry(configName, _default);
|
|
|
|
return config().readEntry(configName + "_" + imagePath, ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasOptionalConfig(QString configName, QString imagePath = QString()) {
|
|
|
|
if(compositingActive)
|
|
|
|
configName = "composite_" + configName;
|
|
|
|
|
|
|
|
return config().hasKey(configName) || config().hasKey(configName + "_" + imagePath);
|
|
|
|
}
|
|
|
|
|
2008-11-04 00:08:39 +01:00
|
|
|
QString findInTheme(const QString &image, const QString &theme) const;
|
|
|
|
void compositingChanged();
|
2008-11-16 21:53:24 +01:00
|
|
|
void discardCache();
|
2008-12-11 07:24:25 +01:00
|
|
|
void discardCache(bool recreateElementsCache);
|
2008-12-19 02:48:42 +01:00
|
|
|
void colorsChanged();
|
2008-12-04 21:13:50 +01:00
|
|
|
bool useCache();
|
2009-01-26 07:22:44 +01:00
|
|
|
void settingsFileChanged(const QString &);
|
2009-02-24 21:49:46 +01:00
|
|
|
void setThemeName(const QString &themeName, bool writeSettings);
|
2008-11-04 00:08:39 +01:00
|
|
|
|
|
|
|
static const char *defaultTheme;
|
2009-01-26 07:22:44 +01:00
|
|
|
static const char *themeRcFile;
|
2008-11-04 00:08:39 +01:00
|
|
|
static PackageStructure::Ptr packageStructure;
|
|
|
|
|
|
|
|
Theme *q;
|
|
|
|
QString themeName;
|
|
|
|
KSharedConfigPtr colors;
|
|
|
|
KColorScheme colorScheme;
|
|
|
|
KColorScheme buttonColorScheme;
|
|
|
|
KConfigGroup cfg;
|
|
|
|
QFont generalFont;
|
|
|
|
QString defaultWallpaperTheme;
|
|
|
|
QString defaultWallpaperSuffix;
|
|
|
|
int defaultWallpaperWidth;
|
|
|
|
int defaultWallpaperHeight;
|
|
|
|
KPixmapCache *pixmapCache;
|
|
|
|
KSharedConfigPtr svgElementsCache;
|
2008-12-11 00:17:12 +01:00
|
|
|
QHash<QString, QSet<QString> > invalidElements;
|
2008-11-04 00:08:39 +01:00
|
|
|
|
|
|
|
#ifdef Q_WS_X11
|
|
|
|
KSelectionWatcher *compositeWatch;
|
|
|
|
#endif
|
|
|
|
bool locolor : 1;
|
|
|
|
bool compositingActive : 1;
|
|
|
|
bool isDefault : 1;
|
|
|
|
bool useGlobal : 1;
|
|
|
|
bool hasWallpapers : 1;
|
2008-12-04 21:13:50 +01:00
|
|
|
bool cacheTheme : 1;
|
2009-02-24 23:42:06 +01:00
|
|
|
bool useNativeWidgetStyle :1;
|
2008-11-04 00:08:39 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
PackageStructure::Ptr ThemePrivate::packageStructure(0);
|
|
|
|
const char *ThemePrivate::defaultTheme = "default";
|
2009-01-26 07:22:44 +01:00
|
|
|
const char *ThemePrivate::themeRcFile = "plasmarc";
|
2008-11-04 00:08:39 +01:00
|
|
|
|
2008-12-04 21:13:50 +01:00
|
|
|
bool ThemePrivate::useCache()
|
|
|
|
{
|
|
|
|
if (cacheTheme && !pixmapCache) {
|
|
|
|
pixmapCache = new KPixmapCache("plasma_theme_" + themeName);
|
2009-01-26 05:41:39 +01:00
|
|
|
pixmapCache->setCacheLimit(cacheConfig().readEntry("ThemeCacheKb", 80 * 1024));
|
2008-12-04 21:13:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return cacheTheme;
|
|
|
|
}
|
2008-12-09 21:37:41 +01:00
|
|
|
|
2008-11-04 00:08:39 +01:00
|
|
|
QString ThemePrivate::findInTheme(const QString &image, const QString &theme) const
|
|
|
|
{
|
|
|
|
//TODO: this should be using Package
|
|
|
|
QString search;
|
|
|
|
|
|
|
|
if (locolor) {
|
|
|
|
search = "desktoptheme/" + theme + "/locolor/" + image;
|
|
|
|
search = KStandardDirs::locate("data", search);
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
} else if (!compositingActive && !config().readEntry<bool>("forceTransparentTheme", false)) {
|
2008-11-04 00:08:39 +01:00
|
|
|
search = "desktoptheme/" + theme + "/opaque/" + image;
|
|
|
|
search = KStandardDirs::locate("data", search);
|
|
|
|
}
|
|
|
|
|
|
|
|
//not found or compositing enabled
|
|
|
|
if (search.isEmpty()) {
|
|
|
|
search = "desktoptheme/" + theme + '/' + image;
|
|
|
|
search = KStandardDirs::locate("data", search);
|
|
|
|
}
|
|
|
|
|
|
|
|
return search;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThemePrivate::compositingChanged()
|
|
|
|
{
|
|
|
|
#ifdef Q_WS_X11
|
|
|
|
bool nowCompositingActive = compositeWatch->owner() != None;
|
|
|
|
|
|
|
|
if (compositingActive != nowCompositingActive) {
|
|
|
|
compositingActive = nowCompositingActive;
|
2008-12-11 07:24:25 +01:00
|
|
|
discardCache(true);
|
2008-11-04 00:08:39 +01:00
|
|
|
emit q->themeChanged();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-11-16 21:53:24 +01:00
|
|
|
void ThemePrivate::discardCache()
|
2008-12-11 07:24:25 +01:00
|
|
|
{
|
|
|
|
discardCache(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThemePrivate::discardCache(bool recreateElementsCache)
|
2008-11-16 21:53:24 +01:00
|
|
|
{
|
2008-12-19 02:48:42 +01:00
|
|
|
KPixmapCache::deleteCache("plasma_theme_" + themeName);
|
2008-12-04 21:13:50 +01:00
|
|
|
delete pixmapCache;
|
|
|
|
pixmapCache = 0;
|
2008-12-11 07:24:25 +01:00
|
|
|
invalidElements.clear();
|
2008-12-04 21:13:50 +01:00
|
|
|
|
2008-12-10 15:21:08 +01:00
|
|
|
svgElementsCache = 0;
|
|
|
|
|
2008-12-04 21:13:50 +01:00
|
|
|
QString svgElementsFile = KStandardDirs::locateLocal("cache", "plasma-svgelements-" + themeName);
|
|
|
|
if (!svgElementsFile.isEmpty()) {
|
|
|
|
QFile f(svgElementsFile);
|
|
|
|
f.remove();
|
|
|
|
}
|
2008-12-11 07:24:25 +01:00
|
|
|
|
|
|
|
if (recreateElementsCache) {
|
|
|
|
svgElementsCache = KSharedConfig::openConfig(svgElementsFile);
|
|
|
|
}
|
2008-11-16 21:53:24 +01:00
|
|
|
}
|
|
|
|
|
2008-12-19 02:48:42 +01:00
|
|
|
void ThemePrivate::colorsChanged()
|
|
|
|
{
|
|
|
|
discardCache(true);
|
|
|
|
colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors);
|
|
|
|
buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors);
|
2008-12-28 18:50:32 +01:00
|
|
|
emit q->themeChanged();
|
2008-12-19 02:48:42 +01:00
|
|
|
}
|
|
|
|
|
2008-11-04 00:08:39 +01:00
|
|
|
class ThemeSingleton
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ThemeSingleton()
|
|
|
|
{
|
|
|
|
self.d->isDefault = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
Theme self;
|
|
|
|
};
|
|
|
|
|
|
|
|
K_GLOBAL_STATIC(ThemeSingleton, privateThemeSelf)
|
|
|
|
|
|
|
|
Theme *Theme::defaultTheme()
|
|
|
|
{
|
|
|
|
return &privateThemeSelf->self;
|
|
|
|
}
|
|
|
|
|
|
|
|
Theme::Theme(QObject *parent)
|
|
|
|
: QObject(parent),
|
|
|
|
d(new ThemePrivate(this))
|
|
|
|
{
|
|
|
|
settingsChanged();
|
|
|
|
|
|
|
|
#ifdef Q_WS_X11
|
|
|
|
Display *dpy = QX11Info::display();
|
|
|
|
int screen = DefaultScreen(dpy);
|
|
|
|
d->locolor = DefaultDepth(dpy, screen) < 16;
|
|
|
|
|
|
|
|
if (!d->locolor) {
|
|
|
|
char net_wm_cm_name[100];
|
|
|
|
sprintf(net_wm_cm_name, "_NET_WM_CM_S%d", screen);
|
|
|
|
d->compositeWatch = new KSelectionWatcher(net_wm_cm_name, -1, this);
|
|
|
|
connect(d->compositeWatch, SIGNAL(newOwner(Window)), this, SLOT(compositingChanged()));
|
|
|
|
connect(d->compositeWatch, SIGNAL(lostOwner()), this, SLOT(compositingChanged()));
|
|
|
|
}
|
|
|
|
#endif
|
2009-01-26 07:22:44 +01:00
|
|
|
|
|
|
|
//FIXME: if/when kconfig gets change notification, this will be unecessary
|
|
|
|
KDirWatch::self()->addFile(KStandardDirs::locateLocal("config", ThemePrivate::themeRcFile));
|
2009-02-28 07:40:54 +01:00
|
|
|
connect(KDirWatch::self(), SIGNAL(created(QString)), this, SLOT(settingsFileChanged(QString)));
|
2009-01-26 07:22:44 +01:00
|
|
|
connect(KDirWatch::self(), SIGNAL(dirty(QString)), this, SLOT(settingsFileChanged(QString)));
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Theme::~Theme()
|
|
|
|
{
|
2008-12-11 00:17:12 +01:00
|
|
|
QHashIterator<QString, QSet<QString> > it(d->invalidElements);
|
|
|
|
while (it.hasNext()) {
|
|
|
|
it.next();
|
|
|
|
KConfigGroup imageGroup(d->svgElementsCache, it.key());
|
|
|
|
imageGroup.writeEntry("invalidElements", it.value().toList()); //FIXME: add QSet support to KConfig
|
|
|
|
}
|
|
|
|
|
2008-11-04 00:08:39 +01:00
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
PackageStructure::Ptr Theme::packageStructure()
|
|
|
|
{
|
|
|
|
if (!ThemePrivate::packageStructure) {
|
|
|
|
ThemePrivate::packageStructure = new ThemePackage();
|
|
|
|
}
|
|
|
|
|
|
|
|
return ThemePrivate::packageStructure;
|
|
|
|
}
|
|
|
|
|
2009-01-26 07:22:44 +01:00
|
|
|
void ThemePrivate::settingsFileChanged(const QString &file)
|
|
|
|
{
|
|
|
|
kDebug() << file;
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
QMap< QString, QString > oldEntries = config().entryMap();
|
|
|
|
|
2009-01-26 07:22:44 +01:00
|
|
|
config().config()->reparseConfiguration();
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
|
|
|
|
if(oldEntries != config().entryMap())
|
|
|
|
q->settingsChanged();
|
2009-01-26 07:22:44 +01:00
|
|
|
}
|
|
|
|
|
2008-11-04 00:08:39 +01:00
|
|
|
void Theme::settingsChanged()
|
|
|
|
{
|
2009-05-01 14:17:04 +02:00
|
|
|
StandardThemeBackgroundProvider::clearCache(); //So we don't waste memory with background images that are not used
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
|
|
|
|
QString newThemeName = d->config().readEntry("name", ThemePrivate::defaultTheme);
|
|
|
|
if(newThemeName != d->themeName) {
|
|
|
|
d->setThemeName(newThemeName, false);
|
|
|
|
}else{
|
|
|
|
///@todo More precise monitoring of attributes
|
|
|
|
d->discardCache(true);
|
|
|
|
emit themeChanged();
|
|
|
|
}
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Theme::setThemeName(const QString &themeName)
|
2009-02-24 21:49:46 +01:00
|
|
|
{
|
|
|
|
d->setThemeName(themeName, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThemePrivate::setThemeName(const QString &tempThemeName, bool writeSettings)
|
2008-11-04 00:08:39 +01:00
|
|
|
{
|
2009-04-28 19:10:17 +02:00
|
|
|
//kDebug() << tempThemeName;
|
2009-02-24 21:49:46 +01:00
|
|
|
QString theme = tempThemeName;
|
|
|
|
if (theme.isEmpty() || theme == themeName) {
|
2008-11-04 00:08:39 +01:00
|
|
|
// let's try and get the default theme at least
|
2009-02-24 21:49:46 +01:00
|
|
|
if (themeName.isEmpty()) {
|
2008-11-04 00:08:39 +01:00
|
|
|
theme = ThemePrivate::defaultTheme;
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO: should we care about names with relative paths in them?
|
|
|
|
QString themePath = KStandardDirs::locate("data", "desktoptheme/" + theme + '/');
|
2009-02-24 21:49:46 +01:00
|
|
|
if (themePath.isEmpty() && themeName.isEmpty()) {
|
2008-11-04 00:08:39 +01:00
|
|
|
themePath = KStandardDirs::locate("data", "desktoptheme/default/");
|
|
|
|
|
|
|
|
if (themePath.isEmpty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
theme = ThemePrivate::defaultTheme;
|
|
|
|
}
|
|
|
|
|
2009-02-24 21:49:46 +01:00
|
|
|
if (themeName == theme) {
|
2008-11-04 00:08:39 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-12-10 15:21:08 +01:00
|
|
|
//discard the old theme cache
|
2009-02-24 21:49:46 +01:00
|
|
|
if (!themeName.isEmpty() && pixmapCache) {
|
|
|
|
discardCache(false);
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
2009-02-24 21:49:46 +01:00
|
|
|
themeName = theme;
|
2008-11-04 00:08:39 +01:00
|
|
|
|
|
|
|
// load the color scheme config
|
|
|
|
QString colorsFile = KStandardDirs::locate("data", "desktoptheme/" + theme + "/colors");
|
|
|
|
//kDebug() << "we're going for..." << colorsFile << "*******************";
|
|
|
|
|
|
|
|
// load the wallpaper settings, if any
|
2008-11-09 21:41:27 +01:00
|
|
|
QString metadataPath(KStandardDirs::locate("data", "desktoptheme/" + theme + "/metadata.desktop"));
|
|
|
|
KConfig metadata(metadataPath);
|
2008-11-04 00:08:39 +01:00
|
|
|
KConfigGroup cg;
|
|
|
|
if (metadata.hasGroup("Wallpaper")) {
|
|
|
|
// we have a theme color config, so let's also check to see if
|
|
|
|
// there is a wallpaper defined in there.
|
|
|
|
cg = KConfigGroup(&metadata, "Wallpaper");
|
|
|
|
} else {
|
|
|
|
// since we didn't find an entry in the theme, let's look in the main
|
|
|
|
// theme config
|
2009-02-24 21:49:46 +01:00
|
|
|
cg = config();
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
2009-02-24 21:49:46 +01:00
|
|
|
defaultWallpaperTheme = cg.readEntry("defaultWallpaperTheme", DEFAULT_WALLPAPER_THEME);
|
|
|
|
defaultWallpaperSuffix = cg.readEntry("defaultFileSuffix", DEFAULT_WALLPAPER_SUFFIX);
|
|
|
|
defaultWallpaperWidth = cg.readEntry("defaultWidth", DEFAULT_WALLPAPER_WIDTH);
|
|
|
|
defaultWallpaperHeight = cg.readEntry("defaultHeight", DEFAULT_WALLPAPER_HEIGHT);
|
2008-11-04 00:08:39 +01:00
|
|
|
|
2009-02-24 23:42:06 +01:00
|
|
|
cg = KConfigGroup(&metadata, "Settings");
|
|
|
|
useNativeWidgetStyle = cg.readEntry("UseNativeWidgetStyle", false);
|
|
|
|
|
2009-02-24 21:49:46 +01:00
|
|
|
QObject::disconnect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
|
|
|
|
q, SLOT(colorsChanged()));
|
2008-11-16 21:53:24 +01:00
|
|
|
|
2008-11-04 00:08:39 +01:00
|
|
|
if (colorsFile.isEmpty()) {
|
2009-02-24 21:49:46 +01:00
|
|
|
colors = 0;
|
|
|
|
QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
|
|
|
|
q, SLOT(colorsChanged()));
|
2008-11-04 00:08:39 +01:00
|
|
|
} else {
|
2009-02-24 21:49:46 +01:00
|
|
|
colors = KSharedConfig::openConfig(colorsFile);
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
2009-02-24 21:49:46 +01:00
|
|
|
colorScheme = KColorScheme(QPalette::Active, KColorScheme::Window, colors);
|
|
|
|
buttonColorScheme = KColorScheme(QPalette::Active, KColorScheme::Button, colors);
|
|
|
|
hasWallpapers = KStandardDirs::exists(KStandardDirs::locateLocal("data", "desktoptheme/" + theme + "/wallpapers/"));
|
2008-11-04 00:08:39 +01:00
|
|
|
|
2009-02-24 21:49:46 +01:00
|
|
|
if (isDefault && writeSettings) {
|
2008-11-04 00:08:39 +01:00
|
|
|
// we're the default theme, let's save our state
|
2009-02-24 21:49:46 +01:00
|
|
|
KConfigGroup &cg = config();
|
|
|
|
if (ThemePrivate::defaultTheme == themeName) {
|
2008-11-04 00:08:39 +01:00
|
|
|
cg.deleteEntry("name");
|
|
|
|
} else {
|
2009-02-24 21:49:46 +01:00
|
|
|
cg.writeEntry("name", themeName);
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
2009-02-28 07:40:54 +01:00
|
|
|
cg.sync();
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
2008-11-09 21:41:27 +01:00
|
|
|
//check for expired cache
|
|
|
|
QFile f(metadataPath);
|
|
|
|
QFileInfo info(f);
|
|
|
|
|
2009-02-24 21:49:46 +01:00
|
|
|
if (useCache() && info.lastModified().toTime_t() > pixmapCache->timestamp()) {
|
|
|
|
discardCache(false);
|
2008-11-09 21:41:27 +01:00
|
|
|
}
|
|
|
|
|
2009-02-24 21:49:46 +01:00
|
|
|
invalidElements.clear();
|
2008-12-04 21:13:50 +01:00
|
|
|
QString svgElementsFile = KStandardDirs::locateLocal("cache", "plasma-svgelements-" + themeName);
|
2009-02-24 21:49:46 +01:00
|
|
|
svgElementsCache = KSharedConfig::openConfig(svgElementsFile);
|
2008-11-04 00:08:39 +01:00
|
|
|
|
2009-02-24 21:49:46 +01:00
|
|
|
emit q->themeChanged();
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QString Theme::themeName() const
|
|
|
|
{
|
|
|
|
return d->themeName;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Theme::imagePath(const QString &name) const
|
|
|
|
{
|
|
|
|
// look for a compressed svg file in the theme
|
|
|
|
if (name.contains("../")) {
|
|
|
|
// we don't support relative paths
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
|
|
|
|
QString path = d->findInTheme(name + ".svgz", d->themeName);
|
|
|
|
|
|
|
|
if (path.isEmpty()) {
|
|
|
|
// try for an uncompressed svg file
|
|
|
|
path = d->findInTheme(name + ".svg", d->themeName);
|
|
|
|
|
|
|
|
if (path.isEmpty() && d->themeName != ThemePrivate::defaultTheme) {
|
|
|
|
// try a compressed svg file in the default theme
|
|
|
|
path = d->findInTheme(name + ".svgz", ThemePrivate::defaultTheme);
|
|
|
|
|
|
|
|
if (path.isEmpty()) {
|
|
|
|
// try an uncompressed svg file in the default theme
|
|
|
|
path = d->findInTheme(name + ".svg", ThemePrivate::defaultTheme);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path.isEmpty()) {
|
|
|
|
kDebug() << "Theme says: bad image path " << name;
|
|
|
|
}
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString Theme::wallpaperPath(const QSize &size) const
|
|
|
|
{
|
|
|
|
QString fullPath;
|
|
|
|
QString image = d->defaultWallpaperTheme;
|
|
|
|
|
|
|
|
image.append("/contents/images/%1x%2").append(d->defaultWallpaperSuffix);
|
|
|
|
QString defaultImage = image.arg(d->defaultWallpaperWidth).arg(d->defaultWallpaperHeight);
|
|
|
|
|
|
|
|
if (size.isValid()) {
|
|
|
|
// try to customize the paper to the size requested
|
|
|
|
//TODO: this should do better than just fallback to the default size.
|
|
|
|
// a "best fit" matching would be far better, so we don't end
|
|
|
|
// up returning a 1920x1200 wallpaper for a 640x480 request ;)
|
|
|
|
image = image.arg(size.width()).arg(size.height());
|
|
|
|
} else {
|
|
|
|
image = defaultImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO: the theme's wallpaper overrides regularly installed wallpapers.
|
|
|
|
// should it be possible for user installed (e.g. locateLocal) wallpapers
|
|
|
|
// to override the theme?
|
|
|
|
if (d->hasWallpapers) {
|
|
|
|
// check in the theme first
|
2009-01-02 11:52:14 +01:00
|
|
|
fullPath = d->findInTheme("wallpapers/" + image, d->themeName);
|
2008-11-04 00:08:39 +01:00
|
|
|
|
|
|
|
if (fullPath.isEmpty()) {
|
2009-01-02 11:52:14 +01:00
|
|
|
fullPath = d->findInTheme("wallpapers/" + defaultImage, d->themeName);
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fullPath.isEmpty()) {
|
|
|
|
// we failed to find it in the theme, so look in the standard directories
|
|
|
|
//kDebug() << "looking for" << image;
|
|
|
|
fullPath = KStandardDirs::locate("wallpaper", image);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fullPath.isEmpty()) {
|
|
|
|
// we still failed to find it in the theme, so look for the default in
|
|
|
|
// the standard directories
|
|
|
|
//kDebug() << "looking for" << defaultImage;
|
|
|
|
fullPath = KStandardDirs::locate("wallpaper", defaultImage);
|
|
|
|
|
|
|
|
if (fullPath.isEmpty()) {
|
|
|
|
kDebug() << "exhausted every effort to find a wallpaper.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return fullPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Theme::currentThemeHasImage(const QString &name) const
|
|
|
|
{
|
|
|
|
if (name.contains("../")) {
|
|
|
|
// we don't support relative paths
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !(d->findInTheme(name + ".svgz", d->themeName).isEmpty()) ||
|
|
|
|
!(d->findInTheme(name + ".svg", d->themeName).isEmpty());
|
|
|
|
}
|
|
|
|
|
|
|
|
KSharedConfigPtr Theme::colorScheme() const
|
|
|
|
{
|
|
|
|
return d->colors;
|
|
|
|
}
|
|
|
|
|
|
|
|
QColor Theme::color(ColorRole role) const
|
|
|
|
{
|
|
|
|
switch (role) {
|
|
|
|
case TextColor:
|
|
|
|
return d->colorScheme.foreground(KColorScheme::NormalText).color();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HighlightColor:
|
|
|
|
return d->colorScheme.background(KColorScheme::ActiveBackground).color();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BackgroundColor:
|
|
|
|
return d->colorScheme.background().color();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ButtonTextColor:
|
|
|
|
return d->buttonColorScheme.foreground(KColorScheme::NormalText).color();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ButtonBackgroundColor:
|
|
|
|
return d->buttonColorScheme.background(KColorScheme::ActiveBackground).color();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return QColor();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Theme::setFont(const QFont &font, FontRole role)
|
|
|
|
{
|
|
|
|
Q_UNUSED(role)
|
|
|
|
d->generalFont = font;
|
|
|
|
}
|
|
|
|
|
|
|
|
QFont Theme::font(FontRole role) const
|
|
|
|
{
|
|
|
|
Q_UNUSED(role)
|
|
|
|
switch (role) {
|
|
|
|
case DesktopFont:
|
|
|
|
{
|
|
|
|
KConfigGroup cg(KGlobal::config(), "General");
|
|
|
|
return cg.readEntry("desktopFont", QFont("Sans Serif", 10));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DefaultFont:
|
|
|
|
default:
|
|
|
|
return d->generalFont;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QFontMetrics Theme::fontMetrics() const
|
|
|
|
{
|
|
|
|
//TODO: allow this to be overridden with a plasma specific font?
|
|
|
|
return QFontMetrics(d->generalFont);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Theme::windowTranslucencyEnabled() const
|
|
|
|
{
|
|
|
|
return d->compositingActive;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Theme::setUseGlobalSettings(bool useGlobal)
|
|
|
|
{
|
|
|
|
if (d->useGlobal == useGlobal) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->useGlobal = useGlobal;
|
|
|
|
d->cfg = KConfigGroup();
|
|
|
|
d->themeName.clear();
|
|
|
|
settingsChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Theme::useGlobalSettings() const
|
|
|
|
{
|
|
|
|
return d->useGlobal;
|
|
|
|
}
|
|
|
|
|
2009-02-24 23:42:06 +01:00
|
|
|
bool Theme::useNativeWidgetStyle() const
|
|
|
|
{
|
|
|
|
return d->useNativeWidgetStyle;
|
|
|
|
}
|
|
|
|
|
2008-11-04 00:08:39 +01:00
|
|
|
bool Theme::findInCache(const QString &key, QPixmap &pix)
|
|
|
|
{
|
2008-12-04 21:13:50 +01:00
|
|
|
return d->useCache() && d->pixmapCache->find(key, pix);
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
2009-03-17 22:08:48 +01:00
|
|
|
// BIC FIXME: Should be merged with the other findInCache method above when we break BC
|
|
|
|
bool Theme::findInCache(const QString &key, QPixmap &pix, unsigned int lastModified)
|
|
|
|
{
|
2009-03-30 21:46:01 +02:00
|
|
|
if (d->useCache() && lastModified > d->pixmapCache->timestamp()) {
|
2009-03-17 22:08:48 +01:00
|
|
|
d->discardCache();
|
|
|
|
}
|
|
|
|
|
|
|
|
return findInCache(key, pix);
|
|
|
|
}
|
|
|
|
|
2008-11-04 00:08:39 +01:00
|
|
|
void Theme::insertIntoCache(const QString& key, const QPixmap& pix)
|
|
|
|
{
|
2008-12-04 21:13:50 +01:00
|
|
|
if (d->useCache()) {
|
2008-11-04 00:08:39 +01:00
|
|
|
d->pixmapCache->insert(key, pix);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Theme::findInRectsCache(const QString &image, const QString &element, QRectF &rect) const
|
|
|
|
{
|
|
|
|
if (!d->pixmapCache) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
KConfigGroup imageGroup(d->svgElementsCache, image);
|
2008-12-11 00:17:12 +01:00
|
|
|
rect = imageGroup.readEntry(element + "Size", QRectF());
|
2008-11-04 00:08:39 +01:00
|
|
|
|
2008-12-11 00:17:12 +01:00
|
|
|
if (rect.isValid()) {
|
|
|
|
return true;
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
2009-01-22 20:59:25 +01:00
|
|
|
//A single _ means the element is empty and we're asked for the size of
|
|
|
|
//the whole image, so the whole image is never invalid
|
|
|
|
if (element.count('_') == 1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-12-11 00:17:12 +01:00
|
|
|
bool invalid = false;
|
|
|
|
|
|
|
|
QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
|
|
|
|
if (it == d->invalidElements.end()) {
|
|
|
|
QSet<QString> elements = imageGroup.readEntry("invalidElements", QStringList()).toSet();
|
|
|
|
d->invalidElements.insert(image, elements);
|
|
|
|
invalid = elements.contains(element);
|
|
|
|
} else {
|
|
|
|
invalid = it.value().contains(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
return invalid;
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Theme::insertIntoRectsCache(const QString& image, const QString &element, const QRectF &rect)
|
|
|
|
{
|
|
|
|
if (!d->pixmapCache) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rect.isValid()) {
|
2008-12-11 00:17:12 +01:00
|
|
|
KConfigGroup imageGroup(d->svgElementsCache, image);
|
|
|
|
imageGroup.writeEntry(element + "Size", rect);
|
|
|
|
} else {
|
|
|
|
QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
|
|
|
|
if (it == d->invalidElements.end()) {
|
|
|
|
d->invalidElements[image].insert(element);
|
|
|
|
} else if (!it.value().contains(element)) {
|
|
|
|
if (it.value().count() > 1000) {
|
|
|
|
it.value().erase(it.value().begin());
|
|
|
|
}
|
|
|
|
|
|
|
|
it.value().insert(element);
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Theme::invalidateRectsCache(const QString& image)
|
|
|
|
{
|
|
|
|
KConfigGroup imageGroup(d->svgElementsCache, image);
|
|
|
|
imageGroup.deleteGroup();
|
2008-12-11 03:45:45 +01:00
|
|
|
|
|
|
|
releaseRectsCache(image);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Theme::releaseRectsCache(const QString &image)
|
|
|
|
{
|
|
|
|
QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
|
|
|
|
if (it != d->invalidElements.end()) {
|
|
|
|
d->invalidElements.erase(it);
|
|
|
|
}
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Theme::setCacheLimit(int kbytes)
|
|
|
|
{
|
2008-12-04 21:13:50 +01:00
|
|
|
if (d->useCache()) {
|
2008-11-04 00:08:39 +01:00
|
|
|
d->pixmapCache->setCacheLimit(kbytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-01 14:17:04 +02:00
|
|
|
|
|
|
|
void StandardThemeBackgroundProvider::clearCache()
|
|
|
|
{
|
|
|
|
m_cachedPatterns.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
StandardThemeBackgroundProvider::StandardThemeBackgroundProvider(Theme* theme, QString imagePath) : m_color(Qt::black), m_patternAlpha(0), m_valid(false)
|
|
|
|
{
|
|
|
|
if(theme->d->locolor)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if((imagePath.startsWith("widgets/panel-") || imagePath.startsWith("dialogs/")) &&
|
|
|
|
(theme->d->hasOptionalConfig("frameBackgroundColor") || theme->d->hasOptionalConfig("frameBackgroundPattern")))
|
|
|
|
{
|
|
|
|
m_valid = true;
|
|
|
|
m_color = theme->d->readOptionalConfig<QColor>("frameBackgroundColor", Qt::black, imagePath);
|
|
|
|
if(theme->d->hasOptionalConfig("frameBackgroundColor"))
|
|
|
|
m_color.setAlpha(theme->d->readOptionalConfig<int>("frameBackgroundColorAlpha", 255, imagePath));
|
|
|
|
else
|
|
|
|
m_color.setAlpha(0);
|
|
|
|
|
|
|
|
m_pattern = theme->d->readOptionalConfig<QString>("frameBackgroundPattern", QString(), imagePath);
|
|
|
|
m_patternAlpha = theme->d->readOptionalConfig<int>("frameBackgroundPatternAlpha", 255, imagePath);
|
|
|
|
m_offsetX = theme->d->readOptionalConfig<int>("frameBackgroundPatternOffsetX", 0, imagePath);
|
|
|
|
m_offsetY = theme->d->readOptionalConfig<int>("frameBackgroundPatternOffsetY", 0, imagePath);
|
|
|
|
int randomX = theme->d->readOptionalConfig<int>("frameBackgroundPatternOffsetRandomX", 0, imagePath);
|
|
|
|
int randomY = theme->d->readOptionalConfig<int>("frameBackgroundPatternOffsetRandomY", 0, imagePath);
|
|
|
|
|
|
|
|
if(randomX || randomY) {
|
|
|
|
//Add "this" so the offsets are different after every startup, but stay same for the same image path
|
|
|
|
qsrand(qHash(imagePath) + ((size_t)this) + randomX + 11 * randomY);
|
|
|
|
if(randomX)
|
|
|
|
m_offsetX += qrand() % randomX;
|
|
|
|
if(randomY)
|
|
|
|
m_offsetY += qrand() % randomY;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
}
|
|
|
|
|
2009-05-01 14:17:04 +02:00
|
|
|
void StandardThemeBackgroundProvider::apply(QPainter& target) const
|
|
|
|
{
|
|
|
|
if(!m_valid)
|
|
|
|
return;
|
|
|
|
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
target.setCompositionMode(QPainter::CompositionMode_DestinationOver);
|
|
|
|
|
|
|
|
//Apply color
|
|
|
|
if(m_color.alpha())
|
|
|
|
target.fillRect(target.clipRegion().boundingRect(), m_color);
|
|
|
|
|
|
|
|
//Apply pattern
|
|
|
|
if(m_patternAlpha && !m_pattern.isEmpty()) {
|
|
|
|
if(!m_cachedPatterns.contains(m_pattern) || m_cachedPatterns[m_pattern].second != m_patternAlpha) {
|
|
|
|
m_cachedPatterns.remove(m_pattern);
|
|
|
|
m_cachedPatterns.insert(m_pattern, PatternAlphaPair(QImage(m_pattern), m_patternAlpha));
|
|
|
|
if(m_patternAlpha != 255) {
|
|
|
|
PatternAlphaPair& cached(m_cachedPatterns[m_pattern]);
|
|
|
|
//Apply lower alpha value to the pattern
|
|
|
|
QImage alpha(cached.first.size(), QImage::Format_ARGB32);
|
|
|
|
alpha.fill(QColor(cached.second, cached.second, cached.second).rgb());
|
|
|
|
cached.first.setAlphaChannel(alpha);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PatternAlphaPair& cached(m_cachedPatterns[m_pattern]);
|
|
|
|
|
|
|
|
if(!cached.first.isNull()) {
|
|
|
|
QBrush brush;
|
|
|
|
QColor col(Qt::white);
|
|
|
|
col.setAlpha(m_patternAlpha);
|
|
|
|
brush.setColor(col);
|
|
|
|
brush.setTextureImage(cached.first);
|
2009-05-01 14:17:04 +02:00
|
|
|
target.setBrushOrigin(-m_offsetX, -m_offsetY);
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
target.fillRect(target.clipRegion().boundingRect(), brush);
|
|
|
|
}else{
|
|
|
|
kDebug() << "failed to load pattern" << m_pattern;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-01 14:17:04 +02:00
|
|
|
StandardThemeBackgroundProvider::operator bool() const
|
|
|
|
{
|
|
|
|
return m_valid;
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
}
|
|
|
|
|
2009-05-01 14:17:04 +02:00
|
|
|
QString StandardThemeBackgroundProvider::identity() const
|
|
|
|
{
|
|
|
|
if(!m_valid)
|
|
|
|
return QString();
|
|
|
|
return QString("bgcolor_%1=").arg(m_color.alpha()) + m_color.name()+QString("_pattern_%1=").arg(m_patternAlpha)+m_pattern + QString("_offsets_%1_%2__").arg(m_offsetX).arg(m_offsetY);
|
- Allow painting a background color, or a background pattern behind freely floating elements of the theme, to provide a better fallback mechanism for transparent themes when composition is not available.
The color/pattern is given through the configuration file, and updating due to changes of the configuration file works perfectly. A simple user-interface to use this will be added to the panel configuration.
If you want to try this out, put into the [Theme] section of your plasmarc file:
frameBackgroundColor=#aacc00 (Your picked color)
frameBackgroundColorAlpha=120 (Alpha value for the color, between 0 and 255, 0=invisible, 255=opaque)
frameBackgroundPattern=/path/to/image
frameBackgroundPatternAlpha=255 (Alpha value for the pattern, as above)
The color is painted first, then the pattern. They are painted into the mask defined by the theme, so this only works nicely with themes that supply proper masks.
svn path=/trunk/KDE/kdelibs/; revision=961915
2009-05-01 02:41:41 +02:00
|
|
|
}
|
2008-11-04 00:08:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#include <theme.moc>
|