#include #include #include #include #include #include namespace scwx::qt::settings { static const std::string logPrefix_ = "scwx::qt::settings::alert_palette_settings"; static const boost::gil::rgba8_pixel_t kColorBlack_ {0, 0, 0, 255}; struct LineData { boost::gil::rgba8_pixel_t borderColor_ {kColorBlack_}; boost::gil::rgba8_pixel_t highlightColor_ {kColorBlack_}; boost::gil::rgba8_pixel_t lineColor_; std::int64_t borderWidth_ {1}; std::int64_t highlightWidth_ {0}; std::int64_t lineWidth_ {3}; }; typedef boost::unordered_flat_map ThreatCategoryPalette; static const boost::unordered_flat_map kThreatCategoryPalettes_ // {{awips::Phenomenon::Marine, {{awips::ibw::ThreatCategory::Base, {.lineColor_ {255, 127, 0, 255}}}}}, {awips::Phenomenon::FlashFlood, {{awips::ibw::ThreatCategory::Base, {.lineColor_ {0, 255, 0, 255}}}, {awips::ibw::ThreatCategory::Considerable, {.highlightColor_ {0, 255, 0, 255}, .lineColor_ {kColorBlack_}, .highlightWidth_ = 1, .lineWidth_ = 1}}, {awips::ibw::ThreatCategory::Catastrophic, {.highlightColor_ {0, 255, 0, 255}, .lineColor_ {255, 0, 0, 255}, .highlightWidth_ = 1, .lineWidth_ = 1}}}}, {awips::Phenomenon::SevereThunderstorm, {{awips::ibw::ThreatCategory::Base, {.lineColor_ {255, 255, 0, 255}}}, {awips::ibw::ThreatCategory::Considerable, {.highlightColor_ {255, 255, 0, 255}, .lineColor_ {255, 0, 0, 255}, .highlightWidth_ = 1, .lineWidth_ = 1}}, {awips::ibw::ThreatCategory::Destructive, {.highlightColor_ {255, 255, 0, 255}, .lineColor_ {255, 0, 0, 255}, .highlightWidth_ = 1, .lineWidth_ = 2}}}}, {awips::Phenomenon::SnowSquall, {{awips::ibw::ThreatCategory::Base, {.lineColor_ {0, 255, 255, 255}}}}}, {awips::Phenomenon::Tornado, {{awips::ibw::ThreatCategory::Base, {.lineColor_ {255, 0, 0, 255}}}, {awips::ibw::ThreatCategory::Considerable, {.lineColor_ {255, 0, 255, 255}}}, {awips::ibw::ThreatCategory::Catastrophic, {.highlightColor_ {255, 0, 255, 255}, .lineColor_ {kColorBlack_}, .highlightWidth_ = 1, .lineWidth_ = 1}}}}}; static const boost::unordered_flat_map kObservedPalettes_ // {{awips::Phenomenon::Tornado, {.highlightColor_ {255, 0, 0, 255}, .lineColor_ {kColorBlack_}, .highlightWidth_ = 1, .lineWidth_ = 1}}}; static const boost::unordered_flat_map kTornadoPossiblePalettes_ // {{awips::Phenomenon::Marine, {.highlightColor_ {255, 127, 0, 255}, .lineColor_ {kColorBlack_}, .highlightWidth_ = 1, .lineWidth_ = 1}}, {awips::Phenomenon::SevereThunderstorm, {.highlightColor_ {255, 255, 0, 255}, .lineColor_ {kColorBlack_}, .highlightWidth_ = 1, .lineWidth_ = 1}}}; static const boost::unordered_flat_map kInactivePalettes_ // { {awips::Phenomenon::Marine, {.lineColor_ {127, 63, 0, 255}}}, {awips::Phenomenon::FlashFlood, {.lineColor_ {0, 127, 0, 255}}}, {awips::Phenomenon::SevereThunderstorm, {.lineColor_ {127, 127, 0, 255}}}, {awips::Phenomenon::SnowSquall, {.lineColor_ {0, 127, 127, 255}}}, {awips::Phenomenon::Tornado, {.lineColor_ {127, 0, 0, 255}}}, }; class AlertPaletteSettings::Impl { public: explicit Impl(awips::Phenomenon phenomenon) : phenomenon_ {phenomenon} { const auto& info = awips::ibw::GetImpactBasedWarningInfo(phenomenon); const auto& threatCategoryPalettes = kThreatCategoryPalettes_.at(phenomenon); for (auto& threatCategory : info.threatCategories_) { std::string threatCategoryName = awips::ibw::GetThreatCategoryName(threatCategory); boost::algorithm::to_lower(threatCategoryName); auto result = threatCategoryMap_.emplace(threatCategory, threatCategoryName); auto& lineSettings = result.first->second; SetDefaultLineData(lineSettings, threatCategoryPalettes.at(threatCategory)); } if (info.hasObservedTag_) { SetDefaultLineData(observed_, kObservedPalettes_.at(phenomenon)); } if (info.hasTornadoPossibleTag_) { SetDefaultLineData(tornadoPossible_, kTornadoPossiblePalettes_.at(phenomenon)); } SetDefaultLineData(inactive_, kInactivePalettes_.at(phenomenon)); } ~Impl() = default; Impl(const Impl&) = delete; Impl& operator=(const Impl&) = delete; Impl(const Impl&&) = delete; Impl& operator=(const Impl&&) = delete; static void SetDefaultLineData(LineSettings& lineSettings, const LineData& lineData); awips::Phenomenon phenomenon_; std::map threatCategoryMap_ {}; LineSettings observed_ {"observed"}; LineSettings tornadoPossible_ {"tornado_possible"}; LineSettings inactive_ {"inactive"}; }; AlertPaletteSettings::AlertPaletteSettings(awips::Phenomenon phenomenon) : SettingsCategory(awips::GetPhenomenonCode(phenomenon)), p(std::make_unique(phenomenon)) { auto& info = awips::ibw::GetImpactBasedWarningInfo(p->phenomenon_); for (auto& threatCategory : p->threatCategoryMap_) { RegisterSubcategory(threatCategory.second); } if (info.hasObservedTag_) { RegisterSubcategory(p->observed_); } if (info.hasTornadoPossibleTag_) { RegisterSubcategory(p->tornadoPossible_); } RegisterSubcategory(p->inactive_); SetDefaults(); } AlertPaletteSettings::~AlertPaletteSettings() = default; AlertPaletteSettings::AlertPaletteSettings(AlertPaletteSettings&&) noexcept = default; AlertPaletteSettings& AlertPaletteSettings::operator=(AlertPaletteSettings&&) noexcept = default; LineSettings& AlertPaletteSettings::threat_category( awips::ibw::ThreatCategory threatCategory) const { auto it = p->threatCategoryMap_.find(threatCategory); if (it != p->threatCategoryMap_.cend()) { return it->second; } return p->threatCategoryMap_.at(awips::ibw::ThreatCategory::Base); } LineSettings& AlertPaletteSettings::inactive() const { return p->inactive_; } LineSettings& AlertPaletteSettings::observed() const { return p->observed_; } LineSettings& AlertPaletteSettings::tornado_possible() const { return p->tornadoPossible_; } void AlertPaletteSettings::Impl::SetDefaultLineData(LineSettings& lineSettings, const LineData& lineData) { lineSettings.border_color().SetDefault( util::color::ToArgbString(lineData.borderColor_)); lineSettings.highlight_color().SetDefault( util::color::ToArgbString(lineData.highlightColor_)); lineSettings.line_color().SetDefault( util::color::ToArgbString(lineData.lineColor_)); lineSettings.border_width().SetDefault(lineData.borderWidth_); lineSettings.highlight_width().SetDefault(lineData.highlightWidth_); lineSettings.line_width().SetDefault(lineData.lineWidth_); } bool operator==(const AlertPaletteSettings& lhs, const AlertPaletteSettings& rhs) { return (lhs.p->phenomenon_ == rhs.p->phenomenon_ && lhs.p->threatCategoryMap_ == rhs.p->threatCategoryMap_ && lhs.p->inactive_ == rhs.p->inactive_ && lhs.p->observed_ == rhs.p->observed_ && lhs.p->tornadoPossible_ == rhs.p->tornadoPossible_); } } // namespace scwx::qt::settings