prototype of more flexyble svg stylesheets

experiment in dynamic repacement of Text and Background
colors, in order to be able to generate icons of different colors
based on where they are (for instance if the normal background
is dark and the button background is light

at the moment supported an option to invert colors, one
to use the "highlight" color (if we want colored icons
on mouse over)
This commit is contained in:
Marco Martin 2014-06-09 17:35:46 +02:00
parent e558e44658
commit cac2704d50
6 changed files with 77 additions and 17 deletions

View File

@ -163,6 +163,13 @@ void IconItem::setActive(bool active)
return; return;
} }
if (m_svgIcon) {
if (active) {
m_svgIcon->setStyleHints(Plasma::Svg::Inverted|Plasma::Svg::Highlighted);
} else {
m_svgIcon->setStyleHints(Plasma::Svg::Normal);
}
}
m_active = active; m_active = active;
m_loadPixmapTimer.start(); m_loadPixmapTimer.start();
emit activeChanged(); emit activeChanged();

View File

@ -106,6 +106,7 @@ public:
QSizeF size; QSizeF size;
QSizeF naturalSize; QSizeF naturalSize;
QChar styleCrc; QChar styleCrc;
Svg::StyleHints styleHints;
unsigned int lastModified; unsigned int lastModified;
qreal devicePixelRatio; qreal devicePixelRatio;
bool multipleImages : 1; bool multipleImages : 1;

View File

