Weather overlay integration¶
This note describes how weather overlays are integrated in the UI and what invariants new overlay providers must keep.
Scope¶
Applies to:
RASP
EDL
XCTherm
Code entry points:
src/PageActions.cppsrc/Weather/WeatherUIState.hppsrc/Weather/MapOverlay/provider-specific glue in
src/Weather/<Provider>/
Ownership model¶
Weather overlays can be active from two contexts:
dedicated weather pages (selected through page layout)
map pages that show the weather cursor bar
The per-overlay :cpp:`OverlaySession` tracks ownership with three flags:
:cpp:`page_entered`: dedicated page currently owns the overlay
:cpp:`suspended_for_pan`: dedicated page ownership is temporarily held while pan mode is active
:cpp:`cursor_initialized`: user made an explicit manual selection, so auto-reset must not discard it
Use :cpp:`OverlaySession::HasPageOwnership()` when behavior should apply while either entered or suspended.
Lifecycle in PageActions¶
The lifecycle is orchestrated in src/PageActions.cpp:
:cpp:`PageActions::ApplyPageOverlay()` selects the overlay for the current :cpp:`PageLayout`.
Provider-specific apply hooks run:
Leaving a page calls :cpp:`LeaveWeatherOverlayPage()` and provider-specific leave hooks.
Entering pan mode calls :cpp:`SuspendWeatherOverlaysForPan()`.
Leaving pan mode calls :cpp:`ResumeWeatherOverlaysAfterPan()`.
For dedicated page entry, first-enter behavior should be explicit and
idempotent. Existing providers use :cpp:`EnterPage()` and branch on
first_enter.
Per-page cursor state¶
Each weather map page owns both cursor axes. Entering a configured page restores its selections; Auto values are recalculated from current GPS time/altitude.
RASP:
Each map page stores its own forecast time in :cpp:`PageLayout::rasp_time` (Auto, Now, or a fixed minute-of-day).
Entering a RASP page applies that page’s field and time via :cpp:`Rasp::ApplyTimeFromPageLayout()`.
:cpp:`WeatherUIState::ResetRaspForDedicatedPage()` clears the effective time only when the page uses Auto (:cpp:`time_auto_advance` is true).
Time changes from the cursor bar or Weather dialog persist to the current page.
EDL:
:cpp:`PageLayout::edl_time` stores Auto, Now, or a fixed UTC forecast hour.
:cpp:`PageLayout::edl_isobar` stores Auto or a fixed pressure level.
page entry applies both values before requesting the overlay.
XCTherm:
:cpp:`PageLayout::xctherm_time` stores Auto or a fixed UTC hour.
:cpp:`PageLayout::xctherm_layer` stores Auto or a fixed altitude layer.
the download Layer, span, cache, and credentials remain global provider settings and are not changed by map Altitude selection.
Threading and async boundaries¶
Keep this split:
UI thread: page transitions, overlay/session state, cursor-bar updates
network/asio thread: download and parse work
handoff back to UI:
UI::Notifycallback before UI state or overlay updates
Do not call UI APIs (CommonInterface, ActionInterface,
window code) directly from network worker code.
Integration checklist for a new provider¶
Add a provider state/session member in :cpp:`WeatherUIState`.
Add dedicated-page apply/leave hooks in
PageActions.cpp.Handle pan suspend/resume in :cpp:`SuspendWeatherOverlaysForPan()` and :cpp:`ResumeWeatherOverlaysAfterPan()`.
Define first-enter behavior:
auto mode reset/refresh path
manual mode preserve path via
cursor_initialized
Trigger refresh/download only from well-defined UI events (first enter, auto-no-data, explicit user action).
Add unit tests for session transitions and reset rules (see
test/src/TestWeatherUIState.cpp).
Common pitfalls¶
clearing manual selections when entering a page
forgetting to clear
suspended_for_panon pan exitperforming UI operations from non-UI threads
adding provider logic without tests for enter/leave/suspend/resume
Page placement UX¶
Weather dialogs provide a Pages setup button that opens
Config → Look → Pages, where map overlays (RASP, EDL, XCTherm) and the
weather cursor bar can be assigned to pages.
Programmatic placement helpers in PageActions /
WeatherMapOverlay::PagePlacement still:
set
bottom = WEATHER_CONTROLSso the shared weather cursor bar is activepersist page layout changes to the profile
clear provider cursor initialization so first-enter behavior is reapplied consistently
When the page limit (PageSettings::MAX_PAGES) is reached, adding a new
page must fail without mutating existing pages.