1 /*
2 SPDX-FileCopyrightText: 2011 Marco Martin <mart@kde.org>
3 SPDX-FileCopyrightText: 2011 Artur Duque de Souza <asouza@kde.org>
4 SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
5
6 SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9 #include "colorscope.h"
10
11 #include <QColor>
12 #include <QQmlContext>
13 #include <QQmlEngine>
14 #include <QQuickWindow>
15
16 #include <PlasmaQuick/AppletQuickItem>
17
18 QHash<QObject *, ColorScope *> ColorScope::s_attachedScopes = QHash<QObject *, ColorScope *>();
19
20 QWeakPointer<Plasma::Theme> ColorScope::s_theme;
21
ColorScope(QQuickItem * parent,QObject * parentObject)22 ColorScope::ColorScope(QQuickItem *parent, QObject *parentObject)
23 : QQuickItem(parent)
24 , m_inherit(false)
25 , m_group(Plasma::Theme::NormalColorGroup)
26 , m_parent(parentObject)
27 , m_actualGroup(Plasma::Theme::NormalColorGroup)
28 {
29 m_theme = s_theme.toStrongRef();
30 if (!m_theme) {
31 QSharedPointer<Plasma::Theme> themePtr(new Plasma::Theme);
32 s_theme = themePtr;
33 m_theme = s_theme.toStrongRef();
34 }
35
36 connect(m_theme.data(), &Plasma::Theme::themeChanged, this, &ColorScope::colorsChanged);
37
38 connect(this, &ColorScope::colorGroupChanged, this, &ColorScope::colorsChanged);
39
40 if (parentObject && qobject_cast<QQuickItem *>(parentObject)) {
41 connect(static_cast<QQuickItem *>(parentObject), &QQuickItem::windowChanged, this, [this]() {
42 findParentScope();
43 checkColorGroupChanged();
44 });
45
46 connect(static_cast<QQuickItem *>(parentObject), &QQuickItem::parentChanged, this, [this]() {
47 findParentScope();
48 checkColorGroupChanged();
49 });
50 } else if (parent) {
51 connect(parent, &QQuickItem::parentChanged, this, &ColorScope::checkColorGroupChanged);
52 }
53 }
54
~ColorScope()55 ColorScope::~ColorScope()
56 {
57 m_deleting = true;
58 s_attachedScopes.remove(m_parent);
59 }
60
qmlAttachedProperties(QObject * object)61 ColorScope *ColorScope::qmlAttachedProperties(QObject *object)
62 {
63 const auto cs = s_attachedScopes.value(object);
64 if (cs) {
65 return cs;
66 }
67
68 ColorScope *s = new ColorScope(nullptr, object);
69 s_attachedScopes[object] = s;
70 s->m_inherit = true;
71 s->setParent(object);
72 s->checkColorGroupChanged();
73
74 return s;
75 }
76
setParentScope(ColorScope * parentScope)77 void ColorScope::setParentScope(ColorScope *parentScope)
78 {
79 if (parentScope == m_parentScope) {
80 return;
81 }
82
83 if (m_parentScope) {
84 disconnect(m_parentScope.data(), &ColorScope::colorGroupChanged, this, &ColorScope::checkColorGroupChanged);
85 }
86
87 m_parentScope = parentScope;
88
89 if (parentScope) {
90 connect(parentScope, &ColorScope::colorGroupChanged, this, &ColorScope::checkColorGroupChanged);
91 }
92 }
93
findParentScope()94 ColorScope *ColorScope::findParentScope()
95 {
96 QObject *candidate = parentItem();
97 if (!candidate) {
98 candidate = parent();
99 }
100
101 while (candidate) {
102 auto *quickCandidate = qobject_cast<QQuickItem *>(candidate);
103 if (quickCandidate && quickCandidate->parentItem()) {
104 candidate = quickCandidate->parentItem();
105 } else {
106 candidate = candidate->parent();
107 }
108
109 ColorScope *s = qobject_cast<ColorScope *>(candidate);
110 if (!s) {
111 // Make sure AppletInterface always has a ColorScope
112 s = static_cast<ColorScope *>(qmlAttachedPropertiesObject<ColorScope>(candidate, qobject_cast<PlasmaQuick::AppletQuickItem *>(candidate)));
113 }
114 if (s && !s->m_deleting) {
115 setParentScope(s);
116 return s;
117 }
118 }
119
120 return nullptr;
121 }
122
setColorGroup(Plasma::Theme::ColorGroup group)123 void ColorScope::setColorGroup(Plasma::Theme::ColorGroup group)
124 {
125 if (m_group == group) {
126 return;
127 }
128
129 m_group = group;
130
131 checkColorGroupChanged();
132 }
133
colorGroup() const134 Plasma::Theme::ColorGroup ColorScope::colorGroup() const
135 {
136 return m_actualGroup;
137 }
138
textColor() const139 QColor ColorScope::textColor() const
140 {
141 return m_theme->color(Plasma::Theme::TextColor, colorGroup());
142 }
143
highlightColor() const144 QColor ColorScope::highlightColor() const
145 {
146 return m_theme->color(Plasma::Theme::HighlightColor, colorGroup());
147 }
148
highlightedTextColor() const149 QColor ColorScope::highlightedTextColor() const
150 {
151 return m_theme->color(Plasma::Theme::HighlightedTextColor, colorGroup());
152 }
153
backgroundColor() const154 QColor ColorScope::backgroundColor() const
155 {
156 return m_theme->color(Plasma::Theme::BackgroundColor, colorGroup());
157 }
158
positiveTextColor() const159 QColor ColorScope::positiveTextColor() const
160 {
161 return m_theme->color(Plasma::Theme::PositiveTextColor, colorGroup());
162 }
163
neutralTextColor() const164 QColor ColorScope::neutralTextColor() const
165 {
166 return m_theme->color(Plasma::Theme::NeutralTextColor, colorGroup());
167 }
168
negativeTextColor() const169 QColor ColorScope::negativeTextColor() const
170 {
171 return m_theme->color(Plasma::Theme::NegativeTextColor, colorGroup());
172 }
173
disabledTextColor() const174 QColor ColorScope::disabledTextColor() const
175 {
176 return m_theme->color(Plasma::Theme::DisabledTextColor, colorGroup());
177 }
178
inherit() const179 bool ColorScope::inherit() const
180 {
181 return m_inherit;
182 }
183
setInherit(bool inherit)184 void ColorScope::setInherit(bool inherit)
185 {
186 if (m_inherit == inherit) {
187 return;
188 }
189 m_inherit = inherit;
190 Q_EMIT inheritChanged();
191 checkColorGroupChanged();
192 }
193
itemChange(ItemChange change,const ItemChangeData & value)194 void ColorScope::itemChange(ItemChange change, const ItemChangeData &value)
195 {
196 if (change == QQuickItem::ItemSceneChange) {
197 // we have a window: create the representations if needed
198 if (value.window) {
199 findParentScope();
200 checkColorGroupChanged();
201 }
202 }
203
204 QQuickItem::itemChange(change, value);
205 }
206
checkColorGroupChanged()207 void ColorScope::checkColorGroupChanged()
208 {
209 const auto last = m_actualGroup;
210 if (m_inherit) {
211 findParentScope();
212 m_actualGroup = m_parentScope ? m_parentScope->colorGroup() : m_group;
213 } else {
214 m_actualGroup = m_group;
215 }
216
217 if (m_actualGroup != last) {
218 Q_EMIT colorGroupChanged();
219 }
220 }
221
222 #include "moc_colorscope.cpp"
223