Add hover callback to alert layer

This commit is contained in:
Dan Paulat 2024-07-16 23:27:53 -05:00
parent 1bf93c6318
commit 204e2e8a0e
3 changed files with 103 additions and 24 deletions

View file

@ -49,6 +49,7 @@ struct GeoLineDrawItem
float width_ {5.0}; float width_ {5.0};
units::angle::degrees<float> angle_ {}; units::angle::degrees<float> angle_ {};
std::string hoverText_ {}; std::string hoverText_ {};
GeoLines::HoverCallback hoverCallback_ {nullptr};
}; };
class GeoLines::Impl class GeoLines::Impl
@ -388,6 +389,16 @@ void GeoLines::SetLineVisible(const std::shared_ptr<GeoLineDrawItem>& di,
} }
} }
void GeoLines::SetLineHoverCallback(const std::shared_ptr<GeoLineDrawItem>& di,
const HoverCallback& callback)
{
if (di->hoverCallback_ != nullptr || callback != nullptr)
{
di->hoverCallback_ = callback;
p->dirtyLines_.insert(di);
}
}
void GeoLines::SetLineHoverText(const std::shared_ptr<GeoLineDrawItem>& di, void GeoLines::SetLineHoverText(const std::shared_ptr<GeoLineDrawItem>& di,
const std::string& text) const std::string& text)
{ {
@ -614,7 +625,8 @@ void GeoLines::Impl::UpdateSingleBuffer(
hoverLines.end(), hoverLines.end(),
[&di](auto& entry) { return entry.di_ == di; }); [&di](auto& entry) { return entry.di_ == di; });
if (di->visible_ && !di->hoverText_.empty()) if (di->visible_ &&
(!di->hoverText_.empty() || di->hoverCallback_ != nullptr))
{ {
const units::angle::radians<double> radians = angle; const units::angle::radians<double> radians = angle;
@ -715,8 +727,8 @@ bool GeoLines::RunMousePicking(
// For each pickable line // For each pickable line
auto it = std::find_if( auto it = std::find_if(
std::execution::par_unseq, std::execution::par_unseq,
p->currentHoverLines_.crbegin(), p->currentHoverLines_.rbegin(),
p->currentHoverLines_.crend(), p->currentHoverLines_.rend(),
[&mapDistance, &selectedTime, &mapMatrix, &mouseCoords](const auto& line) [&mapDistance, &selectedTime, &mapMatrix, &mouseCoords](const auto& line)
{ {
if (( if ((
@ -775,7 +787,15 @@ bool GeoLines::RunMousePicking(
if (it != p->currentHoverLines_.crend()) if (it != p->currentHoverLines_.crend())
{ {
itemPicked = true; itemPicked = true;
util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos);
if (!it->di_->hoverText_.empty())
{
util::tooltip::Show(it->di_->hoverText_, mouseGlobalPos);
}
else if (it->di_->hoverCallback_ != nullptr)
{
it->di_->hoverCallback_(it->di_, mouseGlobalPos);
}
} }
return itemPicked; return itemPicked;

View file

@ -19,6 +19,10 @@ struct GeoLineDrawItem;
class GeoLines : public DrawItem class GeoLines : public DrawItem
{ {
public: public:
typedef std::function<void(std::shared_ptr<const GeoLineDrawItem>&,
const QPointF&)>
HoverCallback;
explicit GeoLines(std::shared_ptr<GlContext> context); explicit GeoLines(std::shared_ptr<GlContext> context);
~GeoLines(); ~GeoLines();
@ -114,6 +118,15 @@ public:
void SetLineVisible(const std::shared_ptr<GeoLineDrawItem>& di, void SetLineVisible(const std::shared_ptr<GeoLineDrawItem>& di,
bool visible); bool visible);
/**
* Sets the hover callback enable of a geo line.
*
* @param [in] di Geo line draw item
* @param [in] enabled Hover enabled
*/
void SetLineHoverCallback(const std::shared_ptr<GeoLineDrawItem>& di,
const HoverCallback& callback);
/** /**
* Sets the hover text of a geo line. * Sets the hover text of a geo line.
* *

View file

@ -4,6 +4,7 @@
#include <scwx/qt/manager/timeline_manager.hpp> #include <scwx/qt/manager/timeline_manager.hpp>
#include <scwx/qt/settings/palette_settings.hpp> #include <scwx/qt/settings/palette_settings.hpp>
#include <scwx/qt/util/color.hpp> #include <scwx/qt/util/color.hpp>
#include <scwx/qt/util/tooltip.hpp>
#include <scwx/util/logger.hpp> #include <scwx/util/logger.hpp>
#include <chrono> #include <chrono>
@ -11,6 +12,7 @@
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <boost/algorithm/string/join.hpp>
#include <boost/container/stable_vector.hpp> #include <boost/container/stable_vector.hpp>
#include <boost/container_hash/hash.hpp> #include <boost/container_hash/hash.hpp>
@ -138,24 +140,28 @@ public:
const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord); const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord);
void ConnectAlertHandlerSignals(); void ConnectAlertHandlerSignals();
void ConnectSignals(); void ConnectSignals();
void
HandleGeoLinesHover(std::shared_ptr<const gl::draw::GeoLineDrawItem>& di,
const QPointF& mouseGlobalPos);
static void AddLine(std::shared_ptr<gl::draw::GeoLines>& geoLines, void AddLine(std::shared_ptr<gl::draw::GeoLines>& geoLines,
std::shared_ptr<gl::draw::GeoLineDrawItem>& di, std::shared_ptr<gl::draw::GeoLineDrawItem>& di,
const common::Coordinate& p1, const common::Coordinate& p1,
const common::Coordinate& p2, const common::Coordinate& p2,
boost::gil::rgba32f_pixel_t color, boost::gil::rgba32f_pixel_t color,
float width, float width,
std::chrono::system_clock::time_point startTime, std::chrono::system_clock::time_point startTime,
std::chrono::system_clock::time_point endTime); std::chrono::system_clock::time_point endTime,
static void bool enableHover);
AddLines(std::shared_ptr<gl::draw::GeoLines>& geoLines, void AddLines(std::shared_ptr<gl::draw::GeoLines>& geoLines,
const std::vector<common::Coordinate>& coordinates, const std::vector<common::Coordinate>& coordinates,
boost::gil::rgba32f_pixel_t color, boost::gil::rgba32f_pixel_t color,
float width, float width,
std::chrono::system_clock::time_point startTime, std::chrono::system_clock::time_point startTime,
std::chrono::system_clock::time_point endTime, std::chrono::system_clock::time_point endTime,
boost::container::stable_vector< bool enableHover,
std::shared_ptr<gl::draw::GeoLineDrawItem>>& drawItems); boost::container::stable_vector<
std::shared_ptr<gl::draw::GeoLineDrawItem>>& drawItems);
const awips::Phenomenon phenomenon_; const awips::Phenomenon phenomenon_;
@ -166,7 +172,10 @@ public:
std::unordered_map<std::shared_ptr<const AlertLayerHandler::SegmentRecord>, std::unordered_map<std::shared_ptr<const AlertLayerHandler::SegmentRecord>,
boost::container::stable_vector< boost::container::stable_vector<
std::shared_ptr<gl::draw::GeoLineDrawItem>>> std::shared_ptr<gl::draw::GeoLineDrawItem>>>
linesBySegment_ {}; linesBySegment_ {};
std::unordered_map<std::shared_ptr<const gl::draw::GeoLineDrawItem>,
std::shared_ptr<const AlertLayerHandler::SegmentRecord>>
segmentsByLine_;
std::mutex linesMutex_ {}; std::mutex linesMutex_ {};
std::unordered_map<bool, boost::gil::rgba32f_pixel_t> lineColor_; std::unordered_map<bool, boost::gil::rgba32f_pixel_t> lineColor_;
@ -402,19 +411,30 @@ void AlertLayer::Impl::AddAlert(
// If draw items were added // If draw items were added
if (drawItems.second) if (drawItems.second)
{ {
// Add border
AddLines(geoLines, AddLines(geoLines,
coordinates, coordinates,
kBlack_, kBlack_,
5.0f, 5.0f,
startTime, startTime,
endTime, endTime,
true,
drawItems.first->second); drawItems.first->second);
// Add only border to segmentsByLine_
for (auto& di : drawItems.first->second)
{
segmentsByLine_.insert({di, segmentRecord});
}
// Add line
AddLines(geoLines, AddLines(geoLines,
coordinates, coordinates,
lineColor, lineColor,
3.0f, 3.0f,
startTime, startTime,
endTime, endTime,
false,
drawItems.first->second); drawItems.first->second);
} }
} }
@ -452,6 +472,7 @@ void AlertLayer::Impl::AddLines(
float width, float width,
std::chrono::system_clock::time_point startTime, std::chrono::system_clock::time_point startTime,
std::chrono::system_clock::time_point endTime, std::chrono::system_clock::time_point endTime,
bool enableHover,
boost::container::stable_vector<std::shared_ptr<gl::draw::GeoLineDrawItem>>& boost::container::stable_vector<std::shared_ptr<gl::draw::GeoLineDrawItem>>&
drawItems) drawItems)
{ {
@ -476,7 +497,8 @@ void AlertLayer::Impl::AddLines(
color, color,
width, width,
startTime, startTime,
endTime); endTime,
enableHover);
drawItems.push_back(di); drawItems.push_back(di);
} }
@ -489,7 +511,8 @@ void AlertLayer::Impl::AddLine(std::shared_ptr<gl::draw::GeoLines>& geoLines,
boost::gil::rgba32f_pixel_t color, boost::gil::rgba32f_pixel_t color,
float width, float width,
std::chrono::system_clock::time_point startTime, std::chrono::system_clock::time_point startTime,
std::chrono::system_clock::time_point endTime) std::chrono::system_clock::time_point endTime,
bool enableHover)
{ {
geoLines->SetLineLocation( geoLines->SetLineLocation(
di, p1.latitude_, p1.longitude_, p2.latitude_, p2.longitude_); di, p1.latitude_, p1.longitude_, p2.latitude_, p2.longitude_);
@ -497,6 +520,29 @@ void AlertLayer::Impl::AddLine(std::shared_ptr<gl::draw::GeoLines>& geoLines,
geoLines->SetLineWidth(di, width); geoLines->SetLineWidth(di, width);
geoLines->SetLineStartTime(di, startTime); geoLines->SetLineStartTime(di, startTime);
geoLines->SetLineEndTime(di, endTime); geoLines->SetLineEndTime(di, endTime);
if (enableHover)
{
geoLines->SetLineHoverCallback(
di,
std::bind(&AlertLayer::Impl::HandleGeoLinesHover,
this,
std::placeholders::_1,
std::placeholders::_2));
}
}
void AlertLayer::Impl::HandleGeoLinesHover(
std::shared_ptr<const gl::draw::GeoLineDrawItem>& di,
const QPointF& mouseGlobalPos)
{
auto it = segmentsByLine_.find(di);
if (it != segmentsByLine_.cend())
{
util::tooltip::Show(
boost::algorithm::join(it->second->segment_->productContent_, "\n"),
mouseGlobalPos);
}
} }
AlertLayerHandler& AlertLayerHandler::Instance() AlertLayerHandler& AlertLayerHandler::Instance()