#region Copyright & License Information /* * Copyright (c) The OpenRA Developers and Contributors * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. For more * information, see COPYING. */ #endregion using System; using System.Collections.Generic; using OpenRA.Graphics; using OpenRA.Mods.Common.EditorBrushes; using OpenRA.Mods.Common.Graphics; using OpenRA.Mods.Common.Traits; namespace OpenRA.Mods.Common.Widgets { public sealed class EditorCopyPasteBrush : IEditorBrush { readonly WorldRenderer worldRenderer; readonly EditorViewportControllerWidget editorWidget; readonly EditorActorLayer editorActorLayer; readonly EditorActionManager editorActionManager; readonly EditorBlitSource clipboard; readonly IResourceLayer resourceLayer; readonly Func getCopyFilters; public CPos PastePreviewPosition { get; private set; } public CellCoordsRegion Region => clipboard.CellCoords; public EditorCopyPasteBrush( EditorViewportControllerWidget editorWidget, WorldRenderer wr, EditorBlitSource clipboard, IResourceLayer resourceLayer, Func getCopyFilters) { this.getCopyFilters = getCopyFilters; this.editorWidget = editorWidget; this.clipboard = clipboard; this.resourceLayer = resourceLayer; worldRenderer = wr; editorActionManager = wr.World.WorldActor.Trait(); editorActorLayer = wr.World.WorldActor.Trait(); PastePreviewPosition = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos); } 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; if (mi.Button == MouseButton.Right) { if (mi.Event == MouseInputEvent.Up) { editorWidget.ClearBrush(); return true; } return false; } if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) { var pastePosition = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos); var editorBlit = new EditorBlit( getCopyFilters(), resourceLayer, pastePosition, worldRenderer.World.Map, clipboard, editorActorLayer, true); var action = new CopyPasteEditorAction(editorBlit); editorActionManager.Add(action); return true; } return false; } void IEditorBrush.TickRender(WorldRenderer wr, Actor self) { } IEnumerable IEditorBrush.RenderAboveShroud(Actor self, WorldRenderer wr) { var filters = getCopyFilters(); var stickToGround = !filters.HasFlag(MapBlitFilters.Terrain) ; var preview = EditorBlit.PreviewBlitSource( clipboard, filters, PastePreviewPosition - Region.TopLeft, wr, stickToGround); foreach (var renderable in preview) yield return renderable; } IEnumerable IEditorBrush.RenderAnnotations(Actor self, WorldRenderer wr) { yield return new EditorSelectionAnnotationRenderable( Region, editorWidget.SelectionAltColor, editorWidget.SelectionAltOffset, PastePreviewPosition - Region.TopLeft); yield return new EditorSelectionAnnotationRenderable( Region, editorWidget.PasteColor, int2.Zero, PastePreviewPosition - Region.TopLeft); } public void Tick() { PastePreviewPosition = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos); } public void Dispose() { } } sealed class CopyPasteEditorAction : IEditorAction { [FluentReference("tiles")] const string CopiedTiles = "notification-copied-tiles"; [FluentReference("actors")] const string CopiedActors = "notification-copied-actors"; [FluentReference("tiles", "actors")] const string CopiedTilesAndActors = "notification-copied-tiles-actors"; public string Text { get; } readonly EditorBlit editorBlit; public CopyPasteEditorAction(EditorBlit editorBlit) { this.editorBlit = editorBlit; var actors = editorBlit.ActorCount(); var tiles = editorBlit.TileCount(); if (tiles > 0 && actors == 0) Text = FluentProvider.GetMessage(CopiedTiles, "tiles", tiles); else if (tiles == 0 && actors > 0) Text = FluentProvider.GetMessage(CopiedActors, "actors", actors); else Text = FluentProvider.GetMessage(CopiedTilesAndActors, "tiles", tiles, "actors", actors); } public void Execute() { Do(); } public void Do() { editorBlit.Commit(); } public void Undo() { editorBlit.Revert(); } } }