afdb5e84a0
there is a new function PanelSvg::mask() that returns a qbitmap of the areas of the svg with alpha=0 that can be used to create the mask of the window, at the moment used in tooltip and dialog (krunner still to come). so now windows that uses svg backgrounds should always set PanelSvg::mask() as their own mask, regardless if composite is active or not. In this commit there are also two (identical) svgs for opaque tooltips and dialogs with pixelated rounded borders that looks good without antialiasing (and unlike the previous version they are vector based now). svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=782727
291 lines
7.1 KiB
C++
291 lines
7.1 KiB
C++
/*
|
|
* 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>
|
|
#ifdef Q_WS_X11
|
|
#include <QX11Info>
|
|
#endif
|
|
|
|
#include <KWindowSystem>
|
|
#include <KColorScheme>
|
|
#include <KConfigGroup>
|
|
#include <KDebug>
|
|
#include <KSelectionWatcher>
|
|
#include <KSharedConfig>
|
|
#include <KStandardDirs>
|
|
#include <KGlobalSettings>
|
|
|
|
#include "plasma/packages_p.h"
|
|
|
|
namespace Plasma
|
|
{
|
|
|
|
class Theme::Private
|
|
{
|
|
public:
|
|
Private()
|
|
: locolor(false),
|
|
compositingActive(KWindowSystem::compositingActive())
|
|
{
|
|
generalFont = QApplication::font();
|
|
}
|
|
|
|
KConfigGroup config()
|
|
{
|
|
QString groupName = "Theme";
|
|
if (!app.isEmpty() && app != "plasma") {
|
|
groupName.append("-").append(app);
|
|
}
|
|
|
|
KSharedConfigPtr config = KSharedConfig::openConfig("plasmarc");
|
|
return KConfigGroup(config, groupName);
|
|
}
|
|
|
|
QString findInTheme(const QString &image, const QString &theme) const;
|
|
static const char *defaultTheme;
|
|
|
|
static PackageStructure::Ptr packageStructure;
|
|
QString themeName;
|
|
QString app;
|
|
KSharedConfigPtr colors;
|
|
QFont generalFont;
|
|
bool locolor;
|
|
bool compositingActive;
|
|
#ifdef Q_WS_X11
|
|
KSelectionWatcher *compositeWatch;
|
|
#endif
|
|
};
|
|
|
|
PackageStructure::Ptr Theme::Private::packageStructure(0);
|
|
const char *Theme::Private::defaultTheme = "default";
|
|
|
|
class ThemeSingleton
|
|
{
|
|
public:
|
|
Theme self;
|
|
};
|
|
|
|
K_GLOBAL_STATIC( ThemeSingleton, privateThemeSelf )
|
|
|
|
Theme* Theme::self()
|
|
{
|
|
return &privateThemeSelf->self;
|
|
}
|
|
|
|
Theme::Theme(QObject* parent)
|
|
: QObject(parent),
|
|
d(new Private)
|
|
{
|
|
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
|
|
}
|
|
|
|
Theme::~Theme()
|
|
{
|
|
d->config().writeEntry("name", d->themeName);
|
|
delete d;
|
|
}
|
|
|
|
PackageStructure::Ptr Theme::packageStructure()
|
|
{
|
|
if (!Private::packageStructure) {
|
|
Private::packageStructure = new ThemePackage();
|
|
}
|
|
|
|
return Private::packageStructure;
|
|
}
|
|
|
|
void Theme::setApplication(const QString &appname)
|
|
{
|
|
if (d->app != appname) {
|
|
d->app = appname;
|
|
settingsChanged();
|
|
}
|
|
}
|
|
|
|
void Theme::settingsChanged()
|
|
{
|
|
setThemeName(d->config().readEntry("name", Private::defaultTheme));
|
|
}
|
|
|
|
void Theme::compositingChanged()
|
|
{
|
|
#ifdef Q_WS_X11
|
|
bool compositingActive = d->compositeWatch->owner() != None;
|
|
|
|
if (d->compositingActive != compositingActive) {
|
|
d->compositingActive = compositingActive;
|
|
emit changed();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void Theme::colorsChanged()
|
|
{
|
|
emit changed();
|
|
}
|
|
|
|
void Theme::setThemeName(const QString &themeName)
|
|
{
|
|
QString theme = themeName;
|
|
if (theme.isEmpty() || theme == d->themeName) {
|
|
// let's try and get the default theme at least
|
|
if (d->themeName.isEmpty()) {
|
|
theme = Private::defaultTheme;
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
//TODO: should we care about names with relative paths in them?
|
|
QString themePath = KStandardDirs::locate("data", "desktoptheme/" + theme + "/");
|
|
if (themePath.isEmpty() && d->themeName.isEmpty()) {
|
|
themePath = KStandardDirs::locate("data", "desktoptheme/default/");
|
|
|
|
if (themePath.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
theme = Private::defaultTheme;
|
|
}
|
|
|
|
d->themeName = theme;
|
|
|
|
// load the color scheme config
|
|
QString colorsFile = KStandardDirs::locate("data", "desktoptheme/" + theme + "/colors");
|
|
//kDebug() << "we're going for..." << colorsFile << "*******************";
|
|
|
|
disconnect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), this, SLOT(colorsChanged()));
|
|
if (colorsFile.isEmpty()) {
|
|
d->colors = 0;
|
|
connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), this, SLOT(colorsChanged()));
|
|
} else {
|
|
d->colors = KSharedConfig::openConfig(colorsFile);
|
|
}
|
|
|
|
KConfigGroup cg = d->config();
|
|
if (cg.readEntry("name", Private::defaultTheme) != d->themeName) {
|
|
cg.writeEntry("name", d->themeName);
|
|
cg.config()->sync();
|
|
}
|
|
|
|
emit changed();
|
|
}
|
|
|
|
QString Theme::themeName() const
|
|
{
|
|
return d->themeName;
|
|
}
|
|
|
|
QString Theme::Private::findInTheme(const QString &image, const QString &theme) const
|
|
{
|
|
//TODO: this should be using Package
|
|
QString search;
|
|
|
|
if (locolor) {
|
|
search = "desktoptheme/" + theme + "/locolor/" + image + ".svg";
|
|
search = KStandardDirs::locate("data", search);
|
|
} else if (!compositingActive) {
|
|
search = "desktoptheme/" + theme + "/opaque/" + image + ".svg";
|
|
search = KStandardDirs::locate("data", search);
|
|
}
|
|
|
|
//not found or compositing enabled
|
|
if (search.isEmpty()) {
|
|
search = "desktoptheme/" + theme + '/' + image + ".svg";
|
|
search = KStandardDirs::locate("data", search);
|
|
}
|
|
|
|
return search;
|
|
}
|
|
|
|
QString Theme::image(const QString& name) const
|
|
{
|
|
QString path = d->findInTheme(name, d->themeName);
|
|
|
|
if (path.isEmpty() && d->themeName != Private::defaultTheme) {
|
|
path = d->findInTheme(name, Private::defaultTheme);
|
|
}
|
|
|
|
if (path.isEmpty()) {
|
|
kDebug() << "Theme says: bad image path " << name;
|
|
}
|
|
|
|
return path;
|
|
}
|
|
|
|
KSharedConfigPtr Theme::colors() const
|
|
{
|
|
return d->colors;
|
|
}
|
|
|
|
QColor Theme::textColor() const
|
|
{
|
|
KColorScheme colors(QPalette::Active, KColorScheme::Window, Theme::self()->colors());
|
|
return colors.foreground(KColorScheme::NormalText).color();
|
|
}
|
|
|
|
QColor Theme::backgroundColor() const
|
|
{
|
|
KColorScheme colors(QPalette::Active, KColorScheme::Window, Theme::self()->colors());
|
|
return colors.background().color();
|
|
}
|
|
|
|
void Theme::setFont(const QFont &font)
|
|
{
|
|
d->generalFont = font;
|
|
}
|
|
|
|
QFont Theme::font() const
|
|
{
|
|
//TODO: allow this to be overridden with a plasma specific font?
|
|
return d->generalFont;
|
|
}
|
|
|
|
QFontMetrics Theme::fontMetrics() const
|
|
{
|
|
//TODO: allow this to be overridden with a plasma specific font?
|
|
return QFontMetrics(d->generalFont);
|
|
}
|
|
|
|
bool Theme::compositingActive() const
|
|
{
|
|
return d->compositingActive;
|
|
}
|
|
|
|
}
|
|
|
|
#include <theme.moc>
|