diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs index cc71069fdb..dfbe4a9b2b 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs @@ -38,26 +38,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic } readonly DropDownButtonWidget ownersDropDown; - readonly ScrollPanelWidget panel; - readonly ScrollItemWidget itemTemplate; readonly Ruleset mapRules; - readonly ActorSelectorActor[] allActors; PlayerReference selectedOwner; [ObjectCreator.UseCtor] public ActorSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer) - : base(widget, world, worldRenderer) + : base(widget, world, worldRenderer, "ACTORTEMPLATE_LIST", "ACTORPREVIEW_TEMPLATE") { mapRules = world.Map.Rules; - ownersDropDown = widget.Get("OWNERS_DROPDOWN"); - - panel = widget.Get("ACTORTEMPLATE_LIST"); - itemTemplate = panel.Get("ACTORPREVIEW_TEMPLATE"); - panel.Layout = new GridLayout(panel); - var editorLayer = world.WorldActor.Trait(); selectedOwner = editorLayer.Players.Players.Values.First(); @@ -136,10 +127,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic FilteredCategories.Add(c); } - var searchTextField = widget.Get("SEARCH_TEXTFIELD"); - searchTextField.OnTextEdited = () => + SearchTextField.OnTextEdited = () => { - searchFilter = searchTextField.Text.Trim(); + searchFilter = SearchTextField.Text.Trim(); FilteredCategories.Clear(); if (!string.IsNullOrEmpty(searchFilter)) @@ -155,40 +145,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic InitializePreviews(); }; - searchTextField.OnEscKey = () => - { - searchTextField.Text = ""; - searchTextField.YieldKeyboardFocus(); - return true; - }; - - var actorCategorySelector = widget.Get("CATEGORIES_DROPDOWN"); - actorCategorySelector.GetText = () => - { - if (SelectedCategories.Count == 0) - return "None"; - - if (!string.IsNullOrEmpty(searchFilter)) - return "Search Results"; - - if (SelectedCategories.Count == 1) - return SelectedCategories.First(); - - if (SelectedCategories.Count == allCategories.Length) - return "All"; - - return "Multiple"; - }; - - actorCategorySelector.OnMouseDown = _ => - { - if (searchTextField != null) - searchTextField.YieldKeyboardFocus(); - - actorCategorySelector.RemovePanel(); - actorCategorySelector.AttachPanel(CreateCategoriesPanel(panel)); - }; - InitializePreviews(); } @@ -202,7 +158,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic protected override void InitializePreviews() { - panel.RemoveChildren(); + Panel.RemoveChildren(); if (!SelectedCategories.Any()) return; @@ -224,7 +180,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic try { - var item = ScrollItemWidget.Setup(itemTemplate, + var item = ScrollItemWidget.Setup(ItemTemplate, () => { var brush = Editor.CurrentBrush as EditorActorBrush; return brush != null && brush.Actor == actor; }, () => Editor.SetBrush(new EditorActorBrush(Editor, actor, selectedOwner, WorldRenderer))); @@ -233,8 +189,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic // Scale templates to fit within the panel var scale = 1f; - if (scale * preview.IdealPreviewSize.X > itemTemplate.Bounds.Width) - scale = (itemTemplate.Bounds.Width - panel.ItemSpacing) / (float)preview.IdealPreviewSize.X; + if (scale * preview.IdealPreviewSize.X > ItemTemplate.Bounds.Width) + scale = (ItemTemplate.Bounds.Width - Panel.ItemSpacing) / (float)preview.IdealPreviewSize.X; preview.GetScale = () => scale; preview.Bounds.Width = (int)(scale * preview.IdealPreviewSize.X); @@ -246,7 +202,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic item.GetTooltipText = () => a.Tooltip; - panel.AddChild(item); + Panel.AddChild(item); } catch { diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/CommonSelectorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/CommonSelectorLogic.cs index 752762efcb..04142281b9 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/CommonSelectorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/CommonSelectorLogic.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; +using System.Linq; using OpenRA.Graphics; using OpenRA.Widgets; @@ -19,9 +20,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic public abstract class CommonSelectorLogic : ChromeLogic { protected readonly Widget Widget; + protected readonly TextFieldWidget SearchTextField; protected readonly World World; protected readonly WorldRenderer WorldRenderer; protected readonly EditorViewportControllerWidget Editor; + protected readonly ScrollPanelWidget Panel; + protected readonly ScrollItemWidget ItemTemplate; protected readonly HashSet SelectedCategories = new HashSet(); protected readonly List FilteredCategories = new List(); @@ -29,17 +33,55 @@ namespace OpenRA.Mods.Common.Widgets.Logic protected string[] allCategories; protected string searchFilter; - public CommonSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer) + public CommonSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer, string templateListId, string previewTemplateId) { this.Widget = widget; this.World = world; this.WorldRenderer = worldRenderer; Editor = widget.Parent.Get("MAP_EDITOR"); + Panel = widget.Get(templateListId); + ItemTemplate = Panel.Get(previewTemplateId); + Panel.Layout = new GridLayout(Panel); + + SearchTextField = widget.Get("SEARCH_TEXTFIELD"); + SearchTextField.OnEscKey = () => + { + SearchTextField.Text = ""; + SearchTextField.YieldKeyboardFocus(); + return true; + }; + + var categorySelector = widget.Get("CATEGORIES_DROPDOWN"); + categorySelector.GetText = () => + { + if (SelectedCategories.Count == 0) + return "None"; + + if (!string.IsNullOrEmpty(searchFilter)) + return "Search Results"; + + if (SelectedCategories.Count == 1) + return SelectedCategories.First(); + + if (SelectedCategories.Count == allCategories.Length) + return "All"; + + return "Multiple"; + }; + + categorySelector.OnMouseDown = _ => + { + if (SearchTextField != null) + SearchTextField.YieldKeyboardFocus(); + + categorySelector.RemovePanel(); + categorySelector.AttachPanel(CreateCategoriesPanel(Panel)); + }; } protected Widget CreateCategoriesPanel(ScrollPanelWidget panel) { - var categoriesPanel = Ui.LoadWidget("ACTOR_CATEGORY_FILTER_PANEL", null, new WidgetArgs()); + var categoriesPanel = Ui.LoadWidget("CATEGORY_FILTER_PANEL", null, new WidgetArgs()); var categoryTemplate = categoriesPanel.Get("CATEGORY_TEMPLATE"); var selectButtons = categoriesPanel.Get("SELECT_CATEGORIES_BUTTONS"); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/TileSelectorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/TileSelectorLogic.cs index 1b3f2bb25e..6603ad105c 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/TileSelectorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/TileSelectorLogic.cs @@ -35,87 +35,44 @@ namespace OpenRA.Mods.Common.Widgets.Logic } readonly TileSet tileset; - readonly ScrollPanelWidget panel; - readonly ScrollItemWidget itemTemplate; readonly TileSelectorTemplate[] allTemplates; - string selectedCategory; - string userSelectedCategory; - [ObjectCreator.UseCtor] - public TileSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer) : - base(widget, world, worldRenderer) + public TileSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer) + : base(widget, world, worldRenderer, "TILETEMPLATE_LIST", "TILEPREVIEW_TEMPLATE") { tileset = world.Map.Rules.TileSet; - - panel = widget.Get("TILETEMPLATE_LIST"); - itemTemplate = panel.Get("TILEPREVIEW_TEMPLATE"); - panel.Layout = new GridLayout(panel); - allTemplates = tileset.Templates.Values.Select(t => new TileSelectorTemplate(t)).ToArray(); - var orderedCategories = allTemplates.SelectMany(t => t.Categories) + allCategories = allTemplates.SelectMany(t => t.Categories) .Distinct() .OrderBy(CategoryOrder) .ToArray(); - var searchTextField = widget.Get("SEARCH_TEXTFIELD"); - searchTextField.OnTextEdited = () => + foreach (var c in allCategories) { - searchFilter = searchTextField.Text.Trim(); - selectedCategory = string.IsNullOrEmpty(searchFilter) ? userSelectedCategory : null; + SelectedCategories.Add(c); + FilteredCategories.Add(c); + } + + SearchTextField.OnTextEdited = () => + { + searchFilter = SearchTextField.Text.Trim(); + FilteredCategories.Clear(); + + if (!string.IsNullOrEmpty(searchFilter)) + FilteredCategories.AddRange( + allTemplates.Where(t => t.SearchTerms.Any( + s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0)) + .SelectMany(t => t.Categories) + .Distinct() + .OrderBy(CategoryOrder)); + else + FilteredCategories.AddRange(allCategories); InitializePreviews(); }; - searchTextField.OnEscKey = () => - { - searchTextField.Text = ""; - searchTextField.YieldKeyboardFocus(); - return true; - }; - - Func categoryTitle = s => s != null ? s : "Search Results"; - Func setupItem = (option, template) => - { - var item = ScrollItemWidget.Setup(template, () => selectedCategory == option, () => - { - selectedCategory = option; - if (option != null) - userSelectedCategory = option; - - InitializePreviews(); - }); - - var title = categoryTitle(option); - item.Get("LABEL").GetText = () => title; - return item; - }; - - var tileCategorySelector = widget.Get("CATEGORIES_DROPDOWN"); - tileCategorySelector.OnClick = () => - { - if (searchTextField != null) - searchTextField.YieldKeyboardFocus(); - - var categories = orderedCategories.AsEnumerable(); - if (!string.IsNullOrEmpty(searchFilter)) - { - var filteredCategories = allTemplates.Where(t => t.SearchTerms.Any( - s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0)) - .SelectMany(t => t.Categories) - .Distinct() - .OrderBy(CategoryOrder); - categories = new string[] { null }.Concat(filteredCategories); - } - - tileCategorySelector.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, categories, setupItem); - }; - - var actorCategorySelector = widget.Get("CATEGORIES_DROPDOWN"); - actorCategorySelector.GetText = () => categoryTitle(selectedCategory); - - selectedCategory = userSelectedCategory = orderedCategories.First(); InitializePreviews(); } @@ -127,18 +84,20 @@ namespace OpenRA.Mods.Common.Widgets.Logic protected override void InitializePreviews() { - panel.RemoveChildren(); + Panel.RemoveChildren(); + if (!SelectedCategories.Any()) + return; foreach (var t in allTemplates) { - if (selectedCategory != null && !t.Categories.Contains(selectedCategory)) + if (!SelectedCategories.Overlaps(t.Categories)) continue; if (!string.IsNullOrEmpty(searchFilter) && !t.SearchTerms.Any(s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0)) continue; var tileId = t.Template.Id; - var item = ScrollItemWidget.Setup(itemTemplate, + var item = ScrollItemWidget.Setup(ItemTemplate, () => { var brush = Editor.CurrentBrush as EditorTileBrush; return brush != null && brush.Template == tileId; }, () => Editor.SetBrush(new EditorTileBrush(Editor, tileId, WorldRenderer))); @@ -149,7 +108,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic // Scale templates to fit within the panel var scale = 1f; - while (scale * bounds.Width > itemTemplate.Bounds.Width) + while (scale * bounds.Width > ItemTemplate.Bounds.Width) scale /= 2; preview.Template = template; @@ -162,7 +121,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic item.IsVisible = () => true; item.GetTooltipText = () => t.Tooltip; - panel.AddChild(item); + Panel.AddChild(item); } } } diff --git a/mods/cnc/chrome/editor.yaml b/mods/cnc/chrome/editor.yaml index 3b3eb9fdfb..0dcad0e2e8 100644 --- a/mods/cnc/chrome/editor.yaml +++ b/mods/cnc/chrome/editor.yaml @@ -569,7 +569,7 @@ Container@EDITOR_WORLD_ROOT: Font: Bold Contrast: true -ScrollPanel@ACTOR_CATEGORY_FILTER_PANEL: +ScrollPanel@CATEGORY_FILTER_PANEL: Width: 190 Children: Container@SELECT_CATEGORIES_BUTTONS: diff --git a/mods/common/chrome/editor.yaml b/mods/common/chrome/editor.yaml index 136e1f83fe..1cd72aeca2 100644 --- a/mods/common/chrome/editor.yaml +++ b/mods/common/chrome/editor.yaml @@ -548,7 +548,7 @@ Container@EDITOR_WORLD_ROOT: Font: Bold Contrast: true -ScrollPanel@ACTOR_CATEGORY_FILTER_PANEL: +ScrollPanel@CATEGORY_FILTER_PANEL: Width: 170 Children: Container@SELECT_CATEGORIES_BUTTONS: