From 6e390a1a9751814882937bbf754fb0a07029600d Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Fri, 24 Nov 2023 06:04:03 -0600 Subject: [PATCH] Add fusion style to settings (enables dark mode) --- scwx-qt/scwx-qt.cmake | 1 + scwx-qt/source/scwx/qt/main/main.cpp | 11 ++ .../scwx/qt/settings/general_settings.cpp | 31 ++++ .../scwx/qt/settings/general_settings.hpp | 1 + scwx-qt/source/scwx/qt/types/qt_types.cpp | 42 +++++ scwx-qt/source/scwx/qt/types/qt_types.hpp | 16 ++ scwx-qt/source/scwx/qt/ui/settings_dialog.cpp | 43 ++++- scwx-qt/source/scwx/qt/ui/settings_dialog.ui | 147 ++++++++++-------- test/data | 2 +- 9 files changed, 227 insertions(+), 67 deletions(-) create mode 100644 scwx-qt/source/scwx/qt/types/qt_types.cpp diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index 6e38717e..809306e9 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -179,6 +179,7 @@ set(SRC_TYPES source/scwx/qt/types/alert_types.cpp source/scwx/qt/types/imgui_font.cpp source/scwx/qt/types/layer_types.cpp source/scwx/qt/types/map_types.cpp + source/scwx/qt/types/qt_types.cpp source/scwx/qt/types/radar_product_record.cpp source/scwx/qt/types/text_event_key.cpp source/scwx/qt/types/text_types.cpp diff --git a/scwx-qt/source/scwx/qt/main/main.cpp b/scwx-qt/source/scwx/qt/main/main.cpp index 2431b218..82e9b152 100644 --- a/scwx-qt/source/scwx/qt/main/main.cpp +++ b/scwx-qt/source/scwx/qt/main/main.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include #include @@ -72,6 +74,15 @@ int main(int argc, char* argv[]) scwx::qt::config::RadarSite::Initialize(); scwx::qt::manager::SettingsManager::Instance().Initialize(); + // Theme + auto uiStyle = scwx::qt::types::GetUiStyle( + scwx::qt::settings::GeneralSettings::Instance().theme().GetValue()); + if (uiStyle != scwx::qt::types::UiStyle::Default) + { + QApplication::setStyle( + QString::fromStdString(scwx::qt::types::GetUiStyleName(uiStyle))); + } + // Run initial setup if required if (scwx::qt::ui::setup::SetupWizard::IsSetupRequired()) { diff --git a/scwx-qt/source/scwx/qt/settings/general_settings.cpp b/scwx-qt/source/scwx/qt/settings/general_settings.cpp index 0eab43e9..bcf5f5ad 100644 --- a/scwx-qt/source/scwx/qt/settings/general_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/general_settings.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include @@ -25,9 +26,12 @@ class GeneralSettings::Impl types::GetAlertActionName(types::AlertAction::Go); std::string defaultMapProviderValue = map::GetMapProviderName(map::MapProvider::MapTiler); + std::string defaultThemeValue = + types::GetUiStyleName(types::UiStyle::Default); boost::to_lower(defaultDefaultAlertActionValue); boost::to_lower(defaultMapProviderValue); + boost::to_lower(defaultThemeValue); antiAliasingEnabled_.SetDefault(true); debugEnabled_.SetDefault(false); @@ -42,6 +46,7 @@ class GeneralSettings::Impl mapProvider_.SetDefault(defaultMapProviderValue); mapboxApiKey_.SetDefault("?"); maptilerApiKey_.SetDefault("?"); + theme_.SetDefault(defaultThemeValue); trackLocation_.SetDefault(false); updateNotificationsEnabled_.SetDefault(true); @@ -102,6 +107,24 @@ class GeneralSettings::Impl { return !value.empty(); }); maptilerApiKey_.SetValidator([](const std::string& value) { return !value.empty(); }); + theme_.SetValidator( + [](const std::string& value) + { + for (types::UiStyle uiStyle : types::UiStyleIterator()) + { + // If the value is equal to a lower case UI style name + std::string uiStyleName = types::GetUiStyleName(uiStyle); + boost::to_lower(uiStyleName); + if (value == uiStyleName) + { + // Regard as a match, valid + return true; + } + } + + // No match found, invalid + return false; + }); } ~Impl() {} @@ -119,6 +142,7 @@ class GeneralSettings::Impl SettingsVariable mapProvider_ {"map_provider"}; SettingsVariable mapboxApiKey_ {"mapbox_api_key"}; SettingsVariable maptilerApiKey_ {"maptiler_api_key"}; + SettingsVariable theme_ {"theme"}; SettingsVariable trackLocation_ {"track_location"}; SettingsVariable updateNotificationsEnabled_ {"update_notifications"}; }; @@ -139,6 +163,7 @@ GeneralSettings::GeneralSettings() : &p->mapProvider_, &p->mapboxApiKey_, &p->maptilerApiKey_, + &p->theme_, &p->trackLocation_, &p->updateNotificationsEnabled_}); SetDefaults(); @@ -215,6 +240,11 @@ SettingsVariable& GeneralSettings::maptiler_api_key() const return p->maptilerApiKey_; } +SettingsVariable& GeneralSettings::theme() const +{ + return p->theme_; +} + SettingsVariable& GeneralSettings::track_location() const { return p->trackLocation_; @@ -259,6 +289,7 @@ bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs) lhs.p->mapProvider_ == rhs.p->mapProvider_ && lhs.p->mapboxApiKey_ == rhs.p->mapboxApiKey_ && lhs.p->maptilerApiKey_ == rhs.p->maptilerApiKey_ && + lhs.p->theme_ == rhs.p->theme_ && lhs.p->trackLocation_ == rhs.p->trackLocation_ && lhs.p->updateNotificationsEnabled_ == rhs.p->updateNotificationsEnabled_); diff --git a/scwx-qt/source/scwx/qt/settings/general_settings.hpp b/scwx-qt/source/scwx/qt/settings/general_settings.hpp index 9c6256b7..90c47e5d 100644 --- a/scwx-qt/source/scwx/qt/settings/general_settings.hpp +++ b/scwx-qt/source/scwx/qt/settings/general_settings.hpp @@ -38,6 +38,7 @@ class GeneralSettings : public SettingsCategory SettingsVariable& map_provider() const; SettingsVariable& mapbox_api_key() const; SettingsVariable& maptiler_api_key() const; + SettingsVariable& theme() const; SettingsVariable& track_location() const; SettingsVariable& update_notifications_enabled() const; diff --git a/scwx-qt/source/scwx/qt/types/qt_types.cpp b/scwx-qt/source/scwx/qt/types/qt_types.cpp new file mode 100644 index 00000000..37717646 --- /dev/null +++ b/scwx-qt/source/scwx/qt/types/qt_types.cpp @@ -0,0 +1,42 @@ +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace types +{ + +static const std::unordered_map uiStyleName_ { + {UiStyle::Default, "Default"}, + {UiStyle::Fusion, "Fusion"}, + {UiStyle::Unknown, "?"}}; + +UiStyle GetUiStyle(const std::string& name) +{ + auto result = + std::find_if(uiStyleName_.cbegin(), + uiStyleName_.cend(), + [&](const std::pair& pair) -> bool + { return boost::iequals(pair.second, name); }); + + if (result != uiStyleName_.cend()) + { + return result->first; + } + else + { + return UiStyle::Unknown; + } +} + +std::string GetUiStyleName(UiStyle uiStyle) +{ + return uiStyleName_.at(uiStyle); +} + +} // namespace types +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/types/qt_types.hpp b/scwx-qt/source/scwx/qt/types/qt_types.hpp index 657b846f..26a41c25 100644 --- a/scwx-qt/source/scwx/qt/types/qt_types.hpp +++ b/scwx-qt/source/scwx/qt/types/qt_types.hpp @@ -1,5 +1,9 @@ #pragma once +#include + +#include + #include namespace scwx @@ -16,6 +20,18 @@ enum ItemDataRole RawDataRole }; +enum UiStyle +{ + Default, + Fusion, + Unknown +}; +typedef scwx::util::Iterator + UiStyleIterator; + +UiStyle GetUiStyle(const std::string& name); +std::string GetUiStyleName(UiStyle alertAction); + } // namespace types } // namespace qt } // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp index ee216db0..efc267bf 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -98,6 +99,7 @@ class SettingsDialogImpl &mapProvider_, &mapboxApiKey_, &mapTilerApiKey_, + &theme_, &defaultAlertAction_, &antiAliasingEnabled_, &updateNotificationsEnabled_, @@ -175,6 +177,7 @@ class SettingsDialogImpl settings::SettingsInterface mapboxApiKey_ {}; settings::SettingsInterface mapTilerApiKey_ {}; settings::SettingsInterface defaultAlertAction_ {}; + settings::SettingsInterface theme_ {}; settings::SettingsInterface antiAliasingEnabled_ {}; settings::SettingsInterface updateNotificationsEnabled_ {}; settings::SettingsInterface debugEnabled_ {}; @@ -366,6 +369,43 @@ void SettingsDialogImpl::ConnectSignals() void SettingsDialogImpl::SetupGeneralTab() { + settings::GeneralSettings& generalSettings = + settings::GeneralSettings::Instance(); + + for (const auto& uiStyle : types::UiStyleIterator()) + { + self_->ui->themeComboBox->addItem( + QString::fromStdString(types::GetUiStyleName(uiStyle))); + } + + theme_.SetSettingsVariable(generalSettings.theme()); + theme_.SetMapFromValueFunction( + [](const std::string& text) -> std::string + { + for (types::UiStyle uiStyle : types::UiStyleIterator()) + { + const std::string uiStyleName = types::GetUiStyleName(uiStyle); + + if (boost::iequals(text, uiStyleName)) + { + // Return UI style label + return uiStyleName; + } + } + + // UI style label not found, return unknown + return "?"; + }); + theme_.SetMapToValueFunction( + [](std::string text) -> std::string + { + // Convert label to lower case and return + boost::to_lower(text); + return text; + }); + theme_.SetEditWidget(self_->ui->themeComboBox); + theme_.SetResetButton(self_->ui->resetThemeButton); + auto radarSites = config::RadarSite::GetAll(); // Sort radar sites by ID @@ -382,9 +422,6 @@ void SettingsDialogImpl::SetupGeneralTab() self_->ui->radarSiteComboBox->addItem(text); } - settings::GeneralSettings& generalSettings = - settings::GeneralSettings::Instance(); - defaultRadarSite_.SetSettingsVariable(generalSettings.default_radar_site()); defaultRadarSite_.SetMapFromValueFunction( [](const std::string& id) -> std::string diff --git a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui index 5ecdc1dd..f770135f 100644 --- a/scwx-qt/source/scwx/qt/ui/settings_dialog.ui +++ b/scwx-qt/source/scwx/qt/ui/settings_dialog.ui @@ -120,7 +120,7 @@ 0 - + ... @@ -131,25 +131,37 @@ - - + + - Grid Width + ... - - + + - ... + Map Provider - - - :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg + + + + + + + + + Grid Height - + + + + + + + ... @@ -160,74 +172,85 @@ - - - - MapTiler API Key + + + + QLineEdit::Password - - + + - ... - - - - :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg + Grid Width - - - - - + + + + Default Alert Action + + - - + + - Grid Height + MapTiler API Key - + Default Radar Site - + QLineEdit::Password - - - - QLineEdit::Password + + + + + + + ... + + + + :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg - - + + - Default Alert Action + ... + + + + :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg - + + + + Mapbox API Key - - + + ... @@ -237,25 +260,19 @@ - - - - - + + ... - - - - - - Map Provider + + + :/res/icons/font-awesome-6/rotate-left-solid.svg:/res/icons/font-awesome-6/rotate-left-solid.svg - + ... @@ -265,11 +282,18 @@ - - + + + + Theme + + - - + + + + + ... @@ -279,9 +303,6 @@ - - - @@ -343,8 +364,8 @@ 0 0 - 512 - 382 + 63 + 18 diff --git a/test/data b/test/data index 49a5bf59..cd36a74a 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 49a5bf59c30822b585b5726d7262b8e4ed4f10a7 +Subproject commit cd36a74a9c678d90d10ec397eae65b389a9640fc