Editor selection refactor pt1

This commit is contained in:
David Wilson
2023-12-14 18:23:04 +10:00
committed by Gustas
parent b58c1ea5bc
commit 2ced4abc24
41 changed files with 1560 additions and 854 deletions

View File

@@ -0,0 +1,90 @@
#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;
using System.Collections.Generic;
namespace OpenRA
{
public readonly struct CellCoordsRegion : IEnumerable<CPos>
{
public struct CellCoordsEnumerator : IEnumerator<CPos>
{
readonly CellCoordsRegion r;
public CellCoordsEnumerator(CellCoordsRegion region)
: this()
{
r = region;
Reset();
}
public bool MoveNext()
{
var x = Current.X + 1;
var y = Current.Y;
// Check for column overflow.
if (x > r.BottomRight.X)
{
y++;
x = r.TopLeft.X;
// Check for row overflow.
if (y > r.BottomRight.Y)
return false;
}
Current = new CPos(x, y);
return true;
}
public void Reset()
{
Current = new CPos(r.TopLeft.X - 1, r.TopLeft.Y);
}
public CPos Current { get; private set; }
readonly object IEnumerator.Current => Current;
public readonly void Dispose() { }
}
public CellCoordsRegion(CPos topLeft, CPos bottomRight)
{
TopLeft = topLeft;
BottomRight = bottomRight;
}
public override string ToString()
{
return $"{TopLeft}->{BottomRight}";
}
public CellCoordsEnumerator GetEnumerator()
{
return new CellCoordsEnumerator(this);
}
IEnumerator<CPos> IEnumerable<CPos>.GetEnumerator()
{
return GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public CPos TopLeft { get; }
public CPos BottomRight { get; }
}
}

View File

@@ -102,6 +102,7 @@ namespace OpenRA
} }
public MapCoordsRegion MapCoords => new(mapTopLeft, mapBottomRight); public MapCoordsRegion MapCoords => new(mapTopLeft, mapBottomRight);
public CellCoordsRegion CellCoords => new(TopLeft, BottomRight);
public CellRegionEnumerator GetEnumerator() public CellRegionEnumerator GetEnumerator()
{ {

View File

@@ -296,6 +296,9 @@ namespace OpenRA.Traits
int2 GetDecorationOrigin(Actor self, WorldRenderer wr, string pos, int2 margin); int2 GetDecorationOrigin(Actor self, WorldRenderer wr, string pos, int2 margin);
} }
public interface IEditorSelectionLayer : ITraitInfoInterface { }
public interface IEditorPasteLayer : ITraitInfoInterface { }
public interface IMapPreviewSignatureInfo : ITraitInfoInterface public interface IMapPreviewSignatureInfo : ITraitInfoInterface
{ {
void PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<(MPos Uv, Color Color)> destinationBuffer); void PopulateMapPreviewSignatureCells(Map map, ActorInfo ai, ActorReference s, List<(MPos Uv, Color Color)> destinationBuffer);

View File

@@ -0,0 +1,35 @@
using System.Collections.Generic;
using OpenRA.Mods.Common.Traits;
namespace OpenRA.Mods.Common.EditorBrushes
{
public readonly struct ClipboardTile
{
public readonly TerrainTile TerrainTile;
public readonly ResourceTile ResourceTile;
public readonly ResourceLayerContents ResourceLayerContents;
public readonly byte Height;
public ClipboardTile(TerrainTile terrainTile, ResourceTile resourceTile, ResourceLayerContents resourceLayerContents, byte height)
{
TerrainTile = terrainTile;
ResourceTile = resourceTile;
ResourceLayerContents = resourceLayerContents;
Height = height;
}
}
public readonly struct EditorClipboard
{
public readonly CellRegion CellRegion;
public readonly Dictionary<string, EditorActorPreview> Actors;
public readonly Dictionary<CPos, ClipboardTile> Tiles;
public EditorClipboard(CellRegion cellRegion, Dictionary<string, EditorActorPreview> actors, Dictionary<CPos, ClipboardTile> tiles)
{
CellRegion = cellRegion;
Actors = actors;
Tiles = tiles;
}
}
}

View File

@@ -13,6 +13,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.EditorBrushes;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
namespace OpenRA.Mods.Common.Widgets namespace OpenRA.Mods.Common.Widgets
@@ -29,29 +30,33 @@ namespace OpenRA.Mods.Common.Widgets
public sealed class EditorCopyPasteBrush : IEditorBrush public sealed class EditorCopyPasteBrush : IEditorBrush
{ {
enum State { SelectFirst, SelectSecond, Paste }
readonly WorldRenderer worldRenderer; readonly WorldRenderer worldRenderer;
readonly EditorViewportControllerWidget editorWidget; readonly EditorViewportControllerWidget editorWidget;
readonly EditorSelectionLayer selectionLayer; readonly EditorActorLayer editorActorLayer;
readonly EditorActorLayer editorLayer;
readonly Func<MapCopyFilters> getCopyFilters;
readonly EditorActionManager editorActionManager; readonly EditorActionManager editorActionManager;
readonly EditorClipboard clipboard;
readonly IResourceLayer resourceLayer;
readonly Func<MapCopyFilters> getCopyFilters;
State state; public CPos? PastePreviewPosition { get; private set; }
CPos start;
CPos end;
public EditorCopyPasteBrush(EditorViewportControllerWidget editorWidget, WorldRenderer wr, Func<MapCopyFilters> getCopyFilters) public CellRegion Region => clipboard.CellRegion;
public EditorCopyPasteBrush(
EditorViewportControllerWidget editorWidget,
WorldRenderer wr,
EditorClipboard clipboard,
IResourceLayer resourceLayer,
Func<MapCopyFilters> getCopyFilters)
{ {
this.getCopyFilters = getCopyFilters;
this.editorWidget = editorWidget; this.editorWidget = editorWidget;
this.clipboard = clipboard;
this.resourceLayer = resourceLayer;
worldRenderer = wr; worldRenderer = wr;
editorActionManager = wr.World.WorldActor.Trait<EditorActionManager>(); editorActionManager = wr.World.WorldActor.Trait<EditorActionManager>();
editorActorLayer = wr.World.WorldActor.Trait<EditorActorLayer>();
selectionLayer = wr.World.WorldActor.Trait<EditorSelectionLayer>();
editorLayer = wr.World.WorldActor.Trait<EditorActorLayer>();
this.getCopyFilters = getCopyFilters;
} }
public bool HandleMouseInput(MouseInput mi) public bool HandleMouseInput(MouseInput mi)
@@ -71,106 +76,31 @@ namespace OpenRA.Mods.Common.Widgets
return false; return false;
} }
if (mi.Button == MouseButton.Left && (mi.Event == MouseInputEvent.Up || mi.Event == MouseInputEvent.Down)) if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
{ {
var cell = worldRenderer.Viewport.ViewToWorld(mi.Location); var pastePosition = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos);
switch (state) var action = new CopyPasteEditorAction(
{ getCopyFilters(),
case State.SelectFirst: resourceLayer,
if (mi.Event != MouseInputEvent.Down) pastePosition,
break; worldRenderer.World.Map,
start = cell; clipboard,
selectionLayer.SetCopyRegion(start, end); editorActorLayer);
state = State.SelectSecond;
break;
case State.SelectSecond:
if (mi.Event != MouseInputEvent.Up)
break;
end = cell;
selectionLayer.SetCopyRegion(start, end);
state = State.Paste;
break;
case State.Paste:
{
if (mi.Event != MouseInputEvent.Down)
break;
var gridType = worldRenderer.World.Map.Grid.Type;
var source = CellRegion.BoundingRegion(gridType, new[] { start, end });
Copy(source, cell - end);
break;
}
}
editorActionManager.Add(action);
return true; return true;
} }
return false; return false;
} }
void Copy(CellRegion source, CVec offset)
{
var gridType = worldRenderer.World.Map.Grid.Type;
var mapTiles = worldRenderer.World.Map.Tiles;
var mapHeight = worldRenderer.World.Map.Height;
var mapResources = worldRenderer.World.Map.Resources;
var dest = new CellRegion(gridType, source.TopLeft + offset, source.BottomRight + offset);
var previews = new Dictionary<string, ActorReference>();
var tiles = new Dictionary<CPos, (TerrainTile, ResourceTile, byte)>();
var copyFilters = getCopyFilters();
foreach (var cell in source)
{
if (!mapTiles.Contains(cell) || !mapTiles.Contains(cell + offset))
continue;
tiles.Add(cell + offset, (mapTiles[cell], mapResources[cell], mapHeight[cell]));
if (copyFilters.HasFlag(MapCopyFilters.Actors))
{
foreach (var preview in editorLayer.PreviewsAt(cell))
{
if (previews.ContainsKey(preview.ID))
continue;
var copy = preview.Export();
var locationInit = copy.GetOrDefault<LocationInit>();
if (locationInit != null)
{
copy.RemoveAll<LocationInit>();
copy.Add(new LocationInit(locationInit.Value + offset));
}
previews.Add(preview.ID, copy);
}
}
}
var action = new CopyPasteEditorAction(copyFilters, worldRenderer.World.Map, tiles, previews, editorLayer, dest);
editorActionManager.Add(action);
}
public void Tick() public void Tick()
{ {
var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos); PastePreviewPosition = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos);
if (state == State.Paste)
{
selectionLayer.SetPasteRegion(cell + (start - end), cell);
return;
}
if (state == State.SelectFirst)
start = end = cell;
else if (state == State.SelectSecond)
end = cell;
selectionLayer.SetCopyRegion(start, end);
} }
public void Dispose() public void Dispose()
{ {
selectionLayer.Clear();
} }
} }
@@ -182,33 +112,64 @@ namespace OpenRA.Mods.Common.Widgets
public string Text { get; } public string Text { get; }
readonly MapCopyFilters copyFilters; readonly MapCopyFilters copyFilters;
readonly Dictionary<CPos, (TerrainTile Tile, ResourceTile Resource, byte Height)> tiles; readonly IResourceLayer resourceLayer;
readonly Dictionary<string, ActorReference> previews; readonly EditorActorLayer editorActorLayer;
readonly EditorActorLayer editorLayer; readonly EditorClipboard clipboard;
readonly CellRegion dest; readonly EditorClipboard undoClipboard;
readonly CellLayer<TerrainTile> mapTiles; readonly CPos pastePosition;
readonly CellLayer<byte> mapHeight; readonly Map map;
readonly CellLayer<ResourceTile> mapResources;
readonly Queue<UndoCopyPaste> undoCopyPastes = new(); public CopyPasteEditorAction(
readonly Queue<EditorActorPreview> removedActors = new(); MapCopyFilters copyFilters,
readonly Queue<EditorActorPreview> addedActorPreviews = new(); IResourceLayer resourceLayer,
CPos pastePosition,
public CopyPasteEditorAction(MapCopyFilters copyFilters, Map map, Map map,
Dictionary<CPos, (TerrainTile Tile, ResourceTile Resource, byte Height)> tiles, Dictionary<string, ActorReference> previews, EditorClipboard clipboard,
EditorActorLayer editorLayer, CellRegion dest) EditorActorLayer editorActorLayer)
{ {
this.copyFilters = copyFilters; this.copyFilters = copyFilters;
this.tiles = tiles; this.resourceLayer = resourceLayer;
this.previews = previews; this.clipboard = clipboard;
this.editorLayer = editorLayer; this.pastePosition = pastePosition;
this.dest = dest; this.editorActorLayer = editorActorLayer;
this.map = map;
mapTiles = map.Tiles; undoClipboard = CopySelectionContents();
mapHeight = map.Height;
mapResources = map.Resources;
Text = TranslationProvider.GetString(CopiedTiles, Translation.Arguments("amount", tiles.Count)); Text = TranslationProvider.GetString(CopiedTiles, Translation.Arguments("amount", clipboard.Tiles.Count));
}
/// <summary>
/// TODO: This is pretty much repeated in MapEditorSelectionLogic.
/// </summary>
/// <returns>Clipboard containing map contents for this region.</returns>
EditorClipboard CopySelectionContents()
{
var selectionSize = clipboard.CellRegion.BottomRight - clipboard.CellRegion.TopLeft;
var source = new CellCoordsRegion(pastePosition, pastePosition + selectionSize);
var selection = new CellRegion(map.Grid.Type, pastePosition, pastePosition + selectionSize);
var mapTiles = map.Tiles;
var mapHeight = map.Height;
var mapResources = map.Resources;
var previews = new Dictionary<string, EditorActorPreview>();
var tiles = new Dictionary<CPos, ClipboardTile>();
foreach (var cell in source)
{
if (!mapTiles.Contains(cell))
continue;
var resourceLayerContents = resourceLayer.GetResource(cell);
tiles.Add(cell, new ClipboardTile(mapTiles[cell], mapResources[cell], resourceLayerContents, mapHeight[cell]));
if (copyFilters.HasFlag(MapCopyFilters.Actors))
foreach (var preview in selection.SelectMany(editorActorLayer.PreviewsAt).Distinct())
previews.TryAdd(preview.ID, preview);
}
return new EditorClipboard(selection, previews, tiles);
} }
public void Execute() public void Execute()
@@ -218,72 +179,88 @@ namespace OpenRA.Mods.Common.Widgets
public void Do() public void Do()
{ {
foreach (var kv in tiles) var sourcePos = clipboard.CellRegion.TopLeft;
var pasteVec = new CVec(pastePosition.X - sourcePos.X, pastePosition.Y - sourcePos.Y);
foreach (var tileKeyValuePair in clipboard.Tiles)
{ {
undoCopyPastes.Enqueue(new UndoCopyPaste(kv.Key, mapTiles[kv.Key], mapResources[kv.Key], mapHeight[kv.Key])); var position = tileKeyValuePair.Key + pasteVec;
if (!map.Contains(position))
continue;
// Clear any existing resources.
if (copyFilters.HasFlag(MapCopyFilters.Resources))
resourceLayer.ClearResources(position);
var tile = tileKeyValuePair.Value;
var resourceLayerContents = tile.ResourceLayerContents;
if (copyFilters.HasFlag(MapCopyFilters.Terrain)) if (copyFilters.HasFlag(MapCopyFilters.Terrain))
mapTiles[kv.Key] = kv.Value.Tile;
if (copyFilters.HasFlag(MapCopyFilters.Resources))
mapResources[kv.Key] = kv.Value.Resource;
mapHeight[kv.Key] = kv.Value.Height;
}
if (copyFilters.HasFlag(MapCopyFilters.Actors))
{
var removeActors = dest.SelectMany(editorLayer.PreviewsAt).Distinct().ToList();
foreach (var preview in removeActors)
{ {
removedActors.Enqueue(preview); map.Tiles[position] = tile.TerrainTile;
editorLayer.Remove(preview); map.Height[position] = tile.Height;
} }
if (copyFilters.HasFlag(MapCopyFilters.Resources) && !string.IsNullOrWhiteSpace(resourceLayerContents.Type))
resourceLayer.AddResource(resourceLayerContents.Type, position, resourceLayerContents.Density);
} }
foreach (var kv in previews) // Clear any existing actors in the paste cells.
addedActorPreviews.Enqueue(editorLayer.Add(kv.Value)); 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 selection = clipboard.CellRegion;
var copy = actorKeyValuePair.Value.Export();
var locationInit = copy.GetOrDefault<LocationInit>();
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<LocationInit>();
copy.Add(new LocationInit(actorPosition));
}
editorActorLayer.Add(copy);
}
} }
public void Undo() public void Undo()
{ {
while (undoCopyPastes.Count > 0) foreach (var tileKeyValuePair in undoClipboard.Tiles)
{ {
var undoCopyPaste = undoCopyPastes.Dequeue(); var position = tileKeyValuePair.Key;
var tile = tileKeyValuePair.Value;
var resourceLayerContents = tile.ResourceLayerContents;
var cell = undoCopyPaste.Cell; // Clear any existing resources.
if (copyFilters.HasFlag(MapCopyFilters.Resources))
resourceLayer.ClearResources(position);
if (copyFilters.HasFlag(MapCopyFilters.Terrain)) if (copyFilters.HasFlag(MapCopyFilters.Terrain))
mapTiles[cell] = undoCopyPaste.MapTile; {
map.Tiles[position] = tile.TerrainTile;
map.Height[position] = tile.Height;
}
if (copyFilters.HasFlag(MapCopyFilters.Resources)) if (copyFilters.HasFlag(MapCopyFilters.Resources) && !string.IsNullOrWhiteSpace(resourceLayerContents.Type))
mapResources[cell] = undoCopyPaste.ResourceTile; resourceLayer.AddResource(resourceLayerContents.Type, position, resourceLayerContents.Density);
mapHeight[cell] = undoCopyPaste.Height;
} }
while (addedActorPreviews.Count > 0) // Clear existing actors.
editorLayer.Remove(addedActorPreviews.Dequeue()); foreach (var regionActor in undoClipboard.CellRegion.SelectMany(editorActorLayer.PreviewsAt).Distinct().ToList())
editorActorLayer.Remove(regionActor);
// Place actors back again.
if (copyFilters.HasFlag(MapCopyFilters.Actors)) if (copyFilters.HasFlag(MapCopyFilters.Actors))
while (removedActors.Count > 0) foreach (var actor in undoClipboard.Actors.Values)
editorLayer.Add(removedActors.Dequeue()); editorActorLayer.Add(actor);
}
}
sealed class UndoCopyPaste
{
public CPos Cell { get; }
public TerrainTile MapTile { get; }
public ResourceTile ResourceTile { get; }
public byte Height { get; }
public UndoCopyPaste(CPos cell, TerrainTile mapTile, ResourceTile resourceTile, byte height)
{
Cell = cell;
MapTile = mapTile;
ResourceTile = resourceTile;
Height = height;
} }
} }
} }

View File

@@ -12,6 +12,7 @@
using System; using System;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets namespace OpenRA.Mods.Common.Widgets
{ {
@@ -21,9 +22,17 @@ namespace OpenRA.Mods.Common.Widgets
void Tick(); void Tick();
} }
public class EditorSelection
{
public CellRegion Area;
public EditorActorPreview Actor;
}
public sealed class EditorDefaultBrush : IEditorBrush public sealed class EditorDefaultBrush : IEditorBrush
{ {
public readonly ActorInfo Actor; const int MinMouseMoveBeforeDrag = 32;
public event Action SelectionChanged;
readonly WorldRenderer worldRenderer; readonly WorldRenderer worldRenderer;
readonly World world; readonly World world;
@@ -32,7 +41,13 @@ namespace OpenRA.Mods.Common.Widgets
readonly EditorActionManager editorActionManager; readonly EditorActionManager editorActionManager;
readonly IResourceLayer resourceLayer; readonly IResourceLayer resourceLayer;
public EditorActorPreview SelectedActor; public CellRegion CurrentDragBounds => selectionBounds ?? Selection.Area;
public EditorSelection Selection = new();
EditorSelection previousSelection;
CellRegion selectionBounds;
int2? selectionStartLocation;
CPos? selectionStartCell;
int2 worldPixel; int2 worldPixel;
public EditorDefaultBrush(EditorViewportControllerWidget editorWidget, WorldRenderer wr) public EditorDefaultBrush(EditorViewportControllerWidget editorWidget, WorldRenderer wr)
@@ -58,13 +73,23 @@ namespace OpenRA.Mods.Common.Widgets
return ((long)pixelDistance << 32) + worldZPosition; return ((long)pixelDistance << 32) + worldZPosition;
} }
public void ClearSelection()
{
if (Selection.Area != null || Selection.Actor != null)
{
previousSelection = Selection;
Selection = new EditorSelection();
editorActionManager.Add(new ChangeSelectionAction(this, Selection, previousSelection));
SelectionChanged?.Invoke();
}
}
public bool HandleMouseInput(MouseInput mi) public bool HandleMouseInput(MouseInput mi)
{ {
// Exclusively uses mouse wheel and both mouse buttons, but nothing else // Exclusively uses mouse wheel and both mouse buttons, but nothing else.
// Mouse move events are important for tooltips, so we always allow these through // Mouse move events are important for tooltips, so we always allow these through.
if ((mi.Button != MouseButton.Left && mi.Button != MouseButton.Right if (mi.Button != MouseButton.Left && mi.Button != MouseButton.Right
&& mi.Event != MouseInputEvent.Move && mi.Event != MouseInputEvent.Scroll) || && mi.Event != MouseInputEvent.Move && mi.Event != MouseInputEvent.Scroll)
mi.Event == MouseInputEvent.Down)
return false; return false;
worldPixel = worldRenderer.Viewport.ViewToWorldPx(mi.Location); worldPixel = worldRenderer.Viewport.ViewToWorldPx(mi.Location);
@@ -80,25 +105,114 @@ namespace OpenRA.Mods.Common.Widgets
else else
editorWidget.SetTooltip(null); editorWidget.SetTooltip(null);
// Finished with mouse move events, so let them bubble up the widget tree // Selection box drag.
if (selectionStartLocation != null &&
(selectionBounds != null || (mi.Location - selectionStartLocation.Value).LengthSquared > MinMouseMoveBeforeDrag))
{
selectionStartCell ??= worldRenderer.Viewport.ViewToWorld(selectionStartLocation.Value);
var topLeft = new CPos(Math.Min(selectionStartCell.Value.X, cell.X), Math.Min(selectionStartCell.Value.Y, cell.Y));
var bottomRight = new CPos(Math.Max(selectionStartCell.Value.X, cell.X), Math.Max(selectionStartCell.Value.Y, cell.Y));
var width = bottomRight.X - topLeft.X;
var height = bottomRight.Y - topLeft.Y;
var gridType = worldRenderer.World.Map.Grid.Type;
// We've dragged enough to capture more than one cell, make a selection box.
if (selectionBounds == null)
{
selectionBounds = new CellRegion(gridType, topLeft, bottomRight);
// Lose focus on any search boxes so we can always copy/paste.
Ui.KeyboardFocusWidget = null;
}
else
{
// We already have a drag box; resize it
selectionBounds = new CellRegion(gridType, topLeft, bottomRight);
}
}
// Finished with mouse move events, so let them bubble up the widget tree.
if (mi.Event == MouseInputEvent.Move) if (mi.Event == MouseInputEvent.Move)
return false; return false;
if (mi.Button == MouseButton.Left) if (mi.Event == MouseInputEvent.Down && mi.Button == MouseButton.Left && selectionStartLocation == null)
{ {
editorWidget.SetTooltip(null); // Start area drag.
SelectedActor = underCursor; selectionStartLocation = mi.Location;
} }
if (mi.Button == MouseButton.Right) if (mi.Event == MouseInputEvent.Up)
{ {
editorWidget.SetTooltip(null); if (mi.Button == MouseButton.Left)
{
editorWidget.SetTooltip(null);
selectionStartLocation = null;
selectionStartCell = null;
if (underCursor != null && underCursor != SelectedActor) // If we've released a bounds drag.
editorActionManager.Add(new RemoveActorAction(editorLayer, underCursor)); if (selectionBounds != null)
{
// Set this as the editor selection.
previousSelection = Selection;
Selection = new EditorSelection
{
Area = selectionBounds
};
if (resourceUnderCursor != null) editorActionManager.Add(new ChangeSelectionAction(this, Selection, previousSelection));
editorActionManager.Add(new RemoveResourceAction(resourceLayer, cell, resourceUnderCursor)); selectionBounds = null;
SelectionChanged?.Invoke();
}
else if (underCursor != null)
{
// We've clicked on an actor.
if (Selection.Actor != underCursor)
{
previousSelection = Selection;
Selection = new EditorSelection
{
Actor = underCursor,
};
editorActionManager.Add(new ChangeSelectionAction(this, Selection, previousSelection));
SelectionChanged?.Invoke();
}
}
else if (Selection.Area != null || Selection.Actor != null)
{
// 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();
}
}
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();
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));
}
}
} }
return true; return true;
@@ -108,6 +222,64 @@ namespace OpenRA.Mods.Common.Widgets
public void Dispose() { } public void Dispose() { }
} }
sealed class ChangeSelectionAction : IEditorAction
{
[TranslationReference("x", "y", "width", "height")]
const string SelectedArea = "notification-selected-area";
[TranslationReference("id")]
const string SelectedActor = "notification-selected-actor";
[TranslationReference]
const string ClearedSelection = "notification-cleared-selection";
public string Text { get; }
readonly EditorSelection selection;
readonly EditorSelection previousSelection;
readonly EditorDefaultBrush defaultBrush;
public ChangeSelectionAction(
EditorDefaultBrush defaultBrush,
EditorSelection selection,
EditorSelection previousSelection)
{
this.defaultBrush = defaultBrush;
this.selection = selection;
this.previousSelection = new EditorSelection
{
Actor = previousSelection.Actor,
Area = previousSelection.Area
};
if (selection.Area != null)
Text = TranslationProvider.GetString(SelectedArea, Translation.Arguments(
"x", selection.Area.TopLeft.X,
"y", selection.Area.TopLeft.Y,
"width", selection.Area.BottomRight.X - selection.Area.TopLeft.X,
"height", selection.Area.BottomRight.Y - selection.Area.TopLeft.Y));
else if (selection.Actor != null)
Text = TranslationProvider.GetString(SelectedActor, Translation.Arguments("id", selection.Actor.ID));
else
Text = TranslationProvider.GetString(ClearedSelection);
}
public void Execute()
{
Do();
}
public void Do()
{
defaultBrush.Selection = selection;
}
public void Undo()
{
defaultBrush.Selection = previousSelection;
}
}
sealed class RemoveActorAction : IEditorAction sealed class RemoveActorAction : IEditorAction
{ {
[TranslationReference("name", "id")] [TranslationReference("name", "id")]

View File

@@ -0,0 +1,84 @@
#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 OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.Graphics
{
/// <summary>
/// Render the current editor area selection or paste region.
/// </summary>
public class EditorSelectionAnnotationRenderable : IRenderable, IFinalizedRenderable
{
readonly Color color;
readonly CellRegion bounds;
readonly int2 altPixelOffset;
readonly CPos? offset;
public EditorSelectionAnnotationRenderable(CellRegion bounds, Color color, int2 altPixelOffset, CPos? offset)
{
this.bounds = bounds;
this.color = color;
this.altPixelOffset = altPixelOffset;
this.offset = offset;
}
public WPos Pos => WPos.Zero;
public int ZOffset => 0;
public bool IsDecoration => true;
public IRenderable WithZOffset(int newOffset) { return this; }
public IRenderable OffsetBy(in WVec vec) { return new EditorSelectionAnnotationRenderable(bounds, color, new int2(vec.X, vec.Y), offset); }
public IRenderable AsDecoration() { return this; }
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
public void Render(WorldRenderer wr)
{
if (bounds == null)
return;
const int Width = 1;
var map = wr.World.Map;
var originalWPos = map.CenterOfCell(bounds.TopLeft);
var wposOffset = offset.HasValue ? map.CenterOfCell(offset.Value) - originalWPos : WVec.Zero;
foreach (var cellPos in bounds.CellCoords)
{
var uv = cellPos.ToMPos(map);
if (!map.Height.Contains(uv))
continue;
var ramp = map.Grid.Ramps[map.Ramp[uv]];
var pos = map.CenterOfCell(cellPos) - new WVec(0, 0, ramp.CenterHeightOffset);
foreach (var p in ramp.Polygons)
{
for (var i = 0; i < p.Length; i++)
{
var j = (i + 1) % p.Length;
var start = pos + p[i];
var end = pos + p[j];
Game.Renderer.RgbaColorRenderer.DrawLine(
wr.Viewport.WorldToViewPx(wr.ScreenPosition(start + wposOffset)) + altPixelOffset,
wr.Viewport.WorldToViewPx(wr.Screen3DPosition(end + wposOffset)) + altPixelOffset,
Width, color, color);
}
}
}
}
public void RenderDebugGeometry(WorldRenderer wr) { }
public Rectangle ScreenBounds(WorldRenderer wr) { return Rectangle.Empty; }
}
}

View File

@@ -11,102 +11,67 @@
using System.Collections.Generic; using System.Collections.Generic;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.Graphics;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Traits; using OpenRA.Traits;
using OpenRA.Widgets;
using Color = OpenRA.Primitives.Color;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
[TraitLocation(SystemActors.EditorWorld)] [TraitLocation(SystemActors.EditorWorld)]
[Desc("Required for the map editor to work. Attach this to the world actor.")] [Desc("Renders the selection grid in the editor.")]
public class EditorSelectionLayerInfo : TraitInfo public class EditorSelectionLayerInfo : TraitInfo, Requires<LoadWidgetAtGameStartInfo>, IEditorSelectionLayer
{ {
[PaletteReference] [Desc("Main color of the selection grid.")]
[Desc("Palette to use for rendering the placement sprite.")] public readonly Color MainColor = Color.White;
public readonly string Palette = TileSet.TerrainPaletteInternalName;
[Desc("Custom opacity to apply to the placement sprite.")] [Desc("Alternate color of the selection grid.")]
public readonly float FootprintAlpha = 1f; public readonly Color AltColor = Color.Black;
[Desc("Sequence image where the selection overlay types are defined.")] [Desc("Main color of the paste grid.")]
public readonly string Image = "editor-overlay"; public readonly Color PasteColor = Color.FromArgb(0xFF4CFF00);
[SequenceReference(nameof(Image))] [Desc("Thickness of the selection grid lines.")]
[Desc("Sequence to use for the copy overlay.")] public readonly int LineThickness = 1;
public readonly string CopySequence = "copy";
[SequenceReference(nameof(Image))] [Desc("Render offset of the secondary grid lines.")]
[Desc("Sequence to use for the paste overlay.")] public readonly int2 AltPixelOffset = new(1, 1);
public readonly string PasteSequence = "paste";
public override object Create(ActorInitializer init) { return new EditorSelectionLayer(init.Self, this); } public override object Create(ActorInitializer init) { return new EditorSelectionLayer(this); }
} }
public class EditorSelectionLayer : IWorldLoaded, IRenderAboveShroud public class EditorSelectionLayer : IRenderAnnotations, IWorldLoaded
{ {
readonly EditorSelectionLayerInfo info; readonly EditorSelectionLayerInfo info;
readonly Map map; EditorViewportControllerWidget editor;
readonly Sprite copyTile, pasteTile;
readonly float copyAlpha, pasteAlpha;
PaletteReference palette;
public CellRegion CopyRegion { get; private set; } public EditorSelectionLayer(EditorSelectionLayerInfo info)
public CellRegion PasteRegion { get; private set; }
public EditorSelectionLayer(Actor self, EditorSelectionLayerInfo info)
{ {
if (self.World.Type != WorldType.Editor)
return;
this.info = info; this.info = info;
map = self.World.Map;
var copySequence = map.Sequences.GetSequence(info.Image, info.CopySequence);
copyTile = copySequence.GetSprite(0);
copyAlpha = copySequence.GetAlpha(0);
var pasteSequence = map.Sequences.GetSequence(info.Image, info.PasteSequence);
pasteTile = pasteSequence.GetSprite(0);
pasteAlpha = pasteSequence.GetAlpha(0);
} }
void IWorldLoaded.WorldLoaded(World w, WorldRenderer wr) void IWorldLoaded.WorldLoaded(World w, WorldRenderer wr)
{ {
if (w.Type != WorldType.Editor) var worldRoot = Ui.Root.Get<ContainerWidget>("EDITOR_WORLD_ROOT");
return; editor = worldRoot.Get<EditorViewportControllerWidget>("MAP_EDITOR");
palette = wr.Palette(info.Palette);
} }
public void SetCopyRegion(CPos start, CPos end) IEnumerable<IRenderable> IRenderAnnotations.RenderAnnotations(Actor self, WorldRenderer wr)
{ {
CopyRegion = CellRegion.BoundingRegion(map.Grid.Type, new[] { start, end }); if (editor.CurrentBrush == editor.DefaultBrush && 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);
}
if (editor.CurrentBrush is EditorCopyPasteBrush pasteBrush && pasteBrush.PastePreviewPosition != null)
{
yield return new EditorSelectionAnnotationRenderable(pasteBrush.Region, info.AltColor, info.AltPixelOffset, pasteBrush.PastePreviewPosition);
yield return new EditorSelectionAnnotationRenderable(pasteBrush.Region, info.PasteColor, int2.Zero, pasteBrush.PastePreviewPosition);
}
} }
public void SetPasteRegion(CPos start, CPos end) bool IRenderAnnotations.SpatiallyPartitionable => false;
{
PasteRegion = CellRegion.BoundingRegion(map.Grid.Type, new[] { start, end });
}
public void Clear()
{
CopyRegion = PasteRegion = null;
}
IEnumerable<IRenderable> IRenderAboveShroud.RenderAboveShroud(Actor self, WorldRenderer wr)
{
if (wr.World.Type != WorldType.Editor)
yield break;
if (CopyRegion != null)
foreach (var c in CopyRegion)
yield return new SpriteRenderable(copyTile, wr.World.Map.CenterOfCell(c),
WVec.Zero, -511, palette, 1f, copyAlpha * info.FootprintAlpha, float3.Ones, TintModifiers.IgnoreWorldTint, true);
if (PasteRegion != null)
foreach (var c in PasteRegion)
yield return new SpriteRenderable(pasteTile, wr.World.Map.CenterOfCell(c),
WVec.Zero, -511, palette, 1f, pasteAlpha * info.FootprintAlpha, float3.Ones, TintModifiers.IgnoreWorldTint, true);
}
bool IRenderAboveShroud.SpatiallyPartitionable => false;
} }
} }