@ -427,14 +427,29 @@ const QString ThemePrivate::processStyleSheet(const QString &css)
return stylesheet; return stylesheet;
} }
const QString ThemePrivate::svgStyleSheet() const QString ThemePrivate::svgStyleSheet(Plasma::Svg::StyleHints hints)
{ {qWarning()<<"BBBBB"<<hints<<(SVGSTYLE+(int)hints);
QString stylesheet = cachedStyleSheets.value(SVGSTYLE); QString stylesheet = cachedStyleSheets.value(SVGSTYLE+(int)hints);
if (stylesheet.isEmpty()) { if (stylesheet.isEmpty()) {
QString skel = QStringLiteral(".ColorScheme-%1{color:%2;}"); QString skel = QStringLiteral(".ColorScheme-%1{color:%2;}");
stylesheet += skel.arg(QStringLiteral("Text"), QStringLiteral("%textcolor")); if ((hints & Svg::Highlighted) && (hints & Svg::Inverted)) {
stylesheet += skel.arg(QStringLiteral("Background"), QStringLiteral("%backgroundcolor")); stylesheet += skel.arg(QStringLiteral("Text"), QStringLiteral("%highlightcolor"));
} else if ((hints & Svg::Inverted) || (hints & Svg::Highlighted)) {
stylesheet += skel.arg(QStringLiteral("Text"), QStringLiteral("%backgroundcolor"));
//Normal
} else {
stylesheet += skel.arg(QStringLiteral("Text"), QStringLiteral("%textcolor"));
}
if ((hints & Svg::Highlighted) && !(hints & Svg::Inverted)) {
stylesheet += skel.arg(QStringLiteral("Background"), QStringLiteral("%highlightcolor"));
} else if (hints & Svg::Inverted) {
stylesheet += skel.arg(QStringLiteral("Background"), QStringLiteral("%textcolor"));
//Normal
} else {
stylesheet += skel.arg(QStringLiteral("Background"), QStringLiteral("%backgroundcolor"));
}
stylesheet += skel.arg(QStringLiteral("Highlight"), QStringLiteral("%highlightcolor")); stylesheet += skel.arg(QStringLiteral("Highlight"), QStringLiteral("%highlightcolor"));
@ -449,7 +464,7 @@ const QString ThemePrivate::svgStyleSheet()
stylesheet += skel.arg(QStringLiteral("ViewFocus"), QStringLiteral("%viewfocuscolor")); stylesheet += skel.arg(QStringLiteral("ViewFocus"), QStringLiteral("%viewfocuscolor"));
stylesheet = processStyleSheet(stylesheet); stylesheet = processStyleSheet(stylesheet);
cachedStyleSheets.insert(SVGSTYLE, stylesheet); cachedStyleSheets.insert(SVGSTYLE+(int)hints, stylesheet);
} }
return stylesheet; return stylesheet;
@ -501,7 +516,7 @@ QColor ThemePrivate::color(Theme::ColorRole role) const
return colorScheme.foreground(KColorScheme::NormalText).color(); return colorScheme.foreground(KColorScheme::NormalText).color();
case Theme::HighlightColor: case Theme::HighlightColor:
return colorScheme.decoration(KColorScheme::HoverColor).color(); return colorScheme.decoration(KColorScheme::FocusColor).color();
case Theme::BackgroundColor: case Theme::BackgroundColor:
return colorScheme.background(KColorScheme::NormalBackground).color(); return colorScheme.background(KColorScheme::NormalBackground).color();

View File

@ -22,6 +22,7 @@
#define PLASMA_THEME_P_H #define PLASMA_THEME_P_H
#include "theme.h" #include "theme.h"
#include "svg.h"
#include <QHash> #include <QHash>
#include <QDebug> #include <QDebug>
@ -82,7 +83,7 @@ public:
void processContrastSettings(KConfigBase *metadata); void processContrastSettings(KConfigBase *metadata);
const QString processStyleSheet(const QString &css); const QString processStyleSheet(const QString &css);
const QString svgStyleSheet(); const QString svgStyleSheet(Plasma::Svg::StyleHints hints);
QColor color(Theme::ColorRole role) const; QColor color(Theme::ColorRole role) const;
public Q_SLOTS: public Q_SLOTS:
@ -133,7 +134,7 @@ public:
QHash<QString, QPixmap> pixmapsToCache; QHash<QString, QPixmap> pixmapsToCache;
QHash<QString, QString> keysToCache; QHash<QString, QString> keysToCache;
QHash<QString, QString> idsToCache; QHash<QString, QString> idsToCache;
QHash<styles, QString> cachedStyleSheets; QHash<int, QString> cachedStyleSheets;
QHash<QString, QString> discoveries; QHash<QString, QString> discoveries;
QTimer *pixmapSaveTimer; QTimer *pixmapSaveTimer;
QTimer *rectSaveTimer; QTimer *rectSaveTimer;

View File

@ -128,13 +128,14 @@ bool SharedSvgRenderer::load(
} }
#define QLSEP QLatin1Char('_') #define QLSEP QLatin1Char('_')
#define CACHE_ID_WITH_SIZE(size, id, devicePixelRatio) QString::number(int(size.width())) % QLSEP % QString::number(int(size.height())) % QLSEP % id % QLSEP % QString::number(int(devicePixelRatio)) #define CACHE_ID_WITH_SIZE(size, id, devicePixelRatio, styleHints) QString::number(int(size.width())) % QLSEP % QString::number(int(size.height())) % QLSEP % id % QLSEP % QString::number(int(devicePixelRatio)) % QLSEP % QString::number(styleHints)
#define CACHE_ID_NATURAL_SIZE(id, devicePixelRatio) QLatin1Literal("Natural") % QLSEP % id % QLSEP % QString::number(int(devicePixelRatio)) #define CACHE_ID_NATURAL_SIZE(id, devicePixelRatio, styleHints) QLatin1Literal("Natural") % QLSEP % id % QLSEP % QString::number(int(devicePixelRatio)) % QLSEP % QString::number(styleHints)
SvgPrivate::SvgPrivate(Svg *svg) SvgPrivate::SvgPrivate(Svg *svg)
: q(svg), : q(svg),
renderer(0), renderer(0),
styleCrc(0), styleCrc(0),
styleHints(Plasma::Svg::Normal),
lastModified(0), lastModified(0),
devicePixelRatio(1.0), devicePixelRatio(1.0),
multipleImages(false), multipleImages(false),
@ -155,16 +156,17 @@ SvgPrivate::~SvgPrivate()
QString SvgPrivate::cacheId(const QString &elementId) QString SvgPrivate::cacheId(const QString &elementId)
{ {
if (size.isValid() && size != naturalSize) { if (size.isValid() && size != naturalSize) {
return CACHE_ID_WITH_SIZE(size, elementId, devicePixelRatio); //the size won't change with another style
return CACHE_ID_WITH_SIZE(size, elementId, devicePixelRatio, 0);
} else { } else {
return CACHE_ID_NATURAL_SIZE(elementId, devicePixelRatio); return CACHE_ID_NATURAL_SIZE(elementId, devicePixelRatio, 0);
} }
} }
//This function is meant for the pixmap cache //This function is meant for the pixmap cache
QString SvgPrivate::cachePath(const QString &path, const QSize &size) QString SvgPrivate::cachePath(const QString &path, const QSize &size)
{ {
return CACHE_ID_WITH_SIZE(size, path, devicePixelRatio); return CACHE_ID_WITH_SIZE(size, path, devicePixelRatio, styleHints);
} }
bool SvgPrivate::setImagePath(const QString &imagePath) bool SvgPrivate::setImagePath(const QString &imagePath)
@ -278,7 +280,7 @@ QPixmap SvgPrivate::findInCache(const QString &elementId, const QSizeF &s)
if (elementsWithSizeHints.isEmpty()) { if (elementsWithSizeHints.isEmpty()) {
// Fetch all size hinted element ids from the theme's rect cache // Fetch all size hinted element ids from the theme's rect cache
// and store them locally. // and store them locally.
QRegExp sizeHintedKeyExpr(CACHE_ID_NATURAL_SIZE("(\\d+)-(\\d+)-(.+)", devicePixelRatio)); QRegExp sizeHintedKeyExpr(CACHE_ID_NATURAL_SIZE("(\\d+)-(\\d+)-(.+)", devicePixelRatio, 0));
foreach (const QString &key, cacheAndColorsTheme()->listCachedRectKeys(path)) { foreach (const QString &key, cacheAndColorsTheme()->listCachedRectKeys(path)) {
if (sizeHintedKeyExpr.exactMatch(key)) { if (sizeHintedKeyExpr.exactMatch(key)) {
@ -415,7 +417,7 @@ void SvgPrivate::createRenderer()
//qDebug() << "FAIL! **************************"; //qDebug() << "FAIL! **************************";
//qDebug() << path << "**"; //qDebug() << path << "**";
QString styleSheet = cacheAndColorsTheme()->d->svgStyleSheet(); QString styleSheet = cacheAndColorsTheme()->d->svgStyleSheet(styleHints);
styleCrc = qChecksum(styleSheet.toUtf8(), styleSheet.size()); styleCrc = qChecksum(styleSheet.toUtf8(), styleSheet.size());
QHash<QString, SharedSvgRenderer::Ptr>::const_iterator it = s_renderers.constFind(styleCrc + path); QHash<QString, SharedSvgRenderer::Ptr>::const_iterator it = s_renderers.constFind(styleCrc + path);
@ -438,7 +440,7 @@ void SvgPrivate::createRenderer()
const QString &elementId = i.key(); const QString &elementId = i.key();
const QRectF &elementRect = i.value(); const QRectF &elementRect = i.value();
const QString cacheId = CACHE_ID_NATURAL_SIZE(elementId, devicePixelRatio); const QString cacheId = CACHE_ID_NATURAL_SIZE(elementId, devicePixelRatio, styleHints);
localRectCache.insert(cacheId, elementRect); localRectCache.insert(cacheId, elementRect);
cacheAndColorsTheme()->insertIntoRectsCache(path, cacheId, elementRect); cacheAndColorsTheme()->insertIntoRectsCache(path, cacheId, elementRect);
} }
@ -685,6 +687,22 @@ qreal Svg::devicePixelRatio()
return d->devicePixelRatio; return d->devicePixelRatio;
} }
void Svg::setStyleHints(Svg::StyleHints hints)
{
if (d->styleHints == hints) {
return;
}
d->styleHints = hints;
d->renderer = 0;
emit styleHintsChanged();
}
Svg::StyleHints Svg::styleHints() const
{
return d->styleHints;
}
QPixmap Svg::pixmap(const QString &elementID) QPixmap Svg::pixmap(const QString &elementID)
{ {
if (elementID.isNull() || d->multipleImages) { if (elementID.isNull() || d->multipleImages) {

View File

@ -61,8 +61,16 @@ class PLASMA_EXPORT Svg : public QObject
Q_PROPERTY(bool multipleImages READ containsMultipleImages WRITE setContainsMultipleImages) Q_PROPERTY(bool multipleImages READ containsMultipleImages WRITE setContainsMultipleImages)
Q_PROPERTY(QString imagePath READ imagePath WRITE setImagePath NOTIFY imagePathChanged) Q_PROPERTY(QString imagePath READ imagePath WRITE setImagePath NOTIFY imagePathChanged)
Q_PROPERTY(bool usingRenderingCache READ isUsingRenderingCache WRITE setUsingRenderingCache) Q_PROPERTY(bool usingRenderingCache READ isUsingRenderingCache WRITE setUsingRenderingCache)
Q_PROPERTY(StyleHints styleHints READ styleHints WRITE setStyleHints NOTIFY styleHintsChanged);
public: public:
enum StyleHint{
Normal = 0,
Inverted = 1,
Highlighted = 2
};
Q_DECLARE_FLAGS(StyleHints, StyleHint)
/** /**
* Constructs an SVG object that implicitly shares and caches rendering. * Constructs an SVG object that implicitly shares and caches rendering.
* *
@ -93,6 +101,9 @@ public:
*/ */
qreal devicePixelRatio(); qreal devicePixelRatio();
void setStyleHints(StyleHints hint);
StyleHints styleHints() const;
/** /**
* Returns a pixmap of the SVG represented by this object. * Returns a pixmap of the SVG represented by this object.
* *
@ -398,6 +409,11 @@ Q_SIGNALS:
*/ */
void imagePathChanged(); void imagePathChanged();
/**
* Emitted whenever the style hints are changed.
*/
void styleHintsChanged();
private: private:
SvgPrivate *const d; SvgPrivate *const d;
bool eventFilter(QObject *watched, QEvent *event); bool eventFilter(QObject *watched, QEvent *event);
@ -412,5 +428,7 @@ private:
} // Plasma namespace } // Plasma namespace
Q_DECLARE_OPERATORS_FOR_FLAGS(Plasma::Svg::StyleHints)
#endif // multiple inclusion guard #endif // multiple inclusion guard