File indexing completed on 2024-05-05 04:46:52
0001 #include "style.h" 0002 #include <QCoreApplication> 0003 #include <QGuiApplication> 0004 #include <QIcon> 0005 #include <QStyle> 0006 #include <QApplication> 0007 #include <QFontDatabase> 0008 0009 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0010 #include <MauiMan3/thememanager.h> 0011 #include <MauiMan3/backgroundmanager.h> 0012 #include <MauiMan3/accessibilitymanager.h> 0013 #else 0014 #include <MauiMan4/thememanager.h> 0015 #include <MauiMan4/backgroundmanager.h> 0016 #include <MauiMan4/accessibilitymanager.h> 0017 0018 #include <QStyleHints> 0019 #endif 0020 0021 #ifdef Q_OS_ANDROID 0022 #include "mauiandroid.h" 0023 #endif 0024 0025 Style *Style::m_instance = nullptr; 0026 0027 void Style::styleChanged() 0028 { 0029 // It should be safe to use qApp->style() unguarded here, because the signal 0030 // will only have been connected if qApp is a QApplication. 0031 Q_ASSERT(qobject_cast<QApplication *>(QCoreApplication::instance())); 0032 auto *style = qApp->style(); 0033 if (!style || QCoreApplication::closingDown()) { 0034 return; 0035 } 0036 0037 Q_ASSERT(style != sender()); 0038 0039 connect(style, &QObject::destroyed, this, &Style::styleChanged); 0040 0041 m_currentIconTheme = QIcon::themeName(); 0042 Q_EMIT currentIconThemeChanged(m_currentIconTheme); 0043 0044 m_monospacedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); 0045 Q_EMIT monospacedFontChanged(); 0046 } 0047 0048 0049 Style::Style(QObject *parent) : QObject(parent) 0050 ,m_iconSizes (new GroupSizes(8,16, 22, 32, 48, 64, 128, this)) 0051 ,m_space( new GroupSizes(4, 6, 8, 16, 24, 32, 40, this)) 0052 ,m_fontSizes(new GroupSizes(this)) 0053 ,m_units(new Units(this)) 0054 ,m_accentColor(QColor("#26c6da")) 0055 ,m_themeSettings( new MauiMan::ThemeManager(this)) 0056 ,m_backgroundSettings( new MauiMan::BackgroundManager(this)) 0057 ,m_accessibilitySettings( new MauiMan::AccessibilityManager(this)) 0058 { 0059 connect(qApp, &QCoreApplication::aboutToQuit, []() 0060 { 0061 delete m_instance; 0062 m_instance = nullptr; 0063 }); 0064 0065 connect(qGuiApp, &QGuiApplication::fontChanged, [this](const QFont &font) 0066 { 0067 m_defaultFont = font; 0068 setFontSizes(); 0069 Q_EMIT defaultFontChanged(); 0070 // Q_EMIT m_fontSizes->sizesChanged(); 0071 Q_EMIT fontSizesChanged(); 0072 Q_EMIT h1FontChanged(); 0073 Q_EMIT h2FontChanged(); 0074 Q_EMIT 0075 }); 0076 0077 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0078 connect(m_themeSettings, &MauiMan::ThemeManager::styleTypeChanged, [this](int type) 0079 { 0080 if(m_styleType_blocked) 0081 return; 0082 0083 m_styleType = static_cast<Style::StyleType>(type); 0084 Q_EMIT styleTypeChanged(m_styleType); 0085 }); 0086 #else 0087 0088 connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, [this](Qt::ColorScheme type) 0089 { 0090 qDebug() << "Color schem style type changed<<"<< type; 0091 if(m_styleType_blocked) 0092 return; 0093 0094 switch(type) 0095 { 0096 case Qt::ColorScheme::Unknown: 0097 m_styleType = static_cast<Style::StyleType>(m_themeSettings->styleType()); 0098 break; 0099 case Qt::ColorScheme::Light: 0100 m_styleType = Style::StyleType::Light; 0101 break; 0102 case Qt::ColorScheme::Dark: 0103 m_styleType = Style::StyleType::Dark; 0104 break; 0105 } 0106 0107 Q_EMIT styleTypeChanged(m_styleType); 0108 }); 0109 0110 connect(m_themeSettings, &MauiMan::ThemeManager::styleTypeChanged, [this](int type) 0111 { 0112 if(m_styleType_blocked) 0113 return; 0114 0115 m_styleType = static_cast<Style::StyleType>(type); 0116 Q_EMIT styleTypeChanged(m_styleType); 0117 }); 0118 0119 #endif 0120 0121 connect(m_themeSettings, &MauiMan::ThemeManager::accentColorChanged, [this](QString color) 0122 { 0123 m_accentColor = color; 0124 Q_EMIT this->accentColorChanged(m_accentColor); 0125 }); 0126 0127 connect(m_themeSettings, &MauiMan::ThemeManager::borderRadiusChanged, [this](uint radius) 0128 { 0129 m_radiusV = radius; 0130 Q_EMIT this->radiusVChanged(m_radiusV); 0131 }); 0132 0133 connect(m_themeSettings, &MauiMan::ThemeManager::iconSizeChanged, [this](uint size) 0134 { 0135 m_iconSize = size; 0136 Q_EMIT this->iconSizeChanged(m_iconSize); 0137 }); 0138 0139 connect(m_themeSettings, &MauiMan::ThemeManager::paddingSizeChanged, [this](uint size) 0140 { 0141 m_defaultPadding = size; 0142 Q_EMIT this->defaultPaddingChanged(); 0143 }); 0144 0145 connect(m_themeSettings, &MauiMan::ThemeManager::marginSizeChanged, [this](uint size) 0146 { 0147 qDebug() << "ContentMARGINS CHANGED" << size; 0148 m_contentMargins = size; 0149 Q_EMIT this->contentMarginsChanged(); 0150 }); 0151 0152 connect(m_themeSettings, &MauiMan::ThemeManager::spacingSizeChanged, [this](uint size) 0153 { 0154 m_defaultSpacing = size; 0155 Q_EMIT this->defaultSpacingChanged(); 0156 }); 0157 0158 connect(m_themeSettings, &MauiMan::ThemeManager::enableEffectsChanged, [this](bool value) 0159 { 0160 m_enableEffects = value; 0161 Q_EMIT this->enableEffectsChanged(m_enableEffects); 0162 }); 0163 0164 connect(m_backgroundSettings, &MauiMan::BackgroundManager::wallpaperSourceChanged, [this](QString source) 0165 { 0166 m_adaptiveColorSchemeSource = QUrl::fromUserInput(source).toLocalFile(); 0167 Q_EMIT this->adaptiveColorSchemeSourceChanged(m_adaptiveColorSchemeSource); 0168 }); 0169 0170 connect(m_themeSettings, &MauiMan::ThemeManager::enableEffectsChanged, [this](bool value) 0171 { 0172 m_enableEffects = value; 0173 Q_EMIT this->enableEffectsChanged(m_enableEffects); 0174 }); 0175 0176 connect(m_accessibilitySettings, &MauiMan::AccessibilityManager::scrollBarPolicyChanged, [this](uint state) 0177 { 0178 qDebug() << "SCROLBAR POLICY CHANGED" << state; 0179 Q_EMIT scrollBarPolicyChanged(state); 0180 }); 0181 0182 if(MauiManUtils::isMauiSession()) 0183 { 0184 connect(m_themeSettings, &MauiMan::ThemeManager::iconThemeChanged, [this](QString name) 0185 { 0186 qDebug() << "Ask to change the icon theme"; 0187 m_currentIconTheme = name; 0188 Q_EMIT currentIconThemeChanged(m_currentIconTheme); 0189 }); 0190 }else 0191 { 0192 // //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? 0193 // QStyle *style = qApp->style(); 0194 // if (style) 0195 // { 0196 // connect(style, &QObject::destroyed, this, &Style::styleChanged); 0197 // } 0198 } 0199 0200 m_defaultFont = qGuiApp->font(); 0201 m_monospacedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); 0202 setFontSizes(); 0203 0204 m_radiusV = m_themeSettings->borderRadius(); 0205 m_iconSize = m_themeSettings->iconSize(); 0206 m_accentColor = m_themeSettings->accentColor(); 0207 0208 m_contentMargins = m_themeSettings->marginSize(); 0209 m_defaultPadding = m_themeSettings->paddingSize(); 0210 m_defaultSpacing = m_themeSettings->spacingSize(); 0211 0212 m_currentIconTheme = QIcon::themeName(); 0213 0214 //TODO Use new Qt6 StyelHint properties for this 0215 0216 0217 0218 0219 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0220 0221 #ifdef Q_OS_ANDROID 0222 MAUIAndroid android; 0223 m_styleType = android.darkModeEnabled() ? StyleType::Dark : StyleType::Light; 0224 #else 0225 m_styleType = static_cast<Style::StyleType>(m_themeSettings->styleType()); 0226 #endif 0227 0228 #else 0229 //For Maui Session we want to use MauiMan 0230 if(!MauiManUtils::isMauiSession()) 0231 { 0232 switch(QGuiApplication::styleHints()->colorScheme()) 0233 { 0234 case Qt::ColorScheme::Unknown: 0235 m_styleType = static_cast<Style::StyleType>(m_themeSettings->styleType()); 0236 break; 0237 case Qt::ColorScheme::Light: 0238 m_styleType = Style::StyleType::Light; 0239 break; 0240 case Qt::ColorScheme::Dark: 0241 m_styleType = Style::StyleType::Dark; 0242 break; 0243 } 0244 } 0245 else 0246 { 0247 m_styleType = static_cast<Style::StyleType>(m_themeSettings->styleType()); 0248 } 0249 #endif 0250 0251 m_adaptiveColorSchemeSource = QUrl::fromUserInput(m_backgroundSettings->wallpaperSource()).toLocalFile(); 0252 m_enableEffects = m_themeSettings->enableEffects(); 0253 } 0254 0255 void Style::setFontSizes() 0256 { 0257 qDebug() << m_defaultFont << m_defaultFont.pointSize(); 0258 0259 m_defaultFontSize = m_defaultFont.pointSize (); 0260 0261 m_fontSizes->m_tiny = m_defaultFont.pointSize ()-2; 0262 m_fontSizes->m_small = m_defaultFont.pointSize ()-1; 0263 m_fontSizes->m_medium = m_defaultFont.pointSize (); 0264 m_fontSizes->m_big = m_defaultFont.pointSize ()+1; 0265 m_fontSizes->m_large = m_defaultFont.pointSize ()+2; 0266 m_fontSizes->m_huge = m_defaultFont.pointSize ()+3; 0267 m_fontSizes->m_enormous = m_defaultFont.pointSize ()+4; 0268 0269 m_h1Font.setPointSize(m_fontSizes->m_enormous); 0270 m_h1Font.setWeight(QFont::Black); 0271 m_h1Font.setBold(true); 0272 0273 m_h2Font.setPointSize(m_fontSizes->m_big); 0274 m_h2Font.setWeight(QFont::DemiBold); 0275 // m_h2Font.setBold(false); 0276 } 0277 0278 void Style::setRadiusV(const uint& radius) 0279 { 0280 if(m_radiusV == radius) 0281 { 0282 return; 0283 } 0284 0285 m_radiusV = radius; 0286 Q_EMIT radiusVChanged(m_radiusV); 0287 } 0288 0289 bool Style::enableEffects() const 0290 { 0291 return m_enableEffects; 0292 } 0293 0294 bool Style::translucencyAvailable() const 0295 { 0296 return m_translucencyAvailable; 0297 } 0298 0299 void Style::setTranslucencyAvailable(const bool &value) 0300 { 0301 if(value == m_translucencyAvailable) 0302 { 0303 return; 0304 } 0305 0306 m_translucencyAvailable = value; 0307 Q_EMIT this->translucencyAvailableChanged(m_translucencyAvailable); 0308 } 0309 0310 0311 Style *Style::qmlAttachedProperties(QObject *object) 0312 { 0313 Q_UNUSED(object) 0314 return Style::instance(); 0315 } 0316 0317 int getClosest(int, int, int); 0318 0319 // Returns element closest to target in arr[] 0320 int findClosest(int arr[], int n, int target) 0321 { 0322 // Corner cases 0323 if (target <= arr[0]) 0324 return arr[0]; 0325 if (target >= arr[n - 1]) 0326 return arr[n - 1]; 0327 0328 // Doing binary search 0329 int i = 0, j = n, mid = 0; 0330 while (i < j) { 0331 mid = (i + j) / 2; 0332 0333 if (arr[mid] == target) 0334 return arr[mid]; 0335 0336 /* If target is less than array element, 0337 * then search in left */ 0338 if (target < arr[mid]) { 0339 0340 // If target is greater than previous 0341 // to mid, return closest of two 0342 if (mid > 0 && target > arr[mid - 1]) 0343 return getClosest(arr[mid - 1], 0344 arr[mid], target); 0345 0346 /* Repeat for left half */ 0347 j = mid; 0348 } 0349 0350 // If target is greater than mid 0351 else { 0352 if (mid < n - 1 && target < arr[mid + 1]) 0353 return getClosest(arr[mid], 0354 arr[mid + 1], target); 0355 // update i 0356 i = mid + 1; 0357 } 0358 } 0359 0360 // Only single element left after search 0361 return arr[mid]; 0362 } 0363 0364 // Method to compare which one is the more close. 0365 // We find the closest by taking the difference 0366 // between the target and both values. It assumes 0367 // that val2 is greater than val1 and target lies 0368 // between these two. 0369 int getClosest(int val1, int val2, 0370 int target) 0371 { 0372 if (target - val1 >= val2 - target) 0373 return val2; 0374 else 0375 return val1; 0376 } 0377 0378 0379 int Style::mapToIconSizes(const int &size) 0380 { 0381 int values[] = {8, 16, 22, 32, 48, 64, 128}; 0382 int n = sizeof(values) / sizeof(values[0]); 0383 return findClosest (values, n, size); 0384 } 0385 0386 GroupSizes::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) 0387 ,m_tiny(tiny) 0388 ,m_small(small) 0389 ,m_medium(medium) 0390 ,m_big(big) 0391 ,m_large(large) 0392 ,m_huge(huge) 0393 ,m_enormous(enormous) 0394 0395 { 0396 0397 } 0398 0399 GroupSizes::GroupSizes(QObject* parent) : QObject(parent) 0400 { 0401 } 0402 0403 0404 QVariant Style::adaptiveColorSchemeSource() const 0405 { 0406 return m_adaptiveColorSchemeSource; 0407 } 0408 0409 void Style::setAdaptiveColorSchemeSource(const QVariant& source) 0410 { 0411 m_adaptiveColorSchemeSource_blocked = true; 0412 if(source == m_adaptiveColorSchemeSource) 0413 { 0414 return; 0415 } 0416 0417 m_adaptiveColorSchemeSource = source; 0418 Q_EMIT adaptiveColorSchemeSourceChanged(m_adaptiveColorSchemeSource); 0419 } 0420 0421 void Style::unsetAdaptiveColorSchemeSource() 0422 { 0423 m_adaptiveColorSchemeSource_blocked = false; 0424 m_adaptiveColorSchemeSource = QUrl::fromUserInput(m_backgroundSettings->wallpaperSource()).toLocalFile(); 0425 Q_EMIT adaptiveColorSchemeSourceChanged(m_adaptiveColorSchemeSource); 0426 } 0427 0428 QColor Style::accentColor() const 0429 { 0430 return m_accentColor; 0431 } 0432 0433 void Style::setAccentColor(const QColor& color) 0434 { 0435 m_accentColor_blocked = true; 0436 0437 if(m_accentColor == color) 0438 { 0439 return; 0440 } 0441 0442 m_accentColor = color; 0443 Q_EMIT accentColorChanged(m_accentColor); 0444 } 0445 0446 void Style::unsetAccentColor() 0447 { 0448 m_accentColor_blocked = false; 0449 m_accentColor = m_themeSettings->accentColor(); 0450 Q_EMIT accentColorChanged(m_accentColor); 0451 } 0452 0453 Style::StyleType Style::styleType() const 0454 { 0455 return m_styleType; 0456 } 0457 0458 void Style::setStyleType(const Style::StyleType &type) 0459 { 0460 m_styleType_blocked = true; 0461 0462 if (m_styleType == type) 0463 return; 0464 0465 m_styleType = type; 0466 Q_EMIT styleTypeChanged(m_styleType); 0467 } 0468 0469 void Style::unsetStyeType() 0470 { 0471 m_styleType_blocked = false; 0472 m_styleType = static_cast<Style::StyleType>(m_themeSettings->styleType()); 0473 Q_EMIT styleTypeChanged(m_styleType); 0474 } 0475 0476 Units::Units(QObject *parent) : QObject(parent) 0477 , m_fontMetrics(QFontMetricsF(QGuiApplication::font())) 0478 , m_gridUnit(m_fontMetrics.height()) 0479 , m_veryLongDuration(400) 0480 , m_longDuration(200) 0481 , m_shortDuration(100) 0482 , m_veryShortDuration(50) 0483 , m_humanMoment(2000) 0484 , m_toolTipDelay(700) 0485 { 0486 0487 } 0488 0489 uint Style::iconSize() const 0490 { 0491 return m_iconSize; 0492 } 0493 0494 QString Style::currentIconTheme() const 0495 { 0496 return m_currentIconTheme; 0497 } 0498 0499 bool Style::menusHaveIcons() const 0500 { 0501 return !qApp->testAttribute(Qt::AA_DontShowIconsInMenus); 0502 } 0503 0504 uint Style::scrollBarPolicy() const 0505 { 0506 return m_accessibilitySettings->scrollBarPolicy(); 0507 } 0508 0509 bool Style::playSounds() const 0510 { 0511 return m_accessibilitySettings->playSounds(); 0512 } 0513 0514 0515 0516