diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake index c36cdeb9..1f2577bb 100644 --- a/scwx-qt/scwx-qt.cmake +++ b/scwx-qt/scwx-qt.cmake @@ -106,17 +106,20 @@ set(HDR_TYPES source/scwx/qt/types/qt_types.hpp source/scwx/qt/types/text_event_key.hpp) set(SRC_TYPES source/scwx/qt/types/radar_product_record.cpp source/scwx/qt/types/text_event_key.cpp) -set(HDR_UI source/scwx/qt/ui/flow_layout.hpp +set(HDR_UI source/scwx/qt/ui/alert_dock_widget.hpp + source/scwx/qt/ui/flow_layout.hpp source/scwx/qt/ui/level2_products_widget.hpp source/scwx/qt/ui/level2_settings_widget.hpp source/scwx/qt/ui/level3_products_widget.hpp source/scwx/qt/ui/radar_site_dialog.hpp) -set(SRC_UI source/scwx/qt/ui/flow_layout.cpp +set(SRC_UI source/scwx/qt/ui/alert_dock_widget.cpp + source/scwx/qt/ui/flow_layout.cpp source/scwx/qt/ui/level2_products_widget.cpp source/scwx/qt/ui/level2_settings_widget.cpp source/scwx/qt/ui/level3_products_widget.cpp source/scwx/qt/ui/radar_site_dialog.cpp) -set(UI_UI source/scwx/qt/ui/radar_site_dialog.ui) +set(UI_UI source/scwx/qt/ui/alert_dock_widget.ui + source/scwx/qt/ui/radar_site_dialog.ui) 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 54573647..ad69cdbd 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.cpp +++ b/scwx-qt/source/scwx/qt/main/main_window.cpp @@ -7,9 +7,8 @@ #include #include #include -#include #include -#include +#include #include #include #include @@ -22,7 +21,6 @@ #include #include -#include #include #include #include @@ -48,9 +46,8 @@ public: activeMap_ {nullptr}, level2ProductsWidget_ {nullptr}, level2SettingsWidget_ {nullptr}, + alertDockWidget_ {nullptr}, radarSiteDialog_ {nullptr}, - alertModel_ {std::make_unique()}, - alertProxyModel_ {std::make_unique()}, radarProductModel_ {nullptr}, maps_ {}, elevationCuts_ {}, @@ -79,15 +76,11 @@ public: settings_.setApiKey(QString {mapboxApiKey.c_str()}); settings_.setCacheDatabasePath(QString {cacheDbPath.c_str()}); settings_.setCacheDatabaseMaximumSize(20 * 1024 * 1024); - - alertProxyModel_->setSourceModel(alertModel_.get()); - alertProxyModel_->setSortRole(types::SortRole); - alertProxyModel_->setFilterCaseSensitivity(Qt::CaseInsensitive); - alertProxyModel_->setFilterKeyColumn(-1); } ~MainWindowImpl() = default; void ConfigureMapLayout(); + void ConnectAlertSignals(); void ConnectMapSignals(); void ConnectOtherSignals(); void HandleFocusChange(QWidget* focused); @@ -114,10 +107,9 @@ public: ui::Level3ProductsWidget* level3ProductsWidget_; + ui::AlertDockWidget* alertDockWidget_; ui::RadarSiteDialog* radarSiteDialog_; - std::unique_ptr alertModel_; - std::unique_ptr alertProxyModel_; std::unique_ptr radarProductModel_; std::vector maps_; @@ -148,6 +140,11 @@ MainWindow::MainWindow(QWidget* parent) : ui->vcpValueLabel->setVisible(false); ui->vcpDescriptionLabel->setVisible(false); + // Configure Alert Dock + p->alertDockWidget_ = new ui::AlertDockWidget(this); + p->alertDockWidget_->setVisible(false); + addDockWidget(Qt::BottomDockWidgetArea, p->alertDockWidget_); + // Configure Menu ui->menuView->insertAction(ui->actionRadarToolbox, ui->radarToolboxDock->toggleViewAction()); @@ -161,8 +158,8 @@ MainWindow::MainWindow(QWidget* parent) : ui->actionResourceExplorer->setVisible(false); ui->menuView->insertAction(ui->actionAlerts, - ui->alertDock->toggleViewAction()); - ui->alertDock->toggleViewAction()->setText(tr("&Alerts")); + p->alertDockWidget_->toggleViewAction()); + p->alertDockWidget_->toggleViewAction()->setText(tr("&Alerts")); ui->actionAlerts->setVisible(false); // Configure Resource Explorer Dock @@ -171,13 +168,6 @@ MainWindow::MainWindow(QWidget* parent) : p->radarProductModel_ = std::make_unique(); ui->resourceTreeView->setModel(p->radarProductModel_->model()); - // Configure Alert Dock - ui->alertDock->setVisible(false); - - ui->alertView->setModel(p->alertProxyModel_.get()); - - ui->alertSettings->addAction(ui->actionActiveAlerts); - // Configure Map p->ConfigureMapLayout(); @@ -475,19 +465,10 @@ void MainWindowImpl::ConnectOtherSignals() &ui::Level2SettingsWidget::ElevationSelected, mainWindow_, [&](float elevation) { SelectElevation(activeMap_, elevation); }); - connect(mainWindow_->ui->alertFilter, - &QLineEdit::textChanged, - alertProxyModel_.get(), - &QSortFilterProxyModel::setFilterWildcard); connect(mainWindow_, &MainWindow::ActiveMapMoved, - alertModel_.get(), - &model::AlertModel::HandleMapUpdate, - Qt::QueuedConnection); - connect(&manager::TextEventManager::Instance(), - &manager::TextEventManager::AlertUpdated, - alertModel_.get(), - &model::AlertModel::HandleAlert, + alertDockWidget_, + &ui::AlertDockWidget::HandleMapUpdate, Qt::QueuedConnection); connect(mainWindow_, &MainWindow::ActiveMapMoved, diff --git a/scwx-qt/source/scwx/qt/main/main_window.ui b/scwx-qt/source/scwx/qt/main/main_window.ui index df7dac09..61159a56 100644 --- a/scwx-qt/source/scwx/qt/main/main_window.ui +++ b/scwx-qt/source/scwx/qt/main/main_window.ui @@ -307,95 +307,6 @@ - - - Alerts - - - 8 - - - - - - - true - - - 0 - - - true - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Filter - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Settings - - - ... - - - - :/res/icons/font-awesome-6/sliders-solid.svg:/res/icons/font-awesome-6/sliders-solid.svg - - - QToolButton::InstantPopup - - - - - - - - - E&xit @@ -431,14 +342,6 @@ &Alerts - - - true - - - &Active Alerts - - diff --git a/scwx-qt/source/scwx/qt/ui/alert_dock_widget.cpp b/scwx-qt/source/scwx/qt/ui/alert_dock_widget.cpp new file mode 100644 index 00000000..21c35098 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/alert_dock_widget.cpp @@ -0,0 +1,139 @@ +#include "alert_dock_widget.hpp" +#include "ui_alert_dock_widget.h" + +#include +#include +#include +#include + +#include + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +static const std::string logPrefix_ = "scwx::qt::ui::alert_dock_widget"; +static const auto logger_ = scwx::util::Logger::Create(logPrefix_); + +class AlertDockWidgetImpl : QObject +{ + Q_OBJECT +public: + explicit AlertDockWidgetImpl(AlertDockWidget* self) : + self_ {self}, + alertModel_ {std::make_unique()}, + proxyModel_ {std::make_unique()}, + mapPosition_ {}, + mapUpdateDeferred_ {false} + { + proxyModel_->setSourceModel(alertModel_.get()); + proxyModel_->setSortRole(types::SortRole); + proxyModel_->setFilterCaseSensitivity(Qt::CaseInsensitive); + proxyModel_->setFilterKeyColumn(-1); + } + ~AlertDockWidgetImpl() = default; + + void ConnectSignals(); + + AlertDockWidget* self_; + std::unique_ptr alertModel_; + std::unique_ptr proxyModel_; + + scwx::common::Coordinate mapPosition_; + bool mapUpdateDeferred_; +}; + +AlertDockWidget::AlertDockWidget(QWidget* parent) : + QDockWidget(parent), + p {std::make_unique(this)}, + ui(new Ui::AlertDockWidget) +{ + ui->setupUi(this); + + ui->alertView->setModel(p->proxyModel_.get()); + + ui->alertSettings->addAction(ui->actionActiveAlerts); + + p->ConnectSignals(); +} + +AlertDockWidget::~AlertDockWidget() +{ + delete ui; +} + +void AlertDockWidget::showEvent(QShowEvent* event) +{ + if (p->mapUpdateDeferred_) + { + p->alertModel_->HandleMapUpdate(p->mapPosition_.latitude_, + p->mapPosition_.longitude_); + p->mapUpdateDeferred_ = false; + } + + QDockWidget::showEvent(event); +} + +void AlertDockWidget::HandleMapUpdate(double latitude, double longitude) +{ + p->mapPosition_ = {latitude, longitude}; + + if (isVisible()) + { + p->alertModel_->HandleMapUpdate(latitude, longitude); + } + else + { + p->mapUpdateDeferred_ = true; + } +} + +void AlertDockWidgetImpl::ConnectSignals() +{ + connect(self_->ui->alertFilter, + &QLineEdit::textChanged, + proxyModel_.get(), + &QSortFilterProxyModel::setFilterWildcard); + connect(&manager::TextEventManager::Instance(), + &manager::TextEventManager::AlertUpdated, + alertModel_.get(), + &model::AlertModel::HandleAlert, + Qt::QueuedConnection); + connect(self_->ui->alertView->selectionModel(), + &QItemSelectionModel::selectionChanged, + 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; + } + }); + connect(self_->ui->alertViewButton, + &QPushButton::clicked, + this, + []() + { + // TODO: View alert + }); + connect(self_->ui->alertGoButton, + &QPushButton::clicked, + this, + []() + { + // TODO: Go to alert + }); +} + +#include "alert_dock_widget.moc" + +} // namespace ui +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/alert_dock_widget.hpp b/scwx-qt/source/scwx/qt/ui/alert_dock_widget.hpp new file mode 100644 index 00000000..f99df345 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/alert_dock_widget.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include + +namespace Ui +{ +class AlertDockWidget; +} + +namespace scwx +{ +namespace qt +{ +namespace ui +{ + +class AlertDockWidgetImpl; + +class AlertDockWidget : public QDockWidget +{ + Q_OBJECT + +public: + explicit AlertDockWidget(QWidget* parent = nullptr); + ~AlertDockWidget(); + +protected: + void showEvent(QShowEvent*) override; + +public slots: + void HandleMapUpdate(double latitude, double longitude); + +private: + friend class AlertDockWidgetImpl; + std::unique_ptr p; + Ui::AlertDockWidget* ui; +}; + +} // namespace ui +} // namespace qt +} // namespace scwx diff --git a/scwx-qt/source/scwx/qt/ui/alert_dock_widget.ui b/scwx-qt/source/scwx/qt/ui/alert_dock_widget.ui new file mode 100644 index 00000000..96328278 --- /dev/null +++ b/scwx-qt/source/scwx/qt/ui/alert_dock_widget.ui @@ -0,0 +1,124 @@ + + + AlertDockWidget + + + + 0 + 0 + 400 + 300 + + + + Alerts + + + + + + + true + + + 0 + + + true + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Filter + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Settings + + + ... + + + + :/res/icons/font-awesome-6/sliders-solid.svg:/res/icons/font-awesome-6/sliders-solid.svg + + + QToolButton::InstantPopup + + + + + + + &View + + + + + + + &Go + + + + + + + + + + + true + + + &Active Alerts + + + + + + + +