From 57450def43172d828aea6e0b04cdcbc42dbd647f Mon Sep 17 00:00:00 2001 From: iisaev Date: Thu, 29 Oct 2026 13:21:43 +0100 Subject: [PATCH] Remove the tool block from the main menu Authoring tools open from the in-game toolbar only. Menu and test drivers quit through ApplicationExit. --- scenes/menu/main_menu.tscn | 8 ---- src/BaseMenuInitializer.cs | 4 +- src/MainMenu.cs | 38 +++---------------- .../src/CollectionEditTestDriverNode.cs | 16 +++++--- .../src/DisplaySettingsTestDriverNode.cs | 2 +- .../hot_reload/src/HotReloadTestDriverNode.cs | 2 +- .../menu_flow/src/MenuFlowTestDriverNode.cs | 2 +- .../new_game/src/NewGameTestDriverNode.cs | 2 +- .../src/SaveDormancyTestDriverNode.cs | 2 +- 9 files changed, 23 insertions(+), 53 deletions(-) diff --git a/scenes/menu/main_menu.tscn b/scenes/menu/main_menu.tscn index a3c1390..ecf58e5 100644 --- a/scenes/menu/main_menu.tscn +++ b/scenes/menu/main_menu.tscn @@ -52,14 +52,6 @@ layout_mode = 2 layout_mode = 2 theme_override_constants/separation = 12 -[node name="space2" type="Control" parent="MenuContainer" unique_id=1261364549] -custom_minimum_size = Vector2(0, 20) -layout_mode = 2 - -[node name="ToolMenuButtons" type="VBoxContainer" parent="MenuContainer" unique_id=43694906] -layout_mode = 2 -theme_override_constants/separation = 12 - [node name="CenterContainer" type="AspectRatioContainer" parent="." unique_id=1751426695] layout_mode = 1 anchors_preset = -1 diff --git a/src/BaseMenuInitializer.cs b/src/BaseMenuInitializer.cs index 7d8c57a..6b62af0 100644 --- a/src/BaseMenuInitializer.cs +++ b/src/BaseMenuInitializer.cs @@ -140,10 +140,10 @@ namespace Cthangover.BaseMenu host.GetNodeOrNull("SettingsPanel")?.Open(); } - /// Quits the application immediately via SceneTree.Quit. + /// Quits the application after engine mods finish their registered cleanup. public static void Exit(Control host) { - host.GetTree().Quit(); + Cthangover.Core.Bootstrap.ApplicationExit.Quit(host.GetTree()); } } } diff --git a/src/MainMenu.cs b/src/MainMenu.cs index 8d8bc91..826b1cf 100644 --- a/src/MainMenu.cs +++ b/src/MainMenu.cs @@ -5,7 +5,6 @@ using Cthangover.Core.Settings; using Cthangover.Core.UI; using Cthangover.Core.UI.Menu; using Cthangover.Core.UI.Theming; -using Cthangover.Core.UI.Tool; using Cthangover.Core.Utils; using Godot; @@ -14,11 +13,10 @@ namespace Cthangover.BaseMenu { /// /// Title screen main menu, fully driven by . The scene - /// only defines named section containers (game, mods, exit, tools); every button — + /// only defines named section containers (game, mods, exit); every button — /// built-in or mod-provided — is created from registry entries, so mods can add, - /// replace or re-order entries without touching this scene. Below the sections, - /// every registered tool appends its own launcher button via - /// , so no tool list is hardcoded here. + /// replace or re-order entries without touching this scene. Authoring tools + /// are launched from the in-game toolbar. /// If GameLogger reports mod compilation errors, a popup lists them. The /// SettingsMenu and SaveLoadMenu panels are instantiated at ready time but stay /// hidden; they are registered in as panels "settings" @@ -50,7 +48,7 @@ namespace Cthangover.BaseMenu /// /// Assembles the runtime UI: theme, hidden settings and save/load panels, - /// telegram link wiring, scene manager initialization and registry/tool + /// telegram link wiring, scene manager initialization and registry /// driven buttons. /// private void BuildUi() @@ -87,7 +85,6 @@ namespace Cthangover.BaseMenu sceneManager.Initialize(); BuildRegistryButtons(); - BuildToolButtons(); CheckModCompilationErrors(); RefreshButtons(); @@ -118,8 +115,8 @@ namespace Cthangover.BaseMenu /// /// Creates one button per entry, routed to the - /// section container matching its Section ("game", "mods", "exit", - /// "tools"). Runs after because the + /// section container matching its Section ("game", "mods", "exit"). + /// Runs after because the /// registry is built during boot and filled by mod initializers; the /// defensive Initialize call keeps direct scene launches working. Each /// button's translation key is registered so @@ -132,7 +129,6 @@ namespace Cthangover.BaseMenu { "game", GetNode("MenuContainer/GameButtons") }, { MenuButtonEntry.SectionMods, GetNode("MenuContainer/ModMenuButtons") }, { "exit", GetNode("MenuContainer/ExitButtons") }, - { "tools", GetNode("MenuContainer/ToolMenuButtons") }, }; MenuBuilder.Build(this, sections); @@ -140,28 +136,6 @@ namespace Cthangover.BaseMenu MenuBuilder.CollectLocaleKeys(container, _btnKeys); } - /// - /// Lets every registered tool append its launcher button to the tool block - /// below Exit (MenuContainer/ToolMenuButtons). Tools register - /// themselves in , so the block stays empty when no - /// tools are installed and needs no changes when a mod introduces a new tool. - /// Each button carries its translation key in metadata, keeping - /// aware of it. - /// - private void BuildToolButtons() - { - var container = GetNodeOrNull("MenuContainer/ToolMenuButtons"); - if (container == null) - return; - - foreach (var tool in ToolFactory.Instance.GetAll()) - tool.AddMenuButton(container); - - MenuBuilder.CollectLocaleKeys(container, _btnKeys); - - GameLogger.Log("MAIN_MENU", $"Built {container.GetChildCount()} tool button(s)"); - } - private void CheckModCompilationErrors() { if (GameLogger.CompilationErrors.Count == 0) diff --git a/test_suites/collection_edit/src/CollectionEditTestDriverNode.cs b/test_suites/collection_edit/src/CollectionEditTestDriverNode.cs index 33d3d47..0f27ab1 100644 --- a/test_suites/collection_edit/src/CollectionEditTestDriverNode.cs +++ b/test_suites/collection_edit/src/CollectionEditTestDriverNode.cs @@ -38,7 +38,11 @@ namespace Mods.CollectionEditTest private const string GameId = "novel_template"; private const string AddedToolset = "dev_tools"; - private const string AddedMod = "editor_tools"; + private static readonly string[] AddedMods = + { + "scenario_editor", "scene_editor", "scene_builder", "map_editor", + "interactive_editor", "light_editor", "catalog_export" + }; private const string StudioMod = "scenario_studio"; private const string GameMenuId = "game_menu"; private const float TimeoutSeconds = 240f; @@ -97,7 +101,7 @@ namespace Mods.CollectionEditTest private static bool Busy => GameSession.IsSwitching || ModManager.Instance.IsReloading || ModHotReloadService.IsReloadRunning; - private static bool EditorsLoaded => ModRegistry.Instance.Mods.ContainsKey(AddedMod); + private static bool EditorsLoaded => AddedMods.All(ModRegistry.Instance.Mods.ContainsKey); /// Scenes of the game entered since the last clear; the main menu does not count. private void OnSceneEntered(SceneEnteredEvent e) @@ -123,7 +127,7 @@ namespace Mods.CollectionEditTest if (startedOnPlayerPackage) GameLogger.Log("TEST", "CollectionEditTest: the game started on the player's own package; the before/switch checks are skipped"); else - Check($"'{AddedMod}' is not loaded before the edit", !EditorsLoaded); + Check("individual editors are not loaded before the edit", !AddedMods.Any(ModRegistry.Instance.Mods.ContainsKey)); AddEditorsToCollection(); Check("the edited collection makes the running game outdated", GameCatalog.IsActiveOutdated()); @@ -168,8 +172,8 @@ namespace Mods.CollectionEditTest return; var reload = ModManager.Instance.LastReload; if (!startedOnPlayerPackage) - Check("New game after the edit switched the mod set", reload?.Applied == true && reload.Plan?.Load.Contains(AddedMod) == true); - Check($"'{AddedMod}' is loaded after the edit", EditorsLoaded); + Check("New game after the edit switched the mod set", reload?.Applied == true && AddedMods.All(id => reload.Plan?.Load.Contains(id) == true)); + Check("all seven individual editors are loaded after the edit", EditorsLoaded); Check($"'{StudioMod}' is loaded after the edit", ModRegistry.Instance.Mods.ContainsKey(StudioMod)); Check("the studio's button is on the game's toolbar", HasToolbarButton(StudioButtonTooltip())); Check("the game matches its edited collection", !GameCatalog.IsActiveOutdated()); @@ -309,7 +313,7 @@ namespace Mods.CollectionEditTest foreach (var failure in failures) GameLogger.Log("TEST", $"CollectionEditTest: failed: {failure}"); GameLogger.Log("TEST", $"[TEST_RESULT] name=collection_edit passed={passed} failed={failures.Count}"); - GetTree().Quit(failures.Count == 0 ? 0 : 1); + Cthangover.Core.Bootstrap.ApplicationExit.Quit(GetTree(), failures.Count == 0 ? 0 : 1); } } } diff --git a/test_suites/display_settings/src/DisplaySettingsTestDriverNode.cs b/test_suites/display_settings/src/DisplaySettingsTestDriverNode.cs index 26a2542..576e58c 100644 --- a/test_suites/display_settings/src/DisplaySettingsTestDriverNode.cs +++ b/test_suites/display_settings/src/DisplaySettingsTestDriverNode.cs @@ -262,7 +262,7 @@ namespace Mods.DisplaySettingsTest foreach (var failure in failures) GameLogger.Log("TEST", $"DisplaySettingsTest: failed: {failure}"); GameLogger.Log("TEST", $"[TEST_RESULT] name=display_settings passed={passed} failed={failures.Count}"); - GetTree().Quit(failures.Count == 0 ? 0 : 1); + Cthangover.Core.Bootstrap.ApplicationExit.Quit(GetTree(), failures.Count == 0 ? 0 : 1); } } } diff --git a/test_suites/hot_reload/src/HotReloadTestDriverNode.cs b/test_suites/hot_reload/src/HotReloadTestDriverNode.cs index d2a2f1d..ffe7d7d 100644 --- a/test_suites/hot_reload/src/HotReloadTestDriverNode.cs +++ b/test_suites/hot_reload/src/HotReloadTestDriverNode.cs @@ -313,7 +313,7 @@ namespace HotReloadProbeApp foreach (var failure in failures) GameLogger.Log("TEST", $"HotReloadTest: failed: {failure}"); GameLogger.Log("TEST", $"[TEST_RESULT] name=hot_reload passed={passed} failed={failures.Count}"); - GetTree().Quit(failures.Count == 0 ? 0 : 1); + Cthangover.Core.Bootstrap.ApplicationExit.Quit(GetTree(), failures.Count == 0 ? 0 : 1); } } } diff --git a/test_suites/menu_flow/src/MenuFlowTestDriverNode.cs b/test_suites/menu_flow/src/MenuFlowTestDriverNode.cs index 105bd7a..8711678 100644 --- a/test_suites/menu_flow/src/MenuFlowTestDriverNode.cs +++ b/test_suites/menu_flow/src/MenuFlowTestDriverNode.cs @@ -274,7 +274,7 @@ namespace Mods.MenuFlowTest foreach (var failure in failures) GameLogger.Log("TEST", $"MenuFlowTest: failed: {failure}"); GameLogger.Log("TEST", $"[TEST_RESULT] name=menu_flow passed={passed} failed={failures.Count}"); - GetTree().Quit(failures.Count == 0 ? 0 : 1); + Cthangover.Core.Bootstrap.ApplicationExit.Quit(GetTree(), failures.Count == 0 ? 0 : 1); } } } diff --git a/test_suites/new_game/src/NewGameTestDriverNode.cs b/test_suites/new_game/src/NewGameTestDriverNode.cs index 8a6a384..26a94a5 100644 --- a/test_suites/new_game/src/NewGameTestDriverNode.cs +++ b/test_suites/new_game/src/NewGameTestDriverNode.cs @@ -356,7 +356,7 @@ namespace Mods.NewGameTest foreach (var failure in failures) GameLogger.Log("TEST", $"NewGameTest: failed: {failure}"); GameLogger.Log("TEST", $"[TEST_RESULT] name=new_game passed={passed} failed={failures.Count}"); - GetTree().Quit(failures.Count == 0 ? 0 : 1); + Cthangover.Core.Bootstrap.ApplicationExit.Quit(GetTree(), failures.Count == 0 ? 0 : 1); } } } diff --git a/test_suites/save_dormancy/src/SaveDormancyTestDriverNode.cs b/test_suites/save_dormancy/src/SaveDormancyTestDriverNode.cs index a7c481c..1f012eb 100644 --- a/test_suites/save_dormancy/src/SaveDormancyTestDriverNode.cs +++ b/test_suites/save_dormancy/src/SaveDormancyTestDriverNode.cs @@ -129,7 +129,7 @@ namespace Mods.SaveDormancyTest foreach (var failure in failures) GameLogger.Log("TEST", $"SaveDormancyTest: failed: {failure}"); GameLogger.Log("TEST", $"[TEST_RESULT] name=save_dormancy passed={passed} failed={failures.Count}"); - GetTree().Quit(failures.Count == 0 ? 0 : 1); + Cthangover.Core.Bootstrap.ApplicationExit.Quit(GetTree(), failures.Count == 0 ? 0 : 1); } } }