View File

@@ -0,0 +1,37 @@
#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;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class RemoveEditorSelectionLayerProperties : UpdateRule
{
public override string Name => "Remove defunct properties from EditorSelectionLayer.";
public override string Description =>
"Map editor was refactored and many of EditorSelectionLayer properties were removed.";
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNodeBuilder actorNode)
{
foreach (var editorSelectionLayer in actorNode.ChildrenMatching("EditorSelectionLayer"))
{
editorSelectionLayer.RemoveNodes("Palette");
editorSelectionLayer.RemoveNodes("FootprintAlpha");
editorSelectionLayer.RemoveNodes("Image");
editorSelectionLayer.RemoveNodes("CopySequence");
editorSelectionLayer.RemoveNodes("PasteSequence");
}
yield break;
}
}
}

View File

@@ -85,6 +85,7 @@ namespace OpenRA.Mods.Common.UpdateRules
new ExtractResourceStorageFromHarvester(), new ExtractResourceStorageFromHarvester(),
new ReplacePaletteModifiers(), new ReplacePaletteModifiers(),
new RemoveConyardChronoReturnAnimation(), new RemoveConyardChronoReturnAnimation(),
new RemoveEditorSelectionLayerProperties(),
// Execute these rules last to avoid premature yaml merge crashes. // Execute these rules last to avoid premature yaml merge crashes.
new ReplaceCloakPalette(), new ReplaceCloakPalette(),

View File

@@ -11,7 +11,6 @@
using System; using System;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Widgets; using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets namespace OpenRA.Mods.Common.Widgets
@@ -26,29 +25,20 @@ namespace OpenRA.Mods.Common.Widgets
readonly Lazy<TooltipContainerWidget> tooltipContainer; readonly Lazy<TooltipContainerWidget> tooltipContainer;
readonly WorldRenderer worldRenderer; readonly WorldRenderer worldRenderer;
readonly EditorActionManager editorActionManager;
bool enableTooltips; bool enableTooltips;
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public EditorViewportControllerWidget(World world, WorldRenderer worldRenderer) public EditorViewportControllerWidget(WorldRenderer worldRenderer)
{ {
this.worldRenderer = worldRenderer; this.worldRenderer = worldRenderer;
tooltipContainer = Exts.Lazy(() => Ui.Root.Get<TooltipContainerWidget>(TooltipContainer)); tooltipContainer = Exts.Lazy(() => Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
CurrentBrush = DefaultBrush = new EditorDefaultBrush(this, worldRenderer); CurrentBrush = DefaultBrush = new EditorDefaultBrush(this, worldRenderer);
editorActionManager = world.WorldActor.Trait<EditorActionManager>();
editorActionManager.OnChange += EditorActionManagerOnChange;
// Allow zooming out to full map size // Allow zooming out to full map size
worldRenderer.Viewport.UnlockMinimumZoom(0.25f); worldRenderer.Viewport.UnlockMinimumZoom(0.25f);
} }
void EditorActionManagerOnChange()
{
DefaultBrush.SelectedActor = null;
}
public void ClearBrush() { SetBrush(null); } public void ClearBrush() { SetBrush(null); }
public void SetBrush(IEditorBrush brush) public void SetBrush(IEditorBrush brush)
{ {
@@ -106,11 +96,5 @@ namespace OpenRA.Mods.Common.Widgets
cachedViewportPosition = worldRenderer.Viewport.CenterPosition; cachedViewportPosition = worldRenderer.Viewport.CenterPosition;
CurrentBrush.Tick(); CurrentBrush.Tick();
} }
public override void Removed()
{
base.Removed();
editorActionManager.OnChange -= EditorActionManagerOnChange;
}
} }
} }

View File

