diff --git a/Core.lua b/Core.lua index 553b15b5..52755c47 100644 --- a/Core.lua +++ b/Core.lua @@ -4065,6 +4065,44 @@ DF._MainEventDispatcher = function(self, event, arg1) end end + -- Migrate personal targeted spells container centre to icon-block midpoint (bug 880). + -- Previously the saved (x, y) was the position of icon 1 (container centre). + -- Now (x, y) is the visual centre of the icon block; the container is offset so + -- the block is centred there. Shift existing positions by halfBlock in the growth + -- direction so icon 1 stays at its old screen location for existing users. + local function MigratePersonalContainerPosition(partyDb) + if not partyDb or partyDb._personalContainerCenterMigrated then return end + local iconSize = partyDb.personalTargetedSpellSize or 40 + local scale = partyDb.personalTargetedSpellScale or 1.0 + local maxIcons = partyDb.personalTargetedSpellMaxIcons or 5 + local spacing = partyDb.personalTargetedSpellSpacing or 4 + local growthDirection = partyDb.personalTargetedSpellGrowth or "RIGHT" + local x = partyDb.personalTargetedSpellX or 0 + local y = partyDb.personalTargetedSpellY or -150 + + local scaledSize = iconSize * scale + local scaledSpacing = spacing * scale + local halfBlock = (maxIcons - 1) / 2 * (scaledSize + scaledSpacing) + + if growthDirection == "RIGHT" then + partyDb.personalTargetedSpellX = x + halfBlock + elseif growthDirection == "LEFT" then + partyDb.personalTargetedSpellX = x - halfBlock + elseif growthDirection == "UP" then + partyDb.personalTargetedSpellY = y + halfBlock + elseif growthDirection == "DOWN" then + partyDb.personalTargetedSpellY = y - halfBlock + -- CENTER_H / CENTER_V: no shift needed + end + partyDb._personalContainerCenterMigrated = true + end + MigratePersonalContainerPosition(DF.db.party) + if DandersFramesDB_v2 and DandersFramesDB_v2.profiles then + for _, profile in pairs(DandersFramesDB_v2.profiles) do + MigratePersonalContainerPosition(profile.party) + end + end + -- Wrap DF.db with overlay proxy (must happen AFTER all migrations, -- BEFORE anything that reads through the proxy) DF:WrapDB() diff --git a/Features/TargetedSpells.lua b/Features/TargetedSpells.lua index 833ce6e8..a79c40e6 100644 --- a/Features/TargetedSpells.lua +++ b/Features/TargetedSpells.lua @@ -2019,18 +2019,50 @@ local function GetPersonalMoverSize() return math.max(width, 50), math.max(height, 50) end +-- Compute the container CENTER offset from the saved icon-block centre (x, y). +-- The saved position represents the visual midpoint of the icon block. The +-- container is shifted opposite to the growth direction so that icon 1 (which +-- anchors to the container's CENTER) ends up in the right place, with the full +-- block symmetrically centred on the saved (x, y). +local function GetPersonalContainerPoint(x, y) + local db = DF:GetDB() + local iconSize = db.personalTargetedSpellSize or 40 + local scale = db.personalTargetedSpellScale or 1.0 + local maxIcons = db.personalTargetedSpellMaxIcons or 5 + local spacing = db.personalTargetedSpellSpacing or 4 + local growthDirection = db.personalTargetedSpellGrowth or "RIGHT" + + local scaledSize = iconSize * scale + local scaledSpacing = spacing * scale + local halfBlock = (maxIcons - 1) / 2 * (scaledSize + scaledSpacing) + + local cx, cy = x, y + if growthDirection == "RIGHT" then + cx = x - halfBlock + elseif growthDirection == "LEFT" then + cx = x + halfBlock + elseif growthDirection == "UP" then + cy = y - halfBlock + elseif growthDirection == "DOWN" then + cy = y + halfBlock + -- CENTER_H / CENTER_V: already symmetric, no adjustment needed + end + return cx, cy +end + -- Create the personal targeted spells container local function CreatePersonalContainer() if personalContainer then return personalContainer end - + local db = DF:GetDB() local x = db.personalTargetedSpellX or 0 local y = db.personalTargetedSpellY or -150 - + local container = CreateFrame("Frame", "DandersFramesPersonalTargetedSpells", UIParent) local w, h = GetPersonalMoverSize() container:SetSize(w, h) - container:SetPoint("CENTER", UIParent, "CENTER", x, y) + local cx, cy = GetPersonalContainerPoint(x, y) + container:SetPoint("CENTER", UIParent, "CENTER", cx, cy) container:SetFrameStrata("HIGH") container:Hide() container:EnableMouse(false) @@ -2696,7 +2728,8 @@ function DF:UpdatePersonalTargetedSpellsPosition() if personalContainer then personalContainer:ClearAllPoints() - personalContainer:SetPoint("CENTER", UIParent, "CENTER", x, y) + local cx, cy = GetPersonalContainerPoint(x, y) + personalContainer:SetPoint("CENTER", UIParent, "CENTER", cx, cy) local w, h = GetPersonalMoverSize() personalContainer:SetSize(w, h) personalContainer:SetAlpha(iconAlpha) @@ -2776,7 +2809,8 @@ function DF:CreatePersonalTargetedSpellsMover() -- Update container position live if personalContainer then personalContainer:ClearAllPoints() - personalContainer:SetPoint("CENTER", UIParent, "CENTER", x, y) + local cx, cy = GetPersonalContainerPoint(x, y) + personalContainer:SetPoint("CENTER", UIParent, "CENTER", cx, cy) end -- Snap preview