diff --git a/OpenRA.Game/Widgets/GridLayout.cs b/OpenRA.Game/Widgets/GridLayout.cs index fcb8efca20..4eabd3ed44 100644 --- a/OpenRA.Game/Widgets/GridLayout.cs +++ b/OpenRA.Game/Widgets/GridLayout.cs @@ -41,6 +41,11 @@ namespace OpenRA.Widgets widget.ContentHeight = Math.Max(widget.ContentHeight, pos.Y + widget.ItemSpacing + w.Bounds.Height); } + + public void AdjustChildren() + { + + } } } diff --git a/OpenRA.Game/Widgets/ListLayout.cs b/OpenRA.Game/Widgets/ListLayout.cs index 69d3526da5..04b7c2c1c8 100644 --- a/OpenRA.Game/Widgets/ListLayout.cs +++ b/OpenRA.Game/Widgets/ListLayout.cs @@ -24,5 +24,16 @@ namespace OpenRA.Widgets w.Bounds.Y += widget.ContentHeight; widget.ContentHeight += w.Bounds.Height + widget.ItemSpacing; } + + + public void AdjustChildren() + { + widget.ContentHeight = widget.ItemSpacing; + foreach (var w in widget.Children) + { + w.Bounds.Y = widget.ContentHeight; + widget.ContentHeight += w.Bounds.Height + widget.ItemSpacing; + } + } } } diff --git a/OpenRA.Game/Widgets/ScrollPanelWidget.cs b/OpenRA.Game/Widgets/ScrollPanelWidget.cs index 365670a007..bb9d21cc96 100644 --- a/OpenRA.Game/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Game/Widgets/ScrollPanelWidget.cs @@ -14,7 +14,7 @@ using OpenRA.Graphics; namespace OpenRA.Widgets { - public interface ILayout { void AdjustChild(Widget w); } + public interface ILayout { void AdjustChild(Widget w); void AdjustChildren(); } public class ScrollPanelWidget : Widget { @@ -95,6 +95,8 @@ 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 75dab0dd9d..cc2abf99a5 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -327,19 +327,26 @@ namespace OpenRA.Mods.RA.Widgets.Logic { // This causes problems for people who are in the process of editing their names (the widgets vanish from beneath them) // Todo: handle this nicer - Players.RemoveChildren(); + var idx = 0; foreach (var kv in orderManager.LobbyInfo.Slots) { var key = kv.Key; var slot = kv.Value; var client = orderManager.LobbyInfo.ClientInSlot(key); - Widget template; + Widget template = null; + + // get template for possible reuse + if (idx < Players.Children.Count) + template = Players.Children [idx]; // Empty slot if (client == null) { - template = EmptySlotTemplate.Clone(); + //template = EmptySlotTemplate.Clone(); + if (template == null || template.Id != EmptySlotTemplate.Id) + template = EmptySlotTemplate.Clone(); + Func getText = () => slot.Closed ? "Closed" : "Open"; var ready = orderManager.LocalClient.IsReady; @@ -367,7 +374,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic else if ((client.Index == orderManager.LocalClient.Index) || (client.Bot != null && Game.IsHost)) { - template = EditablePlayerTemplate.Clone(); + if (template == null || template.Id != EditablePlayerTemplate.Id) + template = EditablePlayerTemplate.Clone(); + var botReady = client.Bot != null && Game.IsHost && orderManager.LocalClient.IsReady; var ready = botReady || client.IsReady; @@ -422,7 +431,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic } else { // Non-editable player in slot - template = NonEditablePlayerTemplate.Clone(); + if (template == null || template.Id != NonEditablePlayerTemplate.Id) + template = NonEditablePlayerTemplate.Clone(); + template.Get("NAME").GetText = () => client.Name; if (client.IsAdmin) template.Get("NAME").Font = "Bold"; @@ -449,20 +460,35 @@ namespace OpenRA.Mods.RA.Widgets.Logic } template.IsVisible = () => true; - Players.AddChild(template); + + 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; + } + idx++; } // Add spectators foreach (var client in orderManager.LobbyInfo.Clients.Where(client => client.Slot == null)) { - Widget template; + Widget template = null; var c = client; var ready = c.IsReady; + // get template for possible reuse + if (idx < Players.Children.Count) + template = Players.Children[idx]; + // Editable spectator if (c.Index == orderManager.LocalClient.Index) { - template = EditableSpectatorTemplate.Clone(); + if (template == null || template.Id != EditableSpectatorTemplate.Id) + template = EditableSpectatorTemplate.Clone(); + var name = template.Get("NAME"); name.IsDisabled = () => ready; LobbyUtils.SetupNameWidget(orderManager, c, name); @@ -481,7 +507,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic // Non-editable spectator else { - template = NonEditableSpectatorTemplate.Clone(); + if (template == null || template.Id != NonEditableSpectatorTemplate.Id) + template = NonEditableSpectatorTemplate.Clone(); + template.Get("NAME").GetText = () => c.Name; if (client.IsAdmin) template.Get("NAME").Font = "Bold"; @@ -497,9 +525,21 @@ namespace OpenRA.Mods.RA.Widgets.Logic } template.IsVisible = () => true; - Players.AddChild(template); + + 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; + } + idx++; } + for (var i = idx; i < Players.Children.Count; i++) + Players.RemoveChild(Players.Children[i]); + // Spectate button if (orderManager.LocalClient.Slot != null) {