diff --git a/OpenRA.Game/Widgets/DropDownButtonWidget.cs b/OpenRA.Game/Widgets/DropDownButtonWidget.cs index 4bd5ef4e3b..dff82bafd1 100644 --- a/OpenRA.Game/Widgets/DropDownButtonWidget.cs +++ b/OpenRA.Game/Widgets/DropDownButtonWidget.cs @@ -105,6 +105,41 @@ namespace OpenRA.Widgets panel.Bounds.Height = Math.Min(height, panel.ContentHeight); AttachPanel(panel); } + + public void ShowDropDown(string panelTemplate, int height, Dictionary> groups, Func setupItem) + { + var substitutions = new Dictionary() {{ "DROPDOWN_WIDTH", Bounds.Width }}; + var panel = (ScrollPanelWidget)Ui.LoadWidget(panelTemplate, null, new WidgetArgs() + {{ "substitutions", substitutions }}); + + var headerTemplate = panel.Get("HEADER"); + var itemTemplate = panel.Get("TEMPLATE"); + panel.RemoveChildren(); + + foreach (var kv in groups) + { + var group = kv.Key; + if (group.Length > 0) + { + var header = ScrollItemWidget.Setup(headerTemplate, () => true, () => {}); + header.Get("LABEL").GetText = () => group; + panel.AddChild(header); + } + + foreach (var option in kv.Value) + { + var o = option; + + var item = setupItem(o, itemTemplate); + var onClick = item.OnClick; + item.OnClick = () => { onClick(); RemovePanel(); }; + + panel.AddChild(item); + } + } + panel.Bounds.Height = Math.Min(height, panel.ContentHeight); + AttachPanel(panel); + } } public class MaskWidget : Widget diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs index 87a26b9e9f..71453508d3 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs @@ -38,21 +38,25 @@ namespace OpenRA.Mods.RA.Widgets.Logic public static void ShowSlotDropDown(DropDownButtonWidget dropdown, Session.Slot slot, Session.Client client, OrderManager orderManager) { - var options = new List() + var options = new Dictionary>() {{"Slot", new List() { new SlotDropDownOption("Open", "slot_open "+slot.PlayerReference, () => (!slot.Closed && client == null)), new SlotDropDownOption("Closed", "slot_close "+slot.PlayerReference, () => slot.Closed) - }; + }}}; + var bots = new List(); if (slot.AllowBots) + { foreach (var b in Rules.Info["player"].Traits.WithInterface().Select(t => t.Name)) { var bot = b; var botController = orderManager.LobbyInfo.Clients.Where(c => c.IsAdmin).FirstOrDefault(); - options.Add(new SlotDropDownOption("Bot: {0}".F(bot), + bots.Add(new SlotDropDownOption(bot, "slot_bot {0} {1} {2}".F(slot.PlayerReference, botController.Index, bot), () => client != null && client.Bot == bot)); } + } + options.Add(bots.Any() ? "Bots" : "Bots Disabled", bots); Func setupItem = (o, itemTemplate) => { @@ -63,7 +67,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic return item; }; - dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 150, options, setupItem); + dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 167, options, setupItem); } public static void ShowTeamDropDown(DropDownButtonWidget dropdown, Session.Client client, diff --git a/mods/cnc/chrome/dialogs.yaml b/mods/cnc/chrome/dialogs.yaml index 6396f33257..ed82c9db78 100644 --- a/mods/cnc/chrome/dialogs.yaml +++ b/mods/cnc/chrome/dialogs.yaml @@ -46,6 +46,18 @@ ScrollPanel@LABEL_DROPDOWN_TEMPLATE: Width:DROPDOWN_WIDTH Background:panel-black Children: + ScrollItem@HEADER: + Width:PARENT_RIGHT-27 + Height:13 + X:2 + Y:0 + Visible:false + Children: + Label@LABEL: + Font:TinyBold + Width:PARENT_RIGHT + Height:10 + Align:Center ScrollItem@TEMPLATE: Width:PARENT_RIGHT-27 Height:25 diff --git a/mods/ra/chrome/dropdowns.yaml b/mods/ra/chrome/dropdowns.yaml index aa008a81a4..2c5289aa72 100644 --- a/mods/ra/chrome/dropdowns.yaml +++ b/mods/ra/chrome/dropdowns.yaml @@ -1,6 +1,18 @@ ScrollPanel@LABEL_DROPDOWN_TEMPLATE: Width:DROPDOWN_WIDTH Children: + ScrollItem@HEADER: + Width:PARENT_RIGHT-27 + Height:13 + X:2 + Y:0 + Visible:false + Children: + Label@LABEL: + Font:TinyBold + Width:PARENT_RIGHT + Height:10 + Align:Center ScrollItem@TEMPLATE: Width:PARENT_RIGHT-27 Height:25