From fc8d65d4d1e6831023669867fd63a13fc431a7c6 Mon Sep 17 00:00:00 2001 From: AdenKoperczak Date: Thu, 28 Nov 2024 13:09:34 -0500 Subject: [PATCH] Add right click to edit location marker --- scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp | 23 +++++++++--- scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp | 10 ++++++ scwx-qt/source/scwx/qt/map/marker_layer.cpp | 38 ++++++++++++++++++-- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp index 9e2a8d17..71501930 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp +++ b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.cpp @@ -38,7 +38,7 @@ static constexpr std::size_t kIntegersPerVertex_ = 4; static constexpr std::size_t kIntegerBufferLength_ = kNumTriangles * kVerticesPerTriangle * kIntegersPerVertex_; -struct GeoIconDrawItem +struct GeoIconDrawItem : types::EventHandler { units::length::nautical_miles threshold_ {}; std::chrono::sys_time startTime_ {}; @@ -691,7 +691,7 @@ void GeoIcons::Impl::UpdateSingleBuffer( hoverIcons.end(), [&di](auto& entry) { return entry.di_ == di; }); - if (di->visible_ && !di->hoverText_.empty()) + if (di->visible_ && (!di->hoverText_.empty() || di->event_ != nullptr)) { const units::angle::radians radians = angle; @@ -903,7 +903,7 @@ bool GeoIcons::RunMousePicking( const QPointF& mouseGlobalPos, const glm::vec2& mouseCoords, const common::Coordinate& /* mouseGeoCoords */, - std::shared_ptr& /* eventHandler */) + std::shared_ptr& eventHandler ) { std::unique_lock lock {p->iconMutex_}; @@ -993,12 +993,27 @@ bool GeoIcons::RunMousePicking( if (it != p->currentHoverIcons_.crend()) { itemPicked = true; - util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos); + if (!it->di_->hoverText_.empty()) + { + // Show tooltip + util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos); + } + if (it->di_->event_ != nullptr) + { + eventHandler = it->di_; + } } return itemPicked; } +void GeoIcons::RegisterEventHandler( + const std::shared_ptr& di, + const std::function& eventHandler) +{ + di->event_ = eventHandler; +} + } // namespace draw } // namespace gl } // namespace qt diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp index 4d819681..073fc118 100644 --- a/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp +++ b/scwx-qt/source/scwx/qt/gl/draw/geo_icons.hpp @@ -183,6 +183,16 @@ public: */ void FinishIcons(); + /** + * Registers an event handler for an icon. + * + * @param [in] di Icon draw item + * @param [in] eventHandler Event handler function + */ + static void + RegisterEventHandler(const std::shared_ptr& di, + const std::function& eventHandler); + private: class Impl; diff --git a/scwx-qt/source/scwx/qt/map/marker_layer.cpp b/scwx-qt/source/scwx/qt/map/marker_layer.cpp index 311a347b..e552c749 100644 --- a/scwx-qt/source/scwx/qt/map/marker_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/marker_layer.cpp @@ -1,8 +1,14 @@ #include #include #include -#include #include +#include +#include + +#include +#include + +#include namespace scwx { @@ -18,7 +24,9 @@ class MarkerLayer::Impl { public: explicit Impl(MarkerLayer* self, std::shared_ptr context) : - self_ {self}, geoIcons_ {std::make_shared(context)} + self_ {self}, + geoIcons_ {std::make_shared(context)}, + editMarkerDialog_ {std::make_shared()} { ConnectSignals(); } @@ -30,6 +38,7 @@ public: MarkerLayer* self_; std::shared_ptr geoIcons_; + std::shared_ptr editMarkerDialog_; }; void MarkerLayer::Impl::ConnectSignals() @@ -55,11 +64,36 @@ void MarkerLayer::Impl::ReloadMarkers() markerManager->for_each( [this](const types::MarkerInfo& marker) { + // must use local ID, instead of reference to marker in event handler + // callback. + types::MarkerId id = marker.id; + std::shared_ptr icon = geoIcons_->AddIcon(); geoIcons_->SetIconTexture(icon, marker.iconName, 0); geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude); geoIcons_->SetIconHoverText(icon, marker.name); geoIcons_->SetIconModulate(icon, marker.iconColor); + geoIcons_->RegisterEventHandler( + icon, + [this, id](QEvent* ev) + { + switch (ev->type()) + { + case QEvent::Type::MouseButtonPress: + { + QMouseEvent* mouseEvent = reinterpret_cast(ev); + if (mouseEvent->buttons() == Qt::MouseButton::RightButton) + { + editMarkerDialog_->setup(id); + editMarkerDialog_->show(); + } + } + break; + + default: + break; + } + }); }); geoIcons_->FinishIcons();