Fix editor area/actor deselection bugs

This commit is contained in:
David Wilson
2024-01-27 14:58:51 +10:00
committed by Gustas
parent 0c22499534
commit d630a6ef7d
30 changed files with 503 additions and 443 deletions

View File

@@ -42,7 +42,8 @@ namespace OpenRA.Mods.Common.Widgets
public void ClearBrush() { SetBrush(null); }
public void SetBrush(IEditorBrush brush)
{
CurrentBrush?.Dispose();
if (CurrentBrush != DefaultBrush)
CurrentBrush?.Dispose();
CurrentBrush = brush ?? DefaultBrush;
}

View File

@@ -55,29 +55,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
ActorIDStatus nextActorIDStatus = ActorIDStatus.Normal;
string initialActorID;
EditorActorPreview currentActorInner;
EditActorPreview editActorPreview;
EditorActorPreview CurrentActor
{
get => currentActorInner;
set
{
if (currentActorInner == value)
return;
if (currentActorInner != null)
{
Reset();
currentActorInner.Selected = false;
}
currentActorInner = value;
if (currentActorInner != null)
currentActorInner.Selected = true;
}
}
EditorActorPreview SelectedActor => editor.DefaultBrush.Selection.Actor;
[ObjectCreator.UseCtor]
public ActorEditLogic(Widget widget, World world, WorldRenderer worldRenderer, Dictionary<string, MiniYaml> logicArgs)
@@ -88,8 +68,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
editorActionManager = world.WorldActor.Trait<EditorActionManager>();
editor = widget.Parent.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR");
var selectTabContainer = widget.Parent.Parent.Get<ContainerWidget>("SELECT_WIDGETS");
editor.DefaultBrush.SelectionChanged += HandleSelectionChanged;
var selectTabContainer = widget.Parent.Parent.Get<ContainerWidget>("SELECT_WIDGETS");
actorEditPanel = selectTabContainer.Get<ContainerWidget>("ACTOR_EDIT_PANEL");
typeLabel = actorEditPanel.Get<LabelWidget>("ACTOR_TYPE_LABEL");
@@ -118,8 +99,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
okButton.OnClick = Save;
cancelButton.OnClick = Cancel;
deleteButton.OnClick = Delete;
actorEditPanel.IsVisible = () => CurrentActor != null
&& editor.CurrentBrush == editor.DefaultBrush;
actorEditPanel.IsVisible = () => editor.CurrentBrush == editor.DefaultBrush && SelectedActor != null;
actorIDField.OnEscKey = _ => actorIDField.YieldKeyboardFocus();
@@ -133,7 +113,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
// Check for duplicate actor ID
if (!CurrentActor.ID.Equals(actorId, StringComparison.OrdinalIgnoreCase) && editorActorLayer[actorId] != null)
if (!SelectedActor.ID.Equals(actorId, StringComparison.OrdinalIgnoreCase) && editorActorLayer[actorId] != null)
{
nextActorIDStatus = ActorIDStatus.Duplicate;
actorIDErrorLabel.Visible = true;
@@ -164,6 +144,185 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return nextActorIDStatus == ActorIDStatus.Normal;
}
protected override void Dispose(bool disposing)
{
editor.DefaultBrush.SelectionChanged -= HandleSelectionChanged;
base.Dispose(disposing);
}
void HandleSelectionChanged()
{
if (SelectedActor != null)
{
Reset();
editActorPreview = new EditActorPreview(SelectedActor);
initialActorID = actorIDField.Text = SelectedActor.ID;
var font = Game.Renderer.Fonts[typeLabel.Font];
var truncatedType = WidgetUtils.TruncateText(TranslationProvider.GetString(SelectedActor.DescriptiveName), typeLabel.Bounds.Width, font);
typeLabel.GetText = () => truncatedType;
actorIDField.CursorPosition = SelectedActor.ID.Length;
nextActorIDStatus = ActorIDStatus.Normal;
// Remove old widgets
var oldInitHeight = initContainer.Bounds.Height;
initContainer.Bounds.Height = 0;
initContainer.RemoveChildren();
// Add owner dropdown
var ownerContainer = dropdownOptionTemplate.Clone();
var owner = TranslationProvider.GetString(Owner);
ownerContainer.Get<LabelWidget>("LABEL").GetText = () => owner;
var ownerDropdown = ownerContainer.Get<DropDownButtonWidget>("OPTION");
var selectedOwner = SelectedActor.Owner;
void UpdateOwner(EditorActorPreview preview, PlayerReference reference)
{
preview.Owner = reference;
preview.ReplaceInit(new OwnerInit(reference.Name));
}
var ownerHandler = new EditorActorOptionActionHandle<PlayerReference>(UpdateOwner, SelectedActor.Owner);
editActorPreview.Add(ownerHandler);
ScrollItemWidget SetupItem(PlayerReference option, ScrollItemWidget template)
{
var item = ScrollItemWidget.Setup(template, () => selectedOwner == option, () =>
{
selectedOwner = option;
UpdateOwner(SelectedActor, selectedOwner);
ownerHandler.OnChange(option);
});
item.Get<LabelWidget>("LABEL").GetText = () => option.Name;
item.GetColor = () => option.Color;
return item;
}
ownerDropdown.GetText = () => selectedOwner.Name;
ownerDropdown.GetColor = () => selectedOwner.Color;
ownerDropdown.OnClick = () =>
{
var owners = editorActorLayer.Players.Players.Values.OrderBy(p => p.Name);
ownerDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, owners, SetupItem);
};
initContainer.Bounds.Height += ownerContainer.Bounds.Height;
initContainer.AddChild(ownerContainer);
// Add new children for inits
var options = SelectedActor.Info.TraitInfos<IEditorActorOptions>()
.SelectMany(t => t.ActorOptions(SelectedActor.Info, worldRenderer.World))
.OrderBy(o => o.DisplayOrder);
foreach (var o in options)
{
if (o is EditorActorCheckbox co)
{
var checkboxContainer = checkboxOptionTemplate.Clone();
checkboxContainer.Bounds.Y = initContainer.Bounds.Height;
initContainer.Bounds.Height += checkboxContainer.Bounds.Height;
var checkbox = checkboxContainer.Get<CheckboxWidget>("OPTION");
checkbox.GetText = () => co.Name;
var editorActionHandle = new EditorActorOptionActionHandle<bool>(co.OnChange, co.GetValue(SelectedActor));
editActorPreview.Add(editorActionHandle);
checkbox.IsChecked = () => co.GetValue(SelectedActor);
checkbox.OnClick = () =>
{
var newValue = co.GetValue(SelectedActor) ^ true;
co.OnChange(SelectedActor, newValue);
editorActionHandle.OnChange(newValue);
};
initContainer.AddChild(checkboxContainer);
}
else if (o is EditorActorSlider so)
{
var sliderContainer = sliderOptionTemplate.Clone();
sliderContainer.Bounds.Y = initContainer.Bounds.Height;
initContainer.Bounds.Height += sliderContainer.Bounds.Height;
sliderContainer.Get<LabelWidget>("LABEL").GetText = () => so.Name;
var slider = sliderContainer.Get<SliderWidget>("OPTION");
slider.MinimumValue = so.MinValue;
slider.MaximumValue = so.MaxValue;
slider.Ticks = so.Ticks;
var editorActionHandle = new EditorActorOptionActionHandle<float>(so.OnChange, so.GetValue(SelectedActor));
editActorPreview.Add(editorActionHandle);
slider.GetValue = () => so.GetValue(SelectedActor);
slider.OnChange += value => so.OnChange(SelectedActor, value);
slider.OnChange += value => editorActionHandle.OnChange(value);
var valueField = sliderContainer.GetOrNull<TextFieldWidget>("VALUE");
if (valueField != null)
{
void UpdateValueField(float f) => valueField.Text = ((int)f).ToString(NumberFormatInfo.CurrentInfo);
UpdateValueField(so.GetValue(SelectedActor));
slider.OnChange += UpdateValueField;
valueField.OnTextEdited = () =>
{
if (float.TryParse(valueField.Text, out var result))
slider.UpdateValue(result);
};
valueField.OnEscKey = _ => { valueField.YieldKeyboardFocus(); return true; };
valueField.OnEnterKey = _ => { valueField.YieldKeyboardFocus(); return true; };
typableFields.Add(valueField);
}
initContainer.AddChild(sliderContainer);
}
else if (o is EditorActorDropdown ddo)
{
var dropdownContainer = dropdownOptionTemplate.Clone();
dropdownContainer.Bounds.Y = initContainer.Bounds.Height;
initContainer.Bounds.Height += dropdownContainer.Bounds.Height;
dropdownContainer.Get<LabelWidget>("LABEL").GetText = () => ddo.Name;
var editorActionHandle = new EditorActorOptionActionHandle<string>(ddo.OnChange, ddo.GetValue(SelectedActor));
editActorPreview.Add(editorActionHandle);
var dropdown = dropdownContainer.Get<DropDownButtonWidget>("OPTION");
ScrollItemWidget DropdownSetup(KeyValuePair<string, string> option, ScrollItemWidget template)
{
var item = ScrollItemWidget.Setup(template,
() => ddo.GetValue(SelectedActor) == option.Key,
() =>
{
ddo.OnChange(SelectedActor, option.Key);
editorActionHandle.OnChange(option.Key);
});
item.Get<LabelWidget>("LABEL").GetText = () => option.Value;
return item;
}
dropdown.GetText = () => ddo.Labels[ddo.GetValue(SelectedActor)];
dropdown.OnClick = () => dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, ddo.Labels, DropdownSetup);
initContainer.AddChild(dropdownContainer);
}
}
buttonContainer.Bounds.Y += initContainer.Bounds.Height - oldInitHeight;
}
else
{
// Selected actor is null, hide the border and edit panel.
Close();
}
}
public override void Tick()
{
if (actorIDStatus != nextActorIDStatus)
@@ -180,188 +339,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
actorIDStatus = nextActorIDStatus;
}
var actor = editor.DefaultBrush.Selection.Actor;
if (actor != null)
{
// If we changed actor, update details
if (CurrentActor != actor)
{
CurrentActor = actor;
editActorPreview = new EditActorPreview(CurrentActor);
initialActorID = actorIDField.Text = actor.ID;
var font = Game.Renderer.Fonts[typeLabel.Font];
var truncatedType = WidgetUtils.TruncateText(actor.DescriptiveName, typeLabel.Bounds.Width, font);
typeLabel.GetText = () => truncatedType;
actorIDField.CursorPosition = actor.ID.Length;
nextActorIDStatus = ActorIDStatus.Normal;
// Remove old widgets
var oldInitHeight = initContainer.Bounds.Height;
initContainer.Bounds.Height = 0;
initContainer.RemoveChildren();
// Add owner dropdown
var ownerContainer = dropdownOptionTemplate.Clone();
var owner = TranslationProvider.GetString(Owner);
ownerContainer.Get<LabelWidget>("LABEL").GetText = () => owner;
var ownerDropdown = ownerContainer.Get<DropDownButtonWidget>("OPTION");
var selectedOwner = actor.Owner;
void UpdateOwner(EditorActorPreview preview, PlayerReference reference)
{
preview.Owner = reference;
preview.ReplaceInit(new OwnerInit(reference.Name));
}
var ownerHandler = new EditorActorOptionActionHandle<PlayerReference>(UpdateOwner, actor.Owner);
editActorPreview.Add(ownerHandler);
ScrollItemWidget SetupItem(PlayerReference option, ScrollItemWidget template)
{
var item = ScrollItemWidget.Setup(template, () => selectedOwner == option, () =>
{
selectedOwner = option;
UpdateOwner(CurrentActor, selectedOwner);
ownerHandler.OnChange(option);
});
item.Get<LabelWidget>("LABEL").GetText = () => option.Name;
item.GetColor = () => option.Color;
return item;
}
ownerDropdown.GetText = () => selectedOwner.Name;
ownerDropdown.GetColor = () => selectedOwner.Color;
ownerDropdown.OnClick = () =>
{
var owners = editorActorLayer.Players.Players.Values.OrderBy(p => p.Name);
ownerDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, owners, SetupItem);
};
initContainer.Bounds.Height += ownerContainer.Bounds.Height;
initContainer.AddChild(ownerContainer);
// Add new children for inits
var options = actor.Info.TraitInfos<IEditorActorOptions>()
.SelectMany(t => t.ActorOptions(actor.Info, worldRenderer.World))
.OrderBy(o => o.DisplayOrder);
foreach (var o in options)
{
if (o is EditorActorCheckbox co)
{
var checkboxContainer = checkboxOptionTemplate.Clone();
checkboxContainer.Bounds.Y = initContainer.Bounds.Height;
initContainer.Bounds.Height += checkboxContainer.Bounds.Height;
var checkbox = checkboxContainer.Get<CheckboxWidget>("OPTION");
checkbox.GetText = () => co.Name;
var editorActionHandle = new EditorActorOptionActionHandle<bool>(co.OnChange, co.GetValue(actor));
editActorPreview.Add(editorActionHandle);
checkbox.IsChecked = () => co.GetValue(actor);
checkbox.OnClick = () =>
{
var newValue = co.GetValue(actor) ^ true;
co.OnChange(actor, newValue);
editorActionHandle.OnChange(newValue);
};
initContainer.AddChild(checkboxContainer);
}
else if (o is EditorActorSlider so)
{
var sliderContainer = sliderOptionTemplate.Clone();
sliderContainer.Bounds.Y = initContainer.Bounds.Height;
initContainer.Bounds.Height += sliderContainer.Bounds.Height;
sliderContainer.Get<LabelWidget>("LABEL").GetText = () => so.Name;
var slider = sliderContainer.Get<SliderWidget>("OPTION");
slider.MinimumValue = so.MinValue;
slider.MaximumValue = so.MaxValue;
slider.Ticks = so.Ticks;
var editorActionHandle = new EditorActorOptionActionHandle<float>(so.OnChange, so.GetValue(actor));
editActorPreview.Add(editorActionHandle);
slider.GetValue = () => so.GetValue(actor);
slider.OnChange += value => so.OnChange(actor, value);
slider.OnChange += value => editorActionHandle.OnChange(value);
var valueField = sliderContainer.GetOrNull<TextFieldWidget>("VALUE");
if (valueField != null)
{
void UpdateValueField(float f) => valueField.Text = ((int)f).ToString(NumberFormatInfo.CurrentInfo);
UpdateValueField(so.GetValue(actor));
slider.OnChange += UpdateValueField;
valueField.OnTextEdited = () =>
{
if (float.TryParse(valueField.Text, out var result))
slider.UpdateValue(result);
};
valueField.OnEscKey = _ => { valueField.YieldKeyboardFocus(); return true; };
valueField.OnEnterKey = _ => { valueField.YieldKeyboardFocus(); return true; };
typableFields.Add(valueField);
}
initContainer.AddChild(sliderContainer);
}
else if (o is EditorActorDropdown ddo)
{
var dropdownContainer = dropdownOptionTemplate.Clone();
dropdownContainer.Bounds.Y = initContainer.Bounds.Height;
initContainer.Bounds.Height += dropdownContainer.Bounds.Height;
dropdownContainer.Get<LabelWidget>("LABEL").GetText = () => ddo.Name;
var editorActionHandle = new EditorActorOptionActionHandle<string>(ddo.OnChange, ddo.GetValue(actor));
editActorPreview.Add(editorActionHandle);
var dropdown = dropdownContainer.Get<DropDownButtonWidget>("OPTION");
ScrollItemWidget DropdownSetup(KeyValuePair<string, string> option, ScrollItemWidget template)
{
var item = ScrollItemWidget.Setup(template,
() => ddo.GetValue(actor) == option.Key,
() =>
{
ddo.OnChange(actor, option.Key);
editorActionHandle.OnChange(option.Key);
});
item.Get<LabelWidget>("LABEL").GetText = () => option.Value;
return item;
}
dropdown.GetText = () => ddo.Labels[ddo.GetValue(actor)];
dropdown.OnClick = () => dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 270, ddo.Labels, DropdownSetup);
initContainer.AddChild(dropdownContainer);
}
}
buttonContainer.Bounds.Y += initContainer.Bounds.Height - oldInitHeight;
}
}
else if (CurrentActor != null)
{
// Selected actor is null, hide the border and edit panel.
Close();
}
}
void Delete()
{
if (CurrentActor != null)
editorActionManager.Add(new RemoveActorAction(editorActorLayer, CurrentActor));
YieldFocus();
Close();
if (SelectedActor != null)
editorActionManager.Add(new RemoveSelectedActorAction(
editor.DefaultBrush,
editorActorLayer,
SelectedActor));
}
void Cancel()
@@ -375,19 +363,26 @@ namespace OpenRA.Mods.Common.Widgets.Logic
editActorPreview?.Reset();
}
void Close()
void YieldFocus()
{
actorIDField.YieldKeyboardFocus();
foreach (var f in typableFields)
f.YieldKeyboardFocus();
}
editor.DefaultBrush.Selection.Actor = null;
CurrentActor = null;
void Close()
{
YieldFocus();
if (SelectedActor != null)
{
editor.DefaultBrush.ClearSelection(updateSelectedTab: true);
}
}
void Save()
{
editorActionManager.Add(new EditActorEditorAction(editorActorLayer, CurrentActor, editActorPreview.GetDirtyHandles()));
editorActionManager.Add(new EditActorEditorAction(editorActorLayer, SelectedActor, editActorPreview.GetDirtyHandles()));
editActorPreview = null;
Close();
}

