Add fusion style to settings (enables dark mode)

This commit is contained in:
Dan Paulat 2023-11-24 06:04:03 -06:00
parent e69f5c8a62
commit 6e390a1a97
9 changed files with 261 additions and 101 deletions

View file

@ -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/imgui_font.cpp
source/scwx/qt/types/layer_types.cpp source/scwx/qt/types/layer_types.cpp
source/scwx/qt/types/map_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/radar_product_record.cpp
source/scwx/qt/types/text_event_key.cpp source/scwx/qt/types/text_event_key.cpp
source/scwx/qt/types/text_types.cpp source/scwx/qt/types/text_types.cpp

View file

@ -6,6 +6,8 @@
#include <scwx/qt/manager/radar_product_manager.hpp> #include <scwx/qt/manager/radar_product_manager.hpp>
#include <scwx/qt/manager/resource_manager.hpp> #include <scwx/qt/manager/resource_manager.hpp>
#include <scwx/qt/manager/settings_manager.hpp> #include <scwx/qt/manager/settings_manager.hpp>
#include <scwx/qt/settings/general_settings.hpp>
#include <scwx/qt/types/qt_types.hpp>
#include <scwx/qt/ui/setup/setup_wizard.hpp> #include <scwx/qt/ui/setup/setup_wizard.hpp>
#include <scwx/network/cpr.hpp> #include <scwx/network/cpr.hpp>
#include <scwx/util/logger.hpp> #include <scwx/util/logger.hpp>
@ -72,6 +74,15 @@ int main(int argc, char* argv[])
scwx::qt::config::RadarSite::Initialize(); scwx::qt::config::RadarSite::Initialize();
scwx::qt::manager::SettingsManager::Instance().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 // Run initial setup if required
if (scwx::qt::ui::setup::SetupWizard::IsSetupRequired()) if (scwx::qt::ui::setup::SetupWizard::IsSetupRequired())
{ {

View file

@ -2,6 +2,7 @@
#include <scwx/qt/settings/settings_container.hpp> #include <scwx/qt/settings/settings_container.hpp>
#include <scwx/qt/map/map_provider.hpp> #include <scwx/qt/map/map_provider.hpp>
#include <scwx/qt/types/alert_types.hpp> #include <scwx/qt/types/alert_types.hpp>
#include <scwx/qt/types/qt_types.hpp>
#include <array> #include <array>
@ -25,9 +26,12 @@ public:
types::GetAlertActionName(types::AlertAction::Go); types::GetAlertActionName(types::AlertAction::Go);
std::string defaultMapProviderValue = std::string defaultMapProviderValue =
map::GetMapProviderName(map::MapProvider::MapTiler); map::GetMapProviderName(map::MapProvider::MapTiler);
std::string defaultThemeValue =
types::GetUiStyleName(types::UiStyle::Default);
boost::to_lower(defaultDefaultAlertActionValue); boost::to_lower(defaultDefaultAlertActionValue);
boost::to_lower(defaultMapProviderValue); boost::to_lower(defaultMapProviderValue);
boost::to_lower(defaultThemeValue);
antiAliasingEnabled_.SetDefault(true); antiAliasingEnabled_.SetDefault(true);
debugEnabled_.SetDefault(false); debugEnabled_.SetDefault(false);
@ -42,6 +46,7 @@ public:
mapProvider_.SetDefault(defaultMapProviderValue); mapProvider_.SetDefault(defaultMapProviderValue);
mapboxApiKey_.SetDefault("?"); mapboxApiKey_.SetDefault("?");
maptilerApiKey_.SetDefault("?"); maptilerApiKey_.SetDefault("?");
theme_.SetDefault(defaultThemeValue);
trackLocation_.SetDefault(false); trackLocation_.SetDefault(false);
updateNotificationsEnabled_.SetDefault(true); updateNotificationsEnabled_.SetDefault(true);
@ -102,6 +107,24 @@ public:
{ return !value.empty(); }); { return !value.empty(); });
maptilerApiKey_.SetValidator([](const std::string& value) maptilerApiKey_.SetValidator([](const std::string& value)
{ return !value.empty(); }); { 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() {} ~Impl() {}
@ -119,6 +142,7 @@ public:
SettingsVariable<std::string> mapProvider_ {"map_provider"}; SettingsVariable<std::string> mapProvider_ {"map_provider"};
SettingsVariable<std::string> mapboxApiKey_ {"mapbox_api_key"}; SettingsVariable<std::string> mapboxApiKey_ {"mapbox_api_key"};
SettingsVariable<std::string> maptilerApiKey_ {"maptiler_api_key"}; SettingsVariable<std::string> maptilerApiKey_ {"maptiler_api_key"};
SettingsVariable<std::string> theme_ {"theme"};
SettingsVariable<bool> trackLocation_ {"track_location"}; SettingsVariable<bool> trackLocation_ {"track_location"};
SettingsVariable<bool> updateNotificationsEnabled_ {"update_notifications"}; SettingsVariable<bool> updateNotificationsEnabled_ {"update_notifications"};
}; };
@ -139,6 +163,7 @@ GeneralSettings::GeneralSettings() :
&p->mapProvider_, &p->mapProvider_,
&p->mapboxApiKey_, &p->mapboxApiKey_,
&p->maptilerApiKey_, &p->maptilerApiKey_,
&p->theme_,
&p->trackLocation_, &p->trackLocation_,
&p->updateNotificationsEnabled_}); &p->updateNotificationsEnabled_});
SetDefaults(); SetDefaults();
@ -215,6 +240,11 @@ SettingsVariable<std::string>& GeneralSettings::maptiler_api_key() const
return p->maptilerApiKey_; return p->maptilerApiKey_;
} }
SettingsVariable<std::string>& GeneralSettings::theme() const
{
return p->theme_;
}
SettingsVariable<bool>& GeneralSettings::track_location() const SettingsVariable<bool>& GeneralSettings::track_location() const
{ {
return p->trackLocation_; return p->trackLocation_;
@ -259,6 +289,7 @@ bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs)
lhs.p->mapProvider_ == rhs.p->mapProvider_ && lhs.p->mapProvider_ == rhs.p->mapProvider_ &&
lhs.p->mapboxApiKey_ == rhs.p->mapboxApiKey_ && lhs.p->mapboxApiKey_ == rhs.p->mapboxApiKey_ &&
lhs.p->maptilerApiKey_ == rhs.p->maptilerApiKey_ && lhs.p->maptilerApiKey_ == rhs.p->maptilerApiKey_ &&
lhs.p->theme_ == rhs.p->theme_ &&
lhs.p->trackLocation_ == rhs.p->trackLocation_ && lhs.p->trackLocation_ == rhs.p->trackLocation_ &&
lhs.p->updateNotificationsEnabled_ == lhs.p->updateNotificationsEnabled_ ==
rhs.p->updateNotificationsEnabled_); rhs.p->updateNotificationsEnabled_);

