mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-29 22:30:04 +00:00
Add alert palette settings widget
This commit is contained in:
parent
da79f47416
commit
f8e0ab5b56
5 changed files with 351 additions and 61 deletions
|
|
@ -309,10 +309,12 @@ set(UI_UI source/scwx/qt/ui/about_dialog.ui
|
|||
source/scwx/qt/ui/serial_port_dialog.ui
|
||||
source/scwx/qt/ui/update_dialog.ui
|
||||
source/scwx/qt/ui/wfo_dialog.ui)
|
||||
set(HDR_UI_SETTINGS source/scwx/qt/ui/settings/hotkey_settings_widget.hpp
|
||||
set(HDR_UI_SETTINGS source/scwx/qt/ui/settings/alert_palette_settings_widget.hpp
|
||||
source/scwx/qt/ui/settings/hotkey_settings_widget.hpp
|
||||
source/scwx/qt/ui/settings/settings_page_widget.hpp
|
||||
source/scwx/qt/ui/settings/unit_settings_widget.hpp)
|
||||
set(SRC_UI_SETTINGS source/scwx/qt/ui/settings/hotkey_settings_widget.cpp
|
||||
set(SRC_UI_SETTINGS source/scwx/qt/ui/settings/alert_palette_settings_widget.cpp
|
||||
source/scwx/qt/ui/settings/hotkey_settings_widget.cpp
|
||||
source/scwx/qt/ui/settings/settings_page_widget.cpp
|
||||
source/scwx/qt/ui/settings/unit_settings_widget.cpp)
|
||||
set(HDR_UI_SETUP source/scwx/qt/ui/setup/audio_codec_page.hpp
|
||||
|
|
|
|||
|
|
@ -0,0 +1,239 @@
|
|||
#include <scwx/qt/ui/settings/alert_palette_settings_widget.hpp>
|
||||
#include <scwx/qt/ui/edit_line_dialog.hpp>
|
||||
#include <scwx/qt/ui/line_label.hpp>
|
||||
#include <scwx/qt/settings/palette_settings.hpp>
|
||||
#include <scwx/awips/impact_based_warnings.hpp>
|
||||
#include <scwx/awips/phenomenon.hpp>
|
||||
|
||||
#include <boost/unordered/unordered_flat_map.hpp>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include <QStackedWidget>
|
||||
#include <QToolButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace ui
|
||||
{
|
||||
|
||||
static const std::string logPrefix_ =
|
||||
"scwx::qt::ui::settings::alert_palette_settings_widget";
|
||||
|
||||
struct PhenomenonInfo
|
||||
{
|
||||
bool hasObservedTag_ {false};
|
||||
bool hasTornadoPossibleTag_ {false};
|
||||
std::vector<awips::ThreatCategory> threatCategories_ {
|
||||
awips::ThreatCategory::Base};
|
||||
};
|
||||
|
||||
static const boost::unordered_flat_map<awips::Phenomenon, PhenomenonInfo>
|
||||
phenomenaInfo_ {{awips::Phenomenon::Marine,
|
||||
PhenomenonInfo {.hasTornadoPossibleTag_ {true}}},
|
||||
{awips::Phenomenon::FlashFlood,
|
||||
PhenomenonInfo {.threatCategories_ {
|
||||
awips::ThreatCategory::Base,
|
||||
awips::ThreatCategory::Considerable,
|
||||
awips::ThreatCategory::Catastrophic}}},
|
||||
{awips::Phenomenon::SevereThunderstorm,
|
||||
PhenomenonInfo {.hasTornadoPossibleTag_ {true},
|
||||
.threatCategories_ {
|
||||
awips::ThreatCategory::Base,
|
||||
awips::ThreatCategory::Considerable,
|
||||
awips::ThreatCategory::Destructive}}},
|
||||
{awips::Phenomenon::SnowSquall, PhenomenonInfo {}},
|
||||
{awips::Phenomenon::Tornado,
|
||||
PhenomenonInfo {.hasObservedTag_ {true},
|
||||
.threatCategories_ {
|
||||
awips::ThreatCategory::Base,
|
||||
awips::ThreatCategory::Considerable,
|
||||
awips::ThreatCategory::Catastrophic}}}};
|
||||
|
||||
class AlertPaletteSettingsWidget::Impl
|
||||
{
|
||||
public:
|
||||
explicit Impl(AlertPaletteSettingsWidget* self) :
|
||||
self_ {self},
|
||||
phenomenonPagesWidget_ {new QStackedWidget(self)},
|
||||
phenomenonListView_ {new QListWidget(self)},
|
||||
editLineDialog_ {new EditLineDialog(self)}
|
||||
{
|
||||
SetupUi();
|
||||
ConnectSignals();
|
||||
}
|
||||
~Impl() = default;
|
||||
|
||||
void
|
||||
AddPhenomenonLine(const std::string& name, QGridLayout* layout, int row);
|
||||
QWidget* CreateStackedWidgetPage(awips::Phenomenon phenomenon);
|
||||
void ConnectSignals();
|
||||
void SelectPhenomenon(awips::Phenomenon phenomenon);
|
||||
void SetupUi();
|
||||
|
||||
AlertPaletteSettingsWidget* self_;
|
||||
|
||||
QStackedWidget* phenomenonPagesWidget_;
|
||||
QListWidget* phenomenonListView_;
|
||||
|
||||
EditLineDialog* editLineDialog_;
|
||||
|
||||
boost::unordered_flat_map<awips::Phenomenon, QWidget*> phenomenonPages_ {};
|
||||
};
|
||||
|
||||
AlertPaletteSettingsWidget::AlertPaletteSettingsWidget(QWidget* parent) :
|
||||
SettingsPageWidget(parent), p {std::make_shared<Impl>(this)}
|
||||
{
|
||||
}
|
||||
|
||||
AlertPaletteSettingsWidget::~AlertPaletteSettingsWidget() = default;
|
||||
|
||||
void AlertPaletteSettingsWidget::Impl::SetupUi()
|
||||
{
|
||||
// Setup primary widget layout
|
||||
QGridLayout* gridLayout = new QGridLayout(self_);
|
||||
gridLayout->setContentsMargins(0, 0, 0, 0);
|
||||
self_->setLayout(gridLayout);
|
||||
|
||||
QWidget* phenomenonIndexPane = new QWidget(self_);
|
||||
phenomenonPagesWidget_->setSizePolicy(QSizePolicy::Policy::Expanding,
|
||||
QSizePolicy::Policy::Preferred);
|
||||
|
||||
gridLayout->addWidget(phenomenonIndexPane, 0, 0);
|
||||
gridLayout->addWidget(phenomenonPagesWidget_, 0, 1);
|
||||
|
||||
QSpacerItem* spacer =
|
||||
new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
gridLayout->addItem(spacer, 1, 0);
|
||||
|
||||
// Setup phenomenon index pane
|
||||
QVBoxLayout* phenomenonIndexLayout = new QVBoxLayout(self_);
|
||||
phenomenonIndexPane->setLayout(phenomenonIndexLayout);
|
||||
|
||||
QLabel* phenomenonLabel = new QLabel(tr("Phenomenon:"), self_);
|
||||
phenomenonListView_->setSizePolicy(QSizePolicy::Policy::Minimum,
|
||||
QSizePolicy::Policy::Expanding);
|
||||
|
||||
phenomenonIndexLayout->addWidget(phenomenonLabel);
|
||||
phenomenonIndexLayout->addWidget(phenomenonListView_);
|
||||
|
||||
// Setup stacked widget
|
||||
auto& paletteSettings = settings::PaletteSettings::Instance();
|
||||
Q_UNUSED(paletteSettings);
|
||||
|
||||
for (auto& phenomenon : settings::PaletteSettings::alert_phenomena())
|
||||
{
|
||||
QWidget* phenomenonWidget = CreateStackedWidgetPage(phenomenon);
|
||||
phenomenonPagesWidget_->addWidget(phenomenonWidget);
|
||||
|
||||
phenomenonPages_.insert_or_assign(phenomenon, phenomenonWidget);
|
||||
|
||||
phenomenonListView_->addItem(
|
||||
QString::fromStdString(awips::GetPhenomenonText(phenomenon)));
|
||||
}
|
||||
|
||||
phenomenonListView_->setCurrentRow(0);
|
||||
}
|
||||
|
||||
void AlertPaletteSettingsWidget::Impl::ConnectSignals()
|
||||
{
|
||||
QObject::connect(
|
||||
phenomenonListView_->selectionModel(),
|
||||
&QItemSelectionModel::selectionChanged,
|
||||
self_,
|
||||
[this](const QItemSelection& selected, const QItemSelection& deselected)
|
||||
{
|
||||
if (selected.size() == 0 && deselected.size() == 0)
|
||||
{
|
||||
// Items which stay selected but change their index are not
|
||||
// included in selected and deselected. Thus, this signal might
|
||||
// be emitted with both selected and deselected empty, if only
|
||||
// the indices of selected items change.
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected.size() > 0)
|
||||
{
|
||||
QModelIndex selectedIndex = selected[0].indexes()[0];
|
||||
QVariant variantData =
|
||||
phenomenonListView_->model()->data(selectedIndex);
|
||||
if (variantData.typeId() == QMetaType::QString)
|
||||
{
|
||||
awips::Phenomenon phenomenon = awips::GetPhenomenonFromText(
|
||||
variantData.toString().toStdString());
|
||||
SelectPhenomenon(phenomenon);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void AlertPaletteSettingsWidget::Impl::SelectPhenomenon(
|
||||
awips::Phenomenon phenomenon)
|
||||
{
|
||||
auto it = phenomenonPages_.find(phenomenon);
|
||||
if (it != phenomenonPages_.cend())
|
||||
{
|
||||
phenomenonPagesWidget_->setCurrentWidget(it->second);
|
||||
}
|
||||
}
|
||||
|
||||
QWidget* AlertPaletteSettingsWidget::Impl::CreateStackedWidgetPage(
|
||||
awips::Phenomenon phenomenon)
|
||||
{
|
||||
QWidget* page = new QWidget(self_);
|
||||
QGridLayout* gridLayout = new QGridLayout(self_);
|
||||
page->setLayout(gridLayout);
|
||||
|
||||
const auto& phenomenonInfo = phenomenaInfo_.at(phenomenon);
|
||||
|
||||
int row = 0;
|
||||
|
||||
// Add a blank label to align left and right widgets
|
||||
gridLayout->addWidget(new QLabel(self_), row++, 0);
|
||||
|
||||
AddPhenomenonLine("Active", gridLayout, row++);
|
||||
|
||||
if (phenomenonInfo.hasObservedTag_)
|
||||
{
|
||||
AddPhenomenonLine("Observed", gridLayout, row++);
|
||||
}
|
||||
|
||||
if (phenomenonInfo.hasTornadoPossibleTag_)
|
||||
{
|
||||
AddPhenomenonLine("Tornado Possible", gridLayout, row++);
|
||||
}
|
||||
|
||||
for (auto& category : phenomenonInfo.threatCategories_)
|
||||
{
|
||||
if (category == awips::ThreatCategory::Base)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AddPhenomenonLine(
|
||||
awips::GetThreatCategoryName(category), gridLayout, row++);
|
||||
}
|
||||
|
||||
AddPhenomenonLine("Inactive", gridLayout, row++);
|
||||
|
||||
QSpacerItem* spacer =
|
||||
new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||||
gridLayout->addItem(spacer, row, 0);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
void AlertPaletteSettingsWidget::Impl::AddPhenomenonLine(
|
||||
const std::string& name, QGridLayout* layout, int row)
|
||||
{
|
||||
layout->addWidget(new QLabel(tr(name.c_str()), self_), row, 0);
|
||||
layout->addWidget(new LineLabel(self_), row, 1);
|
||||
layout->addWidget(new QToolButton(self_), row, 2);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include <scwx/qt/ui/settings/settings_page_widget.hpp>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace scwx
|
||||
{
|
||||
namespace qt
|
||||
{
|
||||
namespace ui
|
||||
{
|
||||
|
||||
class AlertPaletteSettingsWidget : public SettingsPageWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AlertPaletteSettingsWidget(QWidget* parent = nullptr);
|
||||
~AlertPaletteSettingsWidget();
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::shared_ptr<Impl> p;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
} // namespace qt
|
||||
} // namespace scwx
|
||||
|
|
@ -69,6 +69,7 @@ enum class Phenomenon
|
|||
};
|
||||
|
||||
Phenomenon GetPhenomenon(const std::string& code);
|
||||
Phenomenon GetPhenomenonFromText(const std::string& text);
|
||||
const std::string& GetPhenomenonCode(Phenomenon phenomenon);
|
||||
const std::string& GetPhenomenonText(Phenomenon phenomenon);
|
||||
|
||||
|
|
|
|||
|
|
@ -77,64 +77,65 @@ static const PhenomenonCodesBimap phenomenonCodes_ =
|
|||
(Phenomenon::FreezingSpray, "ZY") //
|
||||
(Phenomenon::Unknown, "??");
|
||||
|
||||
static const std::unordered_map<Phenomenon, std::string> phenomenonText_ {
|
||||
{Phenomenon::AshfallLand, "Ashfall (land)"}, //
|
||||
{Phenomenon::AirStagnation, "Air Stagnation"}, //
|
||||
{Phenomenon::BeachHazard, "Beach Hazard"}, //
|
||||
{Phenomenon::BriskWind, "Brisk Wind"}, //
|
||||
{Phenomenon::Blizzard, "Blizzard"}, //
|
||||
{Phenomenon::CoastalFlood, "Coastal Flood"}, //
|
||||
{Phenomenon::DebrisFlow, "Debris Flow"}, //
|
||||
{Phenomenon::DustStorm, "Dust Storm"}, //
|
||||
{Phenomenon::BlowingDust, "Blowing Dust"}, //
|
||||
{Phenomenon::ExtremeCold, "Extreme Cold"}, //
|
||||
{Phenomenon::ExcessiveHeat, "Excessive Heat"}, //
|
||||
{Phenomenon::ExtremeWind, "Extreme Wind"}, //
|
||||
{Phenomenon::Flood, "Flood"}, //
|
||||
{Phenomenon::FlashFlood, "Flash Flood"}, //
|
||||
{Phenomenon::DenseFogLand, "Dense Fog (land)"}, //
|
||||
{Phenomenon::Flood, "Flood (Forecast Points)"}, //
|
||||
{Phenomenon::Frost, "Frost"}, //
|
||||
{Phenomenon::FireWeather, "Fire Weather"}, //
|
||||
{Phenomenon::Freeze, "Freeze"}, //
|
||||
{Phenomenon::Gale, "Gale"}, //
|
||||
{Phenomenon::HurricaneForceWind, "Hurricane Force Wind"}, //
|
||||
{Phenomenon::Heat, "Heat"}, //
|
||||
{Phenomenon::Hurricane, "Hurricane"}, //
|
||||
{Phenomenon::HighWind, "High Wind"}, //
|
||||
{Phenomenon::Hydrologic, "Hydrologic"}, //
|
||||
{Phenomenon::HardFreeze, "Hard Freeze"}, //
|
||||
{Phenomenon::IceStorm, "Ice Storm"}, //
|
||||
{Phenomenon::LakeEffectSnow, "Lake Effect Snow"}, //
|
||||
{Phenomenon::LowWater, "Low Water"}, //
|
||||
{Phenomenon::LakeshoreFlood, "Lakeshore Flood"}, //
|
||||
{Phenomenon::LakeWind, "Lake Wind"}, //
|
||||
{Phenomenon::Marine, "Marine"}, //
|
||||
{Phenomenon::DenseFogMarine, "Dense Fog (marine)"}, //
|
||||
{Phenomenon::AshfallMarine, "Ashfall (marine)"}, //
|
||||
{Phenomenon::DenseSmokeMarine, "Dense Smoke (marine)"}, //
|
||||
{Phenomenon::RipCurrentRisk, "Rip Current Risk"}, //
|
||||
{Phenomenon::SmallCraft, "Small Craft"}, //
|
||||
{Phenomenon::HazardousSeas, "Hazardous Seas"}, //
|
||||
{Phenomenon::DenseSmokeLand, "Dense Smoke (land)"}, //
|
||||
{Phenomenon::Storm, "Storm"}, //
|
||||
{Phenomenon::StormSurge, "Storm Surge"}, //
|
||||
{Phenomenon::SnowSquall, "Snow Squall"}, //
|
||||
{Phenomenon::HighSurf, "High Surf"}, //
|
||||
{Phenomenon::SevereThunderstorm, "Severe Thunderstorm"}, //
|
||||
{Phenomenon::Tornado, "Tornado"}, //
|
||||
{Phenomenon::TropicalStorm, "Tropical Storm"}, //
|
||||
{Phenomenon::Tsunami, "Tsunami"}, //
|
||||
{Phenomenon::Typhoon, "Typhoon"}, //
|
||||
{Phenomenon::HeavyFreezingSpray, "Heavy Freezing Spray"}, //
|
||||
{Phenomenon::WindChill, "Wind Chill"}, //
|
||||
{Phenomenon::Wind, "Wind"}, //
|
||||
{Phenomenon::WinterStorm, "Winter Storm"}, //
|
||||
{Phenomenon::WinterWeather, "Winter Weather"}, //
|
||||
{Phenomenon::FreezingFog, "Freezing Fog"}, //
|
||||
{Phenomenon::FreezingRain, "Freezing Rain"}, //
|
||||
{Phenomenon::FreezingSpray, "Freezing Spray"}, //
|
||||
{Phenomenon::Unknown, "Unknown"}};
|
||||
static const PhenomenonCodesBimap phenomenonText_ =
|
||||
boost::assign::list_of<PhenomenonCodesBimap::relation> //
|
||||
(Phenomenon::AshfallLand, "Ashfall (land)") //
|
||||
(Phenomenon::AirStagnation, "Air Stagnation") //
|
||||
(Phenomenon::BeachHazard, "Beach Hazard") //
|
||||
(Phenomenon::BriskWind, "Brisk Wind") //
|
||||
(Phenomenon::Blizzard, "Blizzard") //
|
||||
(Phenomenon::CoastalFlood, "Coastal Flood") //
|
||||
(Phenomenon::DebrisFlow, "Debris Flow") //
|
||||
(Phenomenon::DustStorm, "Dust Storm") //
|
||||
(Phenomenon::BlowingDust, "Blowing Dust") //
|
||||
(Phenomenon::ExtremeCold, "Extreme Cold") //
|
||||
(Phenomenon::ExcessiveHeat, "Excessive Heat") //
|
||||
(Phenomenon::ExtremeWind, "Extreme Wind") //
|
||||
(Phenomenon::Flood, "Flood") //
|
||||
(Phenomenon::FlashFlood, "Flash Flood") //
|
||||
(Phenomenon::DenseFogLand, "Dense Fog (land)") //
|
||||
(Phenomenon::Flood, "Flood (Forecast Points)") //
|
||||
(Phenomenon::Frost, "Frost") //
|
||||
(Phenomenon::FireWeather, "Fire Weather") //
|
||||
(Phenomenon::Freeze, "Freeze") //
|
||||
(Phenomenon::Gale, "Gale") //
|
||||
(Phenomenon::HurricaneForceWind, "Hurricane Force Wind") //
|
||||
(Phenomenon::Heat, "Heat") //
|
||||
(Phenomenon::Hurricane, "Hurricane") //
|
||||
(Phenomenon::HighWind, "High Wind") //
|
||||
(Phenomenon::Hydrologic, "Hydrologic") //
|
||||
(Phenomenon::HardFreeze, "Hard Freeze") //
|
||||
(Phenomenon::IceStorm, "Ice Storm") //
|
||||
(Phenomenon::LakeEffectSnow, "Lake Effect Snow") //
|
||||
(Phenomenon::LowWater, "Low Water") //
|
||||
(Phenomenon::LakeshoreFlood, "Lakeshore Flood") //
|
||||
(Phenomenon::LakeWind, "Lake Wind") //
|
||||
(Phenomenon::Marine, "Marine") //
|
||||
(Phenomenon::DenseFogMarine, "Dense Fog (marine)") //
|
||||
(Phenomenon::AshfallMarine, "Ashfall (marine)") //
|
||||
(Phenomenon::DenseSmokeMarine, "Dense Smoke (marine)") //
|
||||
(Phenomenon::RipCurrentRisk, "Rip Current Risk") //
|
||||
(Phenomenon::SmallCraft, "Small Craft") //
|
||||
(Phenomenon::HazardousSeas, "Hazardous Seas") //
|
||||
(Phenomenon::DenseSmokeLand, "Dense Smoke (land)") //
|
||||
(Phenomenon::Storm, "Storm") //
|
||||
(Phenomenon::StormSurge, "Storm Surge") //
|
||||
(Phenomenon::SnowSquall, "Snow Squall") //
|
||||
(Phenomenon::HighSurf, "High Surf") //
|
||||
(Phenomenon::SevereThunderstorm, "Severe Thunderstorm") //
|
||||
(Phenomenon::Tornado, "Tornado") //
|
||||
(Phenomenon::TropicalStorm, "Tropical Storm") //
|
||||
(Phenomenon::Tsunami, "Tsunami") //
|
||||
(Phenomenon::Typhoon, "Typhoon") //
|
||||
(Phenomenon::HeavyFreezingSpray, "Heavy Freezing Spray") //
|
||||
(Phenomenon::WindChill, "Wind Chill") //
|
||||
(Phenomenon::Wind, "Wind") //
|
||||
(Phenomenon::WinterStorm, "Winter Storm") //
|
||||
(Phenomenon::WinterWeather, "Winter Weather") //
|
||||
(Phenomenon::FreezingFog, "Freezing Fog") //
|
||||
(Phenomenon::FreezingRain, "Freezing Rain") //
|
||||
(Phenomenon::FreezingSpray, "Freezing Spray") //
|
||||
(Phenomenon::Unknown, "Unknown");
|
||||
|
||||
Phenomenon GetPhenomenon(const std::string& code)
|
||||
{
|
||||
|
|
@ -154,6 +155,24 @@ Phenomenon GetPhenomenon(const std::string& code)
|
|||
return phenomenon;
|
||||
}
|
||||
|
||||
Phenomenon GetPhenomenonFromText(const std::string& text)
|
||||
{
|
||||
Phenomenon phenomenon;
|
||||
|
||||
if (phenomenonText_.right.find(text) != phenomenonText_.right.end())
|
||||
{
|
||||
phenomenon = phenomenonText_.right.at(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
phenomenon = Phenomenon::Unknown;
|
||||
|
||||
logger_->debug("Unrecognized code: \"{}\"", text);
|
||||
}
|
||||
|
||||
return phenomenon;
|
||||
}
|
||||
|
||||
const std::string& GetPhenomenonCode(Phenomenon phenomenon)
|
||||
{
|
||||
return phenomenonCodes_.left.at(phenomenon);
|
||||
|
|
@ -161,7 +180,7 @@ const std::string& GetPhenomenonCode(Phenomenon phenomenon)
|
|||
|
||||
const std::string& GetPhenomenonText(Phenomenon phenomenon)
|
||||
{
|
||||
return phenomenonText_.at(phenomenon);
|
||||
return phenomenonText_.left.at(phenomenon);
|
||||
}
|
||||
|
||||
} // namespace awips
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue