Add Actor Categories and Category dropdown filter in Map editor

This commit is contained in:
rob-v
2017-05-25 13:14:32 +02:00
committed by reaperrr
parent 8f4a92af99
commit 686686417f
4 changed files with 143 additions and 17 deletions

View File

@@ -18,6 +18,7 @@ namespace OpenRA.Mods.Common.Traits
{
public readonly HashSet<string> RequireTilesets = null;
public readonly HashSet<string> ExcludeTilesets = null;
public readonly string[] Categories;
}
public class EditorTilesetFilter { }

View File

@@ -10,11 +10,11 @@
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
@@ -28,6 +28,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly Ruleset mapRules;
readonly World world;
readonly WorldRenderer worldRenderer;
readonly List<string> allCategories;
readonly List<string> selectedCategories = new List<string>();
PlayerReference selectedOwner;
@@ -57,7 +59,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
ownersDropDown.Text = selectedOwner.Name;
ownersDropDown.TextColor = selectedOwner.Color.RGB;
IntializeActorPreviews();
InitializeActorPreviews();
});
item.Get<LabelWidget>("LABEL").GetText = () => option.Name;
@@ -75,15 +77,70 @@ namespace OpenRA.Mods.Common.Widgets.Logic
ownersDropDown.Text = selectedOwner.Name;
ownersDropDown.TextColor = selectedOwner.Color.RGB;
IntializeActorPreviews();
var actorCategorySelector = widget.Get<DropDownButtonWidget>("ACTOR_CATEGORY");
var filtersPanel = Ui.LoadWidget("ACTOR_CATEGORY_FILTER_PANEL", null, new WidgetArgs());
var categoryTemplate = filtersPanel.Get<CheckboxWidget>("CATEGORY_TEMPLATE");
var tileSetId = world.Map.Rules.TileSet.Id;
allCategories = mapRules.Actors.Where(a => !a.Value.Name.Contains('^')).Select(a => a.Value.TraitInfoOrDefault<EditorTilesetFilterInfo>())
.Where(i => i != null && i.Categories != null &&
!(i.ExcludeTilesets != null && i.ExcludeTilesets.Contains(tileSetId)) && !(i.RequireTilesets != null && !i.RequireTilesets.Contains(tileSetId)))
.SelectMany(i => i.Categories).Distinct().OrderBy(i => i).ToList();
selectedCategories.AddRange(allCategories);
var selectButtons = filtersPanel.Get<ContainerWidget>("SELECT_CATEGORIES_BUTTONS");
filtersPanel.AddChild(selectButtons);
filtersPanel.Bounds.Height = Math.Min(allCategories.Count * categoryTemplate.Bounds.Height + 5 + selectButtons.Bounds.Height, panel.Bounds.Height);
var selectAll = selectButtons.Get<ButtonWidget>("SELECT_ALL");
selectAll.OnClick = () =>
{
selectedCategories.Clear();
selectedCategories.AddRange(allCategories);
InitializeActorPreviews();
};
var selectNone = selectButtons.Get<ButtonWidget>("SELECT_NONE");
selectNone.OnClick = () =>
{
selectedCategories.Clear();
InitializeActorPreviews();
};
actorCategorySelector.OnMouseDown = _ =>
{
actorCategorySelector.RemovePanel();
actorCategorySelector.AttachPanel(filtersPanel);
};
foreach (var cat in allCategories)
{
var category = (CheckboxWidget)categoryTemplate.Clone();
category.GetText = () => cat;
category.IsChecked = () => selectedCategories.Contains(cat);
category.IsVisible = () => true;
category.OnClick = () =>
{
if (selectedCategories.Contains(cat))
selectedCategories.Remove(cat);
else
selectedCategories.Add(cat);
InitializeActorPreviews();
};
filtersPanel.AddChild(category);
}
InitializeActorPreviews();
}
void IntializeActorPreviews()
void InitializeActorPreviews()
{
panel.RemoveChildren();
var actors = mapRules.Actors.Where(a => !a.Value.Name.Contains('^'))
.Select(a => a.Value);
var tileSetId = world.Map.Rules.TileSet.Id;
foreach (var a in actors)
{
@@ -95,13 +152,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
continue;
var filter = actor.TraitInfoOrDefault<EditorTilesetFilterInfo>();
if (filter != null)
{
if (filter.ExcludeTilesets != null && filter.ExcludeTilesets.Contains(world.Map.Rules.TileSet.Id))
continue;
if (filter.RequireTilesets != null && !filter.RequireTilesets.Contains(world.Map.Rules.TileSet.Id))
continue;
}
if (filter == null || filter.Categories == null || !filter.Categories.Intersect(selectedCategories).Any())
continue;
if (filter.ExcludeTilesets != null && filter.ExcludeTilesets.Contains(tileSetId))
continue;
if (filter.RequireTilesets != null && !filter.RequireTilesets.Contains(tileSetId))
continue;
var td = new TypeDictionary();
td.Add(new OwnerInit(selectedOwner.Name));

View File

@@ -320,10 +320,16 @@ Container@EDITOR_WORLD_ROOT:
Width: PARENT_RIGHT
Height: 25
Font: Bold
ScrollPanel@ACTORTEMPLATE_LIST:
Y: 24
DropDownButton@ACTOR_CATEGORY:
Y: 25
Width: PARENT_RIGHT
Height: PARENT_BOTTOM - 24
Height: 25
Text: Categories
Font: Bold
ScrollPanel@ACTORTEMPLATE_LIST:
Y: 50
Width: PARENT_RIGHT
Height: PARENT_BOTTOM - 50
TopBottomSpacing: 4
ItemSpacing: 4
Children:
@@ -409,3 +415,29 @@ Container@EDITOR_WORLD_ROOT:
Align: Left
Font: Bold
Contrast: true
ScrollPanel@ACTOR_CATEGORY_FILTER_PANEL:
Width: 250
Children:
Container@SELECT_CATEGORIES_BUTTONS
Width: PARENT_RIGHT
Height: 30
Children:
Button@SELECT_ALL:
X: 10
Y: 2
Width: 100
Height: 25
Text: Select all
Button@SELECT_NONE:
X: 120
Y: 2
Width: 100
Height: 25
Text: Select none
Checkbox@CATEGORY_TEMPLATE:
X: 5
Y: 5
Width: PARENT_RIGHT - 29
Height: 22
Visible: false

View File

@@ -295,11 +295,18 @@ Container@EDITOR_WORLD_ROOT:
Width: 220
Height: 25
Font: Bold
ScrollPanel@ACTORTEMPLATE_LIST:
DropDownButton@ACTOR_CATEGORY:
X: 10
Y: 35
Width: PARENT_RIGHT - 20
Height: PARENT_BOTTOM - 45
Width: 220
Height: 25
Text: Categories
Font: Bold
ScrollPanel@ACTORTEMPLATE_LIST:
X: 10
Y: 60
Width: 220
Height: PARENT_BOTTOM - 70
TopBottomSpacing: 4
ItemSpacing: 4
Children:
@@ -394,3 +401,31 @@ Container@EDITOR_WORLD_ROOT:
Align: Left
Font: Bold
Contrast: true
ScrollPanel@ACTOR_CATEGORY_FILTER_PANEL:
Width: 220
Children:
Container@SELECT_CATEGORIES_BUTTONS
Width: 220
Height: 29
Children:
Button@SELECT_ALL:
X: 5
Y: 2
Width: 90
Height: 25
Text: Select all
Font: Bold
Button@SELECT_NONE:
X: 100
Y: 2
Width: 90
Height: 25
Text: Select none
Font: Bold
Checkbox@CATEGORY_TEMPLATE:
X: 5
Y: 5
Width: PARENT_RIGHT - 29
Height: 20
Visible: false