supercell-wx/scwx-qt/source/scwx/qt/settings/palette_settings.cpp

251 lines
7.2 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() {}
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