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};
units::angle::degrees<float> angle_ {};
std::string hoverText_ {};
GeoLines::HoverCallback hoverCallback_ {nullptr};
};
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,
const std::string& text)
{
@ -614,7 +625,8 @@ void GeoLines::Impl::UpdateSingleBuffer(
hoverLines.end(),
[&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;
@ -715,8 +727,8 @@ bool GeoLines::RunMousePicking(
// For each pickable line
auto it = std::find_if(
std::execution::par_unseq,
p->currentHoverLines_.crbegin(),
p->currentHoverLines_.crend(),
p->currentHoverLines_.rbegin(),
p->currentHoverLines_.rend(),
[&mapDistance, &selectedTime, &mapMatrix, &mouseCoords](const auto& line)
{
if ((
@ -775,7 +787,15 @@ bool GeoLines::RunMousePicking(
if (it != p->currentHoverLines_.crend())
{
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;

View file

@ -19,6 +19,10 @@ struct GeoLineDrawItem;
class GeoLines : public DrawItem
{
public:
typedef std::function<void(std::shared_ptr<const GeoLineDrawItem>&,
const QPointF&)>
HoverCallback;
explicit GeoLines(std::shared_ptr<GlContext> context);
~GeoLines();
@ -114,6 +118,15 @@ public:
void SetLineVisible(const std::shared_ptr<GeoLineDrawItem>& di,
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.
*

View file

@ -4,6 +4,7 @@
#include <scwx/qt/manager/timeline_manager.hpp>
#include <scwx/qt/settings/palette_settings.hpp>
#include <scwx/qt/util/color.hpp>
#include <scwx/qt/util/tooltip.hpp>
#include <scwx/util/logger.hpp>
#include <chrono>
@ -11,6 +12,7 @@
#include <unordered_map>
#include <unordered_set>
#include <boost/algorithm/string/join.hpp>
#include <boost/container/stable_vector.hpp>
#include <boost/container_hash/hash.hpp>
@ -138,24 +140,28 @@ public:
const std::shared_ptr<AlertLayerHandler::SegmentRecord>& segmentRecord);
void ConnectAlertHandlerSignals();
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,
std::shared_ptr<gl::draw::GeoLineDrawItem>& di,
const common::Coordinate& p1,
const common::Coordinate& p2,
boost::gil::rgba32f_pixel_t color,
float width,
std::chrono::system_clock::time_point startTime,
std::chrono::system_clock::time_point endTime);
static void
AddLines(std::shared_ptr<gl::draw::GeoLines>& geoLines,
const std::vector<common::Coordinate>& coordinates,
boost::gil::rgba32f_pixel_t color,
float width,
std::chrono::system_clock::time_point startTime,
std::chrono::system_clock::time_point endTime,
boost::container::stable_vector<
std::shared_ptr<gl::draw::GeoLineDrawItem>>& drawItems);
void AddLine(std::shared_ptr<gl::draw::GeoLines>& geoLines,
std::shared_ptr<gl::draw::GeoLineDrawItem>& di,
const common::Coordinate& p1,
const common::Coordinate& p2,
boost::gil::rgba32f_pixel_t color,
float width,
std::chrono::system_clock::time_point startTime,
std::chrono::system_clock::time_point endTime,
bool enableHover);
void AddLines(std::shared_ptr<gl::draw::GeoLines>& geoLines,
const std::vector<common::Coordinate>& coordinates,
boost::gil::rgba32f_pixel_t color,
float width,
std::chrono::system_clock::time_point startTime,
std::chrono::system_clock::time_point endTime,
bool enableHover,
boost::container::stable_vector<
std::shared_ptr<gl::draw::GeoLineDrawItem>>& drawItems);
const awips::Phenomenon phenomenon_;
@ -166,7 +172,10 @@ public:
std::unordered_map<std::shared_ptr<const AlertLayerHandler::SegmentRecord>,
boost::container::stable_vector<
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::unordered_map<bool, boost::gil::rgba32f_pixel_t> lineColor_;
@ -402,19 +411,30 @@ void AlertLayer::Impl::AddAlert(
// If draw items were added
if (drawItems.second)
{
// Add border
AddLines(geoLines,
coordinates,
kBlack_,
5.0f,
startTime,
endTime,
true,
drawItems.first->second);
// Add only border to segmentsByLine_
for (auto& di : drawItems.first->second)
{
segmentsByLine_.insert({di, segmentRecord});
}
// Add line
AddLines(geoLines,
coordinates,
lineColor,
3.0f,
startTime,
endTime,
false,
drawItems.first->second);
}
}
@ -452,6 +472,7 @@ void AlertLayer::Impl::AddLines(
float width,
std::chrono::system_clock::time_point startTime,
std::chrono::system_clock::time_point endTime,
bool enableHover,
boost::container::stable_vector<std::shared_ptr<gl::draw::GeoLineDrawItem>>&
drawItems)
{
@ -476,7 +497,8 @@ void AlertLayer::Impl::AddLines(
color,
width,
startTime,
endTime);
endTime,
enableHover);
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,
float width,
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(
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->SetLineStartTime(di, startTime);
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()