From 9c7e3eb7e60a4674b52fd2aedee97ca54547091a Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Sat, 13 Jan 2024 23:19:34 -0600 Subject: [PATCH] Add compass icon to map showing bearing, and allow reset to north up --- scwx-qt/source/scwx/qt/map/overlay_layer.cpp | 122 +++++++++++++++++-- 1 file changed, 112 insertions(+), 10 deletions(-) diff --git a/scwx-qt/source/scwx/qt/map/overlay_layer.cpp b/scwx-qt/source/scwx/qt/map/overlay_layer.cpp index df6208f3..f8c01fef 100644 --- a/scwx-qt/source/scwx/qt/map/overlay_layer.cpp +++ b/scwx-qt/source/scwx/qt/map/overlay_layer.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -14,6 +15,7 @@ #include #include +#include #if !defined(_MSC_VER) # include @@ -39,7 +41,11 @@ public: explicit OverlayLayerImpl(std::shared_ptr context) : activeBoxOuter_ {std::make_shared(context)}, activeBoxInner_ {std::make_shared(context)}, - icons_ {std::make_shared(context)}, + geoIcons_ {std::make_shared(context)}, + icons_ {std::make_shared(context)}, + cardinalPointIconName_ { + types::GetTextureName(types::ImageTexture::CardinalPoint24)}, + compassIconName_ {types::GetTextureName(types::ImageTexture::Compass24)}, locationIconName_ { types::GetTextureName(types::ImageTexture::Crosshairs24)} { @@ -52,11 +58,21 @@ public: std::shared_ptr activeBoxOuter_; std::shared_ptr activeBoxInner_; - std::shared_ptr icons_; + std::shared_ptr geoIcons_; + std::shared_ptr icons_; const std::string& locationIconName_; std::shared_ptr locationIcon_ {}; + const std::string& cardinalPointIconName_; + const std::string& compassIconName_; + std::shared_ptr compassIcon_ {}; + bool compassIconDirty_ {false}; + double lastBearing_ {0.0}; + + double lastWidth_ {0.0}; + double lastHeight_ {0.0}; + std::string sweepTimeString_ {}; bool sweepTimeNeedsUpdate_ {true}; bool sweepTimePicked_ {false}; @@ -67,6 +83,7 @@ OverlayLayer::OverlayLayer(std::shared_ptr context) : { AddDrawItem(p->activeBoxOuter_); AddDrawItem(p->activeBoxInner_); + AddDrawItem(p->geoIcons_); AddDrawItem(p->icons_); p->activeBoxOuter_->SetPosition(0.0f, 0.0f); @@ -93,18 +110,68 @@ void OverlayLayer::Initialize() p->currentPosition_ = p->positionManager_->position(); auto coordinate = p->currentPosition_.coordinate(); - p->icons_->StartIconSheets(); - p->icons_->AddIconSheet(p->locationIconName_); - p->icons_->FinishIconSheets(); + // Geo Icons + p->geoIcons_->StartIconSheets(); + p->geoIcons_->AddIconSheet(p->locationIconName_); + p->geoIcons_->FinishIconSheets(); - p->icons_->StartIcons(); - p->locationIcon_ = p->icons_->AddIcon(); + p->geoIcons_->StartIcons(); + p->locationIcon_ = p->geoIcons_->AddIcon(); gl::draw::GeoIcons::SetIconTexture( p->locationIcon_, p->locationIconName_, 0); gl::draw::GeoIcons::SetIconAngle(p->locationIcon_, units::angle::degrees {45.0}); gl::draw::GeoIcons::SetIconLocation( p->locationIcon_, coordinate.latitude(), coordinate.longitude()); + p->geoIcons_->FinishIcons(); + + // Icons + p->icons_->StartIconSheets(); + p->icons_->AddIconSheet(p->cardinalPointIconName_); + p->icons_->AddIconSheet(p->compassIconName_); + p->icons_->FinishIconSheets(); + + p->icons_->StartIcons(); + p->compassIcon_ = p->icons_->AddIcon(); + gl::draw::Icons::SetIconTexture( + p->compassIcon_, p->cardinalPointIconName_, 0); + gl::draw::Icons::RegisterEventHandler( + p->compassIcon_, + [this](QEvent* ev) + { + switch (ev->type()) + { + case QEvent::Type::Enter: + gl::draw::Icons::SetIconModulate( + p->compassIcon_, + boost::gil::rgba32f_pixel_t {1.5f, 1.5f, 1.5f, 1.0f}); + p->compassIconDirty_ = true; + break; + + case QEvent::Type::Leave: + gl::draw::Icons::SetIconModulate( + p->compassIcon_, + boost::gil::rgba32f_pixel_t {1.0f, 1.0f, 1.0f, 1.0f}); + p->compassIconDirty_ = true; + break; + + case QEvent::Type::MouseButtonPress: + { + QMouseEvent* mouseEvent = reinterpret_cast(ev); + if (mouseEvent->buttons() == Qt::MouseButton::LeftButton && + p->lastBearing_ != 0.0) + { + auto map = context()->map().lock(); + if (map != nullptr) + { + map->setBearing(0.0); + } + ev->accept(); + } + break; + } + } + }); p->icons_->FinishIcons(); connect(p->positionManager_.get(), @@ -123,7 +190,7 @@ void OverlayLayer::Initialize() gl::draw::GeoIcons::SetIconLocation(p->locationIcon_, coordinate.latitude(), coordinate.longitude()); - p->icons_->FinishIcons(); + p->geoIcons_->FinishIcons(); Q_EMIT NeedsRendering(); } p->currentPosition_ = position; @@ -176,8 +243,39 @@ void OverlayLayer::Render( } // Location Icon - p->icons_->SetVisible(p->currentPosition_.isValid() && - p->positionManager_->IsLocationTracked()); + p->geoIcons_->SetVisible(p->currentPosition_.isValid() && + p->positionManager_->IsLocationTracked()); + + // Compass Icon + if (params.width != p->lastWidth_ || params.height != p->lastHeight_) + { + gl::draw::Icons::SetIconLocation( + p->compassIcon_, params.width - 24, params.height - 48); + p->compassIconDirty_ = true; + } + if (params.bearing != p->lastBearing_) + { + if (params.bearing == 0.0) + { + gl::draw::Icons::SetIconTexture( + p->compassIcon_, p->cardinalPointIconName_, 0); + gl::draw::Icons::SetIconAngle(p->compassIcon_, + units::angle::degrees {0.0}); + } + else + { + gl::draw::Icons::SetIconTexture( + p->compassIcon_, p->compassIconName_, 0); + gl::draw::Icons::SetIconAngle( + p->compassIcon_, + units::angle::degrees {-45 - params.bearing}); + } + p->compassIconDirty_ = true; + } + if (p->compassIconDirty_) + { + p->icons_->FinishIcons(); + } DrawLayer::Render(params); @@ -242,6 +340,10 @@ void OverlayLayer::Render( ImGui::End(); } + p->lastWidth_ = params.width; + p->lastHeight_ = params.height; + p->lastBearing_ = params.bearing; + SCWX_GL_CHECK_ERROR(); }