Prevent flickering of radar data between two "no data available" products

This commit is contained in:
Dan Paulat 2025-08-30 21:19:33 -05:00
parent 41bf7f731f
commit 07adbb382d
2 changed files with 90 additions and 20 deletions

View file

@ -153,6 +153,9 @@ public:
float lastFontSize_ {0.0f};
QMargins lastColorTableMargins_ {};
types::RadarProductLoadStatus latchedLoadStatus_ {
types::RadarProductLoadStatus::ProductNotAvailable};
double cursorScale_ {1};
boost::signals2::scoped_connection cursorScaleConnection_;
@ -349,12 +352,17 @@ void OverlayLayer::Render(const std::shared_ptr<MapContext>& mapContext,
auto& settings = mapContext->settings();
const float pixelRatio = mapContext->pixel_ratio();
types::RadarProductLoadStatus newLoadStatus =
types::RadarProductLoadStatus::ProductNotLoaded;
ImGuiFrameStart(mapContext);
p->sweepTimePicked_ = false;
if (radarProductView != nullptr)
{
newLoadStatus = radarProductView->load_status();
scwx::util::ClockFormat clockFormat = scwx::util::GetClockFormat(
settings::GeneralSettings::Instance().clock_format().GetValue());
@ -469,6 +477,16 @@ void OverlayLayer::Render(const std::shared_ptr<MapContext>& mapContext,
ImGuiFrameEnd();
if (radarProductView != nullptr &&
// Don't latch a transition from Not Available to Listing Products
!(p->latchedLoadStatus_ ==
types::RadarProductLoadStatus::ProductNotAvailable &&
newLoadStatus == types::RadarProductLoadStatus::ListingProducts))
{
// Latch last load status
p->latchedLoadStatus_ = newLoadStatus;
}
SCWX_GL_CHECK_ERROR();
}
@ -520,11 +538,34 @@ void OverlayLayer::Impl::RenderProductDetails(
ImGuiCond_Always,
ImVec2 {1.0f, 0.0f});
if (radarProductView != nullptr &&
radarProductView->load_status() ==
types::RadarProductLoadStatus::ProductNotAvailable)
bool productNotAvailable = false;
types::RadarProductLoadStatus newLoadStatus =
types::RadarProductLoadStatus::ProductNotLoaded;
if (radarProductView != nullptr)
{
ImGui::Begin("Product Details",
newLoadStatus = radarProductView->load_status();
switch (newLoadStatus)
{
case types::RadarProductLoadStatus::ProductNotAvailable:
productNotAvailable = true;
break;
case types::RadarProductLoadStatus::ListingProducts:
productNotAvailable =
latchedLoadStatus_ ==
types::RadarProductLoadStatus::ProductNotAvailable;
break;
default:
productNotAvailable = false;
}
}
if (productNotAvailable)
{
ImGui::Begin("Product Not Available",
nullptr,
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_AlwaysAutoResize);
@ -592,13 +633,19 @@ void OverlayLayer::Impl::RenderAttribution(
auto attributionFont = manager::FontManager::Instance().GetImGuiFont(
types::FontCategory::Attribution);
ImGui::SetNextWindowPos(ImVec2 {static_cast<float>(params.width),
static_cast<float>(params.height) -
colorTableMargins.bottom()},
ImGuiCond_Always,
ImVec2 {1.0f, 1.0f});
ImGui::SetNextWindowBgAlpha(0.5f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2 {3.0f, 2.0f});
static constexpr float kWindowBgAlpha_ = 0.5f;
static constexpr float kWindowPaddingX_ = 3.0f;
static constexpr float kWindowPaddingY_ = 2.0f;
ImGui::SetNextWindowPos(
ImVec2 {
static_cast<float>(params.width),
static_cast<float>(params.height - colorTableMargins.bottom())},
ImGuiCond_Always,
ImVec2 {1.0f, 1.0f});
ImGui::SetNextWindowBgAlpha(kWindowBgAlpha_);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,
ImVec2 {kWindowPaddingX_, kWindowPaddingY_});
ImGui::PushFont(attributionFont.first->font(),
attributionFont.second.value());
ImGui::Begin("Attribution",

View file

@ -64,7 +64,7 @@ public:
bool colorTableNeedsUpdate_ {false};
bool sweepNeedsUpdate_ {false};
types::RadarProductLoadStatus lastLoadStatus_ {
types::RadarProductLoadStatus latchedLoadStatus_ {
types::RadarProductLoadStatus::ProductNotAvailable};
};
@ -161,7 +161,7 @@ void RadarProductLayer::Initialize(
}
if (reason == types::NoUpdateReason::NoChange)
{
if (p->lastLoadStatus_ ==
if (p->latchedLoadStatus_ ==
types::RadarProductLoadStatus::ProductNotAvailable)
{
// Ensure the radar product is shown by re-rendering
@ -306,10 +306,29 @@ void RadarProductLayer::Render(
std::shared_ptr<view::RadarProductView> radarProductView =
mapContext->radar_product_view();
const bool sweepVisible =
radarProductView != nullptr &&
radarProductView->load_status() !=
types::RadarProductLoadStatus::ProductNotAvailable;
bool sweepVisible = false;
types::RadarProductLoadStatus newLoadStatus =
types::RadarProductLoadStatus::ProductNotLoaded;
if (radarProductView != nullptr)
{
newLoadStatus = radarProductView->load_status();
switch (newLoadStatus)
{
case types::RadarProductLoadStatus::ProductNotAvailable:
sweepVisible = false;
break;
case types::RadarProductLoadStatus::ListingProducts:
sweepVisible = p->latchedLoadStatus_ !=
types::RadarProductLoadStatus::ProductNotAvailable;
break;
default:
sweepVisible = true;
}
}
if (sweepVisible)
{
@ -350,10 +369,14 @@ void RadarProductLayer::Render(
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
if (radarProductView != nullptr)
if (radarProductView != nullptr &&
// Don't latch a transition from Not Available to Listing Products
!(p->latchedLoadStatus_ ==
types::RadarProductLoadStatus::ProductNotAvailable &&
newLoadStatus == types::RadarProductLoadStatus::ListingProducts))
{
// Save last load status
p->lastLoadStatus_ = radarProductView->load_status();
// Latch last load status
p->latchedLoadStatus_ = newLoadStatus;
}
SCWX_GL_CHECK_ERROR();