mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-11-04 08:00:04 +00:00 
			
		
		
		
	Merge pull request #234 from dpaulat/feature/custom-map-style
Allow Custom Map Styles
This commit is contained in:
		
						commit
						7161a5a3b2
					
				
					 11 changed files with 278 additions and 29 deletions
				
			
		| 
						 | 
				
			
			@ -139,6 +139,16 @@ public:
 | 
			
		|||
   }
 | 
			
		||||
   ~MainWindowImpl()
 | 
			
		||||
   {
 | 
			
		||||
      auto& generalSettings = settings::GeneralSettings::Instance();
 | 
			
		||||
 | 
			
		||||
      auto& customStyleUrl       = generalSettings.custom_style_url();
 | 
			
		||||
      auto& customStyleDrawLayer = generalSettings.custom_style_draw_layer();
 | 
			
		||||
 | 
			
		||||
      customStyleUrl.UnregisterValueChangedCallback(
 | 
			
		||||
         customStyleUrlChangedCallbackUuid_);
 | 
			
		||||
      customStyleDrawLayer.UnregisterValueChangedCallback(
 | 
			
		||||
         customStyleDrawLayerChangedCallbackUuid_);
 | 
			
		||||
 | 
			
		||||
      clockTimer_.stop();
 | 
			
		||||
      threadPool_.join();
 | 
			
		||||
   }
 | 
			
		||||
