Add a preview to editor marker brush
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
@@ -26,8 +27,9 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
readonly MarkerLayerOverlay markerLayerOverlay;
|
||||
readonly EditorViewportControllerWidget editorWidget;
|
||||
|
||||
PaintMarkerTileEditorAction action;
|
||||
readonly List<PaintMarkerTile> paintTiles = [];
|
||||
bool painting;
|
||||
CPos cell;
|
||||
|
||||
public EditorMarkerLayerBrush(EditorViewportControllerWidget editorWidget, int? id, WorldRenderer wr)
|
||||
{
|
||||
@@ -39,11 +41,11 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
markerLayerOverlay = world.WorldActor.Trait<MarkerLayerOverlay>();
|
||||
|
||||
Template = id;
|
||||
action = new PaintMarkerTileEditorAction(Template, markerLayerOverlay);
|
||||
}
|
||||
|
||||
public bool HandleMouseInput(MouseInput mi)
|
||||
{
|
||||
// Exclusively uses left and right mouse buttons, but nothing else.
|
||||
if (mi.Button != MouseButton.Left && mi.Button != MouseButton.Right)
|
||||
return false;
|
||||
|
||||
@@ -58,30 +60,71 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mi.Button == MouseButton.Left && mi.Event != MouseInputEvent.Up)
|
||||
{
|
||||
action.Add(worldRenderer.Viewport.ViewToWorld(mi.Location));
|
||||
painting = true;
|
||||
}
|
||||
else if (painting && mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
|
||||
{
|
||||
if (action.DidPaintTiles)
|
||||
editorActionManager.Add(action);
|
||||
if (mi.Button != MouseButton.Left)
|
||||
return true;
|
||||
|
||||
if (mi.Event == MouseInputEvent.Up)
|
||||
{
|
||||
UpdatePreview();
|
||||
if (paintTiles.Count != 0)
|
||||
{
|
||||
editorActionManager.Add(new PaintMarkerTileEditorAction(Template, paintTiles.ToImmutableArray(), markerLayerOverlay));
|
||||
paintTiles.Clear();
|
||||
UpdatePreview(true);
|
||||
}
|
||||
|
||||
action = new PaintMarkerTileEditorAction(Template, markerLayerOverlay);
|
||||
painting = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
painting = true;
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IEditorBrush.TickRender(WorldRenderer wr, Actor self) { }
|
||||
void UpdatePreview(bool forceRefresh = false)
|
||||
{
|
||||
var currentCell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos);
|
||||
if (!forceRefresh && cell == currentCell)
|
||||
return;
|
||||
|
||||
cell = currentCell;
|
||||
|
||||
if (!painting)
|
||||
{
|
||||
foreach (var paintTile in paintTiles)
|
||||
markerLayerOverlay.SetTile(paintTile.Cell, paintTile.Previous);
|
||||
|
||||
paintTiles.Clear();
|
||||
}
|
||||
|
||||
foreach (var cell in markerLayerOverlay.CalculateMirrorPositions(cell))
|
||||
{
|
||||
if (paintTiles.Any(t => t.Cell == cell))
|
||||
continue;
|
||||
|
||||
var existing = markerLayerOverlay.CellLayer[cell];
|
||||
if (existing == Template)
|
||||
continue;
|
||||
|
||||
paintTiles.Add(new PaintMarkerTile(cell, existing));
|
||||
markerLayerOverlay.SetTile(cell, Template);
|
||||
}
|
||||
}
|
||||
|
||||
void IEditorBrush.TickRender(WorldRenderer wr, Actor self) { UpdatePreview(); }
|
||||
IEnumerable<IRenderable> IEditorBrush.RenderAboveShroud(Actor self, WorldRenderer wr) { yield break; }
|
||||
IEnumerable<IRenderable> IEditorBrush.RenderAnnotations(Actor self, WorldRenderer wr) { yield break; }
|
||||
|
||||
public void Tick() { }
|
||||
|
||||
public void Dispose() { }
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var paintTile in paintTiles)
|
||||
markerLayerOverlay.SetTile(paintTile.Cell, paintTile.Previous);
|
||||
}
|
||||
}
|
||||
|
||||
readonly struct PaintMarkerTile
|
||||
@@ -104,27 +147,28 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
[FluentReference("count")]
|
||||
const string RemovedMarkerTiles = "notification-removed-marker-tiles";
|
||||
|
||||
public string Text { get; private set; }
|
||||
public string Text { get; }
|
||||
|
||||
readonly int? type;
|
||||
readonly MarkerLayerOverlay markerLayerOverlay;
|
||||
|
||||
readonly List<PaintMarkerTile> paintTiles = [];
|
||||
|
||||
public bool DidPaintTiles => paintTiles.Count > 0;
|
||||
readonly ImmutableArray<PaintMarkerTile> paintTiles = [];
|
||||
|
||||
public PaintMarkerTileEditorAction(
|
||||
int? type,
|
||||
ImmutableArray<PaintMarkerTile> paintTiles,
|
||||
MarkerLayerOverlay markerLayerOverlay)
|
||||
{
|
||||
this.markerLayerOverlay = markerLayerOverlay;
|
||||
this.type = type;
|
||||
this.paintTiles = paintTiles;
|
||||
this.markerLayerOverlay = markerLayerOverlay;
|
||||
|
||||
Text = type != null
|
||||
? FluentProvider.GetMessage(AddedMarkerTiles, "count", paintTiles.Length, "type", type)
|
||||
: FluentProvider.GetMessage(RemovedMarkerTiles, "count", paintTiles.Length);
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
paintTiles.TrimExcess();
|
||||
}
|
||||
public void Execute() { }
|
||||
|
||||
public void Do()
|
||||
{
|
||||
@@ -137,23 +181,6 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
foreach (var paintTile in paintTiles)
|
||||
markerLayerOverlay.SetTile(paintTile.Cell, paintTile.Previous);
|
||||
}
|
||||
|
||||
public void Add(CPos target)
|
||||
{
|
||||
foreach (var cell in markerLayerOverlay.CalculateMirrorPositions(target))
|
||||
{
|
||||
var existing = markerLayerOverlay.CellLayer[cell];
|
||||
if (existing == type)
|
||||
continue;
|
||||
|
||||
paintTiles.Add(new PaintMarkerTile(cell, existing));
|
||||
markerLayerOverlay.SetTile(cell, type);
|
||||
}
|
||||
|
||||
Text = type != null
|
||||
? FluentProvider.GetMessage(AddedMarkerTiles, "count", paintTiles.Count, "type", type)
|
||||
: FluentProvider.GetMessage(RemovedMarkerTiles, "count", paintTiles.Count);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ClearSelectedMarkerTilesEditorAction : IEditorAction
|
||||
@@ -164,7 +191,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
public string Text { get; }
|
||||
|
||||
readonly MarkerLayerOverlay markerLayerOverlay;
|
||||
readonly HashSet<CPos> tiles;
|
||||
readonly ImmutableArray<CPos> tiles;
|
||||
readonly int tile;
|
||||
|
||||
public ClearSelectedMarkerTilesEditorAction(
|
||||
@@ -174,9 +201,8 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
this.tile = tile;
|
||||
this.markerLayerOverlay = markerLayerOverlay;
|
||||
|
||||
tiles = markerLayerOverlay.Tiles[tile].ToHashSet();
|
||||
|
||||
Text = FluentProvider.GetMessage(ClearedSelectedMarkerTiles, "count", tiles.Count, "type", tile);
|
||||
tiles = markerLayerOverlay.Tiles[tile].ToImmutableArray();
|
||||
Text = FluentProvider.GetMessage(ClearedSelectedMarkerTiles, "count", tiles.Length, "type", tile);
|
||||
}
|
||||
|
||||
public void Execute()
|
||||
@@ -191,7 +217,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
public void Undo()
|
||||
{
|
||||
markerLayerOverlay.SetSelected(tile, tiles);
|
||||
markerLayerOverlay.SetSelected(tile, tiles.AsSpan());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,15 +229,14 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
public string Text { get; }
|
||||
|
||||
readonly MarkerLayerOverlay markerLayerOverlay;
|
||||
readonly Dictionary<int, HashSet<CPos>> tiles;
|
||||
readonly ImmutableDictionary<int, ImmutableArray<CPos>> tiles;
|
||||
|
||||
public ClearAllMarkerTilesEditorAction(
|
||||
MarkerLayerOverlay markerLayerOverlay)
|
||||
{
|
||||
this.markerLayerOverlay = markerLayerOverlay;
|
||||
tiles = new Dictionary<int, HashSet<CPos>>(markerLayerOverlay.Tiles);
|
||||
|
||||
var allTilesCount = tiles.Values.Sum(x => x.Count);
|
||||
tiles = markerLayerOverlay.Tiles.ToImmutableDictionary(t => t.Key, t => t.Value.ToImmutableArray());
|
||||
var allTilesCount = tiles.Values.Sum(x => x.Length);
|
||||
|
||||
Text = FluentProvider.GetMessage(ClearedAllMarkerTiles, "count", allTilesCount);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
@@ -172,7 +173,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
NumSides = file.NumSides;
|
||||
AxisAngle = file.AxisAngle;
|
||||
|
||||
SetAll(file.Tiles.ToDictionary(d => d.Key, d => new HashSet<CPos>(d.Value)));
|
||||
SetAll(file.Tiles.ToImmutableDictionary(d => d.Key, d => d.Value.ToImmutableArray()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -202,7 +203,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
Tiles.Clear();
|
||||
}
|
||||
|
||||
public void SetAll(Dictionary<int, HashSet<CPos>> newTiles)
|
||||
public void SetAll(IImmutableDictionary<int, ImmutableArray<CPos>> newTiles)
|
||||
{
|
||||
ClearAll();
|
||||
|
||||
@@ -222,7 +223,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSelected(int tile, HashSet<CPos> newTiles)
|
||||
public void SetSelected(int tile, ReadOnlySpan<CPos> newTiles)
|
||||
{
|
||||
var type = Tiles[tile];
|
||||
foreach (var pos in type)
|
||||
|
||||
Reference in New Issue
Block a user