diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorClipboard.cs b/OpenRA.Mods.Common/EditorBrushes/EditorClipboard.cs index e92f39b4fa..b505822fc5 100644 --- a/OpenRA.Mods.Common/EditorBrushes/EditorClipboard.cs +++ b/OpenRA.Mods.Common/EditorBrushes/EditorClipboard.cs @@ -1,4 +1,15 @@ -using System.Collections.Generic; +#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.Collections.Generic; using OpenRA.Mods.Common.Traits; namespace OpenRA.Mods.Common.EditorBrushes @@ -7,10 +18,10 @@ namespace OpenRA.Mods.Common.EditorBrushes { public readonly TerrainTile TerrainTile; public readonly ResourceTile ResourceTile; - public readonly ResourceLayerContents ResourceLayerContents; + public readonly ResourceLayerContents? ResourceLayerContents; public readonly byte Height; - public ClipboardTile(TerrainTile terrainTile, ResourceTile resourceTile, ResourceLayerContents resourceLayerContents, byte height) + public ClipboardTile(TerrainTile terrainTile, ResourceTile resourceTile, ResourceLayerContents? resourceLayerContents, byte height) { TerrainTile = terrainTile; ResourceTile = resourceTile; diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs b/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs index acd29aef3f..c0e0a0b4c0 100644 --- a/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs +++ b/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs @@ -161,7 +161,7 @@ namespace OpenRA.Mods.Common.Widgets if (!mapTiles.Contains(cell)) continue; - var resourceLayerContents = resourceLayer.GetResource(cell); + var resourceLayerContents = resourceLayer?.GetResource(cell); tiles.Add(cell, new ClipboardTile(mapTiles[cell], mapResources[cell], resourceLayerContents, mapHeight[cell])); if (copyFilters.HasFlag(MapCopyFilters.Actors)) @@ -189,7 +189,7 @@ namespace OpenRA.Mods.Common.Widgets continue; // Clear any existing resources. - if (copyFilters.HasFlag(MapCopyFilters.Resources)) + if (resourceLayer != null && copyFilters.HasFlag(MapCopyFilters.Resources)) resourceLayer.ClearResources(position); var tile = tileKeyValuePair.Value; @@ -201,33 +201,38 @@ namespace OpenRA.Mods.Common.Widgets map.Height[position] = tile.Height; } - if (copyFilters.HasFlag(MapCopyFilters.Resources) && !string.IsNullOrWhiteSpace(resourceLayerContents.Type)) - resourceLayer.AddResource(resourceLayerContents.Type, position, resourceLayerContents.Density); + if (copyFilters.HasFlag(MapCopyFilters.Resources) && + resourceLayerContents.HasValue && + !string.IsNullOrWhiteSpace(resourceLayerContents.Value.Type)) + resourceLayer.AddResource(resourceLayerContents.Value.Type, position, resourceLayerContents.Value.Density); } - // Clear any existing actors in the paste cells. - var selectionSize = clipboard.CellRegion.BottomRight - clipboard.CellRegion.TopLeft; - var pasteRegion = new CellRegion(map.Grid.Type, pastePosition, pastePosition + selectionSize); - foreach (var regionActor in pasteRegion.SelectMany(editorActorLayer.PreviewsAt).ToHashSet()) - editorActorLayer.Remove(regionActor); - - // Now place actors. - foreach (var actorKeyValuePair in clipboard.Actors) + if (copyFilters.HasFlag(MapCopyFilters.Actors)) { - var selection = clipboard.CellRegion; - var copy = actorKeyValuePair.Value.Export(); - var locationInit = copy.GetOrDefault(); - if (locationInit != null) + // Clear any existing actors in the paste cells. + var selectionSize = clipboard.CellRegion.BottomRight - clipboard.CellRegion.TopLeft; + var pasteRegion = new CellRegion(map.Grid.Type, pastePosition, pastePosition + selectionSize); + foreach (var regionActor in pasteRegion.SelectMany(editorActorLayer.PreviewsAt).ToHashSet()) + editorActorLayer.Remove(regionActor); + + // Now place actors. + foreach (var actorKeyValuePair in clipboard.Actors) { - var actorPosition = locationInit.Value + new CVec(pastePosition.X - selection.TopLeft.X, pastePosition.Y - selection.TopLeft.Y); - if (!map.Contains(actorPosition)) - continue; + var selection = clipboard.CellRegion; + var copy = actorKeyValuePair.Value.Export(); + var locationInit = copy.GetOrDefault(); + if (locationInit != null) + { + var actorPosition = locationInit.Value + new CVec(pastePosition.X - selection.TopLeft.X, pastePosition.Y - selection.TopLeft.Y); + if (!map.Contains(actorPosition)) + continue; - copy.RemoveAll(); - copy.Add(new LocationInit(actorPosition)); + copy.RemoveAll(); + copy.Add(new LocationInit(actorPosition)); + } + + editorActorLayer.Add(copy); } - - editorActorLayer.Add(copy); } } @@ -240,7 +245,7 @@ namespace OpenRA.Mods.Common.Widgets var resourceLayerContents = tile.ResourceLayerContents; // Clear any existing resources. - if (copyFilters.HasFlag(MapCopyFilters.Resources)) + if (resourceLayer != null && copyFilters.HasFlag(MapCopyFilters.Resources)) resourceLayer.ClearResources(position); if (copyFilters.HasFlag(MapCopyFilters.Terrain)) @@ -249,18 +254,22 @@ namespace OpenRA.Mods.Common.Widgets map.Height[position] = tile.Height; } - if (copyFilters.HasFlag(MapCopyFilters.Resources) && !string.IsNullOrWhiteSpace(resourceLayerContents.Type)) - resourceLayer.AddResource(resourceLayerContents.Type, position, resourceLayerContents.Density); + if (copyFilters.HasFlag(MapCopyFilters.Resources) && + resourceLayerContents.HasValue && + !string.IsNullOrWhiteSpace(resourceLayerContents.Value.Type)) + resourceLayer.AddResource(resourceLayerContents.Value.Type, position, resourceLayerContents.Value.Density); } - // Clear existing actors. - foreach (var regionActor in undoClipboard.CellRegion.SelectMany(editorActorLayer.PreviewsAt).Distinct().ToList()) - editorActorLayer.Remove(regionActor); - - // Place actors back again. if (copyFilters.HasFlag(MapCopyFilters.Actors)) + { + // Clear existing actors. + foreach (var regionActor in undoClipboard.CellRegion.SelectMany(editorActorLayer.PreviewsAt).Distinct().ToList()) + editorActorLayer.Remove(regionActor); + + // Place actors back again. foreach (var actor in undoClipboard.Actors.Values) editorActorLayer.Add(actor); + } } } } diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorDefaultBrush.cs b/OpenRA.Mods.Common/EditorBrushes/EditorDefaultBrush.cs index 34f319c8d2..0518095a9d 100644 --- a/OpenRA.Mods.Common/EditorBrushes/EditorDefaultBrush.cs +++ b/OpenRA.Mods.Common/EditorBrushes/EditorDefaultBrush.cs @@ -26,6 +26,8 @@ namespace OpenRA.Mods.Common.Widgets { public CellRegion Area; public EditorActorPreview Actor; + + public bool HasSelection => Area != null || Actor != null; } public sealed class EditorDefaultBrush : IEditorBrush @@ -33,6 +35,7 @@ namespace OpenRA.Mods.Common.Widgets const int MinMouseMoveBeforeDrag = 32; public event Action SelectionChanged; + public event Action UpdateSelectedTab; readonly WorldRenderer worldRenderer; readonly World world; @@ -43,7 +46,8 @@ namespace OpenRA.Mods.Common.Widgets public CellRegion CurrentDragBounds => selectionBounds ?? Selection.Area; - public EditorSelection Selection = new(); + public EditorSelection Selection { get; private set; } = new(); + EditorSelection previousSelection; CellRegion selectionBounds; int2? selectionStartLocation; @@ -73,17 +77,34 @@ namespace OpenRA.Mods.Common.Widgets return ((long)pixelDistance << 32) + worldZPosition; } - public void ClearSelection() + public void ClearSelection(bool updateSelectedTab = false) { - if (Selection.Area != null || Selection.Actor != null) + if (Selection.HasSelection) { previousSelection = Selection; - Selection = new EditorSelection(); + SetSelection(new EditorSelection()); editorActionManager.Add(new ChangeSelectionAction(this, Selection, previousSelection)); - SelectionChanged?.Invoke(); + + if (updateSelectedTab) + UpdateSelectedTab?.Invoke(); } } + public void SetSelection(EditorSelection selection) + { + if (Selection == selection) + return; + + if (Selection.Actor != null) + Selection.Actor.Selected = false; + + Selection = selection; + if (Selection.Actor != null) + Selection.Actor.Selected = true; + + SelectionChanged?.Invoke(); + } + public bool HandleMouseInput(MouseInput mi) { // Exclusively uses mouse wheel and both mouse buttons, but nothing else. @@ -155,14 +176,14 @@ namespace OpenRA.Mods.Common.Widgets { // Set this as the editor selection. previousSelection = Selection; - Selection = new EditorSelection + SetSelection(new EditorSelection { Area = selectionBounds - }; + }); - editorActionManager.Add(new ChangeSelectionAction(this, Selection, previousSelection)); selectionBounds = null; - SelectionChanged?.Invoke(); + editorActionManager.Add(new ChangeSelectionAction(this, Selection, previousSelection)); + UpdateSelectedTab?.Invoke(); } else if (underCursor != null) { @@ -170,48 +191,32 @@ namespace OpenRA.Mods.Common.Widgets if (Selection.Actor != underCursor) { previousSelection = Selection; - Selection = new EditorSelection + SetSelection(new EditorSelection { Actor = underCursor, - }; + }); editorActionManager.Add(new ChangeSelectionAction(this, Selection, previousSelection)); - SelectionChanged?.Invoke(); + UpdateSelectedTab?.Invoke(); } } - else if (Selection.Area != null || Selection.Actor != null) + else if (Selection.HasSelection) { // Released left mouse without dragging or selecting an actor - deselect current. - previousSelection = Selection; - Selection = new EditorSelection(); - - editorActionManager.Add(new ChangeSelectionAction(this, Selection, previousSelection)); - SelectionChanged?.Invoke(); + ClearSelection(updateSelectedTab: true); } } - - if (mi.Button == MouseButton.Right) + else if (mi.Button == MouseButton.Right) { editorWidget.SetTooltip(null); - if (Selection.Area != null) - { - // Release right mouse button with a selection - clear selection. - previousSelection = Selection; - Selection = new EditorSelection(); + // Delete actor. + if (underCursor != null && underCursor != Selection.Actor) + editorActionManager.Add(new RemoveActorAction(editorLayer, underCursor)); - editorActionManager.Add(new ChangeSelectionAction(this, Selection, previousSelection)); - } - else - { - // Release right mouse button with no selection and over an actor - delete actor. - if (underCursor != null && underCursor != Selection.Actor) - editorActionManager.Add(new RemoveActorAction(editorLayer, underCursor)); - - // Or delete resource if found under cursor. - if (resourceUnderCursor != null) - editorActionManager.Add(new RemoveResourceAction(resourceLayer, cell, resourceUnderCursor)); - } + // Or delete resource if found under cursor. + if (resourceUnderCursor != null) + editorActionManager.Add(new RemoveResourceAction(resourceLayer, cell, resourceUnderCursor)); } } @@ -219,6 +224,7 @@ namespace OpenRA.Mods.Common.Widgets } public void Tick() { } + public void Dispose() { } } @@ -271,12 +277,59 @@ namespace OpenRA.Mods.Common.Widgets public void Do() { - defaultBrush.Selection = selection; + defaultBrush.SetSelection(selection); } public void Undo() { - defaultBrush.Selection = previousSelection; + defaultBrush.SetSelection(previousSelection); + } + } + + sealed class RemoveSelectedActorAction : IEditorAction + { + [TranslationReference("name", "id")] + const string RemovedActor = "notification-removed-actor"; + + public string Text { get; } + + readonly EditorSelection selection; + readonly EditorDefaultBrush defaultBrush; + readonly EditorActorLayer editorActorLayer; + readonly EditorActorPreview actor; + + public RemoveSelectedActorAction( + EditorDefaultBrush defaultBrush, + EditorActorLayer editorActorLayer, + EditorActorPreview actor) + { + this.defaultBrush = defaultBrush; + this.editorActorLayer = editorActorLayer; + this.actor = actor; + selection = new EditorSelection + { + Actor = defaultBrush.Selection.Actor + }; + + Text = TranslationProvider.GetString(RemovedActor, + Translation.Arguments("name", actor.Info.Name, "id", actor.ID)); + } + + public void Execute() + { + Do(); + } + + public void Do() + { + defaultBrush.SetSelection(new EditorSelection()); + editorActorLayer.Remove(actor); + } + + public void Undo() + { + editorActorLayer.Add(actor); + defaultBrush.SetSelection(selection); } } diff --git a/OpenRA.Mods.Common/Traits/World/EditorActionManager.cs b/OpenRA.Mods.Common/Traits/World/EditorActionManager.cs index 63fa037aab..986b03e76d 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorActionManager.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorActionManager.cs @@ -156,6 +156,7 @@ namespace OpenRA.Mods.Common.Traits public void Execute() { + Do(); } public void Do() diff --git a/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs index 5911e1dbb2..1c6b62aa1b 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorSelectionLayer.cs @@ -59,7 +59,7 @@ namespace OpenRA.Mods.Common.Traits IEnumerable IRenderAnnotations.RenderAnnotations(Actor self, WorldRenderer wr) { - if (editor.CurrentBrush == editor.DefaultBrush && editor.DefaultBrush.CurrentDragBounds != null) + if (editor.DefaultBrush.CurrentDragBounds != null) { yield return new EditorSelectionAnnotationRenderable(editor.DefaultBrush.CurrentDragBounds, info.AltColor, info.AltPixelOffset, null); yield return new EditorSelectionAnnotationRenderable(editor.DefaultBrush.CurrentDragBounds, info.MainColor, int2.Zero, null); diff --git a/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs index c25d0774ba..de7430b114 100644 --- a/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs @@ -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; } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorEditLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorEditLogic.cs index c4f94897e2..67e38ca274 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorEditLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorEditLogic.cs @@ -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 logicArgs) @@ -88,8 +68,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic editorActionManager = world.WorldActor.Trait(); editor = widget.Parent.Parent.Get("MAP_EDITOR"); - var selectTabContainer = widget.Parent.Parent.Get("SELECT_WIDGETS"); + editor.DefaultBrush.SelectionChanged += HandleSelectionChanged; + var selectTabContainer = widget.Parent.Parent.Get("SELECT_WIDGETS"); actorEditPanel = selectTabContainer.Get("ACTOR_EDIT_PANEL"); typeLabel = actorEditPanel.Get("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("LABEL").GetText = () => owner; + var ownerDropdown = ownerContainer.Get("OPTION"); + var selectedOwner = SelectedActor.Owner; + + void UpdateOwner(EditorActorPreview preview, PlayerReference reference) + { + preview.Owner = reference; + preview.ReplaceInit(new OwnerInit(reference.Name)); + } + + var ownerHandler = new EditorActorOptionActionHandle(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("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() + .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("OPTION"); + checkbox.GetText = () => co.Name; + + var editorActionHandle = new EditorActorOptionActionHandle(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("LABEL").GetText = () => so.Name; + + var slider = sliderContainer.Get("OPTION"); + slider.MinimumValue = so.MinValue; + slider.MaximumValue = so.MaxValue; + slider.Ticks = so.Ticks; + + var editorActionHandle = new EditorActorOptionActionHandle(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("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("LABEL").GetText = () => ddo.Name; + + var editorActionHandle = new EditorActorOptionActionHandle(ddo.OnChange, ddo.GetValue(SelectedActor)); + editActorPreview.Add(editorActionHandle); + + var dropdown = dropdownContainer.Get("OPTION"); + ScrollItemWidget DropdownSetup(KeyValuePair option, ScrollItemWidget template) + { + var item = ScrollItemWidget.Setup(template, + () => ddo.GetValue(SelectedActor) == option.Key, + () => + { + ddo.OnChange(SelectedActor, option.Key); + editorActionHandle.OnChange(option.Key); + }); + + item.Get("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("LABEL").GetText = () => owner; - var ownerDropdown = ownerContainer.Get("OPTION"); - var selectedOwner = actor.Owner; - - void UpdateOwner(EditorActorPreview preview, PlayerReference reference) - { - preview.Owner = reference; - preview.ReplaceInit(new OwnerInit(reference.Name)); - } - - var ownerHandler = new EditorActorOptionActionHandle(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("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() - .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("OPTION"); - checkbox.GetText = () => co.Name; - - var editorActionHandle = new EditorActorOptionActionHandle(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("LABEL").GetText = () => so.Name; - - var slider = sliderContainer.Get("OPTION"); - slider.MinimumValue = so.MinValue; - slider.MaximumValue = so.MaxValue; - slider.Ticks = so.Ticks; - - var editorActionHandle = new EditorActorOptionActionHandle(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("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("LABEL").GetText = () => ddo.Name; - - var editorActionHandle = new EditorActorOptionActionHandle(ddo.OnChange, ddo.GetValue(actor)); - editActorPreview.Add(editorActionHandle); - - var dropdown = dropdownContainer.Get("OPTION"); - ScrollItemWidget DropdownSetup(KeyValuePair option, ScrollItemWidget template) - { - var item = ScrollItemWidget.Setup(template, - () => ddo.GetValue(actor) == option.Key, - () => - { - ddo.OnChange(actor, option.Key); - editorActionHandle.OnChange(option.Key); - }); - - item.Get("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(); } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs index 2b6225c89d..12b77d3897 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs @@ -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(); - resourceLayer = world.WorldActor.Trait(); - editorResourceLayer = world.WorldActor.Trait(); + resourceLayer = world.WorldActor.TraitOrDefault(); + editorResourceLayer = world.WorldActor.TraitOrDefault(); editor = widget.Get("MAP_EDITOR"); editor.DefaultBrush.SelectionChanged += HandleSelectionChanged; @@ -59,8 +59,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic actorEditPanel = selectTabContainer.Get("ACTOR_EDIT_PANEL"); areaEditPanel = selectTabContainer.Get("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("COPY_FILTER_TERRAIN_CHECKBOX"); copyResourcesCheckbox = areaEditPanel.Get("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("REGION_COUNTER_LABEL"); - DimensionsLabel = areaEditPanel.Get("DIMENSION_COUNTER_LABEL"); + AreaEditTitle = areaEditPanel.Get("AREA_EDIT_TITLE"); DiagonalLabel = areaEditPanel.Get("DIAGONAL_COUNTER_LABEL"); ResourceCounterLabel = areaEditPanel.Get("RESOURCES_COUNTER_LABEL"); @@ -97,7 +96,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic pasteButton.IsHighlighted = () => editor.CurrentBrush is EditorCopyPasteBrush; var closeAreaSelectionButton = areaEditPanel.Get("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}"; } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorTabsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorTabsLogic.cs index 5c615ac632..e32161b677 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorTabsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorTabsLogic.cs @@ -29,11 +29,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic { this.widget = widget; editor = widget.Parent.Parent.Get("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(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(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; } } diff --git a/mods/cnc/chrome.yaml b/mods/cnc/chrome.yaml index b6339c1f0b..10aab40efa 100644 --- a/mods/cnc/chrome.yaml +++ b/mods/cnc/chrome.yaml @@ -753,6 +753,9 @@ chrome-radar-gdi: editor: Inherits: ^Chrome Regions: + select: 802, 170, 16, 16 tiles: 768, 170, 16, 16 overlays: 785, 170, 16, 16 + actors: 802, 68, 16, 16 tools: 904, 68, 16, 16 + history: 904, 51, 16, 16 diff --git a/mods/cnc/chrome/editor.yaml b/mods/cnc/chrome/editor.yaml index 1cbfe6e182..eb5170876d 100644 --- a/mods/cnc/chrome/editor.yaml +++ b/mods/cnc/chrome/editor.yaml @@ -506,7 +506,7 @@ Container@EDITOR_WORLD_ROOT: Label@AREA_EDIT_TITLE: X: 6 Y: 7 - Width: 265 + Width: 278 Height: 24 Align: Center Font: Bold @@ -539,71 +539,43 @@ Container@EDITOR_WORLD_ROOT: Text: label-filter-actors Label@AREA_INFO_TITLE: X: 15 - Y: 150 + Y: 139 Width: 281 Height: 24 Align: Center Font: Bold Text: label-area-info - Label@REGION_LABEL: - X: 15 - Y: 175 + Label@DIAGONAL_LABEL: + X: 6 + Y: 171 Width: 55 Height: 20 Font: Bold Align: Left - Text: label-selected-area-selected-region - Label@DIMENSION_LABEL: - X: 15 - Y: 200 - Width: 55 - Height: 25 - Font: Bold - Align: Left - Text: label-selected-area-dimension - Label@DIAGONAL_LABEL: - X: 15 - Y: 225 - Width: 55 - Height: 25 - Font: Bold - Align: Left Text: label-selected-area-diagonal Label@RESOURCE_LABEL: - X: 15 - Y: 250 + X: 6 + Y: 193 Width: 55 Height: 25 Font: Bold Align: Left Text: label-selected-area-resources - Label@REGION_COUNTER_LABEL: - X: 150 - Y: 175 - Width: 55 - Height: 22 - Align: Left - Label@DIMENSION_COUNTER_LABEL: - X: 150 - Y: 200 - Width: 55 - Height: 22 - Align: Left Label@DIAGONAL_COUNTER_LABEL: X: 150 - Y: 225 + Y: 170 Width: 55 Height: 22 Align: Left Label@RESOURCES_COUNTER_LABEL: X: 150 - Y: 250 + Y: 195 Width: 55 Height: 22 Align: Left Button@SELECTION_CANCEL_BUTTON: - X: 107 - Y: 275 + X: 211 + Y: 222 Width: 75 Height: 25 Text: button-selection-cancel @@ -618,7 +590,7 @@ Container@EDITOR_WORLD_ROOT: Label@ACTOR_TYPE_LABEL: X: 6 Y: 2 - Width: 265 + Width: 278 Height: 24 Align: Center Font: Bold @@ -720,8 +692,22 @@ Container@EDITOR_WORLD_ROOT: Height: 25 ClickThrough: false Children: + Button@SELECT_TAB: + Width: 49 + Height: 25 + Key: EditorSelectTab + TooltipTemplate: BUTTON_TOOLTIP + TooltipText: button-map-editor-tab-container-select.tooltip + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + X: 20 + Y: 5 + ImageCollection: editor + ImageName: select Button@TILES_TAB: - Width: 59 + X: 49 + Width: 48 Height: 25 Key: EditorTilesTab TooltipTemplate: BUTTON_TOOLTIP @@ -729,13 +715,13 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Children: Image@ICON: - X: 21 + X: 16 Y: 5 ImageCollection: editor ImageName: tiles Button@OVERLAYS_TAB: - X: 58 - Width: 59 + X: 97 + Width: 48 Height: 25 Key: EditorOverlaysTab TooltipTemplate: BUTTON_TOOLTIP @@ -743,13 +729,13 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Children: Image@ICON: - X: 21 + X: 16 Y: 5 ImageCollection: editor ImageName: overlays Button@ACTORS_TAB: - X: 116 - Width: 58 + X: 145 + Width: 48 Height: 25 Key: EditorActorsTab TooltipTemplate: BUTTON_TOOLTIP @@ -757,13 +743,13 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Children: Image@ICON: - X: 21 + X: 16 Y: 5 - ImageCollection: production-icons - ImageName: infantry + ImageCollection: editor + ImageName: actors Button@TOOLS_TAB: - X: 173 - Width: 59 + X: 193 + Width: 48 Height: 25 Key: EditorToolsTab TooltipTemplate: BUTTON_TOOLTIP @@ -771,13 +757,13 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Children: Image@ICON: - X: 21 + X: 16 Y: 5 ImageCollection: editor ImageName: tools Button@HISTORY_TAB: - X: 231 - Width: 59 + X: 241 + Width: 49 Height: 25 Key: EditorHistoryTab TooltipTemplate: BUTTON_TOOLTIP @@ -785,10 +771,10 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Children: Image@ICON: - X: 21 + X: 16 Y: 5 - ImageCollection: sidebar-bits - ImageName: production-tooltip-time + ImageCollection: editor + ImageName: history Button@UNDO_BUTTON: X: WINDOW_RIGHT - 764 Y: 5 diff --git a/mods/cnc/languages/chrome/en.ftl b/mods/cnc/languages/chrome/en.ftl index 9af8cd941f..952fc3e204 100644 --- a/mods/cnc/languages/chrome/en.ftl +++ b/mods/cnc/languages/chrome/en.ftl @@ -74,8 +74,6 @@ label-actors-bg-categories = Filter: label-actors-bg-owners = Owner: label-area-selection = Area Selection label-area-info = Area Info -label-selected-area-selected-region = Region: -label-selected-area-dimension = Dimensions: label-selected-area-diagonal = Diagonal: label-selected-area-resources= Resources: label-copy-filters = Copy Filters @@ -86,6 +84,9 @@ button-selection-cancel = Cancel label-show-tile-grid = Show Tile Grid label-show-buildable-area = Show Buildable Area +button-map-editor-tab-container-select = + .tooltip = Select + button-map-editor-tab-container-tiles = .tooltip = Tiles diff --git a/mods/cnc/uibits/chrome-2x.png b/mods/cnc/uibits/chrome-2x.png index 3f096a4f9d..7b84da62ff 100644 Binary files a/mods/cnc/uibits/chrome-2x.png and b/mods/cnc/uibits/chrome-2x.png differ diff --git a/mods/cnc/uibits/chrome-3x.png b/mods/cnc/uibits/chrome-3x.png index 4614d48f78..b9e2353295 100644 Binary files a/mods/cnc/uibits/chrome-3x.png and b/mods/cnc/uibits/chrome-3x.png differ diff --git a/mods/cnc/uibits/chrome.png b/mods/cnc/uibits/chrome.png index c226b2813c..d8142060f9 100644 Binary files a/mods/cnc/uibits/chrome.png and b/mods/cnc/uibits/chrome.png differ diff --git a/mods/common/chrome/editor.yaml b/mods/common/chrome/editor.yaml index eaf58aa7df..95734df23a 100644 --- a/mods/common/chrome/editor.yaml +++ b/mods/common/chrome/editor.yaml @@ -448,9 +448,9 @@ Container@EDITOR_WORLD_ROOT: Height: WINDOW_BOTTOM - 458 Children: Label@AREA_EDIT_TITLE: - X: 15 + X: 6 Y: 16 - Width: 281 + Width: 298 Height: 24 Align: Center Font: Bold @@ -482,72 +482,44 @@ Container@EDITOR_WORLD_ROOT: Height: 20 Text: label-filter-actors Label@AREA_INFO_TITLE: - X: 15 - Y: 150 - Width: 281 + X: 6 + Y: 139 + Width: 298 Height: 24 Align: Center Font: Bold Text: label-area-info - Label@REGION_LABEL: - X: 15 - Y: 175 - Width: 55 - Height: 20 - Font: Bold - Align: Left - Text: label-selected-area-selected-region - Label@DIMENSION_LABEL: - X: 15 - Y: 200 - Width: 55 - Height: 25 - Font: Bold - Align: Left - Text: label-selected-area-dimension Label@DIAGONAL_LABEL: X: 15 - Y: 225 + Y: 171 Width: 55 - Height: 25 + Height: 20 Font: Bold Align: Left Text: label-selected-area-diagonal Label@RESOURCE_LABEL: X: 15 - Y: 250 + Y: 193 Width: 55 Height: 25 Font: Bold Align: Left Text: label-selected-area-resources - Label@REGION_COUNTER_LABEL: - X: 150 - Y: 175 - Width: 55 - Height: 22 - Align: Left - Label@DIMENSION_COUNTER_LABEL: - X: 150 - Y: 200 - Width: 55 - Height: 22 - Align: Left Label@DIAGONAL_COUNTER_LABEL: X: 150 - Y: 225 + Y: 170 Width: 55 Height: 22 Align: Left Label@RESOURCES_COUNTER_LABEL: X: 150 - Y: 250 + Y: 195 Width: 55 Height: 22 Align: Left Button@SELECTION_CANCEL_BUTTON: - X: 117 - Y: 275 + X: 222 + Y: 222 Width: 75 Height: 25 Text: button-selection-cancel @@ -660,9 +632,23 @@ Container@EDITOR_WORLD_ROOT: Width: 292 Height: 25 Children: - Button@TILES_TAB: + Button@SELECT_TAB: X: 0 - Width: 58 + Width: 49 + Height: 25 + Key: EditorSelectTab + TooltipTemplate: BUTTON_TOOLTIP + TooltipText: button-map-editor-tab-container-select.tooltip + TooltipContainer: TOOLTIP_CONTAINER + Children: + Image@ICON: + X: 20 + Y: 5 + ImageCollection: editor + ImageName: select + Button@TILES_TAB: + X: 49 + Width: 49 Height: 25 Key: EditorTilesTab TooltipTemplate: BUTTON_TOOLTIP @@ -670,13 +656,13 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Children: Image@ICON: - X: 21 + X: 17 Y: 5 ImageCollection: editor ImageName: tiles Button@OVERLAYS_TAB: - X: 58 - Width: 58 + X: 98 + Width: 49 Height: 25 Key: EditorOverlaysTab TooltipTemplate: BUTTON_TOOLTIP @@ -684,13 +670,13 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Children: Image@ICON: - X: 21 + X: 17 Y: 5 ImageCollection: editor ImageName: overlays Button@ACTORS_TAB: - X: 116 - Width: 59 + X: 147 + Width: 48 Height: 25 Key: EditorActorsTab TooltipTemplate: BUTTON_TOOLTIP @@ -698,13 +684,13 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Children: Image@ICON: - X: 21 + X: 16 Y: 5 - ImageCollection: production-icons - ImageName: infantry + ImageCollection: editor + ImageName: actors Button@TOOLS_TAB: - X: 175 - Width: 58 + X: 195 + Width: 48 Height: 25 Key: EditorToolsTab TooltipTemplate: BUTTON_TOOLTIP @@ -712,13 +698,13 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Children: Image@ICON: - X: 21 + X: 16 Y: 5 ImageCollection: editor ImageName: tools Button@HISTORY_TAB: - X: 233 - Width: 58 + X: 243 + Width: 49 Height: 25 Key: EditorHistoryTab TooltipTemplate: BUTTON_TOOLTIP @@ -726,10 +712,10 @@ Container@EDITOR_WORLD_ROOT: TooltipContainer: TOOLTIP_CONTAINER Children: Image@ICON: - X: 21 + X: 17 Y: 5 - ImageCollection: sidebar-bits - ImageName: production-tooltip-time + ImageCollection: editor + ImageName: history MenuButton@OPTIONS_BUTTON: Logic: MenuButtonsChromeLogic MenuContainer: INGAME_MENU diff --git a/mods/common/hotkeys/editor.yaml b/mods/common/hotkeys/editor.yaml index 1e5f727ea0..d1fbe9cfdc 100644 --- a/mods/common/hotkeys/editor.yaml +++ b/mods/common/hotkeys/editor.yaml @@ -34,32 +34,37 @@ EditorPaste: V Ctrl Platform: OSX: V Meta -EditorTilesTab: E +EditorSelectTab: E + Description: Select Tab + Types: Editor + Contexts: Editor + +EditorTilesTab: R Description: Tiles Tab Types: Editor Contexts: Editor -EditorOverlaysTab: R +EditorOverlaysTab: T Description: Overlays Tab Types: Editor Contexts: Editor -EditorActorsTab: T +EditorActorsTab: Y Description: Actors Tab Types: Editor Contexts: Editor -EditorToolsTab: Y +EditorToolsTab: U Description: Tools Tab Types: Editor Contexts: Editor -EditorHistoryTab: U +EditorHistoryTab: I Description: History Tab Types: Editor Contexts: Editor -EditorSettingsTab: I +EditorSettingsTab: O Description: Settings Tab Types: Editor Contexts: Editor diff --git a/mods/common/languages/chrome/en.ftl b/mods/common/languages/chrome/en.ftl index 9bc0562367..0954524820 100644 --- a/mods/common/languages/chrome/en.ftl +++ b/mods/common/languages/chrome/en.ftl @@ -74,8 +74,6 @@ label-actors-bg-categories = Filter: label-actors-bg-owners = Owner: label-area-selection = Area Selection label-area-info = Area Info -label-selected-area-selected-region = Region: -label-selected-area-dimension = Dimensions: label-selected-area-diagonal = Diagonal: label-selected-area-resources= Resources: label-copy-filters = Copy Filters @@ -86,6 +84,9 @@ button-selection-cancel = Cancel label-show-tile-grid = Show Tile Grid label-show-buildable-area = Show Buildable Area +button-map-editor-tab-container-select = + .tooltip = Select + button-map-editor-tab-container-tiles = .tooltip = Tiles diff --git a/mods/d2k/chrome.yaml b/mods/d2k/chrome.yaml index 34f913fb90..1e2be3563c 100644 --- a/mods/d2k/chrome.yaml +++ b/mods/d2k/chrome.yaml @@ -515,6 +515,9 @@ loadscreen-stripe: editor: Inherits: ^Glyphs Regions: + select: 51, 144, 16, 16 tiles: 0, 144, 16, 16 overlays: 17, 144, 16, 16 + actors: 34, 68, 16, 16 tools: 34, 144, 16, 16 + history: 136, 51, 16, 16 diff --git a/mods/d2k/uibits/glyphs-2x.png b/mods/d2k/uibits/glyphs-2x.png index 70a95779ef..910209f12f 100644 Binary files a/mods/d2k/uibits/glyphs-2x.png and b/mods/d2k/uibits/glyphs-2x.png differ diff --git a/mods/d2k/uibits/glyphs-3x.png b/mods/d2k/uibits/glyphs-3x.png index 62eedd9fa2..38dfff6518 100644 Binary files a/mods/d2k/uibits/glyphs-3x.png and b/mods/d2k/uibits/glyphs-3x.png differ diff --git a/mods/d2k/uibits/glyphs.png b/mods/d2k/uibits/glyphs.png index dbbcbf4b91..48889f22e0 100644 Binary files a/mods/d2k/uibits/glyphs.png and b/mods/d2k/uibits/glyphs.png differ diff --git a/mods/ra/chrome.yaml b/mods/ra/chrome.yaml index d8e3f13878..2799603460 100644 --- a/mods/ra/chrome.yaml +++ b/mods/ra/chrome.yaml @@ -659,6 +659,9 @@ separator: editor: Inherits: ^Glyphs Regions: + select: 34, 187, 16, 16 tiles: 0, 187, 16, 16 overlays: 17, 187, 16, 16 + actors: 34, 68, 16, 16 tools: 136, 68, 16, 16 + history: 136, 51, 16, 16 diff --git a/mods/ra/uibits/glyphs-2x.png b/mods/ra/uibits/glyphs-2x.png index 00dea9ff7c..451873f7cf 100644 Binary files a/mods/ra/uibits/glyphs-2x.png and b/mods/ra/uibits/glyphs-2x.png differ diff --git a/mods/ra/uibits/glyphs-3x.png b/mods/ra/uibits/glyphs-3x.png index ffb635ab79..aa90dcc057 100644 Binary files a/mods/ra/uibits/glyphs-3x.png and b/mods/ra/uibits/glyphs-3x.png differ diff --git a/mods/ra/uibits/glyphs.png b/mods/ra/uibits/glyphs.png index 62e24f484e..5c88e5899b 100644 Binary files a/mods/ra/uibits/glyphs.png and b/mods/ra/uibits/glyphs.png differ diff --git a/mods/ts/chrome.yaml b/mods/ts/chrome.yaml index 68083a84e5..cd6b085d59 100644 --- a/mods/ts/chrome.yaml +++ b/mods/ts/chrome.yaml @@ -790,6 +790,9 @@ loadscreen-stripe: editor: Inherits: ^Glyphs Regions: + select: 51, 144, 16, 16 tiles: 0, 144, 16, 16 overlays: 17, 144, 16, 16 + actors: 34, 68, 16, 16 tools: 34, 144, 16, 16 + history: 136, 51, 16, 16 diff --git a/mods/ts/uibits/glyphs-2x.png b/mods/ts/uibits/glyphs-2x.png index 4b58a6908b..e2e979f344 100644 Binary files a/mods/ts/uibits/glyphs-2x.png and b/mods/ts/uibits/glyphs-2x.png differ diff --git a/mods/ts/uibits/glyphs-3x.png b/mods/ts/uibits/glyphs-3x.png index 42ec614db0..13d12f9ae4 100644 Binary files a/mods/ts/uibits/glyphs-3x.png and b/mods/ts/uibits/glyphs-3x.png differ diff --git a/mods/ts/uibits/glyphs.png b/mods/ts/uibits/glyphs.png index fc10af9791..cfe01e990b 100644 Binary files a/mods/ts/uibits/glyphs.png and b/mods/ts/uibits/glyphs.png differ