| 
						 | 
				
			
			@ -153,6 +163,7 @@ public:
 | 
			
		|||
   void ConnectOtherSignals();
 | 
			
		||||
   void HandleFocusChange(QWidget* focused);
 | 
			
		||||
   void InitializeLayerDisplayActions();
 | 
			
		||||
   void PopulateCustomMapStyle();
 | 
			
		||||
   void PopulateMapStyles();
 | 
			
		||||
   void SelectElevation(map::MapWidget* mapWidget, float elevation);
 | 
			
		||||
   void SelectRadarProduct(map::MapWidget*           mapWidget,
 | 
			
		||||
| 
						 | 
				
			
			@ -202,6 +213,10 @@ public:
 | 
			
		|||
 | 
			
		||||
   QTimer clockTimer_ {};
 | 
			
		||||
 | 
			
		||||
   bool               customStyleAvailable_ {false};
 | 
			
		||||
   boost::uuids::uuid customStyleDrawLayerChangedCallbackUuid_ {};
 | 
			
		||||
   boost::uuids::uuid customStyleUrlChangedCallbackUuid_ {};
 | 
			
		||||
 | 
			
		||||
   std::shared_ptr<manager::AlertManager>  alertManager_;
 | 
			
		||||
   std::shared_ptr<manager::HotkeyManager> hotkeyManager_ {
 | 
			
		||||
      manager::HotkeyManager::Instance()};
 | 
			
		||||
| 
						 | 
				
			
			@ -750,7 +765,8 @@ void MainWindowImpl::ConfigureMapStyles()
 | 
			
		|||
   {
 | 
			
		||||
      std::string styleName = mapSettings.map_style(i).GetValue();
 | 
			
		||||
 | 
			
		||||
      if (std::find_if(mapProviderInfo.mapStyles_.cbegin(),
 | 
			
		||||
      if ((customStyleAvailable_ && styleName == "Custom") ||
 | 
			
		||||
          std::find_if(mapProviderInfo.mapStyles_.cbegin(),
 | 
			
		||||
                       mapProviderInfo.mapStyles_.cend(),
 | 
			
		||||
                       [&](const auto& mapStyle) {
 | 
			
		||||
                          return mapStyle.name_ == styleName;
 | 
			
		||||
| 
						 | 
				
			
			@ -1262,6 +1278,36 @@ void MainWindowImpl::HandleFocusChange(QWidget* focused)
 | 
			
		|||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindowImpl::PopulateCustomMapStyle()
 | 
			
		||||
{
 | 
			
		||||
   auto& generalSettings = settings::GeneralSettings::Instance();
 | 
			
		||||
 | 
			
		||||
   auto customStyleUrl = generalSettings.custom_style_url().GetValue();
 | 
			
		||||
   auto customStyleDrawLayer =
 | 
			
		||||
      generalSettings.custom_style_draw_layer().GetValue();
 | 
			
		||||
 | 
			
		||||
   bool newCustomStyleAvailable =
 | 
			
		||||
      !customStyleUrl.empty() && !customStyleDrawLayer.empty();
 | 
			
		||||
 | 
			
		||||
   if (newCustomStyleAvailable != customStyleAvailable_)
 | 
			
		||||
   {
 | 
			
		||||
      static const QString kCustom {"Custom"};
 | 
			
		||||
 | 
			
		||||
      if (newCustomStyleAvailable)
 | 
			
		||||
      {
 | 
			
		||||
 | 
			
		||||
         mainWindow_->ui->mapStyleComboBox->addItem(kCustom);
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
         int index = mainWindow_->ui->mapStyleComboBox->findText(kCustom);
 | 
			
		||||
         mainWindow_->ui->mapStyleComboBox->removeItem(index);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      customStyleAvailable_ = newCustomStyleAvailable;
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindowImpl::PopulateMapStyles()
 | 
			
		||||
{
 | 
			
		||||
   const auto& mapProviderInfo = map::GetMapProviderInfo(mapProvider_);
 | 
			
		||||
| 
						 | 
				
			
			@ -1270,6 +1316,22 @@ void MainWindowImpl::PopulateMapStyles()
 | 
			
		|||
      mainWindow_->ui->mapStyleComboBox->addItem(
 | 
			
		||||
         QString::fromStdString(mapStyle.name_));
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   auto& generalSettings = settings::GeneralSettings::Instance();
 | 
			
		||||
 | 
			
		||||
   auto& customStyleUrl       = generalSettings.custom_style_url();
 | 
			
		||||
   auto& customStyleDrawLayer = generalSettings.custom_style_draw_layer();
 | 
			
		||||
 | 
			
		||||
   customStyleUrlChangedCallbackUuid_ =
 | 
			
		||||
      customStyleUrl.RegisterValueChangedCallback(
 | 
			
		||||
         [this]([[maybe_unused]] const std::string& value)
 | 
			
		||||
         { PopulateCustomMapStyle(); });
 | 
			
		||||
   customStyleDrawLayerChangedCallbackUuid_ =
 | 
			
		||||
      customStyleDrawLayer.RegisterValueChangedCallback(
 | 
			
		||||
         [this]([[maybe_unused]] const std::string& value)
 | 
			
		||||
         { PopulateCustomMapStyle(); });
 | 
			
		||||
 | 
			
		||||
   PopulateCustomMapStyle();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindowImpl::SelectElevation(map::MapWidget* mapWidget, float elevation)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -178,6 +178,11 @@ static const std::unordered_map<MapProvider, MapProviderInfo> mapProviderInfo_ {
 | 
			
		|||
           .drawBelow_ {"aeroway_runway", "Aeroway"}}}}},
 | 
			
		||||
   {MapProvider::Unknown, MapProviderInfo {}}};
 | 
			
		||||
 | 
			
		||||
bool MapStyle::IsValid() const
 | 
			
		||||
{
 | 
			
		||||
   return !url_.empty() && !drawBelow_.empty();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MapProvider GetMapProvider(const std::string& name)
 | 
			
		||||
{
 | 
			
		||||
   auto result =
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,8 @@ struct MapStyle
 | 
			
		|||
   std::string              name_;
 | 
			
		||||
   std::string              url_;
 | 
			
		||||
   std::vector<std::string> drawBelow_;
 | 
			
		||||
 | 
			
		||||
   bool IsValid() const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct MapProviderInfo
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,7 @@
 | 
			
		|||
#include <boost/algorithm/string/trim.hpp>
 | 
			
		||||
#include <boost/asio/post.hpp>
 | 
			
		||||
#include <boost/asio/thread_pool.hpp>
 | 
			
		||||
#include <boost/range/join.hpp>
 | 
			
		||||
#include <boost/uuid/random_generator.hpp>
 | 
			
		||||
#include <fmt/format.h>
 | 
			
		||||
#include <imgui.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -117,11 +118,15 @@ public:
 | 
			
		|||
      // Initialize ImGui Qt backend
 | 
			
		||||
      ImGui_ImplQt_Init();
 | 
			
		||||
 | 
			
		||||
      InitializeCustomStyles();
 | 
			
		||||
 | 
			
		||||
      ConnectSignals();
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   ~MapWidgetImpl()
 | 
			
		||||
   {
 | 
			
		||||
      DeinitializeCustomStyles();
 | 
			
		||||
 | 
			
		||||
      // Set ImGui Context
 | 
			
		||||
      ImGui::SetCurrentContext(imGuiContext_);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,10 +154,12 @@ public:
 | 
			
		|||
                          const std::string& before);
 | 
			
		||||
   void ConnectMapSignals();
 | 
			
		||||
   void ConnectSignals();
 | 
			
		||||
   void DeinitializeCustomStyles() const;
 | 
			
		||||
   void HandleHotkeyPressed(types::Hotkey hotkey, bool isAutoRepeat);
 | 
			
		||||
   void HandleHotkeyReleased(types::Hotkey hotkey);
 | 
			
		||||
   void HandleHotkeyUpdates();
 | 
			
		||||
   void ImGuiCheckFonts();
 | 
			
		||||
   void InitializeCustomStyles();
 | 
			
		||||
   void InitializeNewRadarProductView(const std::string& colorPalette);
 | 
			
		||||
   void RadarProductManagerConnect();
 | 
			
		||||
   void RadarProductManagerDisconnect();
 | 
			
		||||
| 
						 | 
				
			
			@ -187,9 +194,15 @@ public:
 | 
			
		|||
 | 
			
		||||
   std::vector<std::shared_ptr<GenericLayer>> genericLayers_ {};
 | 
			
		||||
 | 
			
		||||
   const std::vector<MapStyle> emptyStyles_ {};
 | 
			
		||||
   std::vector<MapStyle>       customStyles_ {
 | 
			
		||||
      MapStyle {.name_ {"Custom"}, .url_ {}, .drawBelow_ {}}};
 | 
			
		||||
   QStringList        styleLayers_;
 | 
			
		||||
   types::LayerVector customLayers_;
 | 
			
		||||
 | 
			
		||||
   boost::uuids::uuid customStyleUrlChangedCallbackId_ {};
 | 
			
		||||
   boost::uuids::uuid customStyleDrawBelowChangedCallbackId_ {};
 | 
			
		||||
 | 
			
		||||
   ImGuiContext* imGuiContext_;
 | 
			
		||||
   std::string   imGuiContextName_;
 | 
			
		||||
   bool          imGuiRendererInitialized_;
 | 
			
		||||
| 
						 | 
				
			
			@ -269,6 +282,48 @@ MapWidget::~MapWidget()
 | 
			
		|||
   makeCurrent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MapWidgetImpl::InitializeCustomStyles()
 | 
			
		||||
{
 | 
			
		||||
   auto& generalSettings = settings::GeneralSettings::Instance();
 | 
			
		||||
 | 
			
		||||
   auto& customStyleUrl       = generalSettings.custom_style_url();
 | 
			
		||||
   auto& customStyleDrawLayer = generalSettings.custom_style_draw_layer();
 | 
			
		||||
 | 
			
		||||
   auto& customStyle = customStyles_.at(0);
 | 
			
		||||
   customStyle.url_  = customStyleUrl.GetValue();
 | 
			
		||||
   customStyle.drawBelow_.push_back(customStyleDrawLayer.GetValue());
 | 
			
		||||
 | 
			
		||||
   customStyleUrlChangedCallbackId_ =
 | 
			
		||||
      customStyleUrl.RegisterValueChangedCallback(
 | 
			
		||||
         [this](const std::string& url) { customStyles_[0].url_ = url; });
 | 
			
		||||
   customStyleDrawBelowChangedCallbackId_ =
 | 
			
		||||
      customStyleDrawLayer.RegisterValueChangedCallback(
 | 
			
		||||
         [this](const std::string& drawLayer)
 | 
			
		||||
         {
 | 
			
		||||
            if (!drawLayer.empty())
 | 
			
		||||
            {
 | 
			
		||||
               customStyles_[0].drawBelow_ = {drawLayer};
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
               customStyles_[0].drawBelow_.clear();
 | 
			
		||||
            }
 | 
			
		||||
         });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MapWidgetImpl::DeinitializeCustomStyles() const
 | 
			
		||||
{
 | 
			
		||||
   auto& generalSettings = settings::GeneralSettings::Instance();
 | 
			
		||||
 | 
			
		||||
   auto& customStyleUrl       = generalSettings.custom_style_url();
 | 
			
		||||
   auto& customStyleDrawLayer = generalSettings.custom_style_draw_layer();
 | 
			
		||||
 | 
			
		||||
   customStyleUrl.UnregisterValueChangedCallback(
 | 
			
		||||
      customStyleUrlChangedCallbackId_);
 | 
			
		||||
   customStyleDrawLayer.UnregisterValueChangedCallback(
 | 
			
		||||
      customStyleDrawBelowChangedCallbackId_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MapWidgetImpl::ConnectMapSignals()
 | 
			
		||||
{
 | 
			
		||||
   connect(map_.get(),
 | 
			
		||||
| 
						 | 
				
			
			@ -283,8 +338,8 @@ void MapWidgetImpl::ConnectMapSignals()
 | 
			
		|||
              QTextDocument document {};
 | 
			
		||||
              document.setHtml(copyrightsHtml);
 | 
			
		||||
 | 
			
		||||
              // HTML cannot currently be included in ImGui windows. Where links
 | 
			
		||||
              // can't be included, remove "Improve this map".
 | 
			
		||||
              // HTML cannot currently be included in ImGui windows. Where
 | 
			
		||||
              // links can't be included, remove "Improve this map".
 | 
			
		||||
              std::string copyrights {document.toPlainText().toStdString()};
 | 
			
		||||
              boost::erase_all(copyrights, "Improve this map");
 | 
			
		||||
              boost::trim_right(copyrights);
 | 
			
		||||
| 
						 | 
				
			
			@ -924,7 +979,16 @@ void MapWidget::SetMapStyle(const std::string& styleName)
 | 
			
		|||
{
 | 
			
		||||
   const auto  mapProvider     = p->context_->map_provider();
 | 
			
		||||
   const auto& mapProviderInfo = GetMapProviderInfo(mapProvider);
 | 
			
		||||
   auto&       styles          = mapProviderInfo.mapStyles_;
 | 
			
		||||
   auto&       fixedStyles     = mapProviderInfo.mapStyles_;
 | 
			
		||||
 | 
			
		||||
   auto styles = boost::join(fixedStyles,
 | 
			
		||||
                             p->customStyles_[0].IsValid() ? p->customStyles_ :
 | 
			
		||||
                                                             p->emptyStyles_);
 | 
			
		||||
 | 
			
		||||
   if (p->currentStyleIndex_ >= styles.size())
 | 
			
		||||
   {
 | 
			
		||||
      p->currentStyleIndex_ = 0;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   for (size_t i = 0u; i < styles.size(); ++i)
 | 
			
		||||
   {
 | 
			
		||||
| 
						 | 
				
			
			@ -937,7 +1001,7 @@ void MapWidget::SetMapStyle(const std::string& styleName)
 | 
			
		|||
 | 
			
		||||
         util::maplibre::SetMapStyleUrl(p->context_, styles[i].url_);
 | 
			
		||||
 | 
			
		||||
         if (++p->currentStyleIndex_ == styles.size())
 | 
			
		||||
         if (++p->currentStyleIndex_ >= styles.size())
 | 
			
		||||
         {
 | 
			
		||||
            p->currentStyleIndex_ = 0;
 | 
			
		||||
         }
 | 
			
		||||
| 
						 | 
				
			
			@ -974,7 +1038,16 @@ void MapWidget::changeStyle()
 | 
			
		|||
{
 | 
			
		||||
   const auto  mapProvider     = p->context_->map_provider();
 | 
			
		||||
   const auto& mapProviderInfo = GetMapProviderInfo(mapProvider);
 | 
			
		||||
   auto&       styles          = mapProviderInfo.mapStyles_;
 | 
			
		||||
   auto&       fixedStyles     = mapProviderInfo.mapStyles_;
 | 
			
		||||
 | 
			
		||||
   auto styles = boost::join(fixedStyles,
 | 
			
		||||
                             p->customStyles_[0].IsValid() ? p->customStyles_ :
 | 
			
		||||
                                                             p->emptyStyles_);
 | 
			
		||||
 | 
			
		||||
   if (p->currentStyleIndex_ >= styles.size())
 | 
			
		||||
   {
 | 
			
		||||
      p->currentStyleIndex_ = 0;
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
   p->currentStyle_ = &styles[p->currentStyleIndex_];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -983,7 +1056,7 @@ void MapWidget::changeStyle()
 | 
			
		|||
   util::maplibre::SetMapStyleUrl(p->context_,
 | 
			
		||||
                                  styles[p->currentStyleIndex_].url_);
 | 
			
		||||
 | 
			
		||||
   if (++p->currentStyleIndex_ == styles.size())
 | 
			
		||||
   if (++p->currentStyleIndex_ >= styles.size())
 | 
			
		||||
   {
 | 
			
		||||
      p->currentStyleIndex_ = 0;
 | 
			
		||||
   }
 | 
			
		||||
| 
						 | 
				
			
			@ -1011,7 +1084,16 @@ std::string MapWidgetImpl::FindMapSymbologyLayer()
 | 
			
		|||
                             {
 | 
			
		||||
                                // Perform case-insensitive matching
 | 
			
		||||
                                RE2 re {"(?i)" + styleLayer};
 | 
			
		||||
                                if (re.ok())
 | 
			
		||||
                                {
 | 
			
		||||
                                   return RE2::FullMatch(layer, re);
 | 
			
		||||
                                }
 | 
			
		||||
                                else
 | 
			
		||||
                                {
 | 
			
		||||
                                   // Fall back to basic comparison if RE
 | 
			
		||||
                                   // doesn't compile
 | 
			
		||||
                                   return layer == styleLayer;
 | 
			
		||||
                                }
 | 
			
		||||
                             });
 | 
			
		||||
 | 
			
		||||
      if (it != currentStyle_->drawBelow_.cend())
 | 
			
		||||
| 
						 | 
				
			
			@ -1618,8 +1700,8 @@ void MapWidgetImpl::RadarProductManagerConnect()
 | 
			
		|||
                        // Select loaded record
 | 
			
		||||
                        auto record = request->radar_product_record();
 | 
			
		||||
 | 
			
		||||
                        // Validate record, and verify current map context still
 | 
			
		||||
                        // displays site and product
 | 
			
		||||
                        // Validate record, and verify current map context
 | 
			
		||||
                        // still displays site and product
 | 
			
		||||
                        if (record != nullptr &&
 | 
			
		||||
                            radarProductManager_ != nullptr &&
 | 
			
		||||
                            radarProductManager_->radar_id() ==
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,6 +52,7 @@ public:
 | 
			
		|||
 | 
			
		||||
      antiAliasingEnabled_.SetDefault(true);
 | 
			
		||||
      clockFormat_.SetDefault(defaultClockFormatValue);
 | 
			
		||||
      customStyleDrawLayer_.SetDefault(".*\\.annotations\\.points");
 | 
			
		||||
      debugEnabled_.SetDefault(false);
 | 
			
		||||
      defaultAlertAction_.SetDefault(defaultDefaultAlertActionValue);
 | 
			
		||||
      defaultRadarSite_.SetDefault("KLSX");
 | 
			
		||||
| 
						 | 
				
			
			@ -93,10 +94,17 @@ public:
 | 
			
		|||
      nmeaBaudRate_.SetMinimum(1);
 | 
			
		||||
      nmeaBaudRate_.SetMaximum(999999999);
 | 
			
		||||
 | 
			
		||||
      customStyleDrawLayer_.SetTransform([](const std::string& value)
 | 
			
		||||
                                         { return boost::trim_copy(value); });
 | 
			
		||||
      customStyleUrl_.SetTransform([](const std::string& value)
 | 
			
		||||
                                   { return boost::trim_copy(value); });
 | 
			
		||||
 | 
			
		||||
      clockFormat_.SetValidator(
 | 
			
		||||
         SCWX_SETTINGS_ENUM_VALIDATOR(scwx::util::ClockFormat,
 | 
			
		||||
                                      scwx::util::ClockFormatIterator(),
 | 
			
		||||
                                      scwx::util::GetClockFormatName));
 | 
			
		||||
      customStyleDrawLayer_.SetValidator([](const std::string& value)
 | 
			
		||||
                                         { return !value.empty(); });
 | 
			
		||||
      defaultAlertAction_.SetValidator(
 | 
			
		||||
         SCWX_SETTINGS_ENUM_VALIDATOR(types::AlertAction,
 | 
			
		||||
                                      types::AlertActionIterator(),
 | 
			
		||||
| 
						 | 
				
			
			@ -130,6 +138,9 @@ public:
 | 
			
		|||
 | 
			
		||||
   SettingsVariable<bool>        antiAliasingEnabled_ {"anti_aliasing_enabled"};
 | 
			
		||||
   SettingsVariable<std::string> clockFormat_ {"clock_format"};
 | 
			
		||||
   SettingsVariable<std::string> customStyleDrawLayer_ {
 | 
			
		||||
      "custom_style_draw_layer"};
 | 
			
		||||
   SettingsVariable<std::string> customStyleUrl_ {"custom_style_url"};
 | 
			
		||||
   SettingsVariable<bool>        debugEnabled_ {"debug_enabled"};
 | 
			
		||||
   SettingsVariable<std::string> defaultAlertAction_ {"default_alert_action"};
 | 
			
		||||
   SettingsVariable<std::string> defaultRadarSite_ {"default_radar_site"};
 | 
			
		||||
| 
						 | 
				
			
			@ -158,8 +169,10 @@ public:
 | 
			
		|||
GeneralSettings::GeneralSettings() :
 | 
			
		||||
    SettingsCategory("general"), p(std::make_unique<Impl>())
 | 
			
		||||
{
 | 
			
		||||
   RegisterVariables({&p->antiAliasingEnabled_, //
 | 
			
		||||
   RegisterVariables({&p->antiAliasingEnabled_,
 | 
			
		||||
                      &p->clockFormat_,
 | 
			
		||||
                      &p->customStyleDrawLayer_,
 | 
			
		||||
                      &p->customStyleUrl_,
 | 
			
		||||
                      &p->debugEnabled_,
 | 
			
		||||
                      &p->defaultAlertAction_,
 | 
			
		||||
                      &p->defaultRadarSite_,
 | 
			
		||||
| 
						 | 
				
			
			@ -201,6 +214,16 @@ SettingsVariable<std::string>& GeneralSettings::clock_format() const
 | 
			
		|||
   return p->clockFormat_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SettingsVariable<std::string>& GeneralSettings::custom_style_draw_layer() const
 | 
			
		||||
{
 | 
			
		||||
   return p->customStyleDrawLayer_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SettingsVariable<std::string>& GeneralSettings::custom_style_url() const
 | 
			
		||||
{
 | 
			
		||||
   return p->customStyleUrl_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SettingsVariable<bool>& GeneralSettings::debug_enabled() const
 | 
			
		||||
{
 | 
			
		||||
   return p->debugEnabled_;
 | 
			
		||||
| 
						 | 
				
			
			@ -340,6 +363,8 @@ bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs)
 | 
			
		|||
{
 | 
			
		||||
   return (lhs.p->antiAliasingEnabled_ == rhs.p->antiAliasingEnabled_ &&
 | 
			
		||||
           lhs.p->clockFormat_ == rhs.p->clockFormat_ &&
 | 
			
		||||
           lhs.p->customStyleDrawLayer_ == rhs.p->customStyleDrawLayer_ &&
 | 
			
		||||
           lhs.p->customStyleUrl_ == rhs.p->customStyleUrl_ &&
 | 
			
		||||
           lhs.p->debugEnabled_ == rhs.p->debugEnabled_ &&
 | 
			
		||||
           lhs.p->defaultAlertAction_ == rhs.p->defaultAlertAction_ &&
 | 
			
		||||
           lhs.p->defaultRadarSite_ == rhs.p->defaultRadarSite_ &&
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,8 @@ public:
 | 
			
		|||
 | 
			
		||||
   SettingsVariable<bool>&        anti_aliasing_enabled() const;
 | 
			
		||||
   SettingsVariable<std::string>& clock_format() const;
 | 
			
		||||
   SettingsVariable<std::string>& custom_style_draw_layer() const;
 | 
			
		||||
   SettingsVariable<std::string>& custom_style_url() const;
 | 
			
		||||
   SettingsVariable<bool>&        debug_enabled() const;
 | 
			
		||||
   SettingsVariable<std::string>& default_alert_action() const;
 | 
			
		||||
   SettingsVariable<std::string>& default_radar_site() const;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,7 @@ public:
 | 
			
		|||
   std::optional<T>              staged_ {};
 | 
			
		||||
   std::optional<T>              minimum_ {};
 | 
			
		||||
   std::optional<T>              maximum_ {};
 | 
			
		||||
   std::function<T(const T&)>    transform_ {};
 | 
			
		||||
   std::function<bool(const T&)> validator_ {nullptr};
 | 
			
		||||
 | 
			
		||||
   boost::unordered_flat_map<boost::uuids::uuid, ValueCallbackFunction>
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +80,7 @@ bool SettingsVariable<T>::SetValue(const T& value)
 | 
			
		|||
 | 
			
		||||
   if (Validate(value))
 | 
			
		||||
   {
 | 
			
		||||
      p->value_ = value;
 | 
			
		||||
      p->value_ = (p->transform_ != nullptr) ? p->transform_(value) : value;
 | 
			
		||||
      validated = true;
 | 
			
		||||
 | 
			
		||||
      for (auto& callback : p->valueChangedCallbackFunctions_)
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +103,7 @@ bool SettingsVariable<T>::SetValueOrDefault(const T& value)
 | 
			
		|||
 | 
			
		||||
   if (Validate(value))
 | 
			
		||||
   {
 | 
			
		||||
      p->value_ = value;
 | 
			
		||||
      p->value_ = (p->transform_ != nullptr) ? p->transform_(value) : value;
 | 
			
		||||
      validated = true;
 | 
			
		||||
   }
 | 
			
		||||
   else if (p->minimum_.has_value() && value < p->minimum_)
 | 
			
		||||
| 
						 | 
				
			
			@ -182,9 +183,11 @@ bool SettingsVariable<T>::StageValue(const T& value)
 | 
			
		|||
 | 
			
		||||
   if (Validate(value))
 | 
			
		||||
   {
 | 
			
		||||
      if (p->value_ != value)
 | 
			
		||||
      T transformed = (p->transform_ != nullptr) ? p->transform_(value) : value;
 | 
			
		||||
 | 
			
		||||
      if (p->value_ != transformed)
 | 
			
		||||
      {
 | 
			
		||||
         p->staged_ = value;
 | 
			
		||||
         p->staged_ = transformed;
 | 
			
		||||
      }
 | 
			
		||||
      else
 | 
			
		||||
      {
 | 
			
		||||
| 
						 | 
				
			
			@ -195,7 +198,7 @@ bool SettingsVariable<T>::StageValue(const T& value)
 | 
			
		|||
 | 
			
		||||
      for (auto& callback : p->valueStagedCallbackFunctions_)
 | 
			
		||||
      {
 | 
			
		||||
         callback.second(value);
 | 
			
		||||
         callback.second(transformed);
 | 
			
		||||
      }
 | 
			
		||||
   }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -285,6 +288,12 @@ std::optional<T> SettingsVariable<T>::GetMaximum() const
 | 
			
		|||
   return p->maximum_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
void SettingsVariable<T>::SetTransform(std::function<T(const T&)> transform)
 | 
			
		||||
{
 | 
			
		||||
   p->transform_ = transform;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
void SettingsVariable<T>::SetValidator(std::function<bool(const T&)> validator)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -384,7 +393,7 @@ bool SettingsVariable<T>::Equals(const SettingsVariableBase& o) const
 | 
			
		|||
   // This is only ever called with SettingsVariable<T>, so static_cast is safe
 | 
			
		||||
   const SettingsVariable<T>& v = static_cast<const SettingsVariable<T>&>(o);
 | 
			
		||||
 | 
			
		||||
   // Don't compare validator
 | 
			
		||||
   // Don't compare transform or validator
 | 
			
		||||
   return SettingsVariableBase::Equals(o) && //
 | 
			
		||||
          p->value_ == v.p->value_ &&        //
 | 
			
		||||
          p->default_ == v.p->default_ &&    //
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,6 +165,13 @@ public:
 | 
			
		|||
    */
 | 
			
		||||
   void SetMaximum(const T& value);
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * Sets a custom transform function for the settings variable.
 | 
			
		||||
    *
 | 
			
		||||
    * @param transform Transform function
 | 
			
		||||
    */
 | 
			
		||||
   void SetTransform(std::function<T(const T&)> transform);
 | 
			
		||||
 | 
			
		||||
   /**
 | 
			
		||||
    * Sets a custom validator function for the settings variable.
 | 
			
		||||
    *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,6 +117,8 @@ public:
 | 
			
		|||
          &theme_,
 | 
			
		||||
          &defaultAlertAction_,
 | 
			
		||||
          &clockFormat_,
 | 
			
		||||
          &customStyleDrawLayer_,
 | 
			
		||||
          &customStyleUrl_,
 | 
			
		||||
          &defaultTimeZone_,
 | 
			
		||||
          &positioningPlugin_,
 | 
			
		||||
          &nmeaBaudRate_,
 | 
			
		||||
| 
						 | 
				
			
			@ -222,6 +224,8 @@ public:
 | 
			
		|||
   settings::SettingsInterface<std::string>  mapTilerApiKey_ {};
 | 
			
		||||
   settings::SettingsInterface<std::string>  defaultAlertAction_ {};
 | 
			
		||||
   settings::SettingsInterface<std::string>  clockFormat_ {};
 | 
			
		||||
   settings::SettingsInterface<std::string>  customStyleDrawLayer_ {};
 | 
			
		||||
   settings::SettingsInterface<std::string>  customStyleUrl_ {};
 | 
			
		||||
   settings::SettingsInterface<std::string>  defaultTimeZone_ {};
 | 
			
		||||
   settings::SettingsInterface<std::string>  positioningPlugin_ {};
 | 
			
		||||
   settings::SettingsInterface<std::int64_t> nmeaBaudRate_ {};
 | 
			
		||||
| 
						 | 
				
			
			@ -566,6 +570,15 @@ void SettingsDialogImpl::SetupGeneralTab()
 | 
			
		|||
   mapTilerApiKey_.SetEditWidget(self_->ui->mapTilerApiKeyLineEdit);
 | 
			
		||||
   mapTilerApiKey_.SetResetButton(self_->ui->resetMapTilerApiKeyButton);
 | 
			
		||||
 | 
			
		||||
   customStyleUrl_.SetSettingsVariable(generalSettings.custom_style_url());
 | 
			
		||||
   customStyleUrl_.SetEditWidget(self_->ui->customMapUrlLineEdit);
 | 
			
		||||
   customStyleUrl_.SetResetButton(self_->ui->resetCustomMapUrlButton);
 | 
			
		||||
 | 
			
		||||
   customStyleDrawLayer_.SetSettingsVariable(
 | 
			
		||||
      generalSettings.custom_style_draw_layer());
 | 
			
		||||
   customStyleDrawLayer_.SetEditWidget(self_->ui->customMapLayerLineEdit);
 | 
			
		||||
   customStyleDrawLayer_.SetResetButton(self_->ui->resetCustomMapLayerButton);
 | 
			
		||||
 | 
			
		||||
   defaultAlertAction_.SetSettingsVariable(
 | 
			
		||||
      generalSettings.default_alert_action());
 | 
			
		||||
   SCWX_SETTINGS_COMBO_BOX(defaultAlertAction_,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -135,9 +135,9 @@
 | 
			
		|||
              <property name="geometry">
 | 
			
		||||
               <rect>
 | 
			
		||||
                <x>0</x>
 | 
			
		||||
                <y>0</y>
 | 
			
		||||
                <width>513</width>
 | 
			
		||||
                <height>566</height>
 | 
			
		||||
                <y>-113</y>
 | 
			
		||||
                <width>511</width>
 | 
			
		||||
                <height>669</height>
 | 
			
		||||
               </rect>
 | 
			
		||||
              </property>
 | 
			
		||||
              <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
| 
						 | 
				
			
			@ -482,6 +482,48 @@
 | 
			
		|||
                    </property>
 | 
			
		||||
                   </widget>
 | 
			
		||||
                  </item>
 | 
			
		||||
                  <item row="14" column="2">
 | 
			
		||||
                   <widget class="QLineEdit" name="customMapUrlLineEdit"/>
 | 
			
		||||
                  </item>
 | 
			
		||||
                  <item row="15" column="2">
 | 
			
		||||
                   <widget class="QLineEdit" name="customMapLayerLineEdit"/>
 | 
			
		||||
                  </item>
 | 
			
		||||
                  <item row="14" column="0">
 | 
			
		||||
                   <widget class="QLabel" name="label_26">
 | 
			
		||||
                    <property name="text">
 | 
			
		||||
                     <string>Custom Map URL</string>
 | 
			
		||||
                    </property>
 | 
			
		||||
                   </widget>
 | 
			
		||||
                  </item>
 | 
			
		||||
                  <item row="15" column="0">
 | 
			
		||||
                   <widget class="QLabel" name="label_27">
 | 
			
		||||
                    <property name="text">
 | 
			
		||||
                     <string>Custom Map Layer</string>
 | 
			
		||||
                    </property>
 | 
			
		||||
                   </widget>
 | 
			
		||||
                  </item>
 | 
			
		||||
                  <item row="14" column="4">
 | 
			
		||||
                   <widget class="QToolButton" name="resetCustomMapUrlButton">
 | 
			
		||||
                    <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="15" column="4">
 | 
			
		||||
                   <widget class="QToolButton" name="resetCustomMapLayerButton">
 | 
			
		||||
                    <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>
 | 
			
		||||
                 </layout>
 | 
			
		||||
                </widget>
 | 
			
		||||
               </item>
 | 
			
		||||
| 
						 | 
				
			
			@ -568,8 +610,8 @@
 | 
			
		|||
                   <rect>
 | 
			
		||||
                    <x>0</x>
 | 
			
		||||
                    <y>0</y>
 | 
			
		||||
                    <width>63</width>
 | 
			
		||||
                    <height>18</height>
 | 
			
		||||
                    <width>98</width>
 | 
			
		||||
                    <height>28</height>
 | 
			
		||||
                   </rect>
 | 
			
		||||
                  </property>
 | 
			
		||||
                  <layout class="QGridLayout" name="gridLayout_3">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
Subproject commit 6fe42c4f776ced46f0f808109d0d773ffc2255e3
 | 
			
		||||
Subproject commit 0ea32947d6a6e39a69d931b2827056e7bc58cbba
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue