Menu: conditional buttons, OpenScene returns the opened node

- MenuBuilder skips a button whose MenuButtonEntry.Visible predicate is
  false (e.g. "Continue" only when a last session exists); a throwing
  predicate is logged and the button stays visible.
- MenuBuilder.OpenScene returns the overlay it opened (null when the
  scene failed to build), so callers can configure it.
- Text for mods left out of a game's mod set: mods/not_in_game_reason.
This commit is contained in:
cthangover committed 2026-10-17 14:27:29 +00:00
1 parent b2a0f1c10a
commit 563b42ea9f
3 files changed
+22 -2

No files matched your search

+20 -2
View File
@@ -40,6 +40,9 @@ namespace Cthangover.Mods.Interface.Menu
foreach (var entry in AppServices.Current.Menus.Buttons)
{
if (entry.Visible != null && !SafeVisible(entry))
continue;
if (!sections.TryGetValue(entry.Section ?? MenuButtonEntry.SectionMods, out var container)
&& !sections.TryGetValue(MenuButtonEntry.SectionMods, out container))
{
@@ -62,6 +65,19 @@ namespace Cthangover.Mods.Interface.Menu
/// carry a locale meta key into the host's translation map, so the host
/// keeps them localized across language switches.
/// </summary>
private static bool SafeVisible(MenuButtonEntry entry)
{
try
{
return entry.Visible();
}
catch (System.Exception ex)
{
GameLogger.Log("MENU_BUILDER", $"Visibility check of button '{entry.Id}' failed: {ex.Message}", LogLevel.Warning);
return true;
}
}
public static void CollectLocaleKeys(Container container, Dictionary<Button, string> keys)
{
if (container == null || keys == null)
@@ -116,13 +132,14 @@ namespace Cthangover.Mods.Interface.Menu
/// owns its lifetime and closes itself, or is replaced by another menu
/// scene opening over it.
/// </summary>
public static void OpenScene(Control menuRoot, string scenePath, string label = null)
/// <summary>Opens a mod scene as a full-rect overlay of the menu and returns it (null when it fails to build).</summary>
public static Node OpenScene(Control menuRoot, string scenePath, string label = null)
{
var node = new ModScenePrefab(scenePath).Instantiate();
if (node == null)
{
GameLogger.Log("MENU_BUILDER", $"Open '{label ?? scenePath}': scene '{scenePath}' failed to build", LogLevel.Error);
return;
return null;
}
menuRoot.AddChild(node);
@@ -135,6 +152,7 @@ namespace Cthangover.Mods.Interface.Menu
modWidget.EnsureConstructed();
GameLogger.Log("MENU_BUILDER", $"Opened '{label ?? scenePath}' → {scenePath}");
return node;
}
}
}