1 #region Copyright & License Information 2 /* 3 * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) 4 * This file is part of OpenRA, which is free software. It is made 5 * available to you under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, either version 3 of 7 * the License, or (at your option) any later version. For more 8 * information, see COPYING. 9 */ 10 #endregion 11 12 using System; 13 using System.Linq; 14 using OpenRA.Graphics; 15 using OpenRA.Mods.Common.Traits; 16 using OpenRA.Widgets; 17 18 namespace OpenRA.Mods.Common.Widgets.Logic 19 { 20 public class TileSelectorLogic : CommonSelectorLogic 21 { 22 class TileSelectorTemplate 23 { 24 public readonly TerrainTemplateInfo Template; 25 public readonly string[] Categories; 26 public readonly string[] SearchTerms; 27 public readonly string Tooltip; 28 TileSelectorTemplate(TerrainTemplateInfo template)29 public TileSelectorTemplate(TerrainTemplateInfo template) 30 { 31 Template = template; 32 Categories = template.Categories; 33 Tooltip = template.Id.ToString(); 34 SearchTerms = new[] { Tooltip }; 35 } 36 } 37 38 readonly TileSet tileset; 39 readonly TileSelectorTemplate[] allTemplates; 40 readonly EditorCursorLayer editorCursor; 41 42 [ObjectCreator.UseCtor] TileSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer)43 public TileSelectorLogic(Widget widget, World world, WorldRenderer worldRenderer) 44 : base(widget, world, worldRenderer, "TILETEMPLATE_LIST", "TILEPREVIEW_TEMPLATE") 45 { 46 tileset = world.Map.Rules.TileSet; 47 allTemplates = tileset.Templates.Values.Select(t => new TileSelectorTemplate(t)).ToArray(); 48 editorCursor = world.WorldActor.Trait<EditorCursorLayer>(); 49 50 allCategories = allTemplates.SelectMany(t => t.Categories) 51 .Distinct() 52 .OrderBy(CategoryOrder) 53 .ToArray(); 54 55 foreach (var c in allCategories) 56 { 57 SelectedCategories.Add(c); 58 FilteredCategories.Add(c); 59 } 60 61 SearchTextField.OnTextEdited = () => 62 { 63 searchFilter = SearchTextField.Text.Trim(); 64 FilteredCategories.Clear(); 65 66 if (!string.IsNullOrEmpty(searchFilter)) 67 FilteredCategories.AddRange( 68 allTemplates.Where(t => t.SearchTerms.Any( 69 s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0)) 70 .SelectMany(t => t.Categories) 71 .Distinct() 72 .OrderBy(CategoryOrder)); 73 else 74 FilteredCategories.AddRange(allCategories); 75 76 InitializePreviews(); 77 }; 78 79 InitializePreviews(); 80 } 81 CategoryOrder(string category)82 int CategoryOrder(string category) 83 { 84 var i = tileset.EditorTemplateOrder.IndexOf(category); 85 return i >= 0 ? i : int.MaxValue; 86 } 87 InitializePreviews()88 protected override void InitializePreviews() 89 { 90 Panel.RemoveChildren(); 91 if (!SelectedCategories.Any()) 92 return; 93 94 foreach (var t in allTemplates) 95 { 96 if (!SelectedCategories.Overlaps(t.Categories)) 97 continue; 98 99 if (!string.IsNullOrEmpty(searchFilter) && !t.SearchTerms.Any(s => s.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0)) 100 continue; 101 102 var tileId = t.Template.Id; 103 var item = ScrollItemWidget.Setup(ItemTemplate, 104 () => editorCursor.Type == EditorCursorType.TerrainTemplate && editorCursor.TerrainTemplate.Id == tileId, 105 () => Editor.SetBrush(new EditorTileBrush(Editor, tileId, WorldRenderer))); 106 107 var preview = item.Get<TerrainTemplatePreviewWidget>("TILE_PREVIEW"); 108 var template = tileset.Templates[tileId]; 109 var grid = WorldRenderer.World.Map.Grid; 110 var bounds = WorldRenderer.Theater.TemplateBounds(template, grid.TileSize, grid.Type); 111 112 // Scale templates to fit within the panel 113 var scale = 1f; 114 while (scale * bounds.Width > ItemTemplate.Bounds.Width) 115 scale /= 2; 116 117 preview.Template = template; 118 preview.GetScale = () => scale; 119 preview.Bounds.Width = (int)(scale * bounds.Width); 120 preview.Bounds.Height = (int)(scale * bounds.Height); 121 122 item.Bounds.Width = preview.Bounds.Width + 2 * preview.Bounds.X; 123 item.Bounds.Height = preview.Bounds.Height + 2 * preview.Bounds.Y; 124 item.IsVisible = () => true; 125 item.GetTooltipText = () => t.Tooltip; 126 127 Panel.AddChild(item); 128 } 129 } 130 } 131 } 132