From 1e7df9f236b3eef40fd9c987af3661c1c07c9f60 Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sun, 19 Nov 2023 07:56:52 -0600 Subject: [PATCH] Hover over time for additional product information --- scwx-qt/source/scwx/qt/map/overlay_layer.cpp | 54 ++++++++++++++++--- scwx-qt/source/scwx/qt/map/overlay_layer.hpp | 5 ++ .../scwx/qt/view/level3_product_view.cpp | 42 +++++++++++++++ .../scwx/qt/view/level3_product_view.hpp | 3 ++ .../scwx/qt/view/radar_product_view.cpp | 6 +++ .../scwx/qt/view/radar_product_view.hpp | 3 ++ 6 files changed, 107 insertions(+), 6 deletions(-) diff --git a/scwx-qt/source/scwx/qt/map/overlay_layer.cpp b/scwx-qt/source/scwx/qt/map/overlay_layer.cpp index 75526ba6..c0577063 100644 --- a/scwx-qt/source/scwx/qt/map/overlay_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/overlay_layer.cpp @@ -44,9 +44,7 @@ class OverlayLayerImpl public: explicit OverlayLayerImpl(std::shared_ptr context) : activeBoxOuter_ {std::make_shared(context)}, - activeBoxInner_ {std::make_shared(context)}, - sweepTimeString_ {}, - sweepTimeNeedsUpdate_ {true} + activeBoxInner_ {std::make_shared(context)} { } ~OverlayLayerImpl() = default; @@ -54,8 +52,9 @@ public: std::shared_ptr activeBoxOuter_; std::shared_ptr activeBoxInner_; - std::string sweepTimeString_; - bool sweepTimeNeedsUpdate_; + std::string sweepTimeString_ {}; + bool sweepTimeNeedsUpdate_ {true}; + bool sweepTimePicked_ {false}; }; OverlayLayer::OverlayLayer(std::shared_ptr context) : @@ -96,6 +95,8 @@ void OverlayLayer::Render( context()->set_render_parameters(params); + p->sweepTimePicked_ = false; + if (p->sweepTimeNeedsUpdate_ && radarProductView != nullptr) { const scwx::util::time_zone* currentZone; @@ -154,7 +155,38 @@ void OverlayLayer::Render( nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize); - ImGui::TextUnformatted(p->sweepTimeString_.c_str()); + + if (ImGui::IsWindowHovered()) + { + // Show a detailed product description when the sweep time is hovered + p->sweepTimePicked_ = true; + + auto fields = radarProductView->GetDescriptionFields(); + if (fields.empty()) + { + ImGui::TextUnformatted(p->sweepTimeString_.c_str()); + } + else + { + if (ImGui::BeginTable("Description Fields", 2)) + { + for (auto& field : fields) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(field.first.c_str()); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(field.second.c_str()); + } + ImGui::EndTable(); + } + } + } + else + { + ImGui::TextUnformatted(p->sweepTimeString_.c_str()); + } + ImGui::End(); } @@ -178,6 +210,16 @@ void OverlayLayer::Deinitialize() } } +bool OverlayLayer::RunMousePicking( + const QMapLibreGL::CustomLayerRenderParameters& /* params */, + const QPointF& /* mouseLocalPos */, + const QPointF& /* mouseGlobalPos */, + const glm::vec2& /* mouseCoords */) +{ + // If sweep time was picked, don't process additional items + return p->sweepTimePicked_; +} + void OverlayLayer::UpdateSweepTimeNextFrame() { p->sweepTimeNeedsUpdate_ = true; diff --git a/scwx-qt/source/scwx/qt/map/overlay_layer.hpp b/scwx-qt/source/scwx/qt/map/overlay_layer.hpp index edc6ce09..eb5b55ec 100644 --- a/scwx-qt/source/scwx/qt/map/overlay_layer.hpp +++ b/scwx-qt/source/scwx/qt/map/overlay_layer.hpp @@ -21,6 +21,11 @@ public: void Render(const QMapLibreGL::CustomLayerRenderParameters&) override final; void Deinitialize() override final; + bool RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, + const QPointF& mouseLocalPos, + const QPointF& mouseGlobalPos, + const glm::vec2& mouseCoords) override final; + public slots: void UpdateSweepTimeNextFrame(); diff --git a/scwx-qt/source/scwx/qt/view/level3_product_view.cpp b/scwx-qt/source/scwx/qt/view/level3_product_view.cpp index 6bd8e740..cf6188b6 100644 --- a/scwx-qt/source/scwx/qt/view/level3_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/level3_product_view.cpp @@ -9,6 +9,10 @@ #include #include +#if !defined(_MSC_VER) +# include +#endif + namespace scwx { namespace qt @@ -153,6 +157,44 @@ void Level3ProductView::SelectProduct(const std::string& productName) p->product_ = productName; } +std::vector> +Level3ProductView::GetDescriptionFields() const +{ + std::vector> description {}; + + if (p->graphicMessage_ != nullptr) + { + const scwx::util::time_zone* currentZone; + +#if defined(_MSC_VER) + currentZone = std::chrono::current_zone(); +#else + currentZone = date::current_zone(); +#endif + + auto descriptionBlock = p->graphicMessage_->description_block(); + + if (descriptionBlock != nullptr) + { + auto volumeTime = scwx::util::TimePoint( + descriptionBlock->volume_scan_date(), + descriptionBlock->volume_scan_start_time() * 1000); + auto productTime = scwx::util::TimePoint( + descriptionBlock->generation_date_of_product(), + descriptionBlock->generation_time_of_product() * 1000); + + description.emplace_back( + "Volume Time", + scwx::util::TimeString(volumeTime, currentZone, false)); + description.emplace_back( + "Product Time", + scwx::util::TimeString(productTime, currentZone, false)); + } + } + + return description; +} + void Level3ProductView::LoadColorTable( std::shared_ptr colorTable) { diff --git a/scwx-qt/source/scwx/qt/view/level3_product_view.hpp b/scwx-qt/source/scwx/qt/view/level3_product_view.hpp index 0ea023db..00e42281 100644 --- a/scwx-qt/source/scwx/qt/view/level3_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/level3_product_view.hpp @@ -38,6 +38,9 @@ public: void SelectProduct(const std::string& productName) override; + std::vector> + GetDescriptionFields() const override; + protected: std::shared_ptr graphic_product_message() const; diff --git a/scwx-qt/source/scwx/qt/view/radar_product_view.cpp b/scwx-qt/source/scwx/qt/view/radar_product_view.cpp index 7651a14c..a47cbd70 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.cpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.cpp @@ -144,6 +144,12 @@ RadarProductView::GetCfpMomentData() const return std::tie(data, dataSize, componentSize); } +std::vector> +RadarProductView::GetDescriptionFields() const +{ + return {}; +} + std::chrono::system_clock::time_point RadarProductView::GetSelectedTime() const { return p->selectedTime_; diff --git a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp index b36ceffe..f1c2a8ae 100644 --- a/scwx-qt/source/scwx/qt/view/radar_product_view.hpp +++ b/scwx-qt/source/scwx/qt/view/radar_product_view.hpp @@ -66,6 +66,9 @@ public: GetCfpMomentData() const; std::chrono::system_clock::time_point GetSelectedTime() const; + virtual std::vector> + GetDescriptionFields() const; + protected: virtual boost::asio::thread_pool& thread_pool() = 0;