Prompt users to save when changing loadout

This commit is contained in:
OldManAlpha 2025-08-05 10:59:51 -07:00
parent c8a880f61a
commit 58bd6bd615
4 changed files with 177 additions and 36 deletions

View File

@ -47,6 +47,7 @@ end
function SetSelectedBindingsLoadout(name)
PTBindings.SelectedLoadout = name
PTSettingsGui.LoadBindings()
InitBindingDisplayCache()
end
function GetBindingLoadouts()
@ -83,41 +84,76 @@ function GetBindingLoadoutNames()
return names
end
-- TODO: Not finished
function PruneBindings(bindings)
for k, v in pairs(bindings) do
local shouldRemove = PruneBinding(v)
if shouldRemove then
bindings[k] = nil
function PruneLoadout(loadout, copy)
if copy then
loadout = util.CloneTable(loadout, true)
end
for targetName, target in pairs(loadout.Bindings) do
for modifierName, modifier in pairs(target) do
for button, binding in pairs(modifier) do
local shouldRemove = PruneBinding(binding)
if shouldRemove then
modifier[button] = nil
end
end
if util.IsTableEmpty(modifier) then
target[modifierName] = nil
end
end
end
return loadout
end
function PruneBinding(binding)
if not binding.Type then
return true
end
if binding.Tooltip then
local tooltip = binding.Tooltip
if tooltip.Type ~= "DEFAULT" and (tooltip.Data == nil or tooltip.Data == "") then
tooltip.Type = nil
tooltip.Data = nil
end
if util.IsTableEmpty(tooltip) then
binding.Tooltip = nil
end
end
-- Empty spells are default and don't need to be stored
if binding.Type == "SPELL" and (not binding.Data or binding.Data == "") then
return true
end
if binding.Type == "MULTI" then
if binding.Data.Title == "" then
binding.Data.Title = nil
end
for _, subBinding in ipairs(binding.Data.Bindings) do
PruneBinding(subBinding)
end
end
end
function PruneBinding(binding)
if binding.Tooltip then
local hasTooltipElements = false
local tooltip = binding.Tooltip
local type = tooltip.Type
if type == "CUSTOM" and tooltip.Data == "" then
tooltip.Type = nil
tooltip.Data = nil
elseif type and type ~= "DEFAULT" then
hasTooltipElements = true
else
tooltip.Type = nil
tooltip.Data = nil
end
if tooltip.TextColor then
hasTooltipElements = true
local stringDataBindings = util.ToSet({"SPELL", "ACTION", "ITEM", "MACRO", "SCRIPT"})
function ExpandBinding(binding)
if not binding.Type then
binding.Type = "SPELL"
end
if not binding.Data then
if stringDataBindings[binding.Type] then
binding.Data = ""
elseif binding.Type == "MULTI" then
binding.Data = {Bindings = {}}
end
end
if not binding.Tooltip then
binding.Tooltip = {}
end
end
if not hasTooltipElements then
binding.Tooltip = nil
end
end
if binding.Type == "SPELL" and (not binding.Data or binding.Data == "") then
return true
end
function LoadoutEquals(loadout1, loadout2)
PruneLoadout(loadout1)
PruneLoadout(loadout2)
return util.TableEquals(loadout1, loadout2)
end
-- Returns a copy of the clipboard

View File

