mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 20:50:06 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			255 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			255 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <scwx/qt/settings/palette_settings.hpp>
 | |
| #include <scwx/qt/settings/settings_variable.hpp>
 | |
| #include <scwx/qt/util/color.hpp>
 | |
| 
 | |
| #include <boost/algorithm/string/case_conv.hpp>
 | |
| #include <boost/gil.hpp>
 | |
| #include <fmt/format.h>
 | |
| 
 | |
| namespace scwx::qt::settings
 | |
| {
 | |
| 
 | |
| static const std::string logPrefix_ = "scwx::qt::settings::palette_settings";
 | |
| 
 | |
| static const std::array<std::string, 18> kPaletteKeys_ {
 | |
|    // Level 2 / Common Products
 | |
|    "BR",
 | |
|    "BV",
 | |
|    "SW",
 | |
|    "CC",
 | |
|    "ZDR",
 | |
|    "PHI2",
 | |
|    // Level 3 Products
 | |
|    "DOD",
 | |
|    "DSD",
 | |
|    "ET",
 | |
|    "HC",
 | |
|    "STP",
 | |
|    "OHP",
 | |
|    "STPIN",
 | |
|    "OHPIN",
 | |
|    "PHI3",
 | |
|    "SRV",
 | |
|    "VIL",
 | |
|    "???"};
 | |
| 
 | |
| static const std::unordered_map<std::string, std::string> kDefaultPalettes_ {
 | |
|    // Level 2 / Common Products
 | |
|    {"BR", ":/res/palettes/wct/DR.pal"},
 | |
|    {"BV", ":/res/palettes/wct/DV.pal"},
 | |
|    {"SW", ":/res/palettes/wct/SW.pal"},
 | |
|    {"ZDR", ":/res/palettes/wct/ZDR.pal"},
 | |
|    {"PHI2", ":/res/palettes/wct/KDP2.pal"},
 | |
|    {"CC", ":/res/palettes/wct/CC.pal"},
 | |
|    // Level 3 Products
 | |
|    {"DOD", ":/res/palettes/wct/DOD_DSD.pal"},
 | |
|    {"DSD", ":/res/palettes/wct/DOD_DSD.pal"},
 | |
|    {"ET", ":/res/palettes/wct/ET.pal"},
 | |
|    {"HC", ":/res/palettes/wct/HC.pal"},
 | |
|    {"OHP", ":/res/palettes/wct/OHP.pal"},
 | |
|    {"OHPIN", ""},
 | |
|    {"PHI3", ":/res/palettes/wct/KDP.pal"},
 | |
|    {"SRV", ":/res/palettes/wct/SRV.pal"},
 | |
|    {"STP", ":/res/palettes/wct/STP.pal"},
 | |
|    {"STPIN", ""},
 | |
|    {"VIL", ":/res/palettes/wct/VIL.pal"},
 | |
|    {"???", ":/res/palettes/wct/Default16.pal"}};
 | |
| 
 | |
| static const std::map<
 | |
|    awips::Phenomenon,
 | |
|    std::pair<boost::gil::rgba8_pixel_t, boost::gil::rgba8_pixel_t>>
 | |
|    kAlertColors_ {
 | |
|       {awips::Phenomenon::Marine, {{255, 127, 0, 255}, {127, 63, 0, 255}}},
 | |
|       {awips::Phenomenon::FlashFlood, {{0, 255, 0, 255}, {0, 127, 0, 255}}},
 | |
|       {awips::Phenomenon::SevereThunderstorm,
 | |
|        {{255, 255, 0, 255}, {127, 127, 0, 255}}},
 | |
|       {awips::Phenomenon::SnowSquall, {{0, 255, 255, 255}, {0, 127, 127, 255}}},
 | |
|       {awips::Phenomenon::Tornado, {{255, 0, 0, 255}, {127, 0, 0, 255}}}};
 | |
| 
 | |
| static const std::string       kDefaultKey_ {"???"};
 | |
| static const awips::Phenomenon kDefaultPhenomenon_ {awips::Phenomenon::Marine};
 | |
| 
 | |
| class PaletteSettings::Impl
 | |
| {
 | |
| public:
 | |
|    explicit Impl(PaletteSettings* self) : self_ {self}
 | |
|    {
 | |
|       InitializeColorTables();
 | |
|       InitializeLegacyAlerts();
 | |
|       InitializeAlerts();
 | |
|    }
 | |
| 
 | |
|    ~Impl()                       = default;
 | |
|    Impl(const Impl&)             = delete;
 | |
|    Impl& operator=(const Impl&)  = delete;
 | |
|    Impl(const Impl&&)            = delete;
 | |
|    Impl& operator=(const Impl&&) = delete;
 | |
| 
 | |
|    void InitializeColorTables();
 | |
|    void InitializeLegacyAlerts();
 | |
|    void InitializeAlerts();
 | |
| 
 | |
|    PaletteSettings* self_;
 | |
| 
 | |
|    std::unordered_map<std::string, SettingsVariable<std::string>> palette_ {};
 | |
|    std::unordered_map<awips::Phenomenon, SettingsVariable<std::string>>
 | |
|       activeAlertColor_ {};
 | |
|    std::unordered_map<awips::Phenomenon, SettingsVariable<std::string>>
 | |
|                                       inactiveAlertColor_ {};
 | |
|    std::vector<SettingsVariableBase*> variables_ {};
 | |
| 
 | |
|    std::unordered_map<awips::Phenomenon, AlertPaletteSettings>
 | |
|       alertPaletteMap_ {};
 | |
| };
 | |
| 
 | |
| PaletteSettings::PaletteSettings() :
 | |
|     SettingsCategory("palette"), p(std::make_unique<Impl>(this))
 | |
| {
 | |
|    RegisterVariables(p->variables_);
 | |
|    SetDefaults();
 | |
| 
 | |
|    p->variables_.clear();
 | |
| }
 | |
| PaletteSettings::~PaletteSettings() = default;
 | |
| 
 | |
| PaletteSettings::PaletteSettings(PaletteSettings&&) noexcept = default;
 | |
| PaletteSettings&
 | |
| PaletteSettings::operator=(PaletteSettings&&) noexcept = default;
 | |
| 
 | |
| void PaletteSettings::Impl::InitializeColorTables()
 | |
| {
 | |
|    palette_.reserve(kPaletteKeys_.size());
 | |
| 
 | |
|    for (const auto& name : kPaletteKeys_)
 | |
|    {
 | |
|       const std::string& defaultValue = kDefaultPalettes_.at(name);
 | |
| 
 | |
|       auto result =
 | |
|          palette_.emplace(name, SettingsVariable<std::string> {name});
 | |
| 
 | |
|       SettingsVariable<std::string>& settingsVariable = result.first->second;
 | |
| 
 | |
|       settingsVariable.SetDefault(defaultValue);
 | |
| 
 | |
|       variables_.push_back(&settingsVariable);
 | |
|    };
 | |
| }
 | |
| 
 | |
| void PaletteSettings::Impl::InitializeLegacyAlerts()
 | |
| {
 | |
|    activeAlertColor_.reserve(kAlertColors_.size());
 | |
|    inactiveAlertColor_.reserve(kAlertColors_.size());
 | |
| 
 | |
|    for (auto& alert : kAlertColors_)
 | |
|    {
 | |
|       std::string phenomenonCode = awips::GetPhenomenonCode(alert.first);
 | |
|       std::string activeName     = fmt::format("{}-active", phenomenonCode);
 | |
|       std::string inactiveName   = fmt::format("{}-inactive", phenomenonCode);
 | |
| 
 | |
|       auto activeResult = activeAlertColor_.emplace(
 | |
|          alert.first, SettingsVariable<std::string> {activeName});
 | |
|       auto inactiveResult = inactiveAlertColor_.emplace(
 | |
|          alert.first, SettingsVariable<std::string> {inactiveName});
 | |
| 
 | |
|       SettingsVariable<std::string>& activeVariable =
 | |
|          activeResult.first->second;
 | |
|       SettingsVariable<std::string>& inactiveVariable =
 | |
|          inactiveResult.first->second;
 | |
| 
 | |
|       activeVariable.SetDefault(util::color::ToArgbString(alert.second.first));
 | |
|       inactiveVariable.SetDefault(
 | |
|          util::color::ToArgbString(alert.second.second));
 | |
| 
 | |
|       activeVariable.SetValidator(&util::color::ValidateArgbString);
 | |
|       inactiveVariable.SetValidator(&util::color::ValidateArgbString);
 | |
| 
 | |
|       variables_.push_back(&activeVariable);
 | |
|       variables_.push_back(&inactiveVariable);
 | |
|    }
 | |
| }
 | |
| 
 | |
| void PaletteSettings::Impl::InitializeAlerts()
 | |
| {
 | |
|    std::vector<SettingsCategory*> alertSettings {};
 | |
| 
 | |
|    for (auto phenomenon : PaletteSettings::alert_phenomena())
 | |
|    {
 | |
|       auto  result = alertPaletteMap_.emplace(phenomenon, phenomenon);
 | |
|       auto& it     = result.first;
 | |
|       AlertPaletteSettings& alertPaletteSettings = it->second;
 | |
| 
 | |
|       // Variable registration
 | |
|       alertSettings.push_back(&alertPaletteSettings);
 | |
|    }
 | |
| 
 | |
|    self_->RegisterSubcategoryArray("alerts", alertSettings);
 | |
| }
 | |
| 
 | |
| SettingsVariable<std::string>&
 | |
| PaletteSettings::palette(const std::string& name) const
 | |
| {
 | |
|    auto palette = p->palette_.find(name);
 | |
| 
 | |
|    if (palette == p->palette_.cend())
 | |
|    {
 | |
|       palette = p->palette_.find(kDefaultKey_);
 | |
|    }
 | |
| 
 | |
|    return palette->second;
 | |
| }
 | |
| 
 | |
| SettingsVariable<std::string>&
 | |
| PaletteSettings::alert_color(awips::Phenomenon phenomenon, bool active) const
 | |
| {
 | |
|    if (active)
 | |
|    {
 | |
|       auto alert = p->activeAlertColor_.find(phenomenon);
 | |
|       if (alert == p->activeAlertColor_.cend())
 | |
|       {
 | |
|          alert = p->activeAlertColor_.find(kDefaultPhenomenon_);
 | |
|       }
 | |
|       return alert->second;
 | |
|    }
 | |
|    else
 | |
|    {
 | |
|       auto alert = p->inactiveAlertColor_.find(phenomenon);
 | |
|       if (alert == p->inactiveAlertColor_.cend())
 | |
|       {
 | |
|          alert = p->inactiveAlertColor_.find(kDefaultPhenomenon_);
 | |
|       }
 | |
|       return alert->second;
 | |
|    }
 | |
| }
 | |
| 
 | |
| AlertPaletteSettings&
 | |
| PaletteSettings::alert_palette(awips::Phenomenon phenomenon)
 | |
| {
 | |
|    return p->alertPaletteMap_.at(phenomenon);
 | |
| }
 | |
| 
 | |
| const std::vector<awips::Phenomenon>& PaletteSettings::alert_phenomena()
 | |
| {
 | |
|    static const std::vector<awips::Phenomenon> kAlertPhenomena_ {
 | |
|       awips::Phenomenon::Marine,
 | |
|       awips::Phenomenon::FlashFlood,
 | |
|       awips::Phenomenon::SevereThunderstorm,
 | |
|       awips::Phenomenon::SnowSquall,
 | |
|       awips::Phenomenon::Tornado};
 | |
| 
 | |
|    return kAlertPhenomena_;
 | |
| }
 | |
| 
 | |
| PaletteSettings& PaletteSettings::Instance()
 | |
| {
 | |
|    static PaletteSettings paletteSettings_;
 | |
|    return paletteSettings_;
 | |
| }
 | |
| 
 | |
| bool operator==(const PaletteSettings& lhs, const PaletteSettings& rhs)
 | |
| {
 | |
|    return (lhs.p->palette_ == rhs.p->palette_ &&
 | |
|            lhs.p->activeAlertColor_ == rhs.p->activeAlertColor_ &&
 | |
|            lhs.p->inactiveAlertColor_ == rhs.p->inactiveAlertColor_);
 | |
| }
 | |
| 
 | |
| } // namespace scwx::qt::settings
 | 
