make PlasmaCore.ColorScope work better as advertised

Since attached properties cannot ever change during the lifetime of the object,
a colorscope needs to be created for each obect that asks for the
attached property. now each instance if (internal) has m_inherit
(only those created as an attached property), will search for the property
of the proper ancestor. Not super efficient, but the proeprties should be
actually asked for rarely enough.

doesn't look much nice, but seems to work pretty reliably and the only way to.

Change-Id: I735da5551dbb8c2641be88d245f998d00ed977ac
REVIEW:122988
This commit is contained in:
Marco Martin 2015-03-19 11:20:01 +01:00
parent b7e5392a7b
commit ecbd619566
4 changed files with 126 additions and 16 deletions

View File

@ -25,11 +25,9 @@
#include <QQmlEngine>
ColorScope *ColorScope::s_colorScope = 0;
ColorScope::ColorScope(QQuickItem *parent)
: QQuickItem(parent),
m_inherit(false),
m_group(Plasma::Theme::NormalColorGroup)
{
connect(&m_theme, &Plasma::Theme::themeChanged, this, &ColorScope::colorsChanged);
@ -42,30 +40,59 @@ ColorScope::~ColorScope()
ColorScope *ColorScope::qmlAttachedProperties(QObject *object)
{
QObject *p = object;
QQuickItem *qp = qobject_cast<QQuickItem *>(object);
ColorScope *s = new ColorScope(qp);
if (!qp) {
s->setParent(object);
}
s->m_inherit = true;
return s;
}
ColorScope *ColorScope::findParentScope() const
{
QObject *p = parentItem();
if (!p) {
p = parent();
}
while (p) {
ColorScope *c = qobject_cast<ColorScope *>(p);
if (c) {
return c;
if (c != m_parentScope) {
if (m_parentScope) {
disconnect(m_parentScope.data(), &ColorScope::colorGroupChanged,
this, &ColorScope::colorGroupChanged);
disconnect(m_parentScope.data(), &ColorScope::colorsChanged,
this, &ColorScope::colorsChanged);
}
connect(c, &ColorScope::colorGroupChanged,
this, &ColorScope::colorGroupChanged);
connect(c, &ColorScope::colorsChanged,
this, &ColorScope::colorsChanged);
//HACK
const_cast<ColorScope *>(this)->m_parentScope = c;
}
return m_parentScope;
}
//this will be parent() for qobjects, parentItem for QQuickItems
QQuickItem *item = qobject_cast<QQuickItem *>(p);
if (item) {
p = item->parentItem();
if (QQuickItem *qi = qobject_cast<QQuickItem *>(p)) {
p = qi->parentItem();
} else {
p = p->parent();
}
}
if (!s_colorScope) {
s_colorScope = new ColorScope;
if (m_parentScope) {
disconnect(m_parentScope.data(), &ColorScope::colorGroupChanged,
this, &ColorScope::colorGroupChanged);
disconnect(m_parentScope.data(), &ColorScope::colorsChanged,
this, &ColorScope::colorsChanged);
}
return s_colorScope;
const_cast<ColorScope *>(this)->m_parentScope.clear();
return 0;
}
void ColorScope::setColorGroup(Plasma::Theme::ColorGroup group)
{
if (m_group == group) {
@ -80,22 +107,69 @@ void ColorScope::setColorGroup(Plasma::Theme::ColorGroup group)
Plasma::Theme::ColorGroup ColorScope::colorGroup() const
{
if (m_inherit) {
ColorScope *s = findParentScope();
if (s) {
return s->colorGroup();
}
}
return m_group;
}
QColor ColorScope::textColor() const
{
if (m_inherit) {
ColorScope *s = findParentScope();
if (s) {
return s->textColor();
}
}
return m_theme.color(Plasma::Theme::TextColor, m_group);
}
QColor ColorScope::highlightColor() const
{
if (m_inherit) {
ColorScope *s = findParentScope();
if (s) {
return s->highlightColor();
}
}
return m_theme.color(Plasma::Theme::HighlightColor, m_group);
}
QColor ColorScope::backgroundColor() const
{
if (m_inherit) {
ColorScope *s = findParentScope();
if (s) {
return s->backgroundColor();
}
}
return m_theme.color(Plasma::Theme::BackgroundColor, m_group);
}
void ColorScope::itemChange(ItemChange change, const ItemChangeData &value)
{
if (change == QQuickItem::ItemSceneChange) {
//we have a window: create the representations if needed
if (value.window) {
emit colorGroupChanged();
emit colorsChanged();
}
}
QQuickItem::itemChange(change, value);
}
bool ColorScope::event(QEvent *event)
{
if (event->type() == QEvent::ParentChange) {
emit colorGroupChanged();
emit colorsChanged();
}
return QQuickItem::event(event);
}
#include "moc_colorscope.cpp"

View File

@ -76,14 +76,21 @@ public:
/// @endcond
ColorScope *findParentScope() const;
void itemChange(ItemChange change, const ItemChangeData &value);
protected:
bool event(QEvent *event);
Q_SIGNALS:
void colorGroupChanged();
void colorsChanged();
private:
bool m_inherit;
Plasma::Theme m_theme;
Plasma::Theme::ColorGroup m_group;
static ColorScope *s_colorScope;
QPointer<ColorScope> m_parentScope;
};
QML_DECLARE_TYPEINFO(ColorScope, QML_HAS_ATTACHED_PROPERTIES)

View File

@ -348,6 +348,22 @@ FrameSvgItemMargins *FrameSvgItem::fixedMargins() const
return m_fixedMargins;
}
void FrameSvgItem::setColorGroup(Plasma::Theme::ColorGroup group)
{
if (m_frameSvg->colorGroup() == group) {
return;
}
m_frameSvg->setColorGroup(group);
emit colorGroupChanged();
}
Plasma::Theme::ColorGroup FrameSvgItem::colorGroup() const
{
return m_frameSvg->colorGroup();
}
bool FrameSvgItem::fromCurrentTheme() const
{
return m_frameSvg->fromCurrentTheme();

View File

@ -149,6 +149,15 @@ class FrameSvgItem : public QQuickItem
*/
Q_PROPERTY(bool fromCurrentTheme READ fromCurrentTheme NOTIFY fromCurrentThemeChanged)
/**
* Set a color group for the FrameSvgItem.
* if the Svg uses stylesheets and has elements
* that are eithe TextColor or BackgroundColor class,
* make them use ButtonTextColor/ButtonBackgroundColor
* or ViewTextColor/ViewBackgroundColor, ComplementaryTextColor etc.
*/
Q_PROPERTY(Plasma::Theme::ColorGroup colorGroup READ colorGroup WRITE setColorGroup NOTIFY colorGroupChanged)
public:
/**
* @return true if the svg has the necessary elements with the given prefix
@ -173,6 +182,9 @@ public:
FrameSvgItemMargins *margins() const;
FrameSvgItemMargins *fixedMargins() const;
void setColorGroup(Plasma::Theme::ColorGroup group);
Plasma::Theme::ColorGroup colorGroup() const;
bool fromCurrentTheme() const;
void geometryChanged(const QRectF &newGeometry,
@ -197,6 +209,7 @@ Q_SIGNALS:
void prefixChanged();
void enabledBordersChanged();
void fromCurrentThemeChanged();
void colorGroupChanged();
private Q_SLOTS:
void doUpdate();