#include #include #include #include #include #include namespace scwx::qt::settings { static const std::string logPrefix_ = "scwx::qt::settings::palette_settings"; static const std::array 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 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> 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() {} void InitializeColorTables(); void InitializeLegacyAlerts(); void InitializeAlerts(); PaletteSettings* self_; std::unordered_map> palette_ {}; std::unordered_map> activeAlertColor_ {}; std::unordered_map> inactiveAlertColor_ {}; std::vector variables_ {}; std::unordered_map alertPaletteMap_ {}; }; PaletteSettings::PaletteSettings() : SettingsCategory("palette"), p(std::make_unique(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 {name}); SettingsVariable& 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 {activeName}); auto inactiveResult = inactiveAlertColor_.emplace( alert.first, SettingsVariable {inactiveName}); SettingsVariable& activeVariable = activeResult.first->second; SettingsVariable& 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 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& 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& 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& PaletteSettings::alert_phenomena() { static const std::vector 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