@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly EditorActorLayer editorActorLayer; readonly EditorActorLayer editorActorLayer;
readonly EditorActionManager editorActionManager; readonly EditorActionManager editorActionManager;
readonly EditorViewportControllerWidget editor; readonly EditorViewportControllerWidget editor;
readonly BackgroundWidget actorEditPanel; readonly ContainerWidget actorEditPanel;
readonly LabelWidget typeLabel; readonly LabelWidget typeLabel;
readonly TextFieldWidget actorIDField; readonly TextFieldWidget actorIDField;
readonly HashSet<TextFieldWidget> typableFields = new(); readonly HashSet<TextFieldWidget> typableFields = new();
@@ -51,12 +51,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly Widget sliderOptionTemplate; readonly Widget sliderOptionTemplate;
readonly Widget dropdownOptionTemplate; readonly Widget dropdownOptionTemplate;
readonly int editPanelPadding; // Padding between right edge of actor and the edit panel.
readonly long scrollVisibleTimeout = 100; // Delay after scrolling map before edit widget becomes visible again.
long lastScrollTime = 0;
int2 lastScrollPosition = int2.Zero;
ActorIDStatus actorIDStatus = ActorIDStatus.Normal; ActorIDStatus actorIDStatus = ActorIDStatus.Normal;
ActorIDStatus nextActorIDStatus = ActorIDStatus.Normal; ActorIDStatus nextActorIDStatus = ActorIDStatus.Normal;
string initialActorID; string initialActorID;
@@ -93,8 +87,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
editorActorLayer = world.WorldActor.Trait<EditorActorLayer>(); editorActorLayer = world.WorldActor.Trait<EditorActorLayer>();
editorActionManager = world.WorldActor.Trait<EditorActionManager>(); editorActionManager = world.WorldActor.Trait<EditorActionManager>();
editor = widget.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR"); editor = widget.Parent.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR");
actorEditPanel = editor.Get<BackgroundWidget>("ACTOR_EDIT_PANEL"); var selectTabContainer = widget.Parent.Parent.Get<ContainerWidget>("SELECT_WIDGETS");
actorEditPanel = selectTabContainer.Get<ContainerWidget>("ACTOR_EDIT_PANEL");
typeLabel = actorEditPanel.Get<LabelWidget>("ACTOR_TYPE_LABEL"); typeLabel = actorEditPanel.Get<LabelWidget>("ACTOR_TYPE_LABEL");
actorIDField = actorEditPanel.Get<TextFieldWidget>("ACTOR_ID"); actorIDField = actorEditPanel.Get<TextFieldWidget>("ACTOR_ID");
@@ -118,16 +114,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
? TranslationProvider.GetString(DuplicateActorId) ? TranslationProvider.GetString(DuplicateActorId)
: TranslationProvider.GetString(EnterActorId); : TranslationProvider.GetString(EnterActorId);
if (logicArgs.TryGetValue("EditPanelPadding", out var yaml)) okButton.IsDisabled = () => !IsValid() || editActorPreview == null || !editActorPreview.IsDirty;
editPanelPadding = FieldLoader.GetValue<int>("EditPanelPadding", yaml.Value);
okButton.IsDisabled = () => !IsValid() || !editActorPreview.IsDirty;
okButton.OnClick = Save; okButton.OnClick = Save;
cancelButton.OnClick = Cancel; cancelButton.OnClick = Cancel;
deleteButton.OnClick = Delete; deleteButton.OnClick = Delete;
actorEditPanel.IsVisible = () => CurrentActor != null actorEditPanel.IsVisible = () => CurrentActor != null
&& editor.CurrentBrush == editor.DefaultBrush && editor.CurrentBrush == editor.DefaultBrush;
&& Game.RunTime > lastScrollTime + scrollVisibleTimeout;
actorIDField.OnEscKey = _ => actorIDField.YieldKeyboardFocus(); actorIDField.OnEscKey = _ => actorIDField.YieldKeyboardFocus();
@@ -182,7 +174,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (nextActorIDStatus == ActorIDStatus.Normal) if (nextActorIDStatus == ActorIDStatus.Normal)
offset *= -1; offset *= -1;
actorEditPanel.Bounds.Height += offset;
initContainer.Bounds.Y += offset; initContainer.Bounds.Y += offset;
buttonContainer.Bounds.Y += offset; buttonContainer.Bounds.Y += offset;
} }
@@ -190,22 +181,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
actorIDStatus = nextActorIDStatus; actorIDStatus = nextActorIDStatus;
} }
var actor = editor.DefaultBrush.SelectedActor; var actor = editor.DefaultBrush.Selection.Actor;
if (actor != null) if (actor != null)
{ {
var origin = worldRenderer.Viewport.WorldToViewPx(new int2(actor.Bounds.Right, actor.Bounds.Top)); // If we changed actor, update details
// If we scrolled, hide the edit box for a moment
if (lastScrollPosition.X != origin.X || lastScrollPosition.Y != origin.Y)
{
lastScrollTime = Game.RunTime;
lastScrollPosition = origin;
}
// If we changed actor, move widgets
if (CurrentActor != actor) if (CurrentActor != actor)
{ {
lastScrollTime = 0; // Ensure visible
CurrentActor = actor; CurrentActor = actor;
editActorPreview = new EditActorPreview(CurrentActor); editActorPreview = new EditActorPreview(CurrentActor);
@@ -365,13 +346,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
} }
} }
actorEditPanel.Bounds.Height += initContainer.Bounds.Height - oldInitHeight;
buttonContainer.Bounds.Y += initContainer.Bounds.Height - oldInitHeight; buttonContainer.Bounds.Y += initContainer.Bounds.Height - oldInitHeight;
} }
// Set the edit panel to the right of the selection border.
actorEditPanel.Bounds.X = origin.X + editPanelPadding;
actorEditPanel.Bounds.Y = origin.Y;
} }
else if (CurrentActor != null) else if (CurrentActor != null)
{ {
@@ -405,7 +381,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
foreach (var f in typableFields) foreach (var f in typableFields)
f.YieldKeyboardFocus(); f.YieldKeyboardFocus();
editor.DefaultBrush.SelectedActor = null; editor.DefaultBrush.Selection.Actor = null;
CurrentActor = null; CurrentActor = null;
} }

View File

@@ -52,7 +52,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
ModData = modData; ModData = modData;
World = world; World = world;
WorldRenderer = worldRenderer; WorldRenderer = worldRenderer;
Editor = widget.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR"); Editor = widget.Parent.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR");
Panel = widget.Get<ScrollPanelWidget>(templateListId); Panel = widget.Get<ScrollPanelWidget>(templateListId);
ItemTemplate = Panel.Get<ScrollItemWidget>(previewTemplateId); ItemTemplate = Panel.Get<ScrollItemWidget>(previewTemplateId);
Panel.Layout = new GridLayout(Panel); Panel.Layout = new GridLayout(Panel);
@@ -71,6 +71,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return true; return true;
}; };
Editor.DefaultBrush.SelectionChanged += HandleSelectionChanged;
var none = TranslationProvider.GetString(None); var none = TranslationProvider.GetString(None);
var searchResults = TranslationProvider.GetString(SearchResults); var searchResults = TranslationProvider.GetString(SearchResults);
var all = TranslationProvider.GetString(All); var all = TranslationProvider.GetString(All);
@@ -103,6 +105,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}; };
} }
protected override void Dispose(bool disposing)
{
Editor.DefaultBrush.SelectionChanged -= HandleSelectionChanged;
base.Dispose(disposing);
}
void HandleSelectionChanged()
{
SearchTextField.YieldKeyboardFocus();
}
protected Widget CreateCategoriesPanel(ScrollPanelWidget panel) protected Widget CreateCategoriesPanel(ScrollPanelWidget panel)
{ {
var categoriesPanel = Ui.LoadWidget("CATEGORY_FILTER_PANEL", null, new WidgetArgs()); var categoriesPanel = Ui.LoadWidget("CATEGORY_FILTER_PANEL", null, new WidgetArgs());

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public LayerSelectorLogic(Widget widget, WorldRenderer worldRenderer) public LayerSelectorLogic(Widget widget, WorldRenderer worldRenderer)
{ {
this.worldRenderer = worldRenderer; this.worldRenderer = worldRenderer;
editor = widget.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR"); editor = widget.Parent.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR");
editorCursor = worldRenderer.World.WorldActor.Trait<EditorCursorLayer>(); editorCursor = worldRenderer.World.WorldActor.Trait<EditorCursorLayer>();
layerTemplateList = widget.Get<ScrollPanelWidget>("LAYERTEMPLATE_LIST"); layerTemplateList = widget.Get<ScrollPanelWidget>("LAYERTEMPLATE_LIST");

View File

@@ -18,29 +18,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{ {
public class MapEditorLogic : ChromeLogic public class MapEditorLogic : ChromeLogic
{ {
MapCopyFilters copyFilters = MapCopyFilters.All;
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public MapEditorLogic(Widget widget, World world, WorldRenderer worldRenderer) public MapEditorLogic(Widget widget, World world, WorldRenderer worldRenderer)
{ {
var editorViewport = widget.Get<EditorViewportControllerWidget>("MAP_EDITOR"); var editorViewport = widget.Get<EditorViewportControllerWidget>("MAP_EDITOR");
var copypasteButton = widget.GetOrNull<ButtonWidget>("COPYPASTE_BUTTON");
if (copypasteButton != null)
{
var copyPasteKey = copypasteButton.Key.GetValue();
copypasteButton.OnClick = () => editorViewport.SetBrush(new EditorCopyPasteBrush(editorViewport, worldRenderer, () => copyFilters));
copypasteButton.IsHighlighted = () => editorViewport.CurrentBrush is EditorCopyPasteBrush;
}
var copyFilterDropdown = widget.Get<DropDownButtonWidget>("COPYFILTER_BUTTON");
copyFilterDropdown.OnMouseDown = _ =>
{
copyFilterDropdown.RemovePanel();
copyFilterDropdown.AttachPanel(CreateCategoriesPanel());
};
var coordinateLabel = widget.GetOrNull<LabelWidget>("COORDINATE_LABEL"); var coordinateLabel = widget.GetOrNull<LabelWidget>("COORDINATE_LABEL");
if (coordinateLabel != null) if (coordinateLabel != null)
{ {
@@ -71,25 +53,5 @@ namespace OpenRA.Mods.Common.Widgets.Logic
redoButton.OnClick = () => actionManager.Redo(); redoButton.OnClick = () => actionManager.Redo();
} }
} }
Widget CreateCategoriesPanel()
{
var categoriesPanel = Ui.LoadWidget("COPY_FILTER_PANEL", null, new WidgetArgs());
var categoryTemplate = categoriesPanel.Get<CheckboxWidget>("CATEGORY_TEMPLATE");
MapCopyFilters[] allCategories = { MapCopyFilters.Terrain, MapCopyFilters.Resources, MapCopyFilters.Actors };
foreach (var cat in allCategories)
{
var category = (CheckboxWidget)categoryTemplate.Clone();
category.GetText = () => cat.ToString();
category.IsChecked = () => copyFilters.HasFlag(cat);
category.IsVisible = () => true;
category.OnClick = () => copyFilters ^= cat;
categoriesPanel.AddChild(category);
}
return categoriesPanel;
}
} }
} }

View File

@@ -0,0 +1,128 @@
#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 System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.EditorBrushes;
using OpenRA.Mods.Common.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
{
public class MapEditorSelectionLogic : ChromeLogic
{
readonly EditorViewportControllerWidget editor;
readonly WorldRenderer worldRenderer;
readonly ContainerWidget actorEditPanel;
readonly ContainerWidget areaEditPanel;
readonly CheckboxWidget copyTerrainCheckbox;
readonly CheckboxWidget copyResourcesCheckbox;
readonly CheckboxWidget copyActorsCheckbox;
readonly EditorActorLayer editorActorLayer;
MapCopyFilters copyFilters = MapCopyFilters.All;
EditorClipboard? clipboard;
readonly IResourceLayer resourceLayer;
[ObjectCreator.UseCtor]
public MapEditorSelectionLogic(Widget widget, World world, WorldRenderer worldRenderer)
{
this.worldRenderer = worldRenderer;
editorActorLayer = world.WorldActor.Trait<EditorActorLayer>();
resourceLayer = world.WorldActor.Trait<IResourceLayer>();
editor = widget.Get<EditorViewportControllerWidget>("MAP_EDITOR");
var selectTabContainer = widget.Get("SELECT_WIDGETS");
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();
copyTerrainCheckbox = areaEditPanel.Get<CheckboxWidget>("COPY_FILTER_TERRAIN_CHECKBOX");
copyResourcesCheckbox = areaEditPanel.Get<CheckboxWidget>("COPY_FILTER_RESOURCES_CHECKBOX");
copyActorsCheckbox = areaEditPanel.Get<CheckboxWidget>("COPY_FILTER_ACTORS_CHECKBOX");
copyTerrainCheckbox.IsDisabled = () => editor.CurrentBrush is EditorCopyPasteBrush;
copyResourcesCheckbox.IsDisabled = () => editor.CurrentBrush is EditorCopyPasteBrush;
copyActorsCheckbox.IsDisabled = () => editor.CurrentBrush is EditorCopyPasteBrush;
var copyButton = widget.Get<ButtonWidget>("COPY_BUTTON");
copyButton.OnClick = () => clipboard = CopySelectionContents();
copyButton.IsDisabled = () => editor.DefaultBrush.Selection.Area == null;
var pasteButton = widget.Get<ButtonWidget>("PASTE_BUTTON");
pasteButton.OnClick = () =>
{
if (clipboard == null)
return;
editor.SetBrush(new EditorCopyPasteBrush(
editor,
worldRenderer,
clipboard.Value,
resourceLayer,
() => copyFilters));
};
pasteButton.IsDisabled = () => clipboard == null;
pasteButton.IsHighlighted = () => editor.CurrentBrush is EditorCopyPasteBrush;
var closeAreaSelectionButton = areaEditPanel.Get<ButtonWidget>("SELECTION_CANCEL_BUTTON");
closeAreaSelectionButton.OnClick = () => editor.DefaultBrush.ClearSelection();
CreateCategoryPanel(MapCopyFilters.Terrain, copyTerrainCheckbox);
CreateCategoryPanel(MapCopyFilters.Resources, copyResourcesCheckbox);
CreateCategoryPanel(MapCopyFilters.Actors, copyActorsCheckbox);
}
EditorClipboard CopySelectionContents()
{
var selection = editor.DefaultBrush.Selection.Area;
var source = new CellCoordsRegion(selection.TopLeft, selection.BottomRight);
var mapTiles = worldRenderer.World.Map.Tiles;
var mapHeight = worldRenderer.World.Map.Height;
var mapResources = worldRenderer.World.Map.Resources;
var previews = new Dictionary<string, EditorActorPreview>();
var tiles = new Dictionary<CPos, ClipboardTile>();
foreach (var cell in source)
{
if (!mapTiles.Contains(cell))
continue;
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())
previews.TryAdd(preview.ID, preview);
}
return new EditorClipboard(selection, previews, tiles);
}
void CreateCategoryPanel(MapCopyFilters copyFilter, CheckboxWidget checkbox)
{
checkbox.GetText = () => copyFilter.ToString();
checkbox.IsChecked = () => copyFilters.HasFlag(copyFilter);
checkbox.IsVisible = () => true;
checkbox.OnClick = () => copyFilters ^= copyFilter;
}
}
}

View File

@@ -16,31 +16,74 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public class MapEditorTabsLogic : ChromeLogic public class MapEditorTabsLogic : ChromeLogic
{ {
readonly Widget widget; readonly Widget widget;
readonly EditorViewportControllerWidget editor;
protected enum MenuType { Tiles, Layers, Actors, History } protected enum MenuType { Select, Tiles, Layers, Actors, Tools, History }
protected MenuType menuType = MenuType.Tiles; protected MenuType menuType = MenuType.Tiles;
readonly Widget tabContainer; readonly Widget tabContainer;
MenuType lastSelectedTab = MenuType.Tiles;
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public MapEditorTabsLogic(Widget widget) public MapEditorTabsLogic(Widget widget)
{ {
this.widget = widget; this.widget = widget;
editor = widget.Parent.Parent.Get<EditorViewportControllerWidget>("MAP_EDITOR");
editor.DefaultBrush.SelectionChanged += HandleSelectionChanged;
tabContainer = widget.Get("MAP_EDITOR_TAB_CONTAINER"); tabContainer = widget.Get("MAP_EDITOR_TAB_CONTAINER");
SetupTab(null, "SELECT_WIDGETS", MenuType.Select);
SetupTab("TILES_TAB", "TILE_WIDGETS", MenuType.Tiles); SetupTab("TILES_TAB", "TILE_WIDGETS", MenuType.Tiles);
SetupTab("OVERLAYS_TAB", "LAYER_WIDGETS", MenuType.Layers); SetupTab("OVERLAYS_TAB", "LAYER_WIDGETS", MenuType.Layers);
SetupTab("ACTORS_TAB", "ACTOR_WIDGETS", MenuType.Actors); SetupTab("ACTORS_TAB", "ACTOR_WIDGETS", MenuType.Actors);
SetupTab("TOOLS_TAB", "TOOLS_WIDGETS", MenuType.Tools);
SetupTab("HISTORY_TAB", "HISTORY_WIDGETS", MenuType.History); SetupTab("HISTORY_TAB", "HISTORY_WIDGETS", MenuType.History);
} }
protected override void Dispose(bool disposing)
{
editor.DefaultBrush.SelectionChanged -= HandleSelectionChanged;
base.Dispose(disposing);
}
void SetupTab(string buttonId, string tabId, MenuType tabType) void SetupTab(string buttonId, string tabId, MenuType tabType)
{ {
var tab = tabContainer.Get<ButtonWidget>(buttonId); if (buttonId != null)
tab.IsHighlighted = () => menuType == tabType; {
tab.OnClick = () => menuType = tabType; var tab = tabContainer.Get<ButtonWidget>(buttonId);
tab.IsHighlighted = () => menuType == tabType;
tab.OnClick = () => menuType = SelectTab(tabType);
}
var container = widget.Parent.Get<ContainerWidget>(tabId); var container = widget.Parent.Get<ContainerWidget>(tabId);
container.IsVisible = () => menuType == tabType; container.IsVisible = () => menuType == tabType;
} }
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()
{
var actor = editor.DefaultBrush.Selection.Actor;
var area = editor.DefaultBrush.Selection.Area;
if (menuType != MenuType.Select && (actor != null || area != null))
menuType = MenuType.Select;
else if (menuType == MenuType.Select && actor == null && area == null)
menuType = lastSelectedTab;
}
} }
} }

