1 | /* |
2 | * SPDX-FileCopyrightText: 2017 by Marco Martin <mart@kde.org> |
3 | * SPDX-FileCopyrightText: 2021 Arjen Hiemstra <ahiemstra@heimr.nl> |
4 | * |
5 | * SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #include "basictheme_p.h" |
9 | #include "styleselector.h" |
10 | |
11 | #include <QFile> |
12 | #include <QGuiApplication> |
13 | |
14 | #include "kirigamiplatform_logging.h" |
15 | |
16 | namespace Kirigami |
17 | { |
18 | namespace Platform |
19 | { |
20 | |
21 | BasicThemeDefinition::BasicThemeDefinition(QObject *parent) |
22 | : QObject(parent) |
23 | { |
24 | defaultFont = qGuiApp->font(); |
25 | |
26 | smallFont = qGuiApp->font(); |
27 | smallFont.setPointSize(smallFont.pointSize() - 2); |
28 | } |
29 | |
30 | void BasicThemeDefinition::syncToQml(PlatformTheme *object) |
31 | { |
32 | auto item = qobject_cast<QQuickItem *>(o: object->parent()); |
33 | if (item && qmlAttachedPropertiesObject<PlatformTheme>(obj: item, create: false) == object) { |
34 | Q_EMIT sync(object: item); |
35 | } |
36 | } |
37 | |
38 | BasicThemeInstance::BasicThemeInstance(QObject *parent) |
39 | : QObject(parent) |
40 | { |
41 | } |
42 | |
43 | BasicThemeDefinition &BasicThemeInstance::themeDefinition(QQmlEngine *engine) |
44 | { |
45 | if (m_themeDefinition) { |
46 | return *m_themeDefinition; |
47 | } |
48 | |
49 | auto themeUrl = StyleSelector::componentUrl(QStringLiteral("Theme.qml" )); |
50 | QQmlComponent component(engine); |
51 | component.loadUrl(url: themeUrl); |
52 | |
53 | if (!component.isError()) { |
54 | auto result = component.create(); |
55 | if (auto themeDefinition = qobject_cast<BasicThemeDefinition *>(object: result)) { |
56 | m_themeDefinition.reset(p: themeDefinition); |
57 | } else { |
58 | const auto errors = component.errors(); |
59 | for (auto error : errors) { |
60 | qCWarning(KirigamiPlatform) << error.toString(); |
61 | } |
62 | |
63 | qCWarning(KirigamiPlatform) << "Invalid Theme file, using default Basic theme." ; |
64 | m_themeDefinition = std::make_unique<BasicThemeDefinition>(); |
65 | } |
66 | } else { |
67 | qCDebug(KirigamiPlatform) << "No Theme file found, using default Basic theme" ; |
68 | m_themeDefinition = std::make_unique<BasicThemeDefinition>(); |
69 | } |
70 | |
71 | connect(sender: m_themeDefinition.get(), signal: &BasicThemeDefinition::changed, context: this, slot: &BasicThemeInstance::onDefinitionChanged); |
72 | |
73 | return *m_themeDefinition; |
74 | } |
75 | |
76 | void BasicThemeInstance::onDefinitionChanged() |
77 | { |
78 | for (auto watcher : std::as_const(t&: watchers)) { |
79 | watcher->sync(); |
80 | } |
81 | } |
82 | |
83 | Q_GLOBAL_STATIC(BasicThemeInstance, basicThemeInstance) |
84 | |
85 | BasicTheme::BasicTheme(QObject *parent) |
86 | : PlatformTheme(parent) |
87 | { |
88 | basicThemeInstance()->watchers.append(t: this); |
89 | |
90 | sync(); |
91 | } |
92 | |
93 | BasicTheme::~BasicTheme() |
94 | { |
95 | basicThemeInstance()->watchers.removeOne(t: this); |
96 | } |
97 | |
98 | void BasicTheme::sync() |
99 | { |
100 | auto &definition = basicThemeInstance()->themeDefinition(engine: qmlEngine(parent())); |
101 | |
102 | switch (colorSet()) { |
103 | case BasicTheme::Button: |
104 | setTextColor(tint(color: definition.buttonTextColor)); |
105 | setBackgroundColor(tint(color: definition.buttonBackgroundColor)); |
106 | setAlternateBackgroundColor(tint(color: definition.buttonAlternateBackgroundColor)); |
107 | setHoverColor(tint(color: definition.buttonHoverColor)); |
108 | setFocusColor(tint(color: definition.buttonFocusColor)); |
109 | break; |
110 | case BasicTheme::View: |
111 | setTextColor(tint(color: definition.viewTextColor)); |
112 | setBackgroundColor(tint(color: definition.viewBackgroundColor)); |
113 | setAlternateBackgroundColor(tint(color: definition.viewAlternateBackgroundColor)); |
114 | setHoverColor(tint(color: definition.viewHoverColor)); |
115 | setFocusColor(tint(color: definition.viewFocusColor)); |
116 | break; |
117 | case BasicTheme::Selection: |
118 | setTextColor(tint(color: definition.selectionTextColor)); |
119 | setBackgroundColor(tint(color: definition.selectionBackgroundColor)); |
120 | setAlternateBackgroundColor(tint(color: definition.selectionAlternateBackgroundColor)); |
121 | setHoverColor(tint(color: definition.selectionHoverColor)); |
122 | setFocusColor(tint(color: definition.selectionFocusColor)); |
123 | break; |
124 | case BasicTheme::Tooltip: |
125 | setTextColor(tint(color: definition.tooltipTextColor)); |
126 | setBackgroundColor(tint(color: definition.tooltipBackgroundColor)); |
127 | setAlternateBackgroundColor(tint(color: definition.tooltipAlternateBackgroundColor)); |
128 | setHoverColor(tint(color: definition.tooltipHoverColor)); |
129 | setFocusColor(tint(color: definition.tooltipFocusColor)); |
130 | break; |
131 | case BasicTheme::Complementary: |
132 | setTextColor(tint(color: definition.complementaryTextColor)); |
133 | setBackgroundColor(tint(color: definition.complementaryBackgroundColor)); |
134 | setAlternateBackgroundColor(tint(color: definition.complementaryAlternateBackgroundColor)); |
135 | setHoverColor(tint(color: definition.complementaryHoverColor)); |
136 | setFocusColor(tint(color: definition.complementaryFocusColor)); |
137 | break; |
138 | case BasicTheme::Window: |
139 | default: |
140 | setTextColor(tint(color: definition.textColor)); |
141 | setBackgroundColor(tint(color: definition.backgroundColor)); |
142 | setAlternateBackgroundColor(tint(color: definition.alternateBackgroundColor)); |
143 | setHoverColor(tint(color: definition.hoverColor)); |
144 | setFocusColor(tint(color: definition.focusColor)); |
145 | break; |
146 | } |
147 | |
148 | setDisabledTextColor(tint(color: definition.disabledTextColor)); |
149 | setHighlightColor(tint(color: definition.highlightColor)); |
150 | setHighlightedTextColor(tint(color: definition.highlightedTextColor)); |
151 | setActiveTextColor(tint(color: definition.activeTextColor)); |
152 | setActiveBackgroundColor(tint(color: definition.activeBackgroundColor)); |
153 | setLinkColor(tint(color: definition.linkColor)); |
154 | setLinkBackgroundColor(tint(color: definition.linkBackgroundColor)); |
155 | setVisitedLinkColor(tint(color: definition.visitedLinkColor)); |
156 | setVisitedLinkBackgroundColor(tint(color: definition.visitedLinkBackgroundColor)); |
157 | setNegativeTextColor(tint(color: definition.negativeTextColor)); |
158 | setNegativeBackgroundColor(tint(color: definition.negativeBackgroundColor)); |
159 | setNeutralTextColor(tint(color: definition.neutralTextColor)); |
160 | setNeutralBackgroundColor(tint(color: definition.neutralBackgroundColor)); |
161 | setPositiveTextColor(tint(color: definition.positiveTextColor)); |
162 | setPositiveBackgroundColor(tint(color: definition.positiveBackgroundColor)); |
163 | |
164 | setDefaultFont(definition.defaultFont); |
165 | setSmallFont(definition.smallFont); |
166 | } |
167 | |
168 | bool BasicTheme::event(QEvent *event) |
169 | { |
170 | if (event->type() == PlatformThemeEvents::DataChangedEvent::type) { |
171 | sync(); |
172 | } |
173 | |
174 | if (event->type() == PlatformThemeEvents::ColorSetChangedEvent::type) { |
175 | sync(); |
176 | } |
177 | |
178 | if (event->type() == PlatformThemeEvents::ColorGroupChangedEvent::type) { |
179 | sync(); |
180 | } |
181 | |
182 | if (event->type() == PlatformThemeEvents::ColorChangedEvent::type) { |
183 | basicThemeInstance()->themeDefinition(engine: qmlEngine(parent())).syncToQml(object: this); |
184 | } |
185 | |
186 | if (event->type() == PlatformThemeEvents::FontChangedEvent::type) { |
187 | basicThemeInstance()->themeDefinition(engine: qmlEngine(parent())).syncToQml(object: this); |
188 | } |
189 | |
190 | return PlatformTheme::event(event); |
191 | } |
192 | |
193 | QColor BasicTheme::tint(const QColor &color) |
194 | { |
195 | switch (colorGroup()) { |
196 | case PlatformTheme::Inactive: |
197 | return QColor::fromHsvF(h: color.hueF(), s: color.saturationF() * 0.5, v: color.valueF()); |
198 | case PlatformTheme::Disabled: |
199 | return QColor::fromHsvF(h: color.hueF(), s: color.saturationF() * 0.5, v: color.valueF() * 0.8); |
200 | default: |
201 | return color; |
202 | } |
203 | } |
204 | |
205 | } |
206 | } |
207 | |
208 | #include "moc_basictheme_p.cpp" |
209 | |