diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index 4ab5ebf192..c8b39a4a05 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -274,5 +274,11 @@ namespace OpenRA Map.PreloadRules(); RuleStatus = Map.InvalidCustomRules ? MapRuleStatus.Invalid : MapRuleStatus.Cached; } + + public void Invalidate() + { + Status = MapStatus.Unavailable; + RuleStatus = MapRuleStatus.Unknown; + } } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs index a2c831984c..a9e7b1701a 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MapChooserLogic.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using OpenRA; using OpenRA.Primitives; @@ -90,6 +91,32 @@ namespace OpenRA.Mods.Common.Widgets.Logic randomMapButton.IsDisabled = () => visibleMaps == null || visibleMaps.Length == 0; } + var deleteMapButton = widget.Get("DELETE_MAP_BUTTON"); + deleteMapButton.IsDisabled = () => Game.ModData.MapCache[selectedUid].Class != MapClassification.User; + deleteMapButton.IsVisible = () => currentTab == MapClassification.User; + deleteMapButton.OnClick = () => + { + DeleteOneMap(selectedUid, (string newUid) => + { + RefreshMaps(currentTab, filter); + EnumerateMaps(currentTab, itemTemplate); + if (!tabMaps[currentTab].Any()) + SwitchTab(Game.ModData.MapCache[newUid].Class, itemTemplate); + }); + }; + + var deleteAllMapsButton = widget.Get("DELETE_ALL_MAPS_BUTTON"); + deleteAllMapsButton.IsVisible = () => currentTab == MapClassification.User; + deleteAllMapsButton.OnClick = () => + { + DeleteAllMaps(visibleMaps, (string newUid) => + { + RefreshMaps(currentTab, filter); + EnumerateMaps(currentTab, itemTemplate); + SwitchTab(Game.ModData.MapCache[newUid].Class, itemTemplate); + }); + }; + SetupMapTab(MapClassification.User, filter, "USER_MAPS_TAB_BUTTON", "USER_MAPS_TAB", itemTemplate); SetupMapTab(MapClassification.System, filter, "SYSTEM_MAPS_TAB_BUTTON", "SYSTEM_MAPS_TAB", itemTemplate); @@ -240,5 +267,55 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (visibleMaps.Contains(selectedUid)) scrollpanels[tab].ScrollToItem(selectedUid); } + + string DeleteMap(string map) + { + var path = Game.ModData.MapCache[map].Map.Path; + try + { + File.Delete(path); + Game.ModData.MapCache[map].Invalidate(); + + if (selectedUid == map) + selectedUid = WidgetUtils.ChooseInitialMap(tabMaps[currentTab].Select(mp => mp.Uid).FirstOrDefault()); + } + catch (Exception ex) + { + Game.Debug("Failed to delete map file '{0}'. See the logs for details.", path); + Log.Write("debug", ex.ToString()); + } + + return selectedUid; + } + + void DeleteOneMap(string map, Action after) + { + ConfirmationDialogs.PromptConfirmAction( + "Delete map", + "Delete the map '{0}'?".F(Game.ModData.MapCache[map].Title), + () => + { + var newUid = DeleteMap(map); + if (after != null) + after(newUid); + }, + null, + "Delete"); + } + + void DeleteAllMaps(string[] maps, Action after) + { + ConfirmationDialogs.PromptConfirmAction( + "Delete maps", + "Delete all maps on this page?", + () => + { + maps.Do(m => DeleteMap(m)); + if (after != null) + after(WidgetUtils.ChooseInitialMap(null)); + }, + null, + "Delete"); + } } } diff --git a/mods/cnc/chrome/mapchooser.yaml b/mods/cnc/chrome/mapchooser.yaml index b456366ac6..a2e8f6b3c5 100644 --- a/mods/cnc/chrome/mapchooser.yaml +++ b/mods/cnc/chrome/mapchooser.yaml @@ -126,6 +126,18 @@ Container@MAPCHOOSER_PANEL: Width: 140 Height: 35 Text: Random + Button@DELETE_MAP_BUTTON: + X: PARENT_RIGHT - 300 - WIDTH + Y: 499 + Width: 140 + Height: 35 + Text: Delete Map + Button@DELETE_ALL_MAPS_BUTTON: + X: PARENT_RIGHT - 450 - WIDTH + Y: 499 + Width: 140 + Height: 35 + Text: Delete All Maps Button@BUTTON_OK: Key: return X: PARENT_RIGHT - WIDTH diff --git a/mods/ra/chrome/map-chooser.yaml b/mods/ra/chrome/map-chooser.yaml index c83f79efe8..2e4087741a 100644 --- a/mods/ra/chrome/map-chooser.yaml +++ b/mods/ra/chrome/map-chooser.yaml @@ -117,6 +117,20 @@ Background@MAPCHOOSER_PANEL: Height: 25 Text: Random Map Font: Bold + Button@DELETE_MAP_BUTTON: + X: 160 + Y: PARENT_BOTTOM - 45 + Width: 120 + Height: 25 + Text: Delete Map + Font: Bold + Button@DELETE_ALL_MAPS_BUTTON: + X: 300 + Y: PARENT_BOTTOM - 45 + Width: 120 + Height: 25 + Text: Delete All Maps + Font: Bold Button@BUTTON_OK: X: PARENT_RIGHT - 270 Y: PARENT_BOTTOM - 45