From ad3f378545804a3ce563ef7aa28c1a19fed1abf5 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 31 May 2011 21:14:28 +1200 Subject: [PATCH] Add a hook for widgets being removed, and ensure widgets are removed consistently. --- OpenRA.Game/Game.cs | 3 +- OpenRA.Game/Widgets/Widget.cs | 39 +++++++++++++++---- OpenRA.Mods.Cnc/CncLoadScreen.cs | 2 +- .../Widgets/Logic/CncIngameMenuLogic.cs | 2 +- OpenRA.Mods.RA/NullLoadScreen.cs | 2 +- OpenRA.Mods.RA/OpenWidgetAtGameStart.cs | 2 +- OpenRA.Mods.RA/RALoadScreen.cs | 2 +- .../Widgets/Logic/DiplomacyLogic.cs | 3 +- OpenRA.Mods.RA/Widgets/Logic/GameInitLogic.cs | 2 +- 9 files changed, 40 insertions(+), 17 deletions(-) diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index e398ffef91..1845dab2fb 100755 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -276,8 +276,7 @@ namespace OpenRA ConnectionStateChanged = om => {}; BeforeGameStart = () => {}; AfterGameStart = w => {}; - while (Widget.WindowList.Count > 0) - Widget.CloseWindow(); + Widget.ResetAll(); worldRenderer = null; if (server != null) diff --git a/OpenRA.Game/Widgets/Widget.cs b/OpenRA.Game/Widgets/Widget.cs index 124562ad42..b3fc87faf4 100644 --- a/OpenRA.Game/Widgets/Widget.cs +++ b/OpenRA.Game/Widgets/Widget.cs @@ -29,13 +29,13 @@ namespace OpenRA.Widgets public object LogicObject { get; private set; } public bool Visible = true; - public readonly List Children = new List(); + protected readonly List Children = new List(); // Calculated internally public Rectangle Bounds; public Widget Parent = null; - public static Stack WindowList = new Stack(); + static Stack WindowList = new Stack(); // Common Funcs that most widgets will want public Func OnMouseDown = mi => false; @@ -293,9 +293,24 @@ namespace OpenRA.Widgets Children.Add(child); } - public virtual void RemoveChild(Widget child) { Children.Remove(child); } - public virtual void RemoveChildren() { Children.Clear(); } - + public virtual void RemoveChild(Widget child) + { + Children.Remove(child); + child.Removed(); + } + + public virtual void RemoveChildren() + { + while (Children.Count > 0) + RemoveChild(Children[Children.Count-1]); + } + + public virtual void Removed() + { + foreach (var c in Children.OfType().Reverse()) + c.Removed(); + } + public Widget GetWidget(string id) { if (this.Id == id) @@ -319,9 +334,9 @@ namespace OpenRA.Widgets public static void CloseWindow() { if (WindowList.Count > 0) - RootWidget.Children.Remove(WindowList.Pop()); + RootWidget.RemoveChild(WindowList.Pop()); if (WindowList.Count > 0) - rootWidget.Children.Add(WindowList.Peek()); + rootWidget.AddChild(WindowList.Peek()); } public static Widget OpenWindow(string id) @@ -333,7 +348,7 @@ namespace OpenRA.Widgets { var window = Game.modData.WidgetLoader.LoadWidget(args, rootWidget, id); if (WindowList.Count > 0) - rootWidget.Children.Remove(WindowList.Peek()); + rootWidget.RemoveChild(WindowList.Peek()); WindowList.Push(window); return window; } @@ -352,6 +367,14 @@ namespace OpenRA.Widgets { RootWidget.Draw(); } + + public static void ResetAll() + { + RootWidget.RemoveChildren(); + + while (Widget.WindowList.Count > 0) + Widget.CloseWindow(); + } } public class ContainerWidget : Widget diff --git a/OpenRA.Mods.Cnc/CncLoadScreen.cs b/OpenRA.Mods.Cnc/CncLoadScreen.cs index 9783832f41..205f6f505e 100644 --- a/OpenRA.Mods.Cnc/CncLoadScreen.cs +++ b/OpenRA.Mods.Cnc/CncLoadScreen.cs @@ -105,7 +105,7 @@ namespace OpenRA.Mods.Cnc void TestAndContinue() { - Widget.RootWidget.RemoveChildren(); + Widget.ResetAll(); if (!FileSystem.Exists(Info["TestFile"])) { var args = new WidgetArgs() diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs index d665e4af06..45892e6f95 100644 --- a/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs @@ -42,7 +42,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic world.WorldActor.QueueActivity(new CallFunc(() => { Game.Disconnect(); - Widget.RootWidget.RemoveChildren(); + Widget.ResetAll(); Game.LoadShellMap(); })); }; diff --git a/OpenRA.Mods.RA/NullLoadScreen.cs b/OpenRA.Mods.RA/NullLoadScreen.cs index 59d02a1d73..1952476e8a 100644 --- a/OpenRA.Mods.RA/NullLoadScreen.cs +++ b/OpenRA.Mods.RA/NullLoadScreen.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA public void StartGame() { - Widget.RootWidget.RemoveChildren(); + Widget.ResetAll(); Game.modData.WidgetLoader.LoadWidget( new WidgetArgs(), Widget.RootWidget, "INIT_SETUP" ); } } diff --git a/OpenRA.Mods.RA/OpenWidgetAtGameStart.cs b/OpenRA.Mods.RA/OpenWidgetAtGameStart.cs index d361ec7471..40484d76b7 100644 --- a/OpenRA.Mods.RA/OpenWidgetAtGameStart.cs +++ b/OpenRA.Mods.RA/OpenWidgetAtGameStart.cs @@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA public void WorldLoaded(World world) { // Remove all open widgets - Widget.RootWidget.Children.Clear(); + Widget.ResetAll(); if (world.LocalPlayer != null) Game.OpenWindow(world, Info.Widget); diff --git a/OpenRA.Mods.RA/RALoadScreen.cs b/OpenRA.Mods.RA/RALoadScreen.cs index 768b2ef077..4186a6ccf0 100644 --- a/OpenRA.Mods.RA/RALoadScreen.cs +++ b/OpenRA.Mods.RA/RALoadScreen.cs @@ -67,7 +67,7 @@ namespace OpenRA.Mods.RA public void StartGame() { - Widget.RootWidget.RemoveChildren(); + Widget.ResetAll(); Game.modData.WidgetLoader.LoadWidget( new WidgetArgs(), Widget.RootWidget, "INIT_SETUP" ); } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/DiplomacyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/DiplomacyLogic.cs index b071420557..85eafba4f8 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/DiplomacyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/DiplomacyLogic.cs @@ -47,7 +47,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic // This is shit void LayoutDialog(Widget bg) { - bg.Children.RemoveAll(w => controls.Contains(w)); + foreach (var c in controls) + bg.RemoveChild(c); controls.Clear(); var y = 50; diff --git a/OpenRA.Mods.RA/Widgets/Logic/GameInitLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/GameInitLogic.cs index 9ee83ff5fc..6ba57bf4a5 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/GameInitLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/GameInitLogic.cs @@ -68,7 +68,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic Game.LoadShellMap(); if (Info.InstallMode != "cnc") { - Widget.RootWidget.RemoveChildren(); + Widget.ResetAll(); Widget.OpenWindow("MAINMENU_BG"); } }