View File

@@ -21,6 +21,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class MapEditorSelectionLogic : ChromeLogic
{
[TranslationReference]
const string AreaSelection = "label-area-selection";
readonly EditorViewportControllerWidget editor;
readonly WorldRenderer worldRenderer;
@@ -31,27 +34,24 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly CheckboxWidget copyResourcesCheckbox;
readonly CheckboxWidget copyActorsCheckbox;
readonly EditorActorLayer editorActorLayer;
readonly EditorResourceLayer editorResourceLayer;
readonly IResourceLayer resourceLayer;
public LabelWidget RegionLabel;
public LabelWidget DimensionsLabel;
public LabelWidget AreaEditTitle;
public LabelWidget DiagonalLabel;
public LabelWidget ResourceCounterLabel;
MapCopyFilters copyFilters = MapCopyFilters.All;
EditorClipboard? clipboard;
readonly IResourceLayer resourceLayer;
readonly EditorResourceLayer editorResourceLayer;
[ObjectCreator.UseCtor]
public MapEditorSelectionLogic(Widget widget, World world, WorldRenderer worldRenderer)
{
this.worldRenderer = worldRenderer;
editorActorLayer = world.WorldActor.Trait<EditorActorLayer>();
resourceLayer = world.WorldActor.Trait<IResourceLayer>();
editorResourceLayer = world.WorldActor.Trait<EditorResourceLayer>();
resourceLayer = world.WorldActor.TraitOrDefault<IResourceLayer>();
editorResourceLayer = world.WorldActor.TraitOrDefault<EditorResourceLayer>();
editor = widget.Get<EditorViewportControllerWidget>("MAP_EDITOR");
editor.DefaultBrush.SelectionChanged += HandleSelectionChanged;
@@ -59,8 +59,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
actorEditPanel = selectTabContainer.Get<ContainerWidget>("ACTOR_EDIT_PANEL");
areaEditPanel = selectTabContainer.Get<ContainerWidget>("AREA_EDIT_PANEL");
actorEditPanel.IsVisible = () => editor.CurrentBrush == editor.DefaultBrush && editor.DefaultBrush.Selection.Actor != null;
areaEditPanel.IsVisible = () => !actorEditPanel.IsVisible();
actorEditPanel.IsVisible = () => editor.DefaultBrush.Selection.Actor != null;
areaEditPanel.IsVisible = () => editor.DefaultBrush.Selection.Area != null;
copyTerrainCheckbox = areaEditPanel.Get<CheckboxWidget>("COPY_FILTER_TERRAIN_CHECKBOX");
copyResourcesCheckbox = areaEditPanel.Get<CheckboxWidget>("COPY_FILTER_RESOURCES_CHECKBOX");
@@ -74,8 +74,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
copyButton.OnClick = () => clipboard = CopySelectionContents();
copyButton.IsDisabled = () => editor.DefaultBrush.Selection.Area == null;
RegionLabel = areaEditPanel.Get<LabelWidget>("REGION_COUNTER_LABEL");
DimensionsLabel = areaEditPanel.Get<LabelWidget>("DIMENSION_COUNTER_LABEL");
AreaEditTitle = areaEditPanel.Get<LabelWidget>("AREA_EDIT_TITLE");
DiagonalLabel = areaEditPanel.Get<LabelWidget>("DIAGONAL_COUNTER_LABEL");
ResourceCounterLabel = areaEditPanel.Get<LabelWidget>("RESOURCES_COUNTER_LABEL");
@@ -97,7 +96,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
pasteButton.IsHighlighted = () => editor.CurrentBrush is EditorCopyPasteBrush;
var closeAreaSelectionButton = areaEditPanel.Get<ButtonWidget>("SELECTION_CANCEL_BUTTON");
closeAreaSelectionButton.OnClick = () => editor.DefaultBrush.ClearSelection();
closeAreaSelectionButton.OnClick = () => editor.DefaultBrush.ClearSelection(updateSelectedTab: true);
CreateCategoryPanel(MapCopyFilters.Terrain, copyTerrainCheckbox);
CreateCategoryPanel(MapCopyFilters.Resources, copyResourcesCheckbox);
@@ -121,7 +120,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (!mapTiles.Contains(cell))
continue;
tiles.Add(cell, new ClipboardTile(mapTiles[cell], mapResources[cell], resourceLayer.GetResource(cell), mapHeight[cell]));
tiles.Add(cell, new ClipboardTile(mapTiles[cell], mapResources[cell], resourceLayer?.GetResource(cell), mapHeight[cell]));
if (copyFilters.HasFlag(MapCopyFilters.Actors))
foreach (var preview in selection.SelectMany(editorActorLayer.PreviewsAt).Distinct())
@@ -150,18 +149,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var selectedRegion = editor.DefaultBrush.Selection.Area;
if (selectedRegion == null)
return;
if (editorResourceLayer == null)
return;
var selectionSize = selectedRegion.BottomRight - selectedRegion.TopLeft + new CPos(1, 1);
var diagonalLength = Math.Round(Math.Sqrt(Math.Pow(selectionSize.X, 2) + Math.Pow(selectionSize.Y, 2)), 3);
var resourceValueInRegion = editorResourceLayer.CalculateRegionValue(selectedRegion);
RegionLabel.GetText = () => $"{PositionAsString(selectedRegion.TopLeft)} : {PositionAsString(selectedRegion.BottomRight)}";
DimensionsLabel.GetText = () => PositionAsString(selectionSize);
var areaSelectionLabel = $"{TranslationProvider.GetString(AreaSelection)} ({DimensionsAsString(selectionSize)}) {PositionAsString(selectedRegion.TopLeft)} : {PositionAsString(selectedRegion.BottomRight)}";
AreaEditTitle.GetText = () => areaSelectionLabel;
DiagonalLabel.GetText = () => $"{diagonalLength}";
ResourceCounterLabel.GetText = () => $"{resourceValueInRegion}$";
ResourceCounterLabel.GetText = () => $"${resourceValueInRegion:N0}";
}
static string PositionAsString(CPos cell)
{
return $"{cell.X},{cell.Y}";
}
static string PositionAsString(CPos cell) => $"{cell.X},{cell.Y}";
static string DimensionsAsString(CPos cell) => $"{cell.X}x{cell.Y}";
}
}

View File

@@ -29,11 +29,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
this.widget = widget;
editor = widget.Parent.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR");
editor.DefaultBrush.SelectionChanged += HandleSelectionChanged;
editor.DefaultBrush.UpdateSelectedTab += HandleUpdateSelectedTab;
tabContainer = widget.Get("MAP_EDITOR_TAB_CONTAINER");
SetupTab(null, "SELECT_WIDGETS", MenuType.Select);
SetupTab("SELECT_TAB", "SELECT_WIDGETS", MenuType.Select);
SetupTab("TILES_TAB", "TILE_WIDGETS", MenuType.Tiles);
SetupTab("OVERLAYS_TAB", "LAYER_WIDGETS", MenuType.Layers);
SetupTab("ACTORS_TAB", "ACTOR_WIDGETS", MenuType.Actors);
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
protected override void Dispose(bool disposing)
{
editor.DefaultBrush.SelectionChanged -= HandleSelectionChanged;
editor.DefaultBrush.UpdateSelectedTab -= HandleUpdateSelectedTab;
base.Dispose(disposing);
}
@@ -55,6 +55,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var tab = tabContainer.Get<ButtonWidget>(buttonId);
tab.IsHighlighted = () => menuType == tabType;
tab.OnClick = () => menuType = SelectTab(tabType);
if (tabType == MenuType.Select)
tab.IsDisabled = () => !editor.DefaultBrush.Selection.HasSelection;
}
var container = widget.Parent.Get<ContainerWidget>(tabId);
@@ -63,26 +66,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic
MenuType SelectTab(MenuType newMenuType)
{
if (menuType == MenuType.Select)
{
editor.SetBrush(editor.DefaultBrush);
editor.DefaultBrush.ClearSelection();
}
if (newMenuType != MenuType.Select)
lastSelectedTab = newMenuType;
return newMenuType;
}
void HandleSelectionChanged()
void HandleUpdateSelectedTab()
{
var actor = editor.DefaultBrush.Selection.Actor;
var area = editor.DefaultBrush.Selection.Area;
var hasSelection = editor.DefaultBrush.Selection.HasSelection;
if (menuType != MenuType.Select && (actor != null || area != null))
if (menuType != MenuType.Select && hasSelection)
menuType = MenuType.Select;
else if (menuType == MenuType.Select && actor == null && area == null)
else if (menuType == MenuType.Select && !hasSelection)
menuType = lastSelectedTab;
}
}