From 9e3b2916e15696ddf6924186f04434920fece80b Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Mon, 15 Jan 2024 00:22:40 -0600 Subject: [PATCH] Add select Map Layers to View menu --- scwx-qt/source/scwx/qt/main/main_window.cpp | 95 ++++++++++++++++++++ scwx-qt/source/scwx/qt/main/main_window.hpp | 3 + scwx-qt/source/scwx/qt/main/main_window.ui | 36 +++++++- scwx-qt/source/scwx/qt/model/layer_model.cpp | 53 +++++++++++ scwx-qt/source/scwx/qt/model/layer_model.hpp | 9 ++ scwx-qt/source/scwx/qt/ui/layer_dialog.cpp | 8 +- 6 files changed, 199 insertions(+), 5 deletions(-) diff --git a/scwx-qt/source/scwx/qt/main/main_window.cpp b/scwx-qt/source/scwx/qt/main/main_window.cpp index f1b649a7..41f6fdbe 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.cpp +++ b/scwx-qt/source/scwx/qt/main/main_window.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,8 @@ #include #include +#include + #include #include #include @@ -142,6 +145,7 @@ class MainWindowImpl : public QObject void ConnectMapSignals(); void ConnectOtherSignals(); void HandleFocusChange(QWidget* focused); + void InitializeLayerDisplayActions(); void PopulateMapStyles(); void SelectElevation(map::MapWidget* mapWidget, float elevation); void SelectRadarProduct(map::MapWidget* mapWidget, @@ -197,11 +201,17 @@ class MainWindowImpl : public QObject std::shared_ptr timelineManager_; std::shared_ptr updateManager_; + std::shared_ptr layerModel_ { + model::LayerModel::Instance()}; std::shared_ptr radarSiteModel_ { model::RadarSiteModel::Instance()}; std::map> radarSitePresetsActions_ {}; QMenu* radarSitePresetsMenu_ {nullptr}; + std::set> + layerActions_ {}; + bool layerActionsInitialized_ {false}; + std::vector maps_; std::chrono::system_clock::time_point volumeTime_ {}; @@ -221,6 +231,8 @@ MainWindow::MainWindow(QWidget* parent) : { ui->setupUi(this); + p->InitializeLayerDisplayActions(); + // Assign the bottom left corner to the left dock widget setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); @@ -494,6 +506,26 @@ void MainWindow::on_actionExit_triggered() close(); } +void MainWindow::on_actionColorTable_triggered(bool checked) +{ + p->layerModel_->SetLayerDisplayed(types::LayerType::Information, + types::InformationLayer::ColorTable, + checked); +} + +void MainWindow::on_actionRadarRange_triggered(bool checked) +{ + p->layerModel_->SetLayerDisplayed( + types::LayerType::Data, types::DataLayer::RadarRange, checked); +} + +void MainWindow::on_actionRadarSites_triggered(bool checked) +{ + p->layerModel_->SetLayerDisplayed(types::LayerType::Information, + types::InformationLayer::RadarSite, + checked); +} + void MainWindow::on_actionPlacefileManager_triggered() { p->placefileDialog_->show(); @@ -989,6 +1021,39 @@ void MainWindowImpl::ConnectOtherSignals() &MainWindow::ActiveMapMoved, radarSiteDialog_, &ui::RadarSiteDialog::HandleMapUpdate); + connect(layerModel_.get(), + &model::LayerModel::LayerDisplayChanged, + this, + [this](types::LayerInfo layer) + { + // Find matching layer action + auto it = + std::find_if(layerActions_.begin(), + layerActions_.end(), + [&](const auto& layerAction) + { + const auto& [type, description, action] = + layerAction; + return layer.type_ == type && + layer.description_ == description; + }); + + // If matching layer action was found + if (it != layerActions_.end()) + { + // Check the action if the layer is displayed on any map + bool anyDisplayed = std::find(layer.displayed_.begin(), + layer.displayed_.end(), + true) != layer.displayed_.end(); + + auto& action = std::get<2>(*it); + action->setChecked(anyDisplayed); + } + }); + connect(layerModel_.get(), + &QAbstractItemModel::modelReset, + this, + [this]() { InitializeLayerDisplayActions(); }); connect(radarSiteDialog_, &ui::RadarSiteDialog::accepted, this, @@ -1046,6 +1111,36 @@ void MainWindowImpl::ConnectOtherSignals() clockTimer_.start(1000); } +void MainWindowImpl::InitializeLayerDisplayActions() +{ + if (!layerActionsInitialized_) + { + layerActions_.emplace(types::LayerType::Information, + types::InformationLayer::ColorTable, + mainWindow_->ui->actionColorTable); + layerActions_.emplace(types::LayerType::Information, + types::InformationLayer::RadarSite, + mainWindow_->ui->actionRadarSites); + layerActions_.emplace(types::LayerType::Data, + types::DataLayer::RadarRange, + mainWindow_->ui->actionRadarRange); + layerActionsInitialized_ = true; + } + + for (auto& layerAction : layerActions_) + { + auto& [type, description, action] = layerAction; + + types::LayerInfo layer = layerModel_->GetLayerInfo(type, description); + + bool anyDisplayed = + std::find(layer.displayed_.begin(), layer.displayed_.end(), true) != + layer.displayed_.end(); + + action->setChecked(anyDisplayed); + } +} + void MainWindowImpl::AddRadarSitePreset(const std::string& siteId) { auto radarSite = config::RadarSite::Get(siteId); diff --git a/scwx-qt/source/scwx/qt/main/main_window.hpp b/scwx-qt/source/scwx/qt/main/main_window.hpp index 0ba8f41a..21592538 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.hpp +++ b/scwx-qt/source/scwx/qt/main/main_window.hpp @@ -36,6 +36,9 @@ private slots: void on_actionOpenTextEvent_triggered(); void on_actionSettings_triggered(); void on_actionExit_triggered(); + void on_actionColorTable_triggered(bool checked); + void on_actionRadarRange_triggered(bool checked); + void on_actionRadarSites_triggered(bool checked); void on_actionPlacefileManager_triggered(); void on_actionLayerManager_triggered(); void on_actionImGuiDebug_triggered(); diff --git a/scwx-qt/source/scwx/qt/main/main_window.ui b/scwx-qt/source/scwx/qt/main/main_window.ui index 4bd9b09c..aeb4517f 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.ui +++ b/scwx-qt/source/scwx/qt/main/main_window.ui @@ -75,8 +75,18 @@ &View + + + &Map Layers + + + + + + + @@ -166,7 +176,7 @@ QFrame::Raised - + @@ -447,6 +457,30 @@ Dump &Layer List + + + true + + + Radar &Range + + + + + true + + + &Color Table + + + + + true + + + Radar &Sites + + diff --git a/scwx-qt/source/scwx/qt/model/layer_model.cpp b/scwx-qt/source/scwx/qt/model/layer_model.cpp index 0e545d96..9678b06b 100644 --- a/scwx-qt/source/scwx/qt/model/layer_model.cpp +++ b/scwx-qt/source/scwx/qt/model/layer_model.cpp @@ -395,11 +395,63 @@ void LayerModel::Impl::WriteLayerSettings() util::json::WriteJsonFile(layerSettingsPath_, layerJson); } +types::LayerInfo +LayerModel::GetLayerInfo(types::LayerType type, + types::LayerDescription description) const +{ + // Find the matching layer + auto it = std::find_if(p->layers_.begin(), + p->layers_.end(), + [&](const types::LayerInfo& layer) { + return layer.type_ == type && + layer.description_ == description; + }); + if (it != p->layers_.end()) + { + // Return the layer info + return *it; + } + + return {}; +} + types::LayerVector LayerModel::GetLayers() const { return p->layers_; } +void LayerModel::SetLayerDisplayed(types::LayerType type, + types::LayerDescription description, + bool displayed) +{ + // Find the matching layer + auto it = std::find_if(p->layers_.begin(), + p->layers_.end(), + [&](const types::LayerInfo& layer) { + return layer.type_ == type && + layer.description_ == description; + }); + + if (it != p->layers_.end()) + { + // Find the row + const int row = std::distance(p->layers_.begin(), it); + QModelIndex topLeft = + createIndex(row, static_cast(Column::DisplayMap1)); + QModelIndex bottomRight = + createIndex(row, static_cast(Column::DisplayMap4)); + + // Set the layer to displayed + for (std::size_t i = 0; i < kMapCount_; ++i) + { + it->displayed_[i] = displayed; + } + + // Notify observers + Q_EMIT dataChanged(topLeft, bottomRight); + } +} + void LayerModel::ResetLayers() { // Initialize a new layer vector from the default @@ -751,6 +803,7 @@ bool LayerModel::setData(const QModelIndex& index, if (result) { Q_EMIT dataChanged(index, index); + Q_EMIT LayerDisplayChanged(layer); } return result; diff --git a/scwx-qt/source/scwx/qt/model/layer_model.hpp b/scwx-qt/source/scwx/qt/model/layer_model.hpp index 426615c7..305c0987 100644 --- a/scwx-qt/source/scwx/qt/model/layer_model.hpp +++ b/scwx-qt/source/scwx/qt/model/layer_model.hpp @@ -16,6 +16,7 @@ namespace model class LayerModel : public QAbstractTableModel { + Q_OBJECT Q_DISABLE_COPY_MOVE(LayerModel) public: @@ -36,7 +37,12 @@ class LayerModel : public QAbstractTableModel explicit LayerModel(QObject* parent = nullptr); ~LayerModel(); + types::LayerInfo GetLayerInfo(types::LayerType type, + types::LayerDescription description) const; types::LayerVector GetLayers() const; + void SetLayerDisplayed(types::LayerType type, + types::LayerDescription description, + bool displayed); void ResetLayers(); @@ -77,6 +83,9 @@ class LayerModel : public QAbstractTableModel static std::shared_ptr Instance(); +signals: + void LayerDisplayChanged(types::LayerInfo layer); + private: class Impl; std::unique_ptr p; diff --git a/scwx-qt/source/scwx/qt/ui/layer_dialog.cpp b/scwx-qt/source/scwx/qt/ui/layer_dialog.cpp index 3eec56f1..3fc02859 100644 --- a/scwx-qt/source/scwx/qt/ui/layer_dialog.cpp +++ b/scwx-qt/source/scwx/qt/ui/layer_dialog.cpp @@ -37,8 +37,8 @@ class LayerDialogImpl void UpdateMapDisplayColumns(); void UpdateMoveButtonsEnabled(); - std::vector GetSelectedRows(); - std::vector> GetContiguousRows(); + std::vector GetSelectedRows() const; + std::vector> GetContiguousRows() const; LayerDialog* self_; std::shared_ptr layerModel_; @@ -247,7 +247,7 @@ void LayerDialogImpl::ConnectSignals() }); } -std::vector LayerDialogImpl::GetSelectedRows() +std::vector LayerDialogImpl::GetSelectedRows() const { QModelIndexList selectedRows = self_->ui->layerTreeView->selectionModel()->selectedRows(); @@ -260,7 +260,7 @@ std::vector LayerDialogImpl::GetSelectedRows() return rows; } -std::vector> LayerDialogImpl::GetContiguousRows() +std::vector> LayerDialogImpl::GetContiguousRows() const { std::vector> contiguousRows {}; std::vector currentContiguousRows {};