MauiKit Controls

style.cpp
1#include "style.h"
2#include <QCoreApplication>
3#include <QGuiApplication>
4#include <QIcon>
5#include <QStyle>
6#include <QApplication>
7#include <QFontDatabase>
8#include <QStyleHints>
9#include <QWindow>
10#include <QWidget>
11#include <QMainWindow>
12#include <QToolBar>
13#include <MauiMan4/thememanager.h>
14#include <MauiMan4/backgroundmanager.h>
15#include <MauiMan4/accessibilitymanager.h>
16
17Q_GLOBAL_STATIC(Style, styleInstance)
18
19void Style::styleChanged()
20{
21 // It should be safe to use qApp->style() unguarded here, because the signal
22 // will only have been connected if qApp is a QApplication.
23 qDebug() << "STYLE HAS CHANGED EMITTED";
24
26
27 auto *style = qApp->style();
28 if (!style || QCoreApplication::closingDown()) {
29 return;
30 }
31
32 Q_ASSERT(style != sender());
33
34 connect(style, &QObject::destroyed, this, &Style::styleChanged);
35
36 m_currentIconTheme = QIcon::themeName();
37 Q_EMIT currentIconThemeChanged(m_currentIconTheme);
38
40 Q_EMIT monospacedFontChanged();
41}
42
43Style::Style(QObject *parent) : QObject(parent)
44 ,m_iconSizes (new GroupSizes(8,16, 22, 32, 48, 64, 128, this))
45 ,m_space( new GroupSizes(4, 6, 8, 16, 24, 32, 40, this))
46 ,m_fontSizes(new GroupSizes(this))
47 ,m_units(new Units(this))
48 ,m_accentColor(QColor("#26c6da"))
49 ,m_themeSettings( new MauiMan::ThemeManager(this))
50 ,m_backgroundSettings( new MauiMan::BackgroundManager(this))
51 ,m_accessibilitySettings( new MauiMan::AccessibilityManager(this))
52{
53 qGuiApp->installEventFilter(this);
54 connect(qGuiApp, &QGuiApplication::fontChanged, [this](const QFont &font)
55 {
56 m_defaultFont = font;
57 setFontSizes();
58 Q_EMIT defaultFontChanged();
59 // Q_EMIT m_fontSizes->sizesChanged();
60 Q_EMIT fontSizesChanged();
61 Q_EMIT h1FontChanged();
62 Q_EMIT h2FontChanged();
63 Q_EMIT monospacedFontChanged();
64 });
65
67 {
68 if(m_styleType_blocked)
69 return;
70
71 switch(type)
72 {
73 case Qt::ColorScheme::Unknown:
74 m_styleType = static_cast<Style::StyleType>(m_themeSettings->styleType());
75 break;
76 case Qt::ColorScheme::Light:
77 m_styleType = Style::StyleType::Light;
78 break;
79 case Qt::ColorScheme::Dark:
80 m_styleType = Style::StyleType::Dark;
81 break;
82 }
83 qDebug() << "Color schem style type changed<<"<< type << m_styleType;
84
85 Q_EMIT styleTypeChanged(m_styleType);
86 });
87
88 connect(m_themeSettings, &MauiMan::ThemeManager::styleTypeChanged, [this](int type)
89 {
90 if(m_styleType_blocked)
91 return;
92
93 m_styleType = static_cast<Style::StyleType>(type);
94 Q_EMIT styleTypeChanged(m_styleType);
95 });
96
97 connect(m_themeSettings, &MauiMan::ThemeManager::accentColorChanged, [this](QString color)
98 {
99 m_accentColor = color;
100 Q_EMIT this->accentColorChanged(m_accentColor);
101 });
102
103 connect(m_themeSettings, &MauiMan::ThemeManager::borderRadiusChanged, [this](uint radius)
104 {
105 m_radiusV = radius;
106 Q_EMIT this->radiusVChanged(m_radiusV);
107 });
108
109 connect(m_themeSettings, &MauiMan::ThemeManager::iconSizeChanged, [this](uint size)
110 {
111 m_iconSize = size;
112 Q_EMIT this->iconSizeChanged(m_iconSize);
113 });
114
115 connect(m_themeSettings, &MauiMan::ThemeManager::paddingSizeChanged, [this](uint size)
116 {
117 m_defaultPadding = size;
118 Q_EMIT this->defaultPaddingChanged();
119 });
120
121 connect(m_themeSettings, &MauiMan::ThemeManager::marginSizeChanged, [this](uint size)
122 {
123 qDebug() << "ContentMARGINS CHANGED" << size;
124 m_contentMargins = size;
125 Q_EMIT this->contentMarginsChanged();
126 });
127
128 connect(m_themeSettings, &MauiMan::ThemeManager::spacingSizeChanged, [this](uint size)
129 {
130 m_defaultSpacing = size;
131 Q_EMIT this->defaultSpacingChanged();
132 });
133
134 connect(m_themeSettings, &MauiMan::ThemeManager::enableEffectsChanged, [this](bool value)
135 {
136 m_enableEffects = value;
137 Q_EMIT this->enableEffectsChanged(m_enableEffects);
138 });
139
140 connect(m_backgroundSettings, &MauiMan::BackgroundManager::wallpaperSourceChanged, [this](QString source)
141 {
142 m_adaptiveColorSchemeSource = QUrl::fromUserInput(source).toLocalFile();
143 Q_EMIT this->adaptiveColorSchemeSourceChanged(m_adaptiveColorSchemeSource);
144 });
145
146 connect(m_themeSettings, &MauiMan::ThemeManager::enableEffectsChanged, [this](bool value)
147 {
148 m_enableEffects = value;
149 Q_EMIT this->enableEffectsChanged(m_enableEffects);
150 });
151
152 connect(m_accessibilitySettings, &MauiMan::AccessibilityManager::scrollBarPolicyChanged, [this](uint state)
153 {
154 qDebug() << "SCROLBAR POLICY CHANGED" << state;
155 Q_EMIT scrollBarPolicyChanged(state);
156 });
157
159 {
160 connect(m_themeSettings, &MauiMan::ThemeManager::iconThemeChanged, [this](QString name)
161 {
162 qDebug() << "Ask to change the icon theme";
163 m_currentIconTheme = name;
164 Q_EMIT currentIconThemeChanged(m_currentIconTheme);
165 });
166 }else
167 {
168 // //to be able to check and icon theme change rely on the style being reset, this not even works on Plasma, so do we need it?
169 // QStyle *style = qApp->style();
170 // if (style)
171 // {
172 // connect(style, &QObject::destroyed, this, &Style::styleChanged);
173 // }
174 }
175
176 m_defaultFont = qGuiApp->font();
178 setFontSizes();
179
180 m_radiusV = m_themeSettings->borderRadius();
181 m_iconSize = m_themeSettings->iconSize();
182 m_accentColor = m_themeSettings->accentColor();
183
184 m_contentMargins = m_themeSettings->marginSize();
185 m_defaultPadding = m_themeSettings->paddingSize();
186 m_defaultSpacing = m_themeSettings->spacingSize();
187
188 m_currentIconTheme = QIcon::themeName();
189
190 //TODO Use new Qt6 StyelHint properties for this
191
192 //For Maui Session we want to use MauiMan
194 {
195 switch(QGuiApplication::styleHints()->colorScheme())
196 {
197 case Qt::ColorScheme::Unknown:
198 m_styleType = static_cast<Style::StyleType>(m_themeSettings->styleType());
199 break;
200 case Qt::ColorScheme::Light:
201 m_styleType = Style::StyleType::Light;
202 break;
203 case Qt::ColorScheme::Dark:
204 m_styleType = Style::StyleType::Dark;
205 break;
206 }
207 }
208 else
209 {
210 m_styleType = static_cast<Style::StyleType>(m_themeSettings->styleType());
211 }
212
213 m_adaptiveColorSchemeSource = QUrl::fromUserInput(m_backgroundSettings->wallpaperSource()).toLocalFile();
214 m_enableEffects = m_themeSettings->enableEffects();
215}
216
217void Style::setFontSizes()
218{
219 qDebug() << m_defaultFont << m_defaultFont.pointSize();
220
221 m_defaultFontSize = m_defaultFont.pointSize () > 0 ? m_defaultFont.pointSize () : m_defaultFont.pixelSize();
222
223 m_fontSizes->m_tiny = m_defaultFontSize-2;
224 m_fontSizes->m_small = m_defaultFontSize-1;
225 m_fontSizes->m_medium = m_defaultFontSize;
226 m_fontSizes->m_big = m_defaultFontSize+1;
227 m_fontSizes->m_large = m_defaultFontSize+2;
228 m_fontSizes->m_huge = m_defaultFontSize+3;
229 m_fontSizes->m_enormous = m_defaultFontSize+4;
230
231 m_h1Font.setPointSize(m_fontSizes->m_enormous);
232 m_h1Font.setWeight(QFont::Black);
233 m_h1Font.setBold(true);
234
235 m_h2Font.setPointSize(m_fontSizes->m_big);
236 m_h2Font.setWeight(QFont::DemiBold);
237 // m_h2Font.setBold(false);
238}
239
240void Style::setRadiusV(const uint& radius)
241{
242 if(m_radiusV == radius)
243 {
244 return;
245 }
246
247 m_radiusV = radius;
248 Q_EMIT radiusVChanged(m_radiusV);
249}
250
251bool Style::enableEffects() const
252{
253 return m_enableEffects;
254}
255
257{
258 return m_translucencyAvailable;
259}
260
261void Style::setTranslucencyAvailable(const bool &value)
262{
263 if(value == m_translucencyAvailable)
264 {
265 return;
266 }
267
268 m_translucencyAvailable = value;
269 Q_EMIT this->translucencyAvailableChanged(m_translucencyAvailable);
270}
271
272
273Style *Style::qmlAttachedProperties(QObject *object)
274{
275 Q_UNUSED(object)
276 return Style::instance();
277}
278
279Style *Style::instance()
280{
281 return styleInstance();
282}
283
284int getClosest(int, int, int);
285
286// Returns element closest to target in arr[]
287int findClosest(int arr[], int n, int target)
288{
289 // Corner cases
290 if (target <= arr[0])
291 return arr[0];
292 if (target >= arr[n - 1])
293 return arr[n - 1];
294
295 // Doing binary search
296 int i = 0, j = n, mid = 0;
297 while (i < j) {
298 mid = (i + j) / 2;
299
300 if (arr[mid] == target)
301 return arr[mid];
302
303 /* If target is less than array element,
304 * then search in left */
305 if (target < arr[mid]) {
306
307 // If target is greater than previous
308 // to mid, return closest of two
309 if (mid > 0 && target > arr[mid - 1])
310 return getClosest(arr[mid - 1],
311 arr[mid], target);
312
313 /* Repeat for left half */
314 j = mid;
315 }
316
317 // If target is greater than mid
318 else {
319 if (mid < n - 1 && target < arr[mid + 1])
320 return getClosest(arr[mid],
321 arr[mid + 1], target);
322 // update i
323 i = mid + 1;
324 }
325 }
326
327 // Only single element left after search
328 return arr[mid];
329}
330
331// Method to compare which one is the more close.
332// We find the closest by taking the difference
333// between the target and both values. It assumes
334// that val2 is greater than val1 and target lies
335// between these two.
336int getClosest(int val1, int val2,
337 int target)
338{
339 if (target - val1 >= val2 - target)
340 return val2;
341 else
342 return val1;
343}
344
345
346int Style::mapToIconSizes(const int &size)
347{
348 int values[] = {8, 16, 22, 32, 48, 64, 128};
349 int n = sizeof(values) / sizeof(values[0]);
350 return findClosest (values, n, size);
351}
352
353GroupSizes::GroupSizes(const uint tiny, const uint small, const uint medium, const uint big, const uint large, const uint huge, const uint enormous, QObject *parent) : QObject(parent)
354 ,m_tiny(tiny)
355 ,m_small(small)
356 ,m_medium(medium)
357 ,m_big(big)
358 ,m_large(large)
359 ,m_huge(huge)
360 ,m_enormous(enormous)
361
362{
363
364}
365
366GroupSizes::GroupSizes(QObject* parent) : QObject(parent)
367{
368}
369
370
372{
373 return m_adaptiveColorSchemeSource;
374}
375
376void Style::setAdaptiveColorSchemeSource(const QVariant& source)
377{
378 m_adaptiveColorSchemeSource_blocked = true;
379 if(source == m_adaptiveColorSchemeSource)
380 {
381 return;
382 }
383
384 m_adaptiveColorSchemeSource = source;
385 Q_EMIT adaptiveColorSchemeSourceChanged(m_adaptiveColorSchemeSource);
386}
387
388void Style::unsetAdaptiveColorSchemeSource()
389{
390 m_adaptiveColorSchemeSource_blocked = false;
391 m_adaptiveColorSchemeSource = QUrl::fromUserInput(m_backgroundSettings->wallpaperSource()).toLocalFile();
392 Q_EMIT adaptiveColorSchemeSourceChanged(m_adaptiveColorSchemeSource);
393}
394
396{
397 return m_accentColor;
398}
399
400void Style::setAccentColor(const QColor& color)
401{
402 m_accentColor_blocked = true;
403
404 if(m_accentColor == color)
405 {
406 return;
407 }
408
409 m_accentColor = color;
410 Q_EMIT accentColorChanged(m_accentColor);
411}
412
413void Style::unsetAccentColor()
414{
415 m_accentColor_blocked = false;
416 m_accentColor = m_themeSettings->accentColor();
417 Q_EMIT accentColorChanged(m_accentColor);
418}
419
421{
422 return m_styleType;
423}
424
425void Style::setStyleType(const Style::StyleType &type)
426{
427 m_styleType_blocked = true;
428
429 if (m_styleType == type)
430 return;
431
432 m_styleType = type;
433 Q_EMIT styleTypeChanged(m_styleType);
434}
435
436void Style::unsetStyeType()
437{
438 m_styleType_blocked = false;
439 m_styleType = static_cast<Style::StyleType>(m_themeSettings->styleType());
440 Q_EMIT styleTypeChanged(m_styleType);
441}
442
443Units::Units(QObject *parent) : QObject(parent)
444 , m_fontMetrics(QFontMetricsF(QGuiApplication::font()))
445 , m_gridUnit(m_fontMetrics.height())
446 , m_veryLongDuration(400)
447 , m_longDuration(200)
448 , m_shortDuration(100)
449 , m_veryShortDuration(50)
450 , m_humanMoment(2000)
451 , m_toolTipDelay(700)
452{
453
454}
455
456uint Style::iconSize() const
457{
458 return m_iconSize;
459}
460
462{
463 return m_currentIconTheme;
464}
465
466bool Style::menusHaveIcons() const
467{
468 return !qApp->testAttribute(Qt::AA_DontShowIconsInMenus);
469}
470
471uint Style::scrollBarPolicy() const
472{
473// return m_accessibilitySettings->scrollBarPolicy();
474 return 2;
475}
476
477bool Style::playSounds() const
478{
479 return m_accessibilitySettings->playSounds();
480}
481
482bool Style::eventFilter(QObject *watched, QEvent *event)
483{
484 // qDebug() << "EVENT HAPPENED" << event->type();
485
486 if (event->type() == QEvent::StyleChange || event->type() == QEvent::WindowActivate) {
487
488 if(m_currentIconTheme != QIcon::themeName())
489 {
490
491 m_currentIconTheme = QIcon::themeName();
492 Q_EMIT currentIconThemeChanged( m_currentIconTheme);
493 qDebug() << "ICON THEME CHANGED" << m_currentIconTheme;
494 }
495 return QObject::eventFilter(watched, event);
496 }
497
498 return QObject::eventFilter(watched, event);
499}
500
501
The sizes group for some Style properties, such as Style::iconSize, Style::space, etc.
Definition style.h:55
static bool isMauiSession()
The MauiKit Style preferences singleton object.
Definition style.h:86
QString currentIconTheme
The current system icon theme picked up by the user.
Definition style.h:234
QVariant adaptiveColorSchemeSource
The source for picking up the application color palette when the style type is set to Style....
Definition style.h:212
uint iconSize
The preferred size for painting the icons in places, such as menus, buttons and delegates.
Definition style.h:116
bool menusHaveIcons
Whether the menu entries should display the icon image.
Definition style.h:240
bool playSounds
Whether the user desires for the application to play sounds or not.
Definition style.h:252
bool enableEffects
Whether special effects are desired.
Definition style.h:227
StyleType
The different options for the color scheme style.
Definition style.h:271
@ Light
A light variant designed for Maui.
Definition style.h:275
@ Dark
A dark variant designed for Maui.
Definition style.h:280
uint scrollBarPolicy
The preferred scroll bars policy for displaying them or not.
Definition style.h:246
int mapToIconSizes(const int &size)
Given a size as argument this function will return the best fitted icon size from the standard icon s...
Definition style.cpp:346
StyleType styleType
The preferred style type for setting the color scheme of the application.
Definition style.h:220
bool translucencyAvailable
Whether the application window surface should be transparent and request the compositor to blur the b...
Definition style.h:258
QColor accentColor
Sets the color to be used for highlighted, active, checked and such states of the UI elements.
Definition style.h:205
The Unit group properties.
Definition style.h:25
Type type(const QSqlDatabase &db)
QString name(StandardAction id)
QCoreApplication * instance()
int pixelSize() const const
int pointSize() const const
void setBold(bool enable)
void setPointSize(int pointSize)
void setWeight(Weight weight)
QFont systemFont(SystemFont type)
void fontChanged(const QFont &font)
QStyleHints * styleHints()
QString themeName()
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void destroyed(QObject *obj)
virtual bool event(QEvent *e)
virtual bool eventFilter(QObject *watched, QEvent *event)
void installEventFilter(QObject *filterObj)
T qobject_cast(QObject *object)
QObject * sender() const const
void colorSchemeChanged(Qt::ColorScheme colorScheme)
AA_DontShowIconsInMenus
ColorScheme
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QUrl fromUserInput(const QString &userInput, const QString &workingDirectory, UserInputResolutionOptions options)
QString toLocalFile() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 3 2025 12:00:17 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.