@ -66,13 +66,45 @@ function CreateTab_Bindings()
:SetDynamicOptions(function(addOption, level, args)
for _, name in ipairs(Puppeteer.GetBindingLoadoutNames()) do
addOption("text", name,
"dropdownText", name,
"checked", Puppeteer.GetSelectedBindingsLoadoutName() == name,
"func", args.func)
end
end, {
func = function(self)
Puppeteer.SetSelectedBindingsLoadout(self.text)
local loadoutName = self.text
if Puppeteer.LoadoutEquals(Puppeteer.GetBindings(), EditedBindings, true) then
Puppeteer.SetSelectedBindingsLoadout(loadoutName)
else
local dialog
dialog = PTGuiLib.Get("simple_dialog", TabFrame)
:SetPoint("CENTER", TabFrame, "CENTER")
:SetTitle("Unsaved Changes")
:SetText("You have unsaved changes to your bindings. What would you like to do?")
:AddButton("Save changes & switch", function()
SaveBindings()
Puppeteer.SetSelectedBindingsLoadout(loadoutName)
PopOverlayFrame()
dialog:Dispose()
end)
:AddButton("Discard changes & switch", function()
Puppeteer.SetSelectedBindingsLoadout(loadoutName)
PopOverlayFrame()
dialog:Dispose()
end)
:AddButton("Carry changes over", function()
local editedBindings = EditedBindings
Puppeteer.SetSelectedBindingsLoadout(loadoutName)
EditedBindings = editedBindings
UpdateBindingsInterface()
PopOverlayFrame()
dialog:Dispose()
end)
:AddButton("Cancel", function()
PopOverlayFrame()
dialog:Dispose()
end)
AddOverlayFrame(dialog)
end
end
})
:SetTextUpdater(function(self)
@ -84,10 +116,32 @@ function CreateTab_Bindings()
:SetSize(60, 22)
:SetText("New")
:OnClick(function(self)
local newLoadout = PTGuiLib.Get("puppeteer_new_loadout", TabFrame)
:SetPoint("CENTER", TabFrame, "CENTER")
AddOverlayFrame(newLoadout)
PlaySound("igMainMenuOpen")
if Puppeteer.LoadoutEquals(Puppeteer.GetBindings(), EditedBindings, true) then
PromptNewLoadout()
else
local dialog
dialog = PTGuiLib.Get("simple_dialog", TabFrame)
:SetPoint("CENTER", TabFrame, "CENTER")
:SetTitle("Unsaved Changes")
:SetText("You have unsaved changes to your bindings. What would you like to do?")
:AddButton("Save changes", function()
SaveBindings()
PopOverlayFrame()
dialog:Dispose()
PromptNewLoadout()
end)
:AddButton("Discard changes", function()
LoadBindings()
PopOverlayFrame()
dialog:Dispose()
PromptNewLoadout()
end)
:AddButton("Cancel", function()
PopOverlayFrame()
dialog:Dispose()
end)
AddOverlayFrame(dialog)
end
end)
local deleteLoadout = PTGuiLib.Get("button", container)
:SetPoint("LEFT", newLoadout, "RIGHT", 5, 0)
@ -230,6 +284,13 @@ function CreateTab_Bindings()
end)
end
function PromptNewLoadout()
local newLoadout = PTGuiLib.Get("puppeteer_new_loadout", TabFrame)
:SetPoint("CENTER", TabFrame, "CENTER")
AddOverlayFrame(newLoadout)
PlaySound("igMainMenuOpen")
end
function SetTargetContext(friendlyOrHostile)
BindingsContext.Target = friendlyOrHostile
BindingsForDropdown:UpdateText()
@ -289,7 +350,7 @@ function LoadBindings()
end
function SaveBindings()
Puppeteer.GetBindingLoadouts()[Puppeteer.GetSelectedBindingsLoadoutName()] = EditedBindings
Puppeteer.GetBindingLoadouts()[Puppeteer.GetSelectedBindingsLoadoutName()] = Puppeteer.PruneLoadout(EditedBindings)
LoadBindings()
end

View File

@ -215,6 +215,7 @@ end
function PTSpellLine:SetBinding(binding)
self.Binding = binding
Puppeteer.ExpandBinding(binding)
self:Update()
return self
end

View File

@ -208,6 +208,49 @@ function ClearTable(t)
table.setn(t, 0)
end
function GetTableSize(t)
local size = 0
for _ in pairs(t) do
size = size + 1
end
return size
end
function IsTableEmpty(t)
for _ in pairs(t) do
return false
end
return true
end
-- Recursion not supported
function TableEquals(t1, t2)
-- Verify the tables have the same keys
for k, v in pairs(t1) do
if t2[k] == nil then
return false
end
end
for k, v in pairs(t2) do
if t1[k] == nil then
return false
end
end
-- Verify the tables have equal values
for k, v in pairs(t1) do
if type(v) == "table" then
if type(t2[k]) ~= "table" or not TableEquals(v, t2[k]) then
return false
end
else
if v ~= t2[k] then
return false
end
end
end
return true
end
-- Courtesy of ChatGPT
function SplitString(str, delimiter)
local result = {}