possibility to use a fallback chain as prefix

Summary:
if a framesvgitem has an array as prefix, like

FrameSvg {
 prefix: ["toolbutton-hover", "hover"]
}

it will use the first available prefix, so on themes that
have toolbutton-hover, that one will be used, old themes will
continue to use "hover" as prefix

Test Plan:
tested the calendar with breeze theme has breeze-widget style
toolbuttons, with olt themes as air, the old behavior is still
there, switching on the fly works

Reviewers: davidedmundson, #plasma

Subscribers: davidedmundson, broulik, plasma-devel, #frameworks

Tags: #plasma, #frameworks

Differential Revision: https://phabricator.kde.org/D4827
This commit is contained in:
Marco Martin 2017-02-27 18:54:22 +01:00
parent 6f02cf215b
commit 916bcbf6c0
4 changed files with 53 additions and 14 deletions

View File

@ -281,7 +281,6 @@ void FrameSvgItem::setImagePath(const QString &path)
updateDevicePixelRatio();
m_frameSvg->setImagePath(path);
m_frameSvg->setElementPrefix(m_prefix);
if (implicitWidth() <= 0) {
setImplicitWidth(m_frameSvg->marginSize(Plasma::Types::LeftMargin) + m_frameSvg->marginSize(Plasma::Types::RightMargin));
@ -296,6 +295,8 @@ void FrameSvgItem::setImagePath(const QString &path)
m_fixedMargins->update();
if (isComponentComplete()) {
applyPrefixes();
m_frameSvg->resizeFrame(QSizeF(width(), height()));
m_textureChanged = true;
update();
@ -307,14 +308,22 @@ QString FrameSvgItem::imagePath() const
return m_frameSvg->imagePath();
}
void FrameSvgItem::setPrefix(const QString &prefix)
void FrameSvgItem::setPrefix(const QVariant &prefixes)
{
if (m_prefix == prefix) {
QStringList prefixList;
//is this a simple string?
if (prefixes.canConvert<QString>()) {
prefixList << prefixes.toString();
} else if (prefixes.canConvert<QStringList>()) {
prefixList = prefixes.toStringList();
}
if (m_prefixes == prefixList) {
return;
}
m_frameSvg->setElementPrefix(prefix);
m_prefix = prefix;
m_prefixes = prefixList;
applyPrefixes();
if (implicitWidth() <= 0) {
setImplicitWidth(m_frameSvg->marginSize(Plasma::Types::LeftMargin) + m_frameSvg->marginSize(Plasma::Types::RightMargin));
@ -335,9 +344,9 @@ void FrameSvgItem::setPrefix(const QString &prefix)
}
}
QString FrameSvgItem::prefix() const
QVariant FrameSvgItem::prefix() const
{
return m_prefix;
return m_prefixes;
}
FrameSvgItemMargins *FrameSvgItem::margins() const
@ -416,6 +425,9 @@ void FrameSvgItem::geometryChanged(const QRectF &newGeometry,
void FrameSvgItem::doUpdate()
{
//if the theme changed, the available prefix may have changed as well
applyPrefixes();
if (implicitWidth() <= 0) {
setImplicitWidth(m_frameSvg->marginSize(Plasma::Types::LeftMargin) + m_frameSvg->marginSize(Plasma::Types::RightMargin));
}
@ -445,7 +457,7 @@ Plasma::FrameSvg *FrameSvgItem::frameSvg() const
QSGNode *FrameSvgItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
{
if (!window() || !m_frameSvg ||
(!m_frameSvg->hasElementPrefix(m_frameSvg->actualPrefix()) && !m_frameSvg->hasElementPrefix(m_prefix))) {
(!m_frameSvg->hasElementPrefix(m_frameSvg->actualPrefix()) && !m_frameSvg->hasElementPrefix(m_frameSvg->prefix()))) {
delete oldNode;
return nullptr;
}
@ -542,5 +554,26 @@ void FrameSvgItem::updateDevicePixelRatio()
m_textureChanged = true;
}
void FrameSvgItem::applyPrefixes()
{
if (m_prefixes.isEmpty() || m_frameSvg->imagePath().isEmpty()) {
return;
}
bool found = false;
for (const QString &prefix : m_prefixes) {
if (m_frameSvg->hasElementPrefix(prefix)) {
m_frameSvg->setElementPrefix(prefix);
found = true;
break;
}
}
if (!found) {
qWarning() << "The image" << m_frameSvg->imagePath() << "doesn't contain any of the prefixes" << m_prefixes;
//this setElementPrefix is done to keep the same behavior as before, when it was a simple string
m_frameSvg->setElementPrefix(m_prefixes.last());
}
}
} // Plasma namespace

View File

@ -119,8 +119,12 @@ class FrameSvgItem : public QQuickItem
* prefix for the 9 piece svg, like "pushed" or "normal" for the button
* see http://techbase.kde.org/Development/Tutorials/Plasma/ThemeDetails
* for a list of paths and prefixes
* It can also be an array of strings, specifying a fallback chain in case
* the first element isn't found in the theme, eg ["toolbutton-normal", "normal"]
* so it's easy to keep backwards compatibility with old themes
* (Note: fallback chain is supported only @since 5.32)
*/
Q_PROPERTY(QString prefix READ prefix WRITE setPrefix NOTIFY prefixChanged)
Q_PROPERTY(QVariant prefix READ prefix WRITE setPrefix NOTIFY prefixChanged)
/**
* The margins of the frame, read only
@ -185,8 +189,8 @@ public:
void setImagePath(const QString &path);
QString imagePath() const;
void setPrefix(const QString &prefix);
QString prefix() const;
void setPrefix(const QVariant &prefix);
QVariant prefix() const;
void setEnabledBorders(const Plasma::FrameSvg::EnabledBorders borders);
Plasma::FrameSvg::EnabledBorders enabledBorders() const;
@ -234,10 +238,12 @@ private Q_SLOTS:
void updateDevicePixelRatio();
private:
void applyPrefixes();
Plasma::FrameSvg *m_frameSvg;
FrameSvgItemMargins *m_margins;
FrameSvgItemMargins *m_fixedMargins;
QString m_prefix;
QStringList m_prefixes;
bool m_textureChanged;
bool m_sizeChanged;
bool m_fastPath;

View File

@ -231,7 +231,7 @@ QtQuickControlStyle.ButtonStyle {
id: surfaceNormal
anchors.fill: parent
imagePath: "widgets/button"
prefix: "normal"
prefix: style.flat ? ["toolbutton-hover", "normal"] : "normal"
enabledBorders: {
if (style.flat || !control.parent ||
@ -288,7 +288,7 @@ QtQuickControlStyle.ButtonStyle {
id: surfacePressed
anchors.fill: parent
imagePath: "widgets/button"
prefix: "pressed"
prefix: style.flat ? ["toolbutton-pressed", "pressed"] : "pressed"
enabledBorders: surfaceNormal.enabledBorders
opacity: 0
}