|
if not Platform.developer then |
|
EditedMapVariation = false |
|
return |
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function reset_edited_variation() |
|
EditedMapVariation = false |
|
EditedMapVariationUndoQueue = false |
|
OriginalEditorUndoQueue = false |
|
HiddenMapVariationUndoIndex = false |
|
end |
|
|
|
if FirstLoad then |
|
reset_edited_variation() |
|
end |
|
OnMsg.ChangeMap = reset_edited_variation |
|
|
|
local function start_editing_loaded_variation() |
|
assert(CurrentMapVariation and not EditedMapVariation) |
|
EditedMapVariationUndoQueue = XEditorUndo |
|
OriginalEditorUndoQueue = XEditorUndoQueue:new() |
|
HiddenMapVariationUndoIndex = false |
|
|
|
EditedMapVariation = CurrentMapVariation |
|
XEditorUpdateStatusText() |
|
end |
|
|
|
function OnMsg.GameEnterEditor() |
|
|
|
if CurrentMapVariation and not EditedMapVariation and not HiddenMapVariationUndoIndex then |
|
start_editing_loaded_variation() |
|
end |
|
end |
|
|
|
local function drop_edited_variation_changes() |
|
assert(CurrentMapVariation and EditedMapVariation and not HiddenMapVariationUndoIndex) |
|
|
|
|
|
HiddenMapVariationUndoIndex = XEditorUndo.undo_index |
|
while XEditorUndo.undo_index ~= 0 do |
|
XEditorUndo:UndoRedo("undo") |
|
end |
|
EditedMapVariation = false |
|
EditorMapDirty = false |
|
XEditorUpdateStatusText() |
|
|
|
|
|
XEditorUndo = OriginalEditorUndoQueue |
|
XEditorUpdateToolbars() |
|
end |
|
|
|
local function restore_edited_variation_changes() |
|
assert(CurrentMapVariation and not EditedMapVariation and HiddenMapVariationUndoIndex) |
|
|
|
|
|
XEditorUndo = EditedMapVariationUndoQueue |
|
XEditorUpdateToolbars() |
|
|
|
|
|
while XEditorUndo.undo_index ~= HiddenMapVariationUndoIndex do |
|
XEditorUndo:UndoRedo("redo") |
|
end |
|
HiddenMapVariationUndoIndex = false |
|
EditedMapVariation = CurrentMapVariation |
|
EditorMapDirty = false |
|
XEditorUpdateStatusText() |
|
end |
|
|
|
local function ask_save_and_drop_variation() |
|
assert(CurrentMapVariation) |
|
local save_map = |
|
WaitQuestion(nil, Untranslated("Save changes?"), |
|
Untranslated(string.format("This will remove any changes made by the current map variation '%s'.\nSave it?", MapVariationNameText(CurrentMapVariation))), |
|
Untranslated("Yes"), Untranslated("No")) == "ok" |
|
if HiddenMapVariationUndoIndex then |
|
restore_edited_variation_changes() |
|
end |
|
if save_map then |
|
SaveMap() |
|
end |
|
drop_edited_variation_changes() |
|
end |
|
|
|
local function ensure_map_saved(drop_variation) |
|
if drop_variation and CurrentMapVariation then |
|
ask_save_and_drop_variation() |
|
elseif EditorMapDirty then |
|
if WaitQuestion(nil, Untranslated("Map Not Saved"), Untranslated("The map must be saved before creating/editing a variation.")) ~= "ok" then |
|
return false |
|
end |
|
SaveMap() |
|
end |
|
return true |
|
end |
|
|
|
function IsMapVariationEdited(preset) |
|
return EditedMapVariation == preset or CurrentMapVariation == preset and HiddenMapVariationUndoIndex |
|
end |
|
|
|
function StopEditingCurrentMapVariation(keep_changes) |
|
if not keep_changes and not HiddenMapVariationUndoIndex then |
|
drop_edited_variation_changes() |
|
end |
|
CurrentMapVariation = false |
|
EditedMapVariation = false |
|
EditedMapVariationUndoQueue = false |
|
HiddenMapVariationUndoIndex = false |
|
XEditorUndo = OriginalEditorUndoQueue |
|
OriginalEditorUndoQueue = false |
|
XEditorUpdateStatusText() |
|
end |
|
|
|
|
|
|
|
|
|
function XEditorCreateNewVariation() |
|
if not ensure_map_saved("drop_variation") then |
|
return |
|
end |
|
|
|
local name = WaitInputText(nil, "Map Variation", "Enter variation name...") |
|
if not name then return end |
|
|
|
local save_in = WaitListChoice(nil, DlcComboItems(), "Save In") |
|
if not save_in then return end |
|
save_in = save_in.value |
|
|
|
if FindMapVariation(name, save_in) then |
|
local message = string.format("The map variation '%s' already exists%s.\n\nOverwrite?", |
|
name, save_in =="" and "" or string.format(" in DLC '%s'", save_in), save_in) |
|
if WaitQuestion(nil, Untranslated("Error"), Untranslated(message)) ~= "ok" then |
|
return |
|
end |
|
end |
|
|
|
XEditorUndo = XEditorUndoQueue:new() |
|
CreateMapVariation(name, save_in) |
|
start_editing_loaded_variation() |
|
end |
|
|
|
function XEditorEditVariation(variation) |
|
assert(variation and CurrentMapVariation ~= variation) |
|
if CurrentMapVariation == variation then return end |
|
|
|
if not ensure_map_saved("drop_variation") then |
|
return |
|
end |
|
|
|
|
|
OriginalEditorUndoQueue = XEditorUndo |
|
EditedMapVariationUndoQueue = XEditorUndoQueue:new() |
|
HiddenMapVariationUndoIndex = false |
|
XEditorUndo = EditedMapVariationUndoQueue |
|
XEditorUpdateToolbars() |
|
|
|
|
|
XEditorApplyMapPatch(variation:GetMapPatchPath()) |
|
CurrentMapVariation = variation |
|
EditedMapVariation = variation |
|
XEditorUpdateStatusText() |
|
end |
|
|
|
function XEditorHideShowVariation(variation) |
|
assert(variation == CurrentMapVariation) |
|
if HiddenMapVariationUndoIndex then |
|
if not ensure_map_saved() then |
|
return |
|
end |
|
restore_edited_variation_changes() |
|
else |
|
drop_edited_variation_changes() |
|
end |
|
end |
|
|
|
function XEditorDeleteVariation(variation) |
|
if WaitQuestion(nil, Untranslated("Confirmation"), |
|
Untranslated(string.format("Delete map variation %s?", MapVariationNameText(variation)))) == "ok" |
|
then |
|
if variation == CurrentMapVariation then |
|
StopEditingCurrentMapVariation() |
|
end |
|
variation:OnEditorDelete() |
|
variation:delete() |
|
end |
|
end |
|
|
|
function XEditorMergeVariation(variation) |
|
assert(variation == CurrentMapVariation) |
|
if WaitQuestion(nil, Untranslated("Confirmation"), |
|
Untranslated(string.format("Merge map variation %s into the original map and delete the variation?", MapVariationNameText(variation)))) == "ok" |
|
then |
|
if HiddenMapVariationUndoIndex then |
|
restore_edited_variation_changes() |
|
end |
|
StopEditingCurrentMapVariation("keep_changes") |
|
variation:OnEditorDelete() |
|
variation:delete() |
|
XEditorSaveMap() |
|
end |
|
end |
|
|
|
|
|
|
|
|
|
DefineClass("XDarkModeAwarePopupList", "XPopupList", "XDarkModeAwareDialog") |
|
|
|
function XDarkModeAwarePopupList:Open(...) |
|
XPopupList.Open(self, ...) |
|
self:SetDarkMode(GetDarkModeSetting()) |
|
end |
|
|
|
function XDarkModeAwarePopupList:OnShortcut(shortcut, source, ...) |
|
if shortcut == "Escape" or shortcut == "ButtonB" then |
|
self:Close() |
|
return "break" |
|
end |
|
end |
|
|
|
function XEditorOpenMapVariationsPopup() |
|
local popup = XDarkModeAwarePopupList:new({ |
|
Id = "idMapVariationsPopup", |
|
Margins = box(0, 2, 0, 2), |
|
Padding = box(3, 0, 3, 5), |
|
MinWidth = 360, |
|
LayoutMethod = "VList", |
|
DrawOnTop = true, |
|
HandleMouse = true, |
|
OnMouseButtonUp = function(self, pt, button) |
|
if button == "L" then |
|
if not self:MouseInWindow(pt) then |
|
self:Close() |
|
end |
|
return "break" |
|
elseif button == "R" then |
|
self:Close() |
|
return "break" |
|
end |
|
end, |
|
}, terminal.desktop) |
|
|
|
|
|
local title = XText:new({ TextStyle = "GedTitle", TextHAlign = "center", }, popup) |
|
title:SetText("Map Variations") |
|
XWindow:new({ Background = RGB(0, 0, 0), Margins = box(10, 1, 10, 1), MinHeight = 1 }, popup) |
|
|
|
|
|
local button_holder = XWindow:new({ Dock = "bottom", HAlign = "center", LayoutMethod = "HList" }, popup) |
|
XTextButton:new({ |
|
BorderWidth = 1, |
|
Margins = box(2, 2, 2, 2), |
|
VAlign = "center", |
|
Text = "Create new variation", |
|
FocusedBorderColor = RGB(128, 128, 128), |
|
DisabledBorderColor = RGB(128, 128, 128), |
|
RolloverBorderColor = RGB(128, 128, 128), |
|
PressedBorderColor = RGB(128, 128, 128), |
|
OnPress = function(button) XEditorCloseVariationsPopup() CreateRealTimeThread(XEditorCreateNewVariation) end, |
|
}, button_holder) |
|
if Presets.MapVariationPreset then |
|
XTextButton:new({ |
|
BorderWidth = 1, |
|
Margins = box(2, 2, 2, 2), |
|
VAlign = "center", |
|
Text = "Manage", |
|
FocusedBorderColor = RGB(128, 128, 128), |
|
DisabledBorderColor = RGB(128, 128, 128), |
|
RolloverBorderColor = RGB(128, 128, 128), |
|
PressedBorderColor = RGB(128, 128, 128), |
|
OnPress = function(button) |
|
if CurrentMapVariation then |
|
CurrentMapVariation:OpenEditor() |
|
else |
|
OpenPresetEditor("MapVariationPreset") |
|
end |
|
end, |
|
}, button_holder) |
|
end |
|
local help_text = XText:new({ Dock = "bottom", TextHAlign = "center" }, popup) |
|
help_text:SetText("<color 128 128 128>Map variations are saved as patches over the base map.\nThis allows editing the base map and the variation changes separately.") |
|
|
|
for idx, item in ipairs(MapVariationItems(CurrentMap)) do |
|
local entry = XContextWindow:new({ |
|
IdNode = true, |
|
Margins = box(3, 2, 3, 2), |
|
OnSetRollover = function(self, rollover) |
|
self:SetBackground(rollover and RGBA(128, 128, 128, 40) or 0) |
|
self.idHintText:SetVisible(rollover and CurrentMapVariation ~= self.context.value) |
|
end |
|
}, popup, item) |
|
|
|
|
|
XTextButton:new({ |
|
Dock = "left", |
|
VAlign = "center", |
|
Text = "x", |
|
MaxWidth = 20, |
|
MaxHeight = 16, |
|
LayoutHSpacing = 0, |
|
Padding = box(1, 1, 0, 1), |
|
Background = RGBA(0, 0, 0, 0), |
|
RolloverBackground = RGB(204, 232, 255), |
|
PressedBackground = RGB(121, 189, 241), |
|
OnPress = function(button) XEditorCloseVariationsPopup() CreateRealTimeThread(XEditorDeleteVariation, item.value) end, |
|
}, entry) |
|
|
|
|
|
local showhide_button = XTextButton:new({ |
|
Id = "idShowHideButton", |
|
Dock = "right", |
|
FoldWhenHidden = true, |
|
Margins = box(0, 0, 3, 0), |
|
BorderWidth = 1, |
|
VAlign = "center", |
|
Text = HiddenMapVariationUndoIndex and "Show" or "Hide", |
|
FocusedBorderColor = RGB(128, 128, 128), |
|
DisabledBorderColor = RGB(128, 128, 128), |
|
RolloverBorderColor = RGB(128, 128, 128), |
|
PressedBorderColor = RGB(128, 128, 128), |
|
OnPress = function(button) XEditorCloseVariationsPopup() CreateRealTimeThread(XEditorHideShowVariation, item.value) end, |
|
}, entry) |
|
showhide_button:SetVisible(CurrentMapVariation == item.value) |
|
|
|
|
|
local merge_button = XTextButton:new({ |
|
Id = "idMergeButton", |
|
Dock = "right", |
|
FoldWhenHidden = true, |
|
Margins = box(5, 0, 5, 0), |
|
BorderWidth = 1, |
|
VAlign = "center", |
|
Text = "Merge", |
|
FocusedBorderColor = RGB(128, 128, 128), |
|
DisabledBorderColor = RGB(128, 128, 128), |
|
RolloverBorderColor = RGB(128, 128, 128), |
|
PressedBorderColor = RGB(128, 128, 128), |
|
OnPress = function(button) XEditorCloseVariationsPopup() CreateRealTimeThread(XEditorMergeVariation, item.value) end, |
|
}, entry) |
|
merge_button:SetVisible(CurrentMapVariation == item.value) |
|
|
|
|
|
local hint_text = XText:new({ Id = "idHintText", Dock = "right", HandleMouse = false, }, entry) |
|
hint_text:SetText("(click to edit)") |
|
hint_text:SetVisible(false) |
|
|
|
|
|
local name = XText:new({ Dock = "box", Padding = box(0, 2, 2, 2), }, entry) |
|
name:SetText(item.text) |
|
name:SetTextStyle(CurrentMapVariation == item.value and "GedHighlight" or "GedDefault") |
|
name.OnMouseButtonDown = function(win, pt, button) |
|
XEditorCloseVariationsPopup() |
|
if CurrentMapVariation ~= item.value then |
|
CreateRealTimeThread(XEditorEditVariation, item.value) |
|
end |
|
return "break" |
|
end |
|
end |
|
|
|
popup.idContainer:SetBackground(RGB(255, 255, 255)) |
|
popup:SetAnchor(XEditorGetMapButton("idMapVariationsButton").parent.box) |
|
popup:SetAnchorType("top") |
|
popup:Open() |
|
popup:SetModal() |
|
popup:SetFocus() |
|
popup.popup_parent = GetDialog("XEditor") |
|
Msg("XWindowRecreated", popup) |
|
end |
|
|
|
function XEditorCloseVariationsPopup() |
|
local popup = rawget(terminal.desktop, "idMapVariationsPopup") |
|
if popup then |
|
popup:Close() |
|
end |
|
end |
|
|
|
OnMsg.GameExitEditor = XEditorCloseVariationsPopup |
|
|