diff --git a/OpenRA.Game/Widgets/ListLayout.cs b/OpenRA.Game/Widgets/ListLayout.cs index 04b7c2c1c8..83779fc4ce 100644 --- a/OpenRA.Game/Widgets/ListLayout.cs +++ b/OpenRA.Game/Widgets/ListLayout.cs @@ -21,11 +21,10 @@ namespace OpenRA.Widgets if (widget.Children.Count == 0) widget.ContentHeight = widget.ItemSpacing; - w.Bounds.Y += widget.ContentHeight; + w.Bounds.Y = widget.ContentHeight; widget.ContentHeight += w.Bounds.Height + widget.ItemSpacing; } - public void AdjustChildren() { widget.ContentHeight = widget.ItemSpacing; diff --git a/OpenRA.Game/Widgets/ScrollPanelWidget.cs b/OpenRA.Game/Widgets/ScrollPanelWidget.cs index bb9d21cc96..185a41cfed 100644 --- a/OpenRA.Game/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Game/Widgets/ScrollPanelWidget.cs @@ -50,6 +50,25 @@ namespace OpenRA.Widgets base.AddChild(child); } + public override void RemoveChild(Widget child) + { + base.RemoveChild(child); + Layout.AdjustChildren(); + Scroll(0); + } + + public void ReplaceChild(Widget oldChild, Widget newChild) + { + + oldChild.Removed(); + newChild.Parent = this; + Children[Children.IndexOf(oldChild)] = newChild; + Layout.AdjustChildren(); + Scroll(0); + } + + + public override void DrawOuter() { if (!IsVisible()) @@ -95,8 +114,6 @@ namespace OpenRA.Widgets Game.Renderer.EnableScissor(backgroundRect.X + 1, backgroundRect.Y + 1, backgroundRect.Width - 2, backgroundRect.Height - 2); - Layout.AdjustChildren(); - foreach (var child in Children) child.DrawOuter(); diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs index cc2abf99a5..9f2aaf3acc 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -325,9 +325,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic void UpdatePlayerList() { - // This causes problems for people who are in the process of editing their names (the widgets vanish from beneath them) - // Todo: handle this nicer - var idx = 0; foreach (var kv in orderManager.LobbyInfo.Slots) { @@ -343,7 +340,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic // Empty slot if (client == null) { - //template = EmptySlotTemplate.Clone(); if (template == null || template.Id != EmptySlotTemplate.Id) template = EmptySlotTemplate.Clone(); @@ -463,12 +459,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic if (idx >= Players.Children.Count) Players.AddChild(template); - else if (Players.Children [idx].Id != template.Id) - { - Players.Children [idx].Removed(); - template.Parent = Players; - Players.Children [idx] = template; - } + else if (Players.Children[idx].Id != template.Id) + Players.ReplaceChild(Players.Children[idx], template); + idx++; } @@ -481,7 +474,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic // get template for possible reuse if (idx < Players.Children.Count) - template = Players.Children[idx]; + template = Players.Children[idx]; // Editable spectator if (c.Index == orderManager.LocalClient.Index) @@ -528,28 +521,37 @@ namespace OpenRA.Mods.RA.Widgets.Logic if (idx >= Players.Children.Count) Players.AddChild(template); - else if (Players.Children [idx].Id != template.Id) - { - Players.Children [idx].Removed(); - template.Parent = Players; - Players.Children [idx] = template; - } + else if (Players.Children[idx].Id != template.Id) + Players.ReplaceChild(Players.Children[idx], template); + idx++; } - for (var i = idx; i < Players.Children.Count; i++) - Players.RemoveChild(Players.Children[i]); // Spectate button if (orderManager.LocalClient.Slot != null) { - var spec = NewSpectatorTemplate.Clone(); + Widget spec = null; + if (idx < Players.Children.Count) + spec = Players.Children[idx]; + if (spec == null || spec.Id != NewSpectatorTemplate.Id) + spec = NewSpectatorTemplate.Clone(); + var btn = spec.Get("SPECTATE"); btn.OnClick = () => orderManager.IssueOrder(Order.Command("spectate")); btn.IsDisabled = () => orderManager.LocalClient.IsReady; spec.IsVisible = () => true; - Players.AddChild(spec); + + if (idx >= Players.Children.Count) + Players.AddChild(spec); + else if (Players.Children[idx].Id != spec.Id) + Players.ReplaceChild(Players.Children[idx], spec); + + idx++; } + + while (Players.Children.Count > idx) + Players.RemoveChild(Players.Children[idx]); } void CycleReady()