diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index a8f7911e..2c21cbf6 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -96,8 +96,10 @@ set(SRC_SETTINGS source/scwx/qt/settings/general_settings.cpp source/scwx/qt/settings/palette_settings.cpp) set(HDR_TYPES source/scwx/qt/types/radar_product_record.hpp) set(SRC_TYPES source/scwx/qt/types/radar_product_record.cpp) -set(HDR_UI source/scwx/qt/ui/flow_layout.hpp) -set(SRC_UI source/scwx/qt/ui/flow_layout.cpp) +set(HDR_UI source/scwx/qt/ui/flow_layout.hpp + source/scwx/qt/ui/level2_products_widget.hpp) +set(SRC_UI source/scwx/qt/ui/flow_layout.cpp + source/scwx/qt/ui/level2_products_widget.cpp) set(HDR_UTIL source/scwx/qt/util/font.hpp source/scwx/qt/util/font_buffer.hpp source/scwx/qt/util/json.hpp) diff --git a/scwx-qt/source/scwx/qt/main/main_window.cpp b/scwx-qt/source/scwx/qt/main/main_window.cpp index 9f3fdc04..95179c68 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.cpp +++ b/scwx-qt/source/scwx/qt/main/main_window.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ public: mainWindow_ {mainWindow}, settings_ {}, activeMap_ {nullptr}, + level2ProductsWidget_ {nullptr}, maps_ {}, elevationCuts_ {}, elevationButtonsChanged_ {false}, @@ -70,13 +72,13 @@ public: void ConfigureMapLayout(); void HandleFocusChange(QWidget* focused); void NormalizeElevationButtons(); - void NormalizeLevel2ProductButtons(); void SelectElevation(map::MapWidget* mapWidget, float elevation); - void SelectRadarProduct(map::MapWidget* mapWidget, - common::Level2Product product); + void SelectRadarProduct(map::MapWidget* mapWidget, + common::RadarProductGroup group, + const std::string& productName, + int16_t productCode); void SetActiveMap(map::MapWidget* mapWidget); void UpdateElevationSelection(float elevation); - void UpdateLevel2ProductSelection(common::Level2Product product); void UpdateRadarProductSelection(common::RadarProductGroup group, const std::string& product); void UpdateRadarProductSettings(); @@ -87,6 +89,8 @@ public: QMapboxGLSettings settings_; map::MapWidget* activeMap_; + ui::Level2ProductsWidget* level2ProductsWidget_; + std::vector maps_; std::vector elevationCuts_; @@ -115,24 +119,11 @@ MainWindow::MainWindow(QWidget* parent) : p->ConfigureMapLayout(); // Add Level 2 Products - QLayout* level2Layout = new ui::FlowLayout(); - level2Layout->setContentsMargins(0, 0, 0, 0); - ui->level2ProductFrame->setLayout(level2Layout); - - for (common::Level2Product product : common::Level2ProductIterator()) - { - QToolButton* toolButton = new QToolButton(); - toolButton->setText( - QString::fromStdString(common::GetLevel2Name(product))); - toolButton->setStatusTip( - tr(common::GetLevel2Description(product).c_str())); - level2Layout->addWidget(toolButton); - - connect(toolButton, - &QToolButton::clicked, - this, - [=]() { p->SelectRadarProduct(p->activeMap_, product); }); - } + p->level2ProductsWidget_ = new ui::Level2ProductsWidget(this); + ui->radarProductGroupBox->layout()->replaceWidget(ui->level2ProductFrame, + p->level2ProductsWidget_); + delete ui->level2ProductFrame; + ui->level2ProductFrame = p->level2ProductsWidget_; QLayout* elevationLayout = new ui::FlowLayout(); ui->elevationGroupBox->setLayout(elevationLayout); @@ -140,26 +131,43 @@ MainWindow::MainWindow(QWidget* parent) : ui->settingsGroupBox->setVisible(false); ui->declutterCheckbox->setVisible(false); - p->SelectRadarProduct(p->activeMap_, common::Level2Product::Reflectivity); + p->SelectRadarProduct( + p->maps_.at(0), + common::RadarProductGroup::Level2, + common::GetLevel2Name(common::Level2Product::Reflectivity), + 0); if (p->maps_.size() > 1 && p->maps_.at(1) != nullptr) { - p->SelectRadarProduct(p->maps_.at(1), common::Level2Product::Velocity); + p->SelectRadarProduct( + p->maps_.at(1), + common::RadarProductGroup::Level2, + common::GetLevel2Name(common::Level2Product::Velocity), + 0); } if (p->maps_.size() > 2 && p->maps_.at(2) != nullptr) { - p->maps_.at(2)->SelectRadarProduct( - common::RadarProductGroup::Level3, "N0B", 153); + p->SelectRadarProduct( + p->maps_.at(2), common::RadarProductGroup::Level3, "N0B", 153); } if (p->maps_.size() > 3 && p->maps_.at(3) != nullptr) { - p->maps_.at(3)->SelectRadarProduct( - common::RadarProductGroup::Level3, "N0G", 154); + p->SelectRadarProduct( + p->maps_.at(3), common::RadarProductGroup::Level3, "N0G", 154); } connect(qApp, &QApplication::focusChanged, this, [=](QWidget* old, QWidget* now) { p->HandleFocusChange(now); }); + connect(p->level2ProductsWidget_, + &ui::Level2ProductsWidget::RadarProductSelected, + this, + [&](common::RadarProductGroup group, + const std::string& productName, + int16_t productCode) { + p->SelectRadarProduct( + p->activeMap_, group, productName, productCode); + }); p->HandleFocusChange(p->activeMap_); } @@ -190,35 +198,11 @@ void MainWindow::showEvent(QShowEvent* event) { QMainWindow::showEvent(event); - p->NormalizeLevel2ProductButtons(); p->NormalizeElevationButtons(); resizeDocks({ui->radarToolboxDock}, {150}, Qt::Horizontal); } -void MainWindowImpl::NormalizeLevel2ProductButtons() -{ - // Set each level 2 product's tool button to the same size - int level2MaxWidth = 0; - for (QToolButton* widget : - mainWindow_->ui->level2ProductFrame->findChildren()) - { - if (widget->isVisible()) - { - level2MaxWidth = std::max(level2MaxWidth, widget->width()); - } - } - - if (level2MaxWidth > 0) - { - for (QToolButton* widget : - mainWindow_->ui->level2ProductFrame->findChildren()) - { - widget->setMinimumWidth(level2MaxWidth); - } - } -} - void MainWindowImpl::NormalizeElevationButtons() { // Set each elevation cut's tool button to the same size @@ -412,21 +396,23 @@ void MainWindowImpl::SelectElevation(map::MapWidget* mapWidget, float elevation) } } -void MainWindowImpl::SelectRadarProduct(map::MapWidget* mapWidget, - common::Level2Product product) +void MainWindowImpl::SelectRadarProduct(map::MapWidget* mapWidget, + common::RadarProductGroup group, + const std::string& productName, + int16_t productCode) { - const std::string& productName = common::GetLevel2Name(product); - logger_->debug("Selecting Level 2 radar product: {}", productName); + logger_->debug("Selecting radar product: {}, {}", + common::GetRadarProductGroupName(group), + productName); if (mapWidget == activeMap_) { - UpdateLevel2ProductSelection(product); + UpdateRadarProductSelection(group, productName); UpdateRadarProductSettings(); } - mapWidget->SelectRadarProduct( - common::RadarProductGroup::Level2, productName, 0); + mapWidget->SelectRadarProduct(group, productName, productCode); } void MainWindowImpl::SetActiveMap(map::MapWidget* mapWidget) @@ -474,39 +460,10 @@ void MainWindowImpl::UpdateMapParameters( } } -void MainWindowImpl::UpdateLevel2ProductSelection(common::Level2Product product) -{ - const std::string& productName = common::GetLevel2Name(product); - - for (QToolButton* toolButton : - mainWindow_->ui->level2ProductFrame->findChildren()) - { - if (toolButton->text().toStdString() == productName) - { - toolButton->setCheckable(true); - toolButton->setChecked(true); - } - else - { - toolButton->setChecked(false); - toolButton->setCheckable(false); - } - } -} - void MainWindowImpl::UpdateRadarProductSelection( common::RadarProductGroup group, const std::string& product) { - switch (group) - { - case common::RadarProductGroup::Level2: - UpdateLevel2ProductSelection(common::GetLevel2Product(product)); - break; - - default: - UpdateLevel2ProductSelection(common::Level2Product::Unknown); - break; - } + level2ProductsWidget_->UpdateProductSelection(group, product); } void MainWindowImpl::UpdateRadarProductSettings() diff --git a/scwx-qt/source/scwx/qt/main/main_window.ui b/scwx-qt/source/scwx/qt/main/main_window.ui index f32827dd..31615fe3 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.ui +++ b/scwx-qt/source/scwx/qt/main/main_window.ui @@ -163,16 +163,6 @@ - - - - QFrame::StyledPanel - - - QFrame::Raised - - - diff --git a/scwx-qt/source/scwx/qt/ui/level2_products_widget.cpp b/scwx-qt/source/scwx/qt/ui/level2_products_widget.cpp new file mode 100644 index 00000000..31a3750e --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/level2_products_widget.cpp @@ -0,0 +1,144 @@ +#include +#include +#include + +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +static const std::string logPrefix_ = "scwx::qt::ui::level2_products_widget"; +static const auto logger_ = util::Logger::Create(logPrefix_); + +class Level2ProductsWidgetImpl : public QObject +{ + Q_OBJECT + +public: + explicit Level2ProductsWidgetImpl(Level2ProductsWidget* self) : + self_ {self}, layout_ {new ui::FlowLayout(self)}, productButtons_ {} + { + layout_->setContentsMargins(0, 0, 0, 0); + + for (common::Level2Product product : common::Level2ProductIterator()) + { + QToolButton* toolButton = new QToolButton(); + toolButton->setText( + QString::fromStdString(common::GetLevel2Name(product))); + toolButton->setStatusTip( + tr(common::GetLevel2Description(product).c_str())); + layout_->addWidget(toolButton); + productButtons_.push_back(toolButton); + + QObject::connect(toolButton, + &QToolButton::clicked, + this, + [=]() { SelectProduct(product); }); + } + } + ~Level2ProductsWidgetImpl() = default; + + void NormalizeProductButtons(); + void SelectProduct(common::Level2Product product); + void UpdateProductSelection(common::Level2Product product); + + Level2ProductsWidget* self_; + QLayout* layout_; + std::list productButtons_; +}; + +Level2ProductsWidget::Level2ProductsWidget(QWidget* parent) : + QWidget(parent), p {std::make_shared(this)} +{ +} + +Level2ProductsWidget::~Level2ProductsWidget() = default; + +void Level2ProductsWidget::showEvent(QShowEvent* event) +{ + QWidget::showEvent(event); + + p->NormalizeProductButtons(); +} + +void Level2ProductsWidgetImpl::NormalizeProductButtons() +{ + int level2MaxWidth = 0; + + // Set each level 2 product's tool button to the same size + std::for_each(productButtons_.cbegin(), + productButtons_.cend(), + [&](auto& toolButton) + { + if (toolButton->isVisible()) + { + level2MaxWidth = + std::max(level2MaxWidth, toolButton->width()); + } + }); + + if (level2MaxWidth > 0) + { + std::for_each(productButtons_.cbegin(), + productButtons_.cend(), + [&](auto& toolButton) + { toolButton->setMinimumWidth(level2MaxWidth); }); + } +} + +void Level2ProductsWidgetImpl::SelectProduct(common::Level2Product product) +{ + UpdateProductSelection(product); + + emit self_->RadarProductSelected( + common::RadarProductGroup::Level2, common::GetLevel2Name(product), 0); +} + +void Level2ProductsWidget::UpdateProductSelection( + common::RadarProductGroup group, const std::string& productName) +{ + if (group == common::RadarProductGroup::Level2) + { + common::Level2Product product = common::GetLevel2Product(productName); + p->UpdateProductSelection(product); + } + else + { + p->UpdateProductSelection(common::Level2Product::Unknown); + } +} + +void Level2ProductsWidgetImpl::UpdateProductSelection( + common::Level2Product product) +{ + const std::string& productName = common::GetLevel2Name(product); + + std::for_each(std::execution::par_unseq, + productButtons_.cbegin(), + productButtons_.cend(), + [&](auto& toolButton) + { + if (toolButton->text().toStdString() == productName) + { + toolButton->setCheckable(true); + toolButton->setChecked(true); + } + else + { + toolButton->setChecked(false); + toolButton->setCheckable(false); + } + }); +} + +} // namespace ui +} // namespace qt +} // namespace scwx + +#include "level2_products_widget.moc" diff --git a/scwx-qt/source/scwx/qt/ui/level2_products_widget.hpp b/scwx-qt/source/scwx/qt/ui/level2_products_widget.hpp new file mode 100644 index 00000000..b6b4c010 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/level2_products_widget.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +class Level2ProductsWidgetImpl; + +class Level2ProductsWidget : public QWidget +{ + Q_OBJECT + +public: + explicit Level2ProductsWidget(QWidget* parent = nullptr); + ~Level2ProductsWidget(); + + void showEvent(QShowEvent* event) override; + + void UpdateProductSelection(common::RadarProductGroup group, + const std::string& productName); + +signals: + void RadarProductSelected(common::RadarProductGroup group, + const std::string& productName, + int16_t productCode); + +private: + std::shared_ptr p; +}; + +} // namespace ui +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/ts/scwx_en_US.ts b/scwx-qt/ts/scwx_en_US.ts index ce5a0a17..0b5df9ab 100644 --- a/scwx-qt/ts/scwx_en_US.ts +++ b/scwx-qt/ts/scwx_en_US.ts @@ -14,17 +14,17 @@ - + Level 3 - + Settings - + Declutter @@ -74,27 +74,27 @@ - + Elevation - + E&xit - + About &Supercell Wx... - + &Open... - + Ctrl+O @@ -102,7 +102,7 @@ scwx::qt::main::MainWindow - + Unrecognized NEXRAD Product: