Files
OpenRA/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs
RoosterDragon 2fde98a0d1 Fix uses of LabelWidget.Text and ButtonWidget.Text to use GetText instead.
The Text element of these widgets was changed from display text to a translation key as part of adding translation support. Functions interested in the display text need to invoke GetText instead. Lots of functions have not been updated, resulting in symptoms such as measuring the font size of the translation key rather than the display text and resizing a widget to the wrong size.

Update all callers to use GetText when getting or setting display text. This ensure their existing functionality that was intended to work in terms of the display text and not the translation key works as expected.
2024-01-15 15:16:58 +02:00

239 lines
7.4 KiB
C#

#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
{
public class ActorSelectorLogic : CommonSelectorLogic
{
[TranslationReference("actorType")]
const string ActorTypeTooltip = "label-actor-type";
sealed class ActorSelectorActor
{
public readonly ActorInfo Actor;
public readonly string[] Categories;
public readonly string[] SearchTerms;
public readonly string Tooltip;
public ActorSelectorActor(ActorInfo actor, string[] categories, string[] searchTerms, string tooltip)
{
Actor = actor;
Categories = categories;
SearchTerms = searchTerms;
Tooltip = tooltip;
}
}
readonly DropDownButtonWidget ownersDropDown;
readonly Ruleset mapRules;
readonly ActorSelectorActor[] allActors;
readonly EditorCursorLayer editorCursor;
PlayerReference selectedOwner;
[ObjectCreator.UseCtor]
public ActorSelectorLogic(Widget widget, ModData modData, World world, WorldRenderer worldRenderer)
: base(widget, modData, world, worldRenderer, "ACTORTEMPLATE_LIST", "ACTORPREVIEW_TEMPLATE")
{
mapRules = world.Map.Rules;
ownersDropDown = widget.Get<DropDownButtonWidget>("OWNERS_DROPDOWN");
editorCursor = world.WorldActor.Trait<EditorCursorLayer>();
var editorLayer = world.WorldActor.Trait<EditorActorLayer>();
selectedOwner = editorLayer.Players.Players.Values.First();
ScrollItemWidget SetupItem(PlayerReference option, ScrollItemWidget template)
{
var item = ScrollItemWidget.Setup(template, () => selectedOwner == option, () => SelectOwner(option));
item.Get<LabelWidget>("LABEL").GetText = () => option.Name;
item.GetColor = () => option.Color;
return item;
}
editorLayer.OnPlayerRemoved = () =>
{
if (editorLayer.Players.Players.Values.Any(p => p.Name == selectedOwner.Name))
return;
SelectOwner(editorLayer.Players.Players.Values.First());
};
ownersDropDown.OnClick = () =>
{
var owners = editorLayer.Players.Players.Values.OrderBy(p => p.Name);
ownersDropDown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, owners, SetupItem);
};
var selectedOwnerName = selectedOwner.Name;
ownersDropDown.GetText = () => selectedOwnerName;
ownersDropDown.TextColor = selectedOwner.Color;
var tileSetId = world.Map.Rules.TerrainInfo.Id;
var allActorsTemp = new List<ActorSelectorActor>();
foreach (var a in mapRules.Actors.Values)
{
// Partial templates are not allowed
if (a.Name.Contains('^'))
continue;
// Actor must have a preview associated with it
if (!a.HasTraitInfo<IRenderActorPreviewInfo>())
continue;
var editorData = a.TraitInfoOrDefault<MapEditorDataInfo>();
// Actor must be included in at least one category
if (editorData == null || editorData.Categories == null)
continue;
// Excluded by tileset
if (editorData.ExcludeTilesets != null && editorData.ExcludeTilesets.Contains(tileSetId))
continue;
if (editorData.RequireTilesets != null && !editorData.RequireTilesets.Contains(tileSetId))
continue;
var tooltip = a.TraitInfos<EditorOnlyTooltipInfo>().FirstOrDefault(ti => ti.EnabledByDefault) as TooltipInfoBase
?? a.TraitInfos<TooltipInfo>().FirstOrDefault(ti => ti.EnabledByDefault);
var actorType = TranslationProvider.GetString(ActorTypeTooltip, Translation.Arguments("actorType", a.Name));
var searchTerms = new List<string>() { a.Name };
if (tooltip != null)
{
var actorName = TranslationProvider.GetString(tooltip.Name);
searchTerms.Add(actorName);
allActorsTemp.Add(new ActorSelectorActor(a, editorData.Categories, searchTerms.ToArray(), actorName + $"\n{actorType}"));
}
else
allActorsTemp.Add(new ActorSelectorActor(a, editorData.Categories, searchTerms.ToArray(), actorType));
}
allActors = allActorsTemp.ToArray();
allCategories = allActors.SelectMany(ac => ac.Categories)
.Distinct()
.OrderBy(x => x)
.ToArray();
foreach (var c in allCategories)
{
SelectedCategories.Add(c);
FilteredCategories.Add(c);
}
SearchTextField.OnTextEdited = () =>
{
searchFilter = SearchTextField.Text.Trim();
FilteredCategories.Clear();
if (!string.IsNullOrEmpty(searchFilter))
FilteredCategories.AddRange(
allActors.Where(t => t.SearchTerms.Any(
s => s.Contains(searchFilter, StringComparison.CurrentCultureIgnoreCase)))
.SelectMany(t => t.Categories)
.Distinct()
.OrderBy(x => x));
else
FilteredCategories.AddRange(allCategories);
InitializePreviews();
};
InitializePreviews();
}
void SelectOwner(PlayerReference option)
{
selectedOwner = option;
var optionName = option.Name;
ownersDropDown.GetText = () => optionName;
ownersDropDown.TextColor = option.Color;
InitializePreviews();
var actor = editorCursor.Actor;
if (actor != null)
{
actor.Owner = option;
actor.ReplaceInit(new OwnerInit(option.Name));
actor.ReplaceInit(new FactionInit(option.Faction));
}
}
protected override void InitializePreviews()
{
Panel.RemoveChildren();
if (SelectedCategories.Count == 0)
return;
foreach (var a in allActors)
{
if (!SelectedCategories.Overlaps(a.Categories))
continue;
if (!string.IsNullOrEmpty(searchFilter) &&
!a.SearchTerms.Any(s => s.Contains(searchFilter, StringComparison.CurrentCultureIgnoreCase)))
continue;
var actor = a.Actor;
var td = new TypeDictionary
{
new OwnerInit(selectedOwner.Name),
new FactionInit(selectedOwner.Faction)
};
foreach (var api in actor.TraitInfos<IActorPreviewInitInfo>())
foreach (var o in api.ActorPreviewInits(actor, ActorPreviewType.MapEditorSidebar))
td.Add(o);
try
{
var item = ScrollItemWidget.Setup(ItemTemplate,
() => editorCursor.Type == EditorCursorType.Actor && editorCursor.Actor.Info == actor,
() => Editor.SetBrush(new EditorActorBrush(Editor, actor, selectedOwner, WorldRenderer)));
var preview = item.Get<ActorPreviewWidget>("ACTOR_PREVIEW");
preview.SetPreview(actor, td);
// 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;
preview.GetScale = () => scale;
preview.Bounds.Width = (int)(scale * preview.IdealPreviewSize.X);
preview.Bounds.Height = (int)(scale * preview.IdealPreviewSize.Y);
item.Bounds.Width = preview.Bounds.Width + 2 * preview.Bounds.X;
item.Bounds.Height = preview.Bounds.Height + 2 * preview.Bounds.Y;
item.IsVisible = () => true;
item.GetTooltipText = () => a.Tooltip;
Panel.AddChild(item);
}
catch
{
Log.Write("debug", $"Map editor ignoring actor {actor.Name}, "
+ $"because of missing sprites for tileset {World.Map.Rules.TerrainInfo.Id}.");
}
}
}
}
}