mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-11-04 08:00:04 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			182 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			182 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <scwx/qt/map/marker_layer.hpp>
 | 
						|
#include <scwx/qt/manager/marker_manager.hpp>
 | 
						|
#include <scwx/util/logger.hpp>
 | 
						|
#include <scwx/qt/gl/draw/geo_icons.hpp>
 | 
						|
#include <scwx/qt/types/marker_types.hpp>
 | 
						|
#include <scwx/qt/ui/edit_marker_dialog.hpp>
 | 
						|
 | 
						|
#include <string>
 | 
						|
 | 
						|
#include <QGeoPositionInfo>
 | 
						|
#include <QMouseEvent>
 | 
						|
 | 
						|
namespace scwx::qt::map
 | 
						|
{
 | 
						|
 | 
						|
static const std::string logPrefix_ = "scwx::qt::map::marker_layer";
 | 
						|
static const auto        logger_    = scwx::util::Logger::Create(logPrefix_);
 | 
						|
 | 
						|
class MarkerLayer::Impl
 | 
						|
{
 | 
						|
public:
 | 
						|
   explicit Impl(MarkerLayer*                          self,
 | 
						|
                 const std::shared_ptr<gl::GlContext>& glContext) :
 | 
						|
       self_ {self},
 | 
						|
       geoIcons_ {std::make_shared<gl::draw::GeoIcons>(glContext)},
 | 
						|
       editMarkerDialog_ {std::make_shared<ui::EditMarkerDialog>()}
 | 
						|
   {
 | 
						|
      ConnectSignals();
 | 
						|
   }
 | 
						|
   ~Impl() = default;
 | 
						|
 | 
						|
   Impl(const Impl&)             = delete;
 | 
						|
   Impl& operator=(const Impl&)  = delete;
 | 
						|
   Impl(const Impl&&)            = delete;
 | 
						|
   Impl& operator=(const Impl&&) = delete;
 | 
						|
 | 
						|
   void ReloadMarkers();
 | 
						|
   void ConnectSignals();
 | 
						|
 | 
						|
   std::shared_ptr<manager::MarkerManager> markerManager_ {
 | 
						|
      manager::MarkerManager::Instance()};
 | 
						|
 | 
						|
   void set_icon_sheets();
 | 
						|
 | 
						|
   MarkerLayer* self_;
 | 
						|
 | 
						|
   std::shared_ptr<gl::draw::GeoIcons>   geoIcons_;
 | 
						|
   std::shared_ptr<ui::EditMarkerDialog> editMarkerDialog_;
 | 
						|
};
 | 
						|
 | 
						|
void MarkerLayer::Impl::ConnectSignals()
 | 
						|
{
 | 
						|
   QObject::connect(markerManager_.get(),
 | 
						|
                    &manager::MarkerManager::MarkersUpdated,
 | 
						|
                    self_,
 | 
						|
                    [this]() { ReloadMarkers(); });
 | 
						|
   QObject::connect(markerManager_.get(),
 | 
						|
                    &manager::MarkerManager::IconsReady,
 | 
						|
                    self_,
 | 
						|
                    [this]() { set_icon_sheets(); });
 | 
						|
   QObject::connect(markerManager_.get(),
 | 
						|
                    &manager::MarkerManager::IconAdded,
 | 
						|
                    self_,
 | 
						|
                    [this]() { set_icon_sheets(); });
 | 
						|
}
 | 
						|
 | 
						|
void MarkerLayer::Impl::ReloadMarkers()
 | 
						|
{
 | 
						|
   logger_->debug("ReloadMarkers()");
 | 
						|
 | 
						|
   geoIcons_->StartIcons();
 | 
						|
   markerManager_->for_each(
 | 
						|
      [this](const types::MarkerInfo& marker)
 | 
						|
      {
 | 
						|
         // must use local ID, instead of reference to marker in event handler
 | 
						|
         // callback.
 | 
						|
         const types::MarkerId id = marker.id;
 | 
						|
 | 
						|
         const std::shared_ptr<gl::draw::GeoIconDrawItem> icon =
 | 
						|
            geoIcons_->AddIcon();
 | 
						|
 | 
						|
         const std::string latitudeString =
 | 
						|
            common::GetLatitudeString(marker.latitude);
 | 
						|
         const std::string longitudeString =
 | 
						|
            common::GetLongitudeString(marker.longitude);
 | 
						|
 | 
						|
         const std::string hoverText =
 | 
						|
            marker.name != "" ?
 | 
						|
               fmt::format(
 | 
						|
                  "{}\n{}, {}", marker.name, latitudeString, longitudeString) :
 | 
						|
               fmt::format("{}, {}", latitudeString, longitudeString);
 | 
						|
 | 
						|
         auto iconInfo = markerManager_->get_icon(marker.iconName);
 | 
						|
         if (iconInfo)
 | 
						|
         {
 | 
						|
            geoIcons_->SetIconTexture(icon, iconInfo->name, 0);
 | 
						|
         }
 | 
						|
         else
 | 
						|
         {
 | 
						|
            geoIcons_->SetIconTexture(icon, marker.iconName, 0);
 | 
						|
         }
 | 
						|
 | 
						|
         geoIcons_->SetIconLocation(icon, marker.latitude, marker.longitude);
 | 
						|
         geoIcons_->SetIconHoverText(icon, hoverText);
 | 
						|
         geoIcons_->SetIconModulate(icon, marker.iconColor);
 | 
						|
         geoIcons_->RegisterEventHandler(
 | 
						|
            icon,
 | 
						|
            [this, id](QEvent* ev)
 | 
						|
            {
 | 
						|
               switch (ev->type())
 | 
						|
               {
 | 
						|
               case QEvent::Type::MouseButtonPress:
 | 
						|
               {
 | 
						|
                  auto* mouseEvent = reinterpret_cast<QMouseEvent*>(ev);
 | 
						|
                  if (mouseEvent->buttons() == Qt::MouseButton::RightButton)
 | 
						|
                  {
 | 
						|
                     editMarkerDialog_->setup(id);
 | 
						|
                     editMarkerDialog_->show();
 | 
						|
                  }
 | 
						|
               }
 | 
						|
               break;
 | 
						|
 | 
						|
               default:
 | 
						|
                  break;
 | 
						|
               }
 | 
						|
            });
 | 
						|
      });
 | 
						|
 | 
						|
   geoIcons_->FinishIcons();
 | 
						|
   Q_EMIT self_->NeedsRendering();
 | 
						|
}
 | 
						|
 | 
						|
MarkerLayer::MarkerLayer(const std::shared_ptr<gl::GlContext>& glContext) :
 | 
						|
    DrawLayer(glContext, "MarkerLayer"),
 | 
						|
    p(std::make_unique<MarkerLayer::Impl>(this, glContext))
 | 
						|
{
 | 
						|
   AddDrawItem(p->geoIcons_);
 | 
						|
}
 | 
						|
 | 
						|
MarkerLayer::~MarkerLayer() = default;
 | 
						|
 | 
						|
void MarkerLayer::Initialize(const std::shared_ptr<MapContext>& mapContext)
 | 
						|
{
 | 
						|
   logger_->debug("Initialize()");
 | 
						|
   DrawLayer::Initialize(mapContext);
 | 
						|
 | 
						|
   p->set_icon_sheets();
 | 
						|
   p->ReloadMarkers();
 | 
						|
}
 | 
						|
 | 
						|
void MarkerLayer::Impl::set_icon_sheets()
 | 
						|
{
 | 
						|
   geoIcons_->StartIconSheets();
 | 
						|
   for (auto& markerIcon : markerManager_->get_icons())
 | 
						|
   {
 | 
						|
      geoIcons_->AddIconSheet(markerIcon.second.name,
 | 
						|
                              0,
 | 
						|
                              0,
 | 
						|
                              markerIcon.second.hotX,
 | 
						|
                              markerIcon.second.hotY);
 | 
						|
   }
 | 
						|
   geoIcons_->FinishIconSheets();
 | 
						|
}
 | 
						|
 | 
						|
void MarkerLayer::Render(const std::shared_ptr<MapContext>& mapContext,
 | 
						|
                         const QMapLibre::CustomLayerRenderParameters& params)
 | 
						|
{
 | 
						|
   gl::OpenGLFunctions& gl = gl_context()->gl();
 | 
						|
 | 
						|
   DrawLayer::Render(mapContext, params);
 | 
						|
 | 
						|
   SCWX_GL_CHECK_ERROR();
 | 
						|
}
 | 
						|
 | 
						|
void MarkerLayer::Deinitialize()
 | 
						|
{
 | 
						|
   logger_->debug("Deinitialize()");
 | 
						|
 | 
						|
   DrawLayer::Deinitialize();
 | 
						|
}
 | 
						|
 | 
						|
} // namespace scwx::qt::map
 |