diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs b/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs index 3c7478cdb8..fca76cee34 100644 --- a/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs +++ b/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs @@ -17,6 +17,16 @@ using OpenRA.Mods.Common.Traits; namespace OpenRA.Mods.Common.Widgets { + [Flags] + public enum MapCopyFilters + { + None = 0, + Terrain = 1, + Resources = 2, + Actors = 4, + All = Terrain | Resources | Actors + } + public sealed class EditorCopyPasteBrush : IEditorBrush { enum State { SelectFirst, SelectSecond, Paste } @@ -25,18 +35,20 @@ namespace OpenRA.Mods.Common.Widgets readonly EditorViewportControllerWidget editorWidget; readonly EditorSelectionLayer selectionLayer; readonly EditorActorLayer editorLayer; + readonly Func getCopyFilters; State state; CPos start; CPos end; - public EditorCopyPasteBrush(EditorViewportControllerWidget editorWidget, WorldRenderer wr) + public EditorCopyPasteBrush(EditorViewportControllerWidget editorWidget, WorldRenderer wr, Func getCopyFilters) { this.editorWidget = editorWidget; worldRenderer = wr; selectionLayer = wr.World.WorldActor.Trait(); editorLayer = wr.World.WorldActor.Trait(); + this.getCopyFilters = getCopyFilters; } public bool HandleMouseInput(MouseInput mi) @@ -102,6 +114,7 @@ namespace OpenRA.Mods.Common.Widgets var previews = new Dictionary(); var tiles = new Dictionary>(); + var copyFilters = getCopyFilters(); foreach (var cell in source) { @@ -110,33 +123,43 @@ namespace OpenRA.Mods.Common.Widgets tiles.Add(cell + offset, Tuple.Create(mapTiles[cell], mapResources[cell], mapHeight[cell])); - foreach (var preview in editorLayer.PreviewsAt(cell)) + if (copyFilters.HasFlag(MapCopyFilters.Actors)) { - if (previews.ContainsKey(preview.ID)) - continue; - - var copy = preview.Export(); - if (copy.InitDict.Contains()) + foreach (var preview in editorLayer.PreviewsAt(cell)) { - var location = copy.InitDict.Get(); - copy.InitDict.Remove(location); - copy.InitDict.Add(new LocationInit(location.Value(worldRenderer.World) + offset)); - } + if (previews.ContainsKey(preview.ID)) + continue; - previews.Add(preview.ID, copy); + var copy = preview.Export(); + if (copy.InitDict.Contains()) + { + var location = copy.InitDict.Get(); + copy.InitDict.Remove(location); + copy.InitDict.Add(new LocationInit(location.Value(worldRenderer.World) + offset)); + } + + previews.Add(preview.ID, copy); + } } } foreach (var kv in tiles) { - mapTiles[kv.Key] = kv.Value.Item1; - mapResources[kv.Key] = kv.Value.Item2; + if (copyFilters.HasFlag(MapCopyFilters.Terrain)) + mapTiles[kv.Key] = kv.Value.Item1; + + if (copyFilters.HasFlag(MapCopyFilters.Resources)) + mapResources[kv.Key] = kv.Value.Item2; + mapHeight[kv.Key] = kv.Value.Item3; } - var removeActors = dest.SelectMany(editorLayer.PreviewsAt).Distinct().ToList(); - foreach (var preview in removeActors) - editorLayer.Remove(preview); + if (copyFilters.HasFlag(MapCopyFilters.Actors)) + { + var removeActors = dest.SelectMany(editorLayer.PreviewsAt).Distinct().ToList(); + foreach (var preview in removeActors) + editorLayer.Remove(preview); + } foreach (var kv in previews) editorLayer.Add(kv.Value); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorLogic.cs index ff1d739d4b..5dce26be69 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorLogic.cs @@ -22,6 +22,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic [ChromeLogicArgsHotkeys("ChangeZoomKey")] public class MapEditorLogic : ChromeLogic { + MapCopyFilters copyFilters = MapCopyFilters.All; + [ObjectCreator.UseCtor] public MapEditorLogic(Widget widget, ModData modData, World world, WorldRenderer worldRenderer, Dictionary logicArgs) { @@ -86,10 +88,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic var copypasteButton = widget.GetOrNull("COPYPASTE_BUTTON"); if (copypasteButton != null) { - copypasteButton.OnClick = () => editorViewport.SetBrush(new EditorCopyPasteBrush(editorViewport, worldRenderer)); + copypasteButton.OnClick = () => editorViewport.SetBrush(new EditorCopyPasteBrush(editorViewport, worldRenderer, () => copyFilters)); copypasteButton.IsHighlighted = () => editorViewport.CurrentBrush is EditorCopyPasteBrush; } + var copyFilterDropdown = widget.Get("COPYFILTER_BUTTON"); + copyFilterDropdown.OnMouseDown = _ => + { + copyFilterDropdown.RemovePanel(); + copyFilterDropdown.AttachPanel(CreateCategoriesPanel()); + }; + var coordinateLabel = widget.GetOrNull("COORDINATE_LABEL"); if (coordinateLabel != null) { @@ -110,5 +119,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic cashLabel.GetText = () => "$ {0}".F(reslayer.NetWorth); } } + + Widget CreateCategoriesPanel() + { + var categoriesPanel = Ui.LoadWidget("COPY_FILTER_PANEL", null, new WidgetArgs()); + var categoryTemplate = categoriesPanel.Get("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; + } } } diff --git a/mods/cnc/chrome/editor.yaml b/mods/cnc/chrome/editor.yaml index 0dcad0e2e8..e4696181d9 100644 --- a/mods/cnc/chrome/editor.yaml +++ b/mods/cnc/chrome/editor.yaml @@ -522,7 +522,7 @@ Container@EDITOR_WORLD_ROOT: Text: Actors Font: Bold Button@GRID_BUTTON: - X: WINDOW_RIGHT - 500 + X: WINDOW_RIGHT - 650 Y: 5 Width: 100 Height: 25 @@ -533,7 +533,7 @@ Container@EDITOR_WORLD_ROOT: TooltipText: Toggle the terrain grid TooltipContainer: TOOLTIP_CONTAINER Label@ZOOM_LABEL: - X: WINDOW_RIGHT - 580 - 55 + X: WINDOW_RIGHT - 730 - 55 Y: 5 Width: 50 Height: 25 @@ -542,18 +542,25 @@ Container@EDITOR_WORLD_ROOT: Font: Bold Contrast: true DropDownButton@ZOOM_BUTTON: - X: WINDOW_RIGHT - 580 + X: WINDOW_RIGHT - 730 Y: 5 Width: 70 Height: 25 Font: Bold Key: TogglePixelDouble Button@COPYPASTE_BUTTON: - X: WINDOW_RIGHT - 390 + X: WINDOW_RIGHT - 540 Y: 5 Width: 96 Height: 25 Text: Copy/Paste + DropDownButton@COPYFILTER_BUTTON: + X: WINDOW_RIGHT - 435 + Y: 5 + Width: 140 + Height: 25 + Text: Copy Filters + Font: Bold Label@COORDINATE_LABEL: X: 10 Width: 50 @@ -594,3 +601,14 @@ ScrollPanel@CATEGORY_FILTER_PANEL: Width: PARENT_RIGHT - 29 Height: 22 Visible: false + +ScrollPanel@COPY_FILTER_PANEL: + Width: 140 + Height: 65 + Children: + Checkbox@CATEGORY_TEMPLATE: + X: 5 + Y: 5 + Width: PARENT_RIGHT - 29 + Height: 20 + Visible: false \ No newline at end of file diff --git a/mods/common/chrome/editor.yaml b/mods/common/chrome/editor.yaml index 1cd72aeca2..d14b01dfae 100644 --- a/mods/common/chrome/editor.yaml +++ b/mods/common/chrome/editor.yaml @@ -509,8 +509,14 @@ Container@EDITOR_WORLD_ROOT: Height: 25 Text: Copy/Paste Font: Bold - Button@GRID_BUTTON: + DropDownButton@COPYFILTER_BUTTON: X: 270 + Width: 140 + Height: 25 + Text: Copy Filters + Font: Bold + Button@GRID_BUTTON: + X: 420 Width: 70 Height: 25 Text: Grid @@ -520,7 +526,7 @@ Container@EDITOR_WORLD_ROOT: Font: Bold Key: f1 Label@ZOOM_LABEL: - X: 345 + X: 495 Width: 50 Height: 25 Text: Zoom: @@ -528,20 +534,20 @@ Container@EDITOR_WORLD_ROOT: Font: Bold Contrast: true DropDownButton@ZOOM_BUTTON: - X: 400 + X: 550 Width: 70 Height: 25 Font: Bold Key: TogglePixelDouble Label@COORDINATE_LABEL: - X: 485 + X: 635 Width: 50 Height: 25 Align: Left Font: Bold Contrast: true Label@CASH_LABEL: - X: 600 + X: 750 Width: 50 Height: 25 Align: Left @@ -575,3 +581,14 @@ ScrollPanel@CATEGORY_FILTER_PANEL: Width: PARENT_RIGHT - 29 Height: 20 Visible: false + +ScrollPanel@COPY_FILTER_PANEL: + Width: 140 + Height: 65 + Children: + Checkbox@CATEGORY_TEMPLATE: + X: 5 + Y: 5 + Width: PARENT_RIGHT - 29 + Height: 20 + Visible: false \ No newline at end of file