M6.16: Unified hybrid species grid + codex-styled hover popover
StepSpecies hybrid mode now uses one grid combining sire-clade species (under a "SIRE — <Clade>" eyebrow) and dam-clade species (under "DAM — <Clade>"). Cards are click-to-select like the purebred path — since clades are guaranteed disjoint by StepClade's parent-conflict rule, the lineage is implicit from the species' clade and no per-card toggles are needed. Hover popover now picks up the codex theme: parchment Bg2 panel with a gild border, rounded 14px corners, and soft drop shadow; H3 display serif title, mono Eyebrow tag, CardBody description. Detriment popovers swap to a 3px seal-red border via the panel_detriment stylebox override (replaces the old red Modulate hack). Theme propagation fix: CanvasLayer breaks Godot's Control theme inheritance, so the popup was rendering on Godot defaults. _Ready defers a lookup of the parent Control's theme and assigns it directly to the popup so the codex parchment + Cormorant/CrimsonPro fonts actually resolve. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -46,18 +46,33 @@ public partial class PopoverLayer : CanvasLayer
|
||||
{
|
||||
Layer = 100;
|
||||
BuildPopover();
|
||||
// Theme inheritance walks Control descendants only — CanvasLayer is
|
||||
// a plain Node, so it breaks the propagation chain from the Wizard
|
||||
// Control above. _Ready is bottom-up, so the parent Wizard hasn't
|
||||
// assigned its codex theme yet — defer the lookup until parent's
|
||||
// _Ready has run, then pull its theme onto the popup directly.
|
||||
CallDeferred(MethodName.InheritParentTheme);
|
||||
}
|
||||
|
||||
private void InheritParentTheme()
|
||||
{
|
||||
if (GetParent() is Control parentControl && parentControl.Theme is not null)
|
||||
_popup.Theme = parentControl.Theme;
|
||||
}
|
||||
|
||||
private void BuildPopover()
|
||||
{
|
||||
// Ignore so clicks/scroll/hover all pass through to whatever's
|
||||
// beneath. The popover is purely a visual readout; the chip
|
||||
// owns the lifecycle entirely.
|
||||
// owns the lifecycle entirely. ThemeTypeVariation pulls the
|
||||
// CodexPopover stylebox (parchment bg2 + gild border + rounded
|
||||
// corners + soft shadow) defined in CodexTheme.
|
||||
_popup = new PanelContainer
|
||||
{
|
||||
Visible = false,
|
||||
MouseFilter = Control.MouseFilterEnum.Ignore,
|
||||
ZIndex = 100,
|
||||
ThemeTypeVariation = "CodexPopover",
|
||||
};
|
||||
AddChild(_popup);
|
||||
|
||||
@@ -66,19 +81,29 @@ public partial class PopoverLayer : CanvasLayer
|
||||
_popup.AddChild(v);
|
||||
|
||||
var nameRow = new HBoxContainer();
|
||||
nameRow.AddThemeConstantOverride("separation", 8);
|
||||
nameRow.AddThemeConstantOverride("separation", 10);
|
||||
v.AddChild(nameRow);
|
||||
|
||||
_titleLabel = new Label();
|
||||
// Display-serif title at H3 size (20px) — pulls the trait name
|
||||
// out of the body copy below.
|
||||
_titleLabel = new Label { ThemeTypeVariation = "H3" };
|
||||
nameRow.AddChild(_titleLabel);
|
||||
|
||||
_tagLabel = new Label { Visible = false };
|
||||
// Mono uppercase tag label, vertically centred against the title.
|
||||
_tagLabel = new Label
|
||||
{
|
||||
Visible = false,
|
||||
ThemeTypeVariation = "Eyebrow",
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
SizeFlagsVertical = Control.SizeFlags.ShrinkCenter,
|
||||
};
|
||||
nameRow.AddChild(_tagLabel);
|
||||
|
||||
_descLabel = new Label
|
||||
{
|
||||
AutowrapMode = TextServer.AutowrapMode.WordSmart,
|
||||
CustomMinimumSize = new Vector2(220, 0),
|
||||
ThemeTypeVariation = "CardBody",
|
||||
};
|
||||
v.AddChild(_descLabel);
|
||||
}
|
||||
@@ -91,10 +116,18 @@ public partial class PopoverLayer : CanvasLayer
|
||||
_tagLabel.Text = !string.IsNullOrEmpty(tag) ? tag.ToUpperInvariant()
|
||||
: (detriment ? "DETRIMENT" : "");
|
||||
|
||||
// M6.3 default-theme tint: detriment popover gets a red modulate so
|
||||
// it reads visually distinct from a regular trait. The proper
|
||||
// codex StyleBox swap lands in the theming pass.
|
||||
_popup.Modulate = detriment ? new Color(1f, 0.78f, 0.78f) : Colors.White;
|
||||
// Detriment popover swaps to the seal-bordered stylebox via
|
||||
// override; non-detriment clears the override so the default
|
||||
// CodexPopover panel takes effect again.
|
||||
if (detriment && _popup.HasThemeStylebox("panel_detriment", "CodexPopover"))
|
||||
{
|
||||
var box = _popup.GetThemeStylebox("panel_detriment", "CodexPopover");
|
||||
_popup.AddThemeStyleboxOverride("panel", box);
|
||||
}
|
||||
else
|
||||
{
|
||||
_popup.RemoveThemeStyleboxOverride("panel");
|
||||
}
|
||||
|
||||
_popup.Visible = true;
|
||||
_popup.ResetSize();
|
||||
|
||||
Reference in New Issue
Block a user