View file

@ -38,6 +38,7 @@ public:
SettingsVariable<std::string>& map_provider() const; SettingsVariable<std::string>& map_provider() const;
SettingsVariable<std::string>& mapbox_api_key() const; SettingsVariable<std::string>& mapbox_api_key() const;
SettingsVariable<std::string>& maptiler_api_key() const; SettingsVariable<std::string>& maptiler_api_key() const;
SettingsVariable<std::string>& theme() const;
SettingsVariable<bool>& track_location() const; SettingsVariable<bool>& track_location() const;
SettingsVariable<bool>& update_notifications_enabled() const; SettingsVariable<bool>& update_notifications_enabled() const;

View file

@ -0,0 +1,42 @@
#include <scwx/qt/types/qt_types.hpp>
#include <boost/algorithm/string.hpp>
namespace scwx
{
namespace qt
{
namespace types
{
static const std::unordered_map<UiStyle, std::string> 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<UiStyle, std::string>& 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

View file

@ -1,5 +1,9 @@
#pragma once #pragma once
#include <scwx/util/iterator.hpp>
#include <string>
#include <Qt> #include <Qt>
namespace scwx namespace scwx
@ -16,6 +20,18 @@ enum ItemDataRole
RawDataRole RawDataRole
}; };
enum UiStyle
{
Default,
Fusion,
Unknown
};
typedef scwx::util::Iterator<UiStyle, UiStyle::Default, UiStyle::Fusion>
UiStyleIterator;
UiStyle GetUiStyle(const std::string& name);
std::string GetUiStyleName(UiStyle alertAction);
} // namespace types } // namespace types
} // namespace qt } // namespace qt
} // namespace scwx } // namespace scwx

View file

@ -12,6 +12,7 @@
#include <scwx/qt/settings/text_settings.hpp> #include <scwx/qt/settings/text_settings.hpp>
#include <scwx/qt/types/alert_types.hpp> #include <scwx/qt/types/alert_types.hpp>
#include <scwx/qt/types/font_types.hpp> #include <scwx/qt/types/font_types.hpp>
#include <scwx/qt/types/qt_types.hpp>
#include <scwx/qt/types/text_types.hpp> #include <scwx/qt/types/text_types.hpp>
#include <scwx/qt/ui/radar_site_dialog.hpp> #include <scwx/qt/ui/radar_site_dialog.hpp>
#include <scwx/qt/util/color.hpp> #include <scwx/qt/util/color.hpp>
@ -98,6 +99,7 @@ public:
&mapProvider_, &mapProvider_,
&mapboxApiKey_, &mapboxApiKey_,
&mapTilerApiKey_, &mapTilerApiKey_,
&theme_,
&defaultAlertAction_, &defaultAlertAction_,
&antiAliasingEnabled_, &antiAliasingEnabled_,
&updateNotificationsEnabled_, &updateNotificationsEnabled_,
@ -175,6 +177,7 @@ public:
settings::SettingsInterface<std::string> mapboxApiKey_ {}; settings::SettingsInterface<std::string> mapboxApiKey_ {};
settings::SettingsInterface<std::string> mapTilerApiKey_ {}; settings::SettingsInterface<std::string> mapTilerApiKey_ {};
settings::SettingsInterface<std::string> defaultAlertAction_ {}; settings::SettingsInterface<std::string> defaultAlertAction_ {};
settings::SettingsInterface<std::string> theme_ {};
settings::SettingsInterface<bool> antiAliasingEnabled_ {}; settings::SettingsInterface<bool> antiAliasingEnabled_ {};
settings::SettingsInterface<bool> updateNotificationsEnabled_ {}; settings::SettingsInterface<bool> updateNotificationsEnabled_ {};
settings::SettingsInterface<bool> debugEnabled_ {}; settings::SettingsInterface<bool> debugEnabled_ {};
@ -366,6 +369,43 @@ void SettingsDialogImpl::ConnectSignals()
void SettingsDialogImpl::SetupGeneralTab() 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(); auto radarSites = config::RadarSite::GetAll();
// Sort radar sites by ID // Sort radar sites by ID
@ -382,9 +422,6 @@ void SettingsDialogImpl::SetupGeneralTab()
self_->ui->radarSiteComboBox->addItem(text); self_->ui->radarSiteComboBox->addItem(text);
} }
settings::GeneralSettings& generalSettings =
settings::GeneralSettings::Instance();
defaultRadarSite_.SetSettingsVariable(generalSettings.default_radar_site()); defaultRadarSite_.SetSettingsVariable(generalSettings.default_radar_site());
defaultRadarSite_.SetMapFromValueFunction( defaultRadarSite_.SetMapFromValueFunction(
[](const std::string& id) -> std::string [](const std::string& id) -> std::string

View file

@ -120,7 +120,7 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="4" column="4"> <item row="5" column="4">
<widget class="QToolButton" name="resetMapProviderButton"> <widget class="QToolButton" name="resetMapProviderButton">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
@ -131,25 +131,37 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="3">
<widget class="QLabel" name="label_2"> <widget class="QToolButton" name="radarSiteSelectButton">
<property name="text">
<string>Grid Width</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QToolButton" name="resetGridHeightButton">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
<property name="icon"> </widget>
<iconset resource="../../../../scwx-qt.qrc"> </item>
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset> <item row="5" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Map Provider</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="4"> <item row="1" column="2">
<widget class="QComboBox" name="radarSiteComboBox"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Grid Height</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="gridHeightSpinBox"/>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="gridWidthSpinBox"/>
</item>
<item row="1" column="4">
<widget class="QToolButton" name="resetRadarSiteButton"> <widget class="QToolButton" name="resetRadarSiteButton">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
@ -160,101 +172,52 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>MapTiler API Key</string>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QToolButton" name="resetMapboxApiKeyButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="gridHeightSpinBox"/>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="gridWidthSpinBox"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Grid Height</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Default Radar Site</string>
</property>
</widget>
</item>
<item row="6" column="2"> <item row="6" column="2">
<widget class="QLineEdit" name="mapTilerApiKeyLineEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLineEdit" name="mapboxApiKeyLineEdit"> <widget class="QLineEdit" name="mapboxApiKeyLineEdit">
<property name="echoMode"> <property name="echoMode">
<enum>QLineEdit::Password</enum> <enum>QLineEdit::Password</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Grid Width</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="defaultAlertActionLabel"> <widget class="QLabel" name="defaultAlertActionLabel">
<property name="text"> <property name="text">
<string>Default Alert Action</string> <string>Default Alert Action</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0"> <item row="7" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
<string>Mapbox API Key</string> <string>MapTiler API Key</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Default Radar Site</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QLineEdit" name="mapTilerApiKeyLineEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QComboBox" name="defaultAlertActionComboBox"/>
</item>
<item row="7" column="4"> <item row="7" column="4">
<widget class="QToolButton" name="resetDefaultAlertActionButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QComboBox" name="mapProviderComboBox"/>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="radarSiteSelectButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Map Provider</string>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QToolButton" name="resetMapTilerApiKeyButton"> <widget class="QToolButton" name="resetMapTilerApiKeyButton">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
@ -265,10 +228,28 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="2"> <item row="3" column="4">
<widget class="QComboBox" name="defaultAlertActionComboBox"/> <widget class="QToolButton" name="resetGridHeightButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item> </item>
<item row="1" column="4"> <item row="5" column="2">
<widget class="QComboBox" name="mapProviderComboBox"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Mapbox API Key</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QToolButton" name="resetGridWidthButton"> <widget class="QToolButton" name="resetGridWidthButton">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
@ -279,8 +260,48 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="4">
<widget class="QToolButton" name="resetDefaultAlertActionButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QToolButton" name="resetMapboxApiKeyButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Theme</string>
</property>
</widget>
</item>
<item row="0" column="2"> <item row="0" column="2">
<widget class="QComboBox" name="radarSiteComboBox"/> <widget class="QComboBox" name="themeComboBox"/>
</item>
<item row="0" column="4">
<widget class="QToolButton" name="resetThemeButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -343,8 +364,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>512</width> <width>63</width>
<height>382</height> <height>18</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">

@ -1 +1 @@
Subproject commit 49a5bf59c30822b585b5726d7262b8e4ed4f10a7 Subproject commit cd36a74a9c678d90d10ec397eae65b389a9640fc