View File

@@ -30,10 +30,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly TerrainGeometryOverlay terrainGeometryTrait; readonly TerrainGeometryOverlay terrainGeometryTrait;
readonly BuildableTerrainOverlay buildableTerrainTrait; readonly BuildableTerrainOverlay buildableTerrainTrait;
readonly Widget widget;
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public MapOverlaysLogic(Widget widget, World world, ModData modData, Dictionary<string, MiniYaml> logicArgs) public MapOverlaysLogic(Widget widget, World world, ModData modData, Dictionary<string, MiniYaml> logicArgs)
{ {
this.widget = widget;
terrainGeometryTrait = world.WorldActor.Trait<TerrainGeometryOverlay>(); terrainGeometryTrait = world.WorldActor.Trait<TerrainGeometryOverlay>();
buildableTerrainTrait = world.WorldActor.Trait<BuildableTerrainOverlay>(); buildableTerrainTrait = world.WorldActor.Trait<BuildableTerrainOverlay>();
@@ -81,28 +84,23 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Widget CreateOverlaysPanel() Widget CreateOverlaysPanel()
{ {
var categoriesPanel = Ui.LoadWidget("OVERLAY_PANEL", null, new WidgetArgs()); var categoriesPanel = widget.Get<Widget>("TOOLS_WIDGETS");
var categoryTemplate = categoriesPanel.Get<CheckboxWidget>("CATEGORY_TEMPLATE"); var showGridCheckbox = categoriesPanel.Get<CheckboxWidget>("SHOW_TILE_GRID");
var showBuildableAreaCheckbox = categoriesPanel.Get<CheckboxWidget>("SHOW_BUILDABLE_AREA");
MapOverlays[] allCategories = { MapOverlays.Grid, MapOverlays.Buildable }; MapOverlays[] allCategories = { MapOverlays.Grid, MapOverlays.Buildable };
foreach (var cat in allCategories) foreach (var cat in allCategories)
{ {
var category = (CheckboxWidget)categoryTemplate.Clone();
category.GetText = () => cat.ToString();
category.IsVisible = () => true;
if (cat.HasFlag(MapOverlays.Grid)) if (cat.HasFlag(MapOverlays.Grid))
{ {
category.IsChecked = () => terrainGeometryTrait.Enabled; showGridCheckbox.IsChecked = () => terrainGeometryTrait.Enabled;
category.OnClick = () => terrainGeometryTrait.Enabled ^= true; showGridCheckbox.OnClick = () => terrainGeometryTrait.Enabled ^= true;
} }
else if (cat.HasFlag(MapOverlays.Buildable)) else if (cat.HasFlag(MapOverlays.Buildable))
{ {
category.IsChecked = () => buildableTerrainTrait.Enabled; showBuildableAreaCheckbox.IsChecked = () => buildableTerrainTrait.Enabled;
category.OnClick = () => buildableTerrainTrait.Enabled ^= true; showBuildableAreaCheckbox.OnClick = () => buildableTerrainTrait.Enabled ^= true;
} }
categoriesPanel.AddChild(category);
} }
return categoriesPanel; return categoriesPanel;

View File

@@ -749,3 +749,10 @@ chrome-radar-gdi:
Inherits: ^Chrome Inherits: ^Chrome
Regions: Regions:
logo: 644, 320, 132, 132 logo: 644, 320, 132, 132
editor:
Inherits: ^Chrome
Regions:
tiles: 768, 170, 16, 16
overlays: 785, 170, 16, 16
tools: 904, 68, 16, 16

View File

@@ -215,7 +215,7 @@ Container@EDITOR_ROOT:
TooltipContainer@TOOLTIP_CONTAINER: TooltipContainer@TOOLTIP_CONTAINER:
Container@EDITOR_WORLD_ROOT: Container@EDITOR_WORLD_ROOT:
Logic: LoadIngamePerfLogic, MapEditorLogic, ActorEditLogic, MapOverlaysLogic Logic: LoadIngamePerfLogic, MapEditorLogic, ActorEditLogic, MapOverlaysLogic, MapEditorSelectionLogic
ToggleGridOverlayKey: EditorToggleGridOverlay ToggleGridOverlayKey: EditorToggleGridOverlay
ToggleBuildableOverlayKey: EditorToggleBuildableOverlay ToggleBuildableOverlayKey: EditorToggleBuildableOverlay
Children: Children:
@@ -226,106 +226,6 @@ Container@EDITOR_WORLD_ROOT:
Height: WINDOW_BOTTOM Height: WINDOW_BOTTOM
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
TooltipTemplate: SIMPLE_TOOLTIP TooltipTemplate: SIMPLE_TOOLTIP
Children:
Background@ACTOR_EDIT_PANEL:
Background: panel-black
Width: 269
Height: 89
Children:
Label@ACTOR_TYPE_LABEL:
X: 2
Y: 2
Width: 265
Height: 24
Align: Center
Font: Bold
Label@ACTOR_ID_LABEL:
Y: 30
Width: 55
Height: 24
Text: label-actor-edit-panel-id
Align: Right
TextField@ACTOR_ID:
X: 67
Y: 29
Width: 189
Height: 25
Label@ACTOR_ID_ERROR_LABEL:
X: 67
Y: 55
Width: 189
Height: 15
Font: TinyBold
TextColor: FF0000
Container@ACTOR_INIT_CONTAINER:
Y: 57
Width: PARENT_RIGHT
Children:
Container@CHECKBOX_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 22
Children:
Checkbox@OPTION:
X: 67
Y: 1
Width: PARENT_RIGHT - 67
Height: 20
Container@SLIDER_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 22
Children:
Label@LABEL:
Y: 1
Width: 55
Height: 16
Align: Right
Slider@OPTION:
X: 58
Y: 1
Width: 146
Height: 20
TextField@VALUE:
X: 206
Y: 1
Width: 50
Height: 20
Type: Integer
Container@DROPDOWN_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 27
Children:
Label@LABEL:
Y: 2
Width: 55
Height: 24
Align: Right
DropDownButton@OPTION:
X: 67
Y: 1
Width: 189
Height: 25
Font: Bold
Container@BUTTON_CONTAINER:
Y: 60
Children:
Button@DELETE_BUTTON:
X: 4
Width: 75
Height: 25
Text: button-container-delete
Font: Bold
Button@CANCEL_BUTTON:
X: 110
Width: 75
Height: 25
Text: button-container-cancel
Font: Bold
Button@OK_BUTTON:
X: 190
Width: 75
Height: 25
Text: button-container-ok
Font: Bold
ViewportController: ViewportController:
Width: WINDOW_RIGHT Width: WINDOW_RIGHT
Height: WINDOW_BOTTOM Height: WINDOW_BOTTOM
@@ -525,6 +425,31 @@ Container@EDITOR_WORLD_ROOT:
X: 4 X: 4
Y: 4 Y: 4
Visible: true Visible: true
Container@TOOLS_WIDGETS:
X: WINDOW_RIGHT - 295
Y: 318
Width: 290
Height: WINDOW_BOTTOM - 410
ClickThrough: false
Children:
Background@TOOLS_EDIT_PANEL:
X: 0
Y: 0
Width: PARENT_RIGHT
Height: PARENT_BOTTOM
Background: scrollpanel-bg
Checkbox@SHOW_TILE_GRID:
X: 6
Y: 7
Width: PARENT_RIGHT - 29
Height: 20
Text: label-show-tile-grid
Checkbox@SHOW_BUILDABLE_AREA:
X: 6
Y: 32
Width: PARENT_RIGHT - 29
Height: 20
Text: label-show-buildable-area
Container@HISTORY_WIDGETS: Container@HISTORY_WIDGETS:
Logic: HistoryLogLogic Logic: HistoryLogLogic
X: WINDOW_RIGHT - 295 X: WINDOW_RIGHT - 295
@@ -558,6 +483,171 @@ Container@EDITOR_WORLD_ROOT:
Width: PARENT_RIGHT Width: PARENT_RIGHT
Height: 25 Height: 25
Align: Left Align: Left
Container@SELECT_WIDGETS:
Visible: false
X: WINDOW_RIGHT - 295
Y: 318
Width: 290
Height: WINDOW_BOTTOM - 410
Children:
Background@SELECT_BG:
X: 0
Y: 0
Width: PARENT_RIGHT
Height: PARENT_BOTTOM
Background: scrollpanel-bg
Container@AREA_EDIT_PANEL:
X: 0
Y: 0
Width: PARENT_RIGHT
Height: PARENT_BOTTOM
#Background: scrollpanel-bg
Children:
Label@AREA_EDIT_TITLE:
X: 6
Y: 7
Width: 265
Height: 24
Align: Center
Font: Bold
Text: label-area-selection
Label@AREA_FILTERS_LABEL:
X: 6
Y: 36
Width: 55
Height: 25
Font: Bold
Align: Left
Text: label-copy-filters
Checkbox@COPY_FILTER_TERRAIN_CHECKBOX:
X: 6
Y: 61
Width: PARENT_RIGHT - 29
Height: 20
Text: label-filter-terrain
Checkbox@COPY_FILTER_RESOURCES_CHECKBOX:
X: 6
Y: 86
Width: PARENT_RIGHT - 29
Height: 20
Text: label-filter-resources
Checkbox@COPY_FILTER_ACTORS_CHECKBOX:
X: 6
Y: 111
Width: PARENT_RIGHT - 29
Height: 20
Text: label-filter-actors
Button@SELECTION_CANCEL_BUTTON:
X: 209
Y: 136
Width: 75
Height: 25
Text: button-selection-cancel
Font: Bold
Container@ACTOR_EDIT_PANEL:
X: 0
Y: 0
Width: PARENT_RIGHT
Height: PARENT_BOTTOM
#Background: scrollpanel-bg
Children:
Label@ACTOR_TYPE_LABEL:
X: 6
Y: 2
Width: 265
Height: 24
Align: Center
Font: Bold
Label@ACTOR_ID_LABEL:
X: 0
Y: 29
Width: 55
Height: 25
Text: label-actor-edit-panel-id
Align: Right
TextField@ACTOR_ID:
X: 67
Y: 29
Width: 210
Height: 25
Label@ACTOR_ID_ERROR_LABEL:
X: 67
Y: 45
Width: 210
Height: 15
Font: TinyBold
TextColor: FF0000
Container@ACTOR_INIT_CONTAINER:
Y: 57
Width: PARENT_RIGHT
Children:
Container@CHECKBOX_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 22
Children:
Checkbox@OPTION:
X: 84
Y: 1
Width: PARENT_RIGHT - 100
Height: 20
Container@SLIDER_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 22
Children:
Label@LABEL:
X: 0
Y: 1
Width: 55
Height: 16
Align: Right
Slider@OPTION:
X: 58
Y: 1
Width: 167
Height: 20
TextField@VALUE:
X: 227
Y: 1
Width: 50
Height: 20
Type: Integer
Container@DROPDOWN_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 27
Children:
Label@LABEL:
X: 0
Y: 2
Width: 55
Height: 24
Align: Right
DropDownButton@OPTION:
X: 67
Y: 1
Width: 210
Height: 25
Font: Bold
Container@BUTTON_CONTAINER:
Y: 60
Children:
Button@DELETE_BUTTON:
X: 4
Width: 75
Height: 25
Text: button-container-delete
Font: Bold
Button@CANCEL_BUTTON:
X: 131
Width: 75
Height: 25
Text: button-container-cancel
Font: Bold
Button@OK_BUTTON:
X: 211
Width: 75
Height: 25
Text: button-container-ok
Font: Bold
Container@MAP_EDITOR_TAB_CONTAINER: Container@MAP_EDITOR_TAB_CONTAINER:
Logic: MapEditorTabsLogic Logic: MapEditorTabsLogic
X: WINDOW_RIGHT - 295 X: WINDOW_RIGHT - 295
@@ -567,46 +657,76 @@ Container@EDITOR_WORLD_ROOT:
ClickThrough: false ClickThrough: false
Children: Children:
Button@TILES_TAB: Button@TILES_TAB:
Width: 71 Width: 59
Height: 25 Height: 25
Text: button-map-editor-tab-container-tiles.label
Font: Bold
Key: EditorTilesTab Key: EditorTilesTab
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-map-editor-tab-container-tiles.tooltip TooltipText: button-map-editor-tab-container-tiles.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Children:
Image@ICON:
X: 21
Y: 5
ImageCollection: editor
ImageName: tiles
Button@OVERLAYS_TAB: Button@OVERLAYS_TAB:
X: 70 X: 58
Width: 80 Width: 59
Height: 25 Height: 25
Text: button-map-editor-tab-container-overlays.label
Font: Bold
Key: EditorOverlaysTab Key: EditorOverlaysTab
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-map-editor-tab-container-overlays.tooltip TooltipText: button-map-editor-tab-container-overlays.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Children:
Image@ICON:
X: 21
Y: 5
ImageCollection: editor
ImageName: overlays
Button@ACTORS_TAB: Button@ACTORS_TAB:
X: 149 X: 116
Width: 71 Width: 58
Height: 25 Height: 25
Text: button-map-editor-tab-container-actors.label
Font: Bold
Key: EditorActorsTab Key: EditorActorsTab
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-map-editor-tab-container-actors.tooltip TooltipText: button-map-editor-tab-container-actors.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Button@HISTORY_TAB: Children:
X: 219 Image@ICON:
Width: 71 X: 21
Y: 5
ImageCollection: production-icons
ImageName: infantry
Button@TOOLS_TAB:
X: 173
Width: 59
Height: 25
Key: EditorToolsTab
TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-map-editor-tab-container-tools.tooltip
TooltipContainer: TOOLTIP_CONTAINER
Children:
Image@ICON:
X: 21
Y: 5
ImageCollection: editor
ImageName: tools
Button@HISTORY_TAB:
X: 231
Width: 59
Height: 25 Height: 25
Text: button-map-editor-tab-container-history.label
Font: Bold
Key: EditorHistoryTab Key: EditorHistoryTab
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-map-editor-tab-container-history.tooltip TooltipText: button-map-editor-tab-container-history.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Children:
Image@ICON:
X: 21
Y: 5
ImageCollection: sidebar-bits
ImageName: production-tooltip-time
Button@UNDO_BUTTON: Button@UNDO_BUTTON:
X: WINDOW_RIGHT - 800 X: WINDOW_RIGHT - 764
Y: 5 Y: 5
Height: 25 Height: 25
Width: 100 Width: 100
@@ -617,7 +737,7 @@ Container@EDITOR_WORLD_ROOT:
TooltipText: button-editor-world-root-undo.tooltip TooltipText: button-editor-world-root-undo.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Button@REDO_BUTTON: Button@REDO_BUTTON:
X: WINDOW_RIGHT - 690 X: WINDOW_RIGHT - 654
Y: 5 Y: 5
Height: 25 Height: 25
Width: 100 Width: 100
@@ -627,30 +747,28 @@ Container@EDITOR_WORLD_ROOT:
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-editor-world-root-redo.tooltip TooltipText: button-editor-world-root-redo.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Button@COPYPASTE_BUTTON: Button@COPY_BUTTON:
X: WINDOW_RIGHT - 580 X: WINDOW_RIGHT - 544
Y: 5 Y: 5
Width: 96
Height: 25 Height: 25
Text: button-editor-world-root-copypaste.label Width: 100
Text: button-editor-world-root-copy.label
Font: Bold
Key: EditorCopy Key: EditorCopy
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-editor-world-root-copypaste.tooltip TooltipText: button-editor-world-root-copy.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
DropDownButton@COPYFILTER_BUTTON: Button@PASTE_BUTTON:
X: WINDOW_RIGHT - 475 X: WINDOW_RIGHT - 434
Y: 5 Y: 5
Width: 140
Height: 25 Height: 25
Text: dropdownbutton-editor-world-root-copyfilter-button Width: 100
Font: Bold Text: button-editor-world-root-paste.label
DropDownButton@OVERLAY_BUTTON:
X: WINDOW_RIGHT - 950
Y: 5
Width: 140
Height: 25
Text: dropdownbutton-editor-world-root-overlay-button
Font: Bold Font: Bold
Key: EditorPaste
TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-editor-world-root-paste.tooltip
TooltipContainer: TOOLTIP_CONTAINER
Label@COORDINATE_LABEL: Label@COORDINATE_LABEL:
X: 10 X: 10
Width: 50 Width: 50
@@ -693,19 +811,6 @@ ScrollPanel@CATEGORY_FILTER_PANEL:
Height: 20 Height: 20
Visible: false Visible: false
ScrollPanel@COPY_FILTER_PANEL:
Width: 140
Height: 80
ItemSpacing: 5
TopBottomSpacing: 0
Children:
Checkbox@CATEGORY_TEMPLATE:
X: 5
Y: 5
Width: PARENT_RIGHT - 29
Height: 20
Visible: false
ScrollPanel@OVERLAY_PANEL: ScrollPanel@OVERLAY_PANEL:
Width: 140 Width: 140
Height: 55 Height: 55

View File

@@ -72,23 +72,38 @@ label-tiles-bg-categories = Filter:
label-actors-bg-search = Search: label-actors-bg-search = Search:
label-actors-bg-categories = Filter: label-actors-bg-categories = Filter:
label-actors-bg-owners = Owner: label-actors-bg-owners = Owner:
label-area-selection = Area Selection
label-copy-filters = Copy Filters
label-filter-terrain = Terrain
label-filter-resources = Resources
label-filter-actors = Actors
button-selection-cancel = Cancel
label-show-tile-grid = Show Tile Grid
label-show-buildable-area = Show Buildable Area
button-map-editor-tab-container-tiles = button-map-editor-tab-container-tiles =
.label = Tiles
.tooltip = Tiles .tooltip = Tiles
button-map-editor-tab-container-overlays = button-map-editor-tab-container-overlays =
.label = Overlays
.tooltip = Overlays .tooltip = Overlays
button-map-editor-tab-container-actors = button-map-editor-tab-container-actors =
.label = Actors
.tooltip = Actors .tooltip = Actors
button-map-editor-tab-container-tools =
.tooltip = Tools
button-map-editor-tab-container-history = button-map-editor-tab-container-history =
.label = History
.tooltip = History .tooltip = History
button-editor-world-root-copy =
.label = Copy
.tooltip = Copy
button-editor-world-root-paste =
.label = Paste
.tooltip = Paste
button-editor-world-root-undo = button-editor-world-root-undo =
.label = Undo .label = Undo
.tooltip = Undo last step .tooltip = Undo last step
@@ -97,12 +112,6 @@ button-editor-world-root-redo =
.label = Redo .label = Redo
.tooltip = Redo last step .tooltip = Redo last step
button-editor-world-root-copypaste =
.label = Copy/Paste
.tooltip = Copy
dropdownbutton-editor-world-root-copyfilter-button = Copy Filters
dropdownbutton-editor-world-root-overlay-button = Overlays
button-select-categories-buttons-all = All button-select-categories-buttons-all = All
button-select-categories-buttons-none = None button-select-categories-buttons-none = None

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 KiB

After

Width:  |  Height:  |  Size: 464 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 652 KiB

After

Width:  |  Height:  |  Size: 853 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 178 KiB

View File

@@ -204,7 +204,7 @@ Container@EDITOR_ROOT:
TooltipContainer@TOOLTIP_CONTAINER: TooltipContainer@TOOLTIP_CONTAINER:
Container@EDITOR_WORLD_ROOT: Container@EDITOR_WORLD_ROOT:
Logic: LoadIngamePerfLogic, MapEditorLogic, ActorEditLogic, MapOverlaysLogic Logic: LoadIngamePerfLogic, MapEditorLogic, ActorEditLogic, MapOverlaysLogic, MapEditorSelectionLogic
ToggleGridOverlayKey: EditorToggleGridOverlay ToggleGridOverlayKey: EditorToggleGridOverlay
ToggleBuildableOverlayKey: EditorToggleBuildableOverlay ToggleBuildableOverlayKey: EditorToggleBuildableOverlay
Children: Children:
@@ -215,110 +215,6 @@ Container@EDITOR_WORLD_ROOT:
Height: WINDOW_BOTTOM Height: WINDOW_BOTTOM
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
TooltipTemplate: SIMPLE_TOOLTIP TooltipTemplate: SIMPLE_TOOLTIP
Children:
Background@ACTOR_EDIT_PANEL:
X: 32
Y: 32
Width: 294
Height: 114
Children:
Label@ACTOR_TYPE_LABEL:
X: 15
Y: 16
Width: 265
Height: 24
Align: Center
Font: Bold
Label@ACTOR_ID_LABEL:
X: 15
Y: 45
Width: 55
Height: 25
Text: label-actor-edit-panel-id
Align: Right
TextField@ACTOR_ID:
X: 84
Y: 45
Width: 192
Height: 25
Label@ACTOR_ID_ERROR_LABEL:
X: 84
Y: 71
Width: 192
Height: 15
Font: TinyBold
TextColor: FF0000
Container@ACTOR_INIT_CONTAINER:
Y: 73
Width: PARENT_RIGHT
Children:
Container@CHECKBOX_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 22
Children:
Checkbox@OPTION:
X: 84
Y: 1
Width: PARENT_RIGHT - 84
Height: 20
Container@SLIDER_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 22
Children:
Label@LABEL:
X: 15
Y: 1
Width: 55
Height: 16
Align: Right
Slider@OPTION:
X: 75
Y: 1
Width: 149
Height: 20
TextField@VALUE:
X: 226
Y: 1
Width: 50
Height: 20
Type: Integer
Container@DROPDOWN_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 27
Children:
Label@LABEL:
X: 15
Y: 2
Width: 55
Height: 24
Align: Right
DropDownButton@OPTION:
X: 84
Y: 1
Width: 192
Height: 25
Font: Bold
Container@BUTTON_CONTAINER:
Y: 75
Children:
Button@DELETE_BUTTON:
X: 15
Width: 75
Height: 25
Text: button-container-delete
Font: Bold
Button@CANCEL_BUTTON:
X: 125
Width: 75
Height: 25
Text: button-container-cancel
Font: Bold
Button@OK_BUTTON:
X: 205
Width: 75
Height: 25
Text: button-container-ok
Font: Bold
ViewportController: ViewportController:
Width: WINDOW_RIGHT Width: WINDOW_RIGHT
Height: WINDOW_BOTTOM Height: WINDOW_BOTTOM
@@ -347,230 +243,429 @@ Container@EDITOR_WORLD_ROOT:
Y: 10 Y: 10
Width: PARENT_RIGHT - 19 Width: PARENT_RIGHT - 19
Height: PARENT_BOTTOM - 19 Height: PARENT_BOTTOM - 19
Background@TOOLS_BG:
X: WINDOW_RIGHT - 320
Y: 330
Width: 310
Height: WINDOW_BOTTOM - 422
Container@TILE_WIDGETS: Container@TILE_WIDGETS:
X: WINDOW_RIGHT - 320
Y: 354
Width: 310
Height: WINDOW_BOTTOM - 458
Logic: TileSelectorLogic Logic: TileSelectorLogic
Children: Children:
Background@TILES_BG: Label@SEARCH_LABEL:
X: WINDOW_RIGHT - 320 Y: 12
Y: 360 Width: 55
Width: 310 Height: 25
Height: WINDOW_BOTTOM - 452 Text: label-tiles-bg-search
Align: Right
Font: TinyBold
TextField@SEARCH_TEXTFIELD:
X: 60
Y: 10
Width: PARENT_RIGHT - 70
Height: 25
Label@CATEGORIES_LABEL:
Y: 36
Width: 55
Height: 25
Text: label-tiles-bg-categories
Align: Right
Font: TinyBold
DropDownButton@CATEGORIES_DROPDOWN:
X: 60
Y: 34
Width: PARENT_RIGHT - 70
Height: 25
Font: Bold
ScrollPanel@TILETEMPLATE_LIST:
X: 10
Y: 58
Width: PARENT_RIGHT - 20
Height: PARENT_BOTTOM - 55
TopBottomSpacing: 4
ItemSpacing: 4
Children: Children:
Label@SEARCH_LABEL: ScrollItem@TILEPREVIEW_TEMPLATE:
Y: 12 Visible: false
Width: 55 Width: PARENT_RIGHT - 35
Height: 25 TooltipContainer: TOOLTIP_CONTAINER
Text: label-tiles-bg-search
Align: Right
Font: TinyBold
TextField@SEARCH_TEXTFIELD:
X: 60
Y: 10
Width: PARENT_RIGHT - 70
Height: 25
Label@CATEGORIES_LABEL:
Y: 36
Width: 55
Height: 25
Text: label-tiles-bg-categories
Align: Right
Font: TinyBold
DropDownButton@CATEGORIES_DROPDOWN:
X: 60
Y: 34
Width: PARENT_RIGHT - 70
Height: 25
Font: Bold
ScrollPanel@TILETEMPLATE_LIST:
X: 10
Y: 58
Width: PARENT_RIGHT - 20
Height: PARENT_BOTTOM - 68
TopBottomSpacing: 4
ItemSpacing: 4
Children: Children:
ScrollItem@TILEPREVIEW_TEMPLATE: TerrainTemplatePreview@TILE_PREVIEW:
Visible: false X: 4
Width: PARENT_RIGHT - 35 Y: 4
TooltipContainer: TOOLTIP_CONTAINER
Children:
TerrainTemplatePreview@TILE_PREVIEW:
X: 4
Y: 4
Container@LAYER_WIDGETS: Container@LAYER_WIDGETS:
X: WINDOW_RIGHT - 320
Y: 354
Width: 310
Height: WINDOW_BOTTOM - 458
Visible: false Visible: false
Logic: LayerSelectorLogic Logic: LayerSelectorLogic
Children: Children:
Background@LAYERS_BG: ScrollPanel@LAYERTEMPLATE_LIST:
X: WINDOW_RIGHT - 320 X: 10
Y: 360 Y: 10
Width: 310 Width: PARENT_RIGHT - 20
Height: WINDOW_BOTTOM - 452 Height: PARENT_BOTTOM - 7
TopBottomSpacing: 4
ItemSpacing: 4
Children: Children:
ScrollPanel@LAYERTEMPLATE_LIST: ScrollItem@LAYERPREVIEW_TEMPLATE:
X: 10 Visible: false
Y: 10 IgnoreChildMouseOver: true
Width: PARENT_RIGHT - 20 TooltipContainer: TOOLTIP_CONTAINER
Height: PARENT_BOTTOM - 20
TopBottomSpacing: 4
ItemSpacing: 4
Children: Children:
ScrollItem@LAYERPREVIEW_TEMPLATE: ResourcePreview@LAYER_PREVIEW:
X: 4
Y: 4
Visible: false Visible: false
IgnoreChildMouseOver: true
TooltipContainer: TOOLTIP_CONTAINER
Children:
ResourcePreview@LAYER_PREVIEW:
X: 4
Y: 4
Visible: false
Container@ACTOR_WIDGETS: Container@ACTOR_WIDGETS:
X: WINDOW_RIGHT - 320
Y: 354
Width: 310
Height: WINDOW_BOTTOM - 458
Visible: false Visible: false
Logic: ActorSelectorLogic Logic: ActorSelectorLogic
Children: Children:
Background@ACTORS_BG: Label@SEARCH_LABEL:
X: WINDOW_RIGHT - 320 Y: 12
Y: 360 Width: 55
Width: 310 Height: 25
Height: WINDOW_BOTTOM - 452 Text: label-actors-bg-search
Align: Right
Font: TinyBold
TextField@SEARCH_TEXTFIELD:
X: 60
Y: 10
Width: PARENT_RIGHT - 70
Height: 25
Label@CATEGORIES_LABEL:
Y: 36
Width: 55
Height: 25
Text: label-actors-bg-categories
Align: Right
Font: TinyBold
DropDownButton@CATEGORIES_DROPDOWN:
X: 60
Y: 34
Width: PARENT_RIGHT - 70
Height: 25
Font: Bold
Label@OWNERS_LABEL:
Y: 60
Width: 55
Height: 25
Text: label-actors-bg-owners
Align: Right
Font: TinyBold
DropDownButton@OWNERS_DROPDOWN:
X: 60
Y: 58
Width: PARENT_RIGHT - 70
Height: 25
Font: Bold
ScrollPanel@ACTORTEMPLATE_LIST:
X: 10
Y: 82
Width: PARENT_RIGHT - 20
Height: PARENT_BOTTOM - 79
TopBottomSpacing: 4
ItemSpacing: 4
Children: Children:
Label@SEARCH_LABEL: ScrollItem@ACTORPREVIEW_TEMPLATE:
Y: 12 Visible: false
Width: 55 Width: PARENT_RIGHT - 35
Height: 25 TooltipContainer: TOOLTIP_CONTAINER
Text: label-actors-bg-search TooltipTemplate: SIMPLE_TOOLTIP
Align: Right IgnoreChildMouseOver: true
Font: TinyBold
TextField@SEARCH_TEXTFIELD:
X: 60
Y: 10
Width: PARENT_RIGHT - 70
Height: 25
Label@CATEGORIES_LABEL:
Y: 36
Width: 55
Height: 25
Text: label-actors-bg-categories
Align: Right
Font: TinyBold
DropDownButton@CATEGORIES_DROPDOWN:
X: 60
Y: 34
Width: PARENT_RIGHT - 70
Height: 25
Font: Bold
Label@OWNERS_LABEL:
Y: 60
Width: 55
Height: 25
Text: label-actors-bg-owners
Align: Right
Font: TinyBold
DropDownButton@OWNERS_DROPDOWN:
X: 60
Y: 58
Width: PARENT_RIGHT - 70
Height: 25
Font: Bold
ScrollPanel@ACTORTEMPLATE_LIST:
X: 10
Y: 82
Width: PARENT_RIGHT - 20
Height: PARENT_BOTTOM - 92
TopBottomSpacing: 4
ItemSpacing: 4
Children: Children:
ScrollItem@ACTORPREVIEW_TEMPLATE: ActorPreview@ACTOR_PREVIEW:
Visible: false X: 4
Width: PARENT_RIGHT - 35 Y: 4
TooltipContainer: TOOLTIP_CONTAINER Visible: true
TooltipTemplate: SIMPLE_TOOLTIP Container@TOOLS_WIDGETS:
IgnoreChildMouseOver: true X: WINDOW_RIGHT - 320
Children: Y: 354
ActorPreview@ACTOR_PREVIEW: Width: 310
X: 4 Height: WINDOW_BOTTOM - 458
Y: 4 Visible: false
Visible: true Children:
Checkbox@SHOW_TILE_GRID:
X: 15
Y: 15
Width: PARENT_RIGHT - 15
Height: 20
Text: label-show-tile-grid
Checkbox@SHOW_BUILDABLE_AREA:
X: 15
Y: 40
Width: PARENT_RIGHT - 15
Height: 20
Text: label-show-buildable-area
Container@HISTORY_WIDGETS: Container@HISTORY_WIDGETS:
X: WINDOW_RIGHT - 320
Y: 354
Width: 310
Height: WINDOW_BOTTOM - 458
Logic: HistoryLogLogic Logic: HistoryLogLogic
Visible: false Visible: false
Children: Children:
Background@HISTORY_BG: ScrollPanel@HISTORY_LIST:
X: WINDOW_RIGHT - 320 X: 10
Y: 360 Y: 10
Width: 310 Width: PARENT_RIGHT - 20
Height: WINDOW_BOTTOM - 452 Height: PARENT_BOTTOM - 7
CollapseHiddenChildren: True
TopBottomSpacing: 4
ItemSpacing: 4
Children: Children:
ScrollPanel@HISTORY_LIST: ScrollItem@HISTORY_TEMPLATE:
X: 10 X: 4
Y: 10 Visible: false
Width: PARENT_RIGHT - 20 Width: PARENT_RIGHT - 31
Height: PARENT_BOTTOM - 20 Height: 25
CollapseHiddenChildren: True IgnoreChildMouseOver: true
TopBottomSpacing: 4 TextColor: ffffff
ItemSpacing: 4 TextColorDisabled: 8f8f8f
Children: Children:
ScrollItem@HISTORY_TEMPLATE: Label@TITLE:
X: 4 X: 5
Visible: false Width: PARENT_RIGHT
Width: PARENT_RIGHT - 31
Height: 25 Height: 25
IgnoreChildMouseOver: true Align: Left
TextColor: ffffff Container@SELECT_WIDGETS:
TextColorDisabled: 8f8f8f X: WINDOW_RIGHT - 320
Y: 354
Width: 310
Height: WINDOW_BOTTOM - 458
Visible: false
Children:
Container@AREA_EDIT_PANEL:
Width: 310
Height: WINDOW_BOTTOM - 458
Children:
Label@AREA_EDIT_TITLE:
X: 15
Y: 16
Width: 281
Height: 24
Align: Center
Font: Bold
Text: label-area-selection
Label@AREA_FILTERS_LABEL:
X: 15
Y: 45
Width: 55
Height: 25
Font: Bold
Align: Left
Text: label-copy-filters
Checkbox@COPY_FILTER_TERRAIN_CHECKBOX:
X: 15
Y: 70
Width: PARENT_RIGHT - 29
Height: 20
Text: label-filter-terrain
Checkbox@COPY_FILTER_RESOURCES_CHECKBOX:
X: 15
Y: 95
Width: PARENT_RIGHT - 29
Height: 20
Text: label-filter-resources
Checkbox@COPY_FILTER_ACTORS_CHECKBOX:
X: 15
Y: 120
Width: PARENT_RIGHT - 29
Height: 20
Text: label-filter-actors
Button@SELECTION_CANCEL_BUTTON:
X: 222
Y: 145
Width: 75
Height: 25
Text: button-selection-cancel
Font: Bold
Container@ACTOR_EDIT_PANEL:
Width: 310
Height: WINDOW_BOTTOM - 458
Children:
Label@ACTOR_TYPE_LABEL:
X: 15
Y: 16
Width: 281
Height: 24
Align: Center
Font: Bold
Label@ACTOR_ID_LABEL:
X: 15
Y: 45
Width: 55
Height: 25
Text: label-actor-edit-panel-id
Align: Right
TextField@ACTOR_ID:
X: 84
Y: 45
Width: 208
Height: 25
Label@ACTOR_ID_ERROR_LABEL:
X: 84
Y: 71
Width: 208
Height: 15
Font: TinyBold
TextColor: FF0000
Container@ACTOR_INIT_CONTAINER:
Y: 73
Width: PARENT_RIGHT
Children:
Container@CHECKBOX_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 22
Children: Children:
Label@TITLE: Checkbox@OPTION:
X: 5 X: 84
Width: PARENT_RIGHT Y: 1
Width: PARENT_RIGHT - 100
Height: 20
Container@SLIDER_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 22
Children:
Label@LABEL:
X: 15
Y: 1
Width: 55
Height: 16
Align: Right
Slider@OPTION:
X: 75
Y: 1
Width: 165
Height: 20
TextField@VALUE:
X: 242
Y: 1
Width: 50
Height: 20
Type: Integer
Container@DROPDOWN_OPTION_TEMPLATE:
Width: PARENT_RIGHT
Height: 27
Children:
Label@LABEL:
X: 15
Y: 2
Width: 55
Height: 24
Align: Right
DropDownButton@OPTION:
X: 84
Y: 1
Width: 208
Height: 25 Height: 25
Align: Left Font: Bold
Container@BUTTON_CONTAINER:
Y: 75
Children:
Button@DELETE_BUTTON:
X: 15
Width: 75
Height: 25
Text: button-container-delete
Font: Bold
Button@CANCEL_BUTTON:
X: 142
Width: 75
Height: 25
Text: button-container-cancel
Font: Bold
Button@OK_BUTTON:
X: 222
Width: 75
Height: 25
Text: button-container-ok
Font: Bold
Container@MAP_EDITOR_TAB_CONTAINER: Container@MAP_EDITOR_TAB_CONTAINER:
Logic: MapEditorTabsLogic Logic: MapEditorTabsLogic
X: WINDOW_RIGHT - 315 X: WINDOW_RIGHT - 311
Y: 330 Y: 339
Width: 310 Width: 292
Height: 25 Height: 25
Children: Children:
Button@TILES_TAB: Button@TILES_TAB:
X: 0 X: 0
Width: 70 Width: 58
Height: 25 Height: 25
Text: button-map-editor-tab-container-tiles.label
Font: Bold
Key: EditorTilesTab Key: EditorTilesTab
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-map-editor-tab-container-tiles.tooltip TooltipText: button-map-editor-tab-container-tiles.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Children:
Image@ICON:
X: 21
Y: 5
ImageCollection: editor
ImageName: tiles
Button@OVERLAYS_TAB: Button@OVERLAYS_TAB:
X: 70 X: 58
Width: 90 Width: 58
Height: 25 Height: 25
Text: button-map-editor-tab-container-overlays.label
Font: Bold
Key: EditorOverlaysTab Key: EditorOverlaysTab
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-map-editor-tab-container-overlays.tooltip TooltipText: button-map-editor-tab-container-overlays.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Children:
Image@ICON:
X: 21
Y: 5
ImageCollection: editor
ImageName: overlays
Button@ACTORS_TAB: Button@ACTORS_TAB:
X: 160 X: 116
Width: 70 Width: 59
Height: 25 Height: 25
Text: button-map-editor-tab-container-actors.label
Font: Bold
Key: EditorActorsTab Key: EditorActorsTab
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-map-editor-tab-container-actors.tooltip TooltipText: button-map-editor-tab-container-actors.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Button@HISTORY_TAB: Children:
X: 230 Image@ICON:
Width: 70 X: 21
Y: 5
ImageCollection: production-icons
ImageName: infantry
Button@TOOLS_TAB:
X: 175
Width: 58
Height: 25
Key: EditorToolsTab
TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-map-editor-tab-container-tools.tooltip
TooltipContainer: TOOLTIP_CONTAINER
Children:
Image@ICON:
X: 21
Y: 5
ImageCollection: editor
ImageName: tools
Button@HISTORY_TAB:
X: 233
Width: 58
Height: 25 Height: 25
Text: button-map-editor-tab-container-history.label
Font: Bold
Key: EditorHistoryTab Key: EditorHistoryTab
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-map-editor-tab-container-history.tooltip TooltipText: button-map-editor-tab-container-history.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Children:
Image@ICON:
X: 21
Y: 5
ImageCollection: sidebar-bits
ImageName: production-tooltip-time
MenuButton@OPTIONS_BUTTON: MenuButton@OPTIONS_BUTTON:
Logic: MenuButtonsChromeLogic Logic: MenuButtonsChromeLogic
MenuContainer: INGAME_MENU MenuContainer: INGAME_MENU
@@ -583,24 +678,8 @@ Container@EDITOR_WORLD_ROOT:
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Font: Bold Font: Bold
Key: escape Key: escape
Button@COPYPASTE_BUTTON:
X: 70
Width: 90
Height: 25
Text: button-editor-world-root-copypaste.label
TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-editor-world-root-copypaste.tooltip
TooltipContainer: TOOLTIP_CONTAINER
Font: Bold
Key: EditorCopy
DropDownButton@COPYFILTER_BUTTON:
X: 170
Width: 140
Height: 25
Text: dropdownbutton-editor-world-root-copyfilter-button
Font: Bold
Button@UNDO_BUTTON: Button@UNDO_BUTTON:
X: 320 X: 70
Height: 25 Height: 25
Width: 70 Width: 70
Text: button-editor-world-root-undo.label Text: button-editor-world-root-undo.label
@@ -610,7 +689,7 @@ Container@EDITOR_WORLD_ROOT:
TooltipText: button-editor-world-root-undo.tooltip TooltipText: button-editor-world-root-undo.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
Button@REDO_BUTTON: Button@REDO_BUTTON:
X: 400 X: 150
Height: 25 Height: 25
Width: 70 Width: 70
Text: button-editor-world-root-redo.label Text: button-editor-world-root-redo.label
@@ -619,21 +698,35 @@ Container@EDITOR_WORLD_ROOT:
TooltipTemplate: BUTTON_TOOLTIP TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-editor-world-root-redo.tooltip TooltipText: button-editor-world-root-redo.tooltip
TooltipContainer: TOOLTIP_CONTAINER TooltipContainer: TOOLTIP_CONTAINER
DropDownButton@OVERLAY_BUTTON: Button@COPY_BUTTON:
X: 480 X: 230
Width: 140
Height: 25 Height: 25
Text: dropdownbutton-editor-world-root-overlay-button Text: button-editor-world-root-copy.label
Width: 70
Font: Bold Font: Bold
Key: EditorCopy
TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-editor-world-root-copy.tooltip
TooltipContainer: TOOLTIP_CONTAINER
Button@PASTE_BUTTON:
X: 310
Width: 70
Height: 25
Text: button-editor-world-root-paste.label
Font: Bold
Key: EditorPaste
TooltipTemplate: BUTTON_TOOLTIP
TooltipText: button-editor-world-root-paste.tooltip
TooltipContainer: TOOLTIP_CONTAINER
Label@COORDINATE_LABEL: Label@COORDINATE_LABEL:
X: 630 X: 470
Width: 50 Width: 50
Height: 25 Height: 25
Align: Left Align: Left
Font: Bold Font: Bold
Contrast: true Contrast: true
Label@CASH_LABEL: Label@CASH_LABEL:
X: 745 X: 595
Width: 50 Width: 50
Height: 25 Height: 25
Align: Left Align: Left
@@ -669,29 +762,3 @@ ScrollPanel@CATEGORY_FILTER_PANEL:
Height: 20 Height: 20
Visible: false Visible: false
ScrollPanel@COPY_FILTER_PANEL:
Width: 140
Height: 80
ItemSpacing: 5
TopBottomSpacing: 0
Children:
Checkbox@CATEGORY_TEMPLATE:
X: 5
Y: 5
Width: PARENT_RIGHT - 29
Height: 20
Visible: false
ScrollPanel@OVERLAY_PANEL:
Width: 140
Height: 55
ItemSpacing: 5
TopBottomSpacing: 0
Children:
Checkbox@CATEGORY_TEMPLATE:
X: 5
Y: 5
Width: PARENT_RIGHT - 29
Height: 20
Visible: false

View File

@@ -27,6 +27,13 @@ EditorQuickSave: S Ctrl
Platform: Platform:
OSX: S Meta OSX: S Meta
EditorPaste: V Ctrl
Description: Paste
Types: Editor
Contexts: Editor
Platform:
OSX: V Meta
EditorTilesTab: E EditorTilesTab: E
Description: Tiles Tab Description: Tiles Tab
Types: Editor Types: Editor
@@ -42,11 +49,21 @@ EditorActorsTab: T
Types: Editor Types: Editor
Contexts: Editor Contexts: Editor
EditorHistoryTab: Y EditorToolsTab: Y
Description: Tools Tab
Types: Editor
Contexts: Editor
EditorHistoryTab: U
Description: History Tab Description: History Tab
Types: Editor Types: Editor
Contexts: Editor Contexts: Editor
EditorSettingsTab: I
Description: Settings Tab
Types: Editor
Contexts: Editor
EditorToggleGridOverlay: F1 EditorToggleGridOverlay: F1
Description: Grid Overlay Description: Grid Overlay
Types: Editor Types: Editor

View File

@@ -72,32 +72,41 @@ label-tiles-bg-categories = Filter:
label-actors-bg-search = Search: label-actors-bg-search = Search:
label-actors-bg-categories = Filter: label-actors-bg-categories = Filter:
label-actors-bg-owners = Owner: label-actors-bg-owners = Owner:
label-area-selection = Area Selection
label-copy-filters = Copy Filters
label-filter-terrain = Terrain
label-filter-resources = Resources
label-filter-actors = Actors
button-selection-cancel = Cancel
label-show-tile-grid = Show Tile Grid
label-show-buildable-area = Show Buildable Area
button-map-editor-tab-container-tiles = button-map-editor-tab-container-tiles =
.label = Tiles
.tooltip = Tiles .tooltip = Tiles
button-map-editor-tab-container-overlays = button-map-editor-tab-container-overlays =
.label = Overlays
.tooltip = Overlays .tooltip = Overlays
button-map-editor-tab-container-actors = button-map-editor-tab-container-actors =
.label = Actors
.tooltip = Actors .tooltip = Actors
button-map-editor-tab-container-tools =
.tooltip = Tools
button-map-editor-tab-container-history = button-map-editor-tab-container-history =
.label = History
.tooltip = History .tooltip = History
button-editor-world-root-options = button-editor-world-root-options =
.label = Menu .label = Menu
.tooltip = Menu .tooltip = Menu
button-editor-world-root-copypaste = button-editor-world-root-copy =
.label = Copy/Paste .label = Copy
.tooltip = Copy .tooltip = Copy
dropdownbutton-editor-world-root-copyfilter-button = Copy Filters button-editor-world-root-paste =
.label = Paste
.tooltip = Paste
button-editor-world-root-undo = button-editor-world-root-undo =
.label = Undo .label = Undo
@@ -107,7 +116,6 @@ button-editor-world-root-redo =
.label = Redo .label = Redo
.tooltip = Redo last step .tooltip = Redo last step
dropdownbutton-editor-world-root-overlay-button = Overlays
button-select-categories-buttons-all = All button-select-categories-buttons-all = All
button-select-categories-buttons-none = None button-select-categories-buttons-none = None

View File

@@ -805,6 +805,9 @@ notification-copied-tiles =
} }
## EditorDefaultBrush ## EditorDefaultBrush
notification-selected-area = Selected area { $x },{ $y } ({ $width },{ $height })
notification-selected-actor = Selected actor { $id }
notification-cleared-selection = Cleared selection
notification-removed-actor = Removed { $name } ({ $id }) notification-removed-actor = Removed { $name } ({ $id })
notification-removed-resource = Removed { $type } notification-removed-resource = Removed { $type }

View File

@@ -511,3 +511,10 @@ loadscreen-stripe:
Inherits: ^LoadScreen Inherits: ^LoadScreen
PanelRegion: 258, 0, 0, 0, 253, 256, 0, 0 PanelRegion: 258, 0, 0, 0, 253, 256, 0, 0
PanelSides: Center PanelSides: Center
editor:
Inherits: ^Glyphs
Regions:
tiles: 0, 144, 16, 16
overlays: 17, 144, 16, 16
tools: 34, 144, 16, 16

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -655,3 +655,10 @@ dropdown-separators:
separator: separator:
Inherits: button Inherits: button
editor:
Inherits: ^Glyphs
Regions:
tiles: 0, 187, 16, 16
overlays: 17, 187, 16, 16
tools: 136, 68, 16, 16

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -786,3 +786,10 @@ loadscreen-stripe:
Inherits: ^LoadScreen Inherits: ^LoadScreen
PanelRegion: 258, 0, 0, 0, 253, 256, 0, 0 PanelRegion: 258, 0, 0, 0, 253, 256, 0, 0
PanelSides: Center PanelSides: Center
editor:
Inherits: ^Glyphs
Regions:
tiles: 0, 144, 16, 16
overlays: 17, 144, 16, 16
tools: 34, 144, 16, 16

View File

@@ -423,8 +423,7 @@ EditorWorld:
MaxDensity: 2 MaxDensity: 2
VeinholeActors: veinhole VeinholeActors: veinhole
EditorSelectionLayer: EditorSelectionLayer:
Palette: ra AltPixelOffset: 0,1
FootprintAlpha: 0.7
LoadWidgetAtGameStart: LoadWidgetAtGameStart:
EditorActionManager: EditorActionManager:
BuildableTerrainOverlay: BuildableTerrainOverlay:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 17 KiB