fix(engine): popover rows stay visible regardless of action-bar fade

Quat: opening Modes / Menu showed a solid dark-purple block in the
top-right with no readable content. Cause: the auto-fade system on
the top-level action bar was fading the popover rows too — they
share the `ActionButton` marker so `paint_action_buttons` can still
paint hover/press, but `apply_action_fade` matched the same marker
and dropped their alpha to whatever the cursor-position-based
fade happened to be (typically 0 because the cursor was inside the
opened popover, well below the top reveal zone). The popover
container stayed at full opacity (its background is `BG_ELEVATED`,
not driven by the fade), so what the player saw was the empty
rounded box with no labels.

Fix: new `PopoverRow` marker on the rows in `spawn_modes_popover`
and `spawn_menu_popover` (both share the same row-spawn shape).
`apply_action_fade` excludes `PopoverRow` via `Without<PopoverRow>`.
Hover / press paint still applies — the popover rows just opt out
of the cursor-position auto-fade since they only render when the
player has explicitly opened the dropdown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
funman300
2026-05-06 05:54:34 +00:00
parent a4bc063497
commit cc635328be
+24 -1
View File
@@ -206,6 +206,16 @@ pub const SCORE_FLOATER_THRESHOLD: i32 = 50;
#[derive(Component, Debug)]
pub struct ActionButton;
/// Marker on rows inside a popover panel ([`ModesPopover`] or
/// [`MenuPopover`]). Popover rows already carry `ActionButton` so the
/// hover/press paint path applies to them, but the auto-fade applied
/// to the top-level action bar must NOT also fade these rows — the
/// popover only renders when the player has explicitly opened it, so
/// its content should always be at full opacity. `apply_action_fade`
/// excludes entities with this marker via `Without<PopoverRow>`.
#[derive(Component, Debug)]
pub struct PopoverRow;
/// Marker on the "New Game" action button anchored top-right of the play
/// area. Click fires [`NewGameRequestEvent`]; the existing
/// `ConfirmNewGameScreen` modal handles confirmation when a game is in
@@ -856,6 +866,7 @@ fn spawn_modes_popover(
.spawn((
option,
ActionButton,
PopoverRow,
Button,
Tooltip::new(tooltip),
Node {
@@ -1009,6 +1020,7 @@ fn spawn_menu_popover(commands: &mut Commands, font_res: Option<&FontResource>)
.spawn((
option,
ActionButton,
PopoverRow,
Button,
Tooltip::new(tooltip),
Node {
@@ -1139,9 +1151,20 @@ fn update_action_fade(
/// `Last` (after `paint_action_buttons`) so a hover-state change in the
/// same frame doesn't override the fade with an opaque idle / hover
/// colour.
#[allow(clippy::type_complexity)]
fn apply_action_fade(
fade: Res<HudActionFade>,
mut buttons: Query<(&Children, &mut BackgroundColor), With<ActionButton>>,
// Excludes `PopoverRow` so the auto-fade only applies to the
// top-level action bar buttons. Popover rows live inside an
// explicitly-opened dropdown panel and need to stay visible
// regardless of the bar's fade state — without the exclusion
// the rows fade to invisible while the popover container stays
// visible, leaving a solid background block with no readable
// content.
mut buttons: Query<
(&Children, &mut BackgroundColor),
(With<ActionButton>, Without<PopoverRow>),
>,
mut text_q: Query<&mut TextColor>,
) {
for (children, mut bg) in &mut buttons {