Libplasma

plasmatheme.cpp
1/*
2 SPDX-FileCopyrightText: 2023 Marco Martin <mart@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "plasmatheme.h"
8#include <KIconLoader>
9#include <QDebug>
10#include <QGuiApplication>
11#include <QPalette>
12#include <QQmlContext>
13#include <QQmlEngine>
14#include <QQuickRenderControl>
15#include <QQuickWindow>
16#include <QScopeGuard>
17
18#include <KColorScheme>
19#include <KConfigGroup>
20#include <KIconColors>
21
22PlasmaTheme::PlasmaTheme(QObject *parent)
23 : PlatformTheme(parent)
24{
25 setSupportsIconColoring(true);
26
27 auto parentItem = qobject_cast<QQuickItem *>(parent);
28 if (parentItem) {
29 connect(parentItem, &QQuickItem::windowChanged, this, &PlasmaTheme::syncWindow);
30 connect(parentItem, &QQuickItem::enabledChanged, this, &PlasmaTheme::syncColors);
31 connect(parentItem, &QQuickItem::visibleChanged, this, [this, parentItem] {
32 if (!parentItem->isVisible()) {
33 return;
34 }
35 syncColors();
36 });
37 }
38
39 setDefaultFont(qGuiApp->font());
40
41 KSharedConfigPtr ptr = KSharedConfig::openConfig();
42 KConfigGroup general(ptr->group(QStringLiteral("general")));
43
44 setSmallFont(general.readEntry("smallestReadableFont", []() {
45 auto smallFont = qApp->font();
46#ifndef Q_OS_WIN
47 if (smallFont.pixelSize() != -1) {
48 smallFont.setPixelSize(smallFont.pixelSize() - 2);
49 } else {
50 smallFont.setPointSize(smallFont.pointSize() - 2);
51 }
52#endif
53 return smallFont;
54 }()));
55
56 syncWindow();
57 syncColors();
58 connect(&m_theme, &Plasma::Theme::themeChanged, this, &PlasmaTheme::syncColors);
59}
60
61PlasmaTheme::~PlasmaTheme()
62{
63}
64
65QIcon PlasmaTheme::iconFromTheme(const QString &name, const QColor &customColor)
66{
67 KIconColors colors(Plasma::Theme::globalPalette());
68 KColorScheme colorScheme(QPalette::Active, KColorScheme::Window, Plasma::Theme::globalColorScheme());
69
70 colors.setPositiveText(colorScheme.foreground(KColorScheme::PositiveText).color().name());
71 colors.setNeutralText(colorScheme.foreground(KColorScheme::NeutralText).color().name());
72 colors.setNegativeText(colorScheme.foreground(KColorScheme::NegativeText).color().name());
73 colors.setActiveText(colorScheme.foreground(KColorScheme::ActiveText).color().name());
74
75 if (customColor != Qt::transparent) {
76 colors.setText(customColor);
77 }
78
79 return KDE::icon(name, colors);
80}
81
82void PlasmaTheme::syncWindow()
83{
84 if (m_window) {
85 disconnect(m_window.data(), &QWindow::activeChanged, this, &PlasmaTheme::syncColors);
86 }
87
88 QWindow *window = nullptr;
89
90 auto parentItem = qobject_cast<QQuickItem *>(parent());
91 if (parentItem) {
92 QQuickWindow *qw = parentItem->window();
93
95 if (!window) {
96 window = qw;
97 }
98 if (qw) {
99 connect(qw, &QQuickWindow::sceneGraphInitialized, this, &PlasmaTheme::syncWindow, Qt::UniqueConnection);
100 }
101 }
102 m_window = window;
103
104 if (window) {
105 connect(m_window.data(), &QWindow::activeChanged, this, &PlasmaTheme::syncColors);
106 syncColors();
107 }
108}
109
110void PlasmaTheme::syncColors()
111{
113 return;
114 }
115
117 auto parentItem = qobject_cast<QQuickItem *>(parent());
118 if (parentItem) {
119 if (!parentItem->isVisible()) {
120 return;
121 }
122 if (!parentItem->isEnabled()) {
123 paletteGroup = QPalette::Disabled;
124 // Why also check if the window is exposed?
125 // in the case of QQuickWidget the window() will never be active
126 // and the widgets will always have the inactive palette.
127 // better to always show it active than always show it inactive
128 } else if (m_window && !m_window->isActive() && m_window->isExposed()) {
129 paletteGroup = QPalette::Inactive;
130 }
131 }
132
133 Plasma::Theme::ColorGroup group;
134 switch (colorSet()) {
135 case View:
136 group = Plasma::Theme::ViewColorGroup;
137 break;
138 case Button:
139 group = Plasma::Theme::ButtonColorGroup;
140 break;
141 case Tooltip:
142 group = Plasma::Theme::ToolTipColorGroup;
143 break;
144 case Complementary:
145 group = Plasma::Theme::ComplementaryColorGroup;
146 break;
147 case Header:
148 group = Plasma::Theme::HeaderColorGroup;
149 break;
150 case Selection: // Plasma::Theme doesn't have selection group
151 case Window:
152 default:
153 group = Plasma::Theme::NormalColorGroup;
154 }
155
156 // foreground
157 if (paletteGroup == QPalette::Disabled) {
158 setTextColor(m_theme.color(Plasma::Theme::DisabledTextColor, group));
159 } else {
160 setTextColor(m_theme.color(Plasma::Theme::TextColor, group));
161 }
162 setDisabledTextColor(m_theme.color(Plasma::Theme::DisabledTextColor, group));
163 setHighlightedTextColor(m_theme.color(Plasma::Theme::HighlightedTextColor, group));
164 // Plasma::Theme doesn't have ActiveText, use PositiveTextColor
165 setActiveTextColor(m_theme.color(Plasma::Theme::PositiveTextColor, group));
166 setLinkColor(m_theme.color(Plasma::Theme::LinkColor, group));
167 setVisitedLinkColor(m_theme.color(Plasma::Theme::VisitedLinkColor, group));
168 setNegativeTextColor(m_theme.color(Plasma::Theme::NegativeTextColor, group));
169 setNeutralTextColor(m_theme.color(Plasma::Theme::NeutralTextColor, group));
170 setPositiveTextColor(m_theme.color(Plasma::Theme::PositiveTextColor, group));
171
172 // background
173 setBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group));
174 setHighlightColor(m_theme.color(Plasma::Theme::HighlightColor, group));
175 // Plasma::Theme doesn't have AlternateBackground
176 setAlternateBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group));
177
178 // Plasma::Theme doesn't have any different background color type
179 setActiveBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group));
180 setLinkBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group));
181 setVisitedLinkBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group));
182 setNegativeBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group));
183 setNeutralBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group));
184 setPositiveBackgroundColor(m_theme.color(Plasma::Theme::BackgroundColor, group));
185
186 // decoration
187 setHoverColor(m_theme.color(Plasma::Theme::HoverColor, group));
188 setFocusColor(m_theme.color(Plasma::Theme::FocusColor, group));
189}
190
191bool PlasmaTheme::event(QEvent *event)
192{
193 if (event->type() == Kirigami::Platform::PlatformThemeEvents::ColorSetChangedEvent::type) {
194 syncColors();
195 }
196
197 if (event->type() == Kirigami::Platform::PlatformThemeEvents::ColorGroupChangedEvent::type) {
198 syncColors();
199 }
200
201 return PlatformTheme::event(event);
202}
203
204#include "moc_plasmatheme.cpp"
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
void themeChanged()
Emitted when the user changes the theme.
@ DisabledTextColor
color of disabled text
Definition theme.h:71
@ PositiveTextColor
color of foreground objects with a "positive message" connotation (usually green)
Definition theme.h:68
@ HighlightedTextColor
color contrasting with HighlightColor, to be used for instance with
Definition theme.h:67
@ VisitedLinkColor
color visited clickable links
Definition theme.h:66
@ HighlightColor
the text highlight color to be used by items resting on the background
Definition theme.h:61
@ LinkColor
color for clickable links
Definition theme.h:65
@ NeutralTextColor
color of foreground objects with a "neutral message" connotation (usually yellow)
Definition theme.h:69
@ HoverColor
color for hover effect on view
Definition theme.h:63
@ NegativeTextColor
color of foreground objects with a "negative message" connotation (usually red)
Definition theme.h:70
@ BackgroundColor
the default background color
Definition theme.h:60
@ TextColor
the text color to be used by items resting on the background
Definition theme.h:59
@ FocusColor
color for focus effect on view
Definition theme.h:64
QWidget * window(QObject *job)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QObject * parent() const const
T qobject_cast(QObject *object)
void enabledChanged()
void visibleChanged()
void windowChanged(QQuickWindow *window)
QWindow * renderWindowFor(QQuickWindow *win, QPoint *offset)
void sceneGraphInitialized()
UniqueConnection
transparent
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void activeChanged()
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 11 2025 11:56:56 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.