diff --git a/RelationshipsPVP.lua b/RelationshipsPVP.lua index 91f60d2..674b973 100644 --- a/RelationshipsPVP.lua +++ b/RelationshipsPVP.lua @@ -89,15 +89,85 @@ local function EnsureDB() return db end +-- Clamp a UIParent-relative CENTER offset so the button stays visible on screen. +function RelationshipsPVP_ClampScreenOffset(x, y) + x = x or 0 + y = y or 0 + if not UIParent or not UIParent.GetWidth then return x, y end + local w = UIParent:GetWidth() or 1024 + local h = UIParent:GetHeight() or 768 + local pad = -60 + local maxX = (w / 2) - pad + local maxY = (h / 2) - pad + if x > maxX then x = maxX end + if x < -maxX then x = -maxX end + if y > maxY then y = maxY end + if y < -maxY then y = -maxY end + return x, y +end + +-- Position the icon anywhere on screen (parented to UIParent for free drag). +function RelationshipsPVP_SetIconPosition(x, y, save) + local btn = RelationshipsPVPMinimapButton + if not btn or not UIParent then return end + x, y = RelationshipsPVP_ClampScreenOffset(x, y) + btn:ClearAllPoints() + btn:SetParent(UIParent) + btn:SetPoint("CENTER", UIParent, "CENTER", x, y) + if btn.SetFrameStrata then btn:SetFrameStrata("MEDIUM") end + if btn.SetFrameLevel then btn:SetFrameLevel(10) end + if save then + local db = EnsureDB() + db.icon.point = "CENTER" + db.icon.relPoint = "CENTER" + db.icon.parent = "UIParent" + db.icon.x = x + db.icon.y = y + end +end + +-- Read the button's current center in UIParent coordinates and persist it. function RelationshipsPVP_SaveIconPos() local db = EnsureDB() + local btn = RelationshipsPVPMinimapButton + if not btn or not UIParent then return end + local x = db.icon.x or 0 + local y = db.icon.y or 0 + if btn.GetCenter and UIParent.GetCenter then + local bx, by = btn:GetCenter() + local ux, uy = UIParent:GetCenter() + if bx and by and ux and uy then + x = bx - ux + y = by - uy + end + end + x, y = RelationshipsPVP_ClampScreenOffset(x, y) + db.icon.point = "CENTER" + db.icon.relPoint = "CENTER" + db.icon.parent = "UIParent" + db.icon.x = x + db.icon.y = y +end + +-- Free drag: reparent to UIParent and let the client move the frame. +function RelationshipsPVP_StartIconDrag() local btn = RelationshipsPVPMinimapButton if not btn then return end - local point, _, _, x, y = btn:GetPoint() - db.icon.point = point or "CENTER" - db.icon.x = x or 0 - db.icon.y = y or 0 - db.icon.parent = "Minimap" + btn:SetParent(UIParent) + if btn.SetFrameStrata then btn:SetFrameStrata("MEDIUM") end + if btn.SetFrameLevel then btn:SetFrameLevel(10) end + if btn.StartMoving then btn:StartMoving() end +end + +function RelationshipsPVP_StopIconDrag() + local btn = RelationshipsPVPMinimapButton + if not btn then return end + if btn.StopMovingOrSizing then btn:StopMovingOrSizing() end + RelationshipsPVP_SaveIconPos() + local db = EnsureDB() + -- Re-anchor cleanly to a single CENTER/CENTER offset so the saved value is + -- exactly what we restore on next login. + RelationshipsPVP_SetIconPosition(db.icon.x, db.icon.y, 1) end local function ApplyIconVisibility() @@ -107,10 +177,8 @@ local function ApplyIconVisibility() if db.showIcon then btn:Show() else btn:Hide() end end --- The Minimap frame can be briefly hidden during loading screens / entering --- battlegrounds; when it re-shows, child buttons parented to it sometimes --- stay hidden until touched. This ticker re-asserts our intended visibility --- once per second so the icon never "randomly disappears". +-- Loading screens / entering BGs can briefly hide parent frames; re-assert +-- our intended visibility so the icon never "randomly disappears". local iconWatcher local function InstallIconWatcher() if iconWatcher then return end @@ -136,9 +204,22 @@ local function RestoreIconPos() local db = EnsureDB() local btn = RelationshipsPVPMinimapButton if not btn then return end - local parent = (db.icon.parent == "UIParent") and UIParent or Minimap - btn:ClearAllPoints() - btn:SetPoint(db.icon.point, parent, db.icon.point, db.icon.x, db.icon.y) + + -- Migrate any prior Minimap-relative save into a UIParent-relative offset + -- so free-drag mode has a valid starting position. + if db.icon.parent == "Minimap" and Minimap and Minimap.GetCenter and UIParent and UIParent.GetCenter then + local mx, my = Minimap:GetCenter() + local ux, uy = UIParent:GetCenter() + if mx and my and ux and uy then + db.icon.x = (mx - ux) + (db.icon.x or 0) + db.icon.y = (my - uy) + (db.icon.y or 0) + end + db.icon.parent = "UIParent" + db.icon.point = "CENTER" + db.icon.relPoint = "CENTER" + end + + RelationshipsPVP_SetIconPosition(db.icon.x or 0, db.icon.y or 0, 1) ApplyIconVisibility() InstallIconWatcher() end @@ -853,12 +934,12 @@ function RelationshipsPVP_ResetPositions() end if RelationshipsPVPMinimapButton then - RelationshipsPVPMinimapButton:ClearAllPoints() - RelationshipsPVPMinimapButton:SetPoint("CENTER", UIParent, "CENTER", 0, 0) - db.icon.point = "CENTER" - db.icon.x = 0 - db.icon.y = 0 - db.icon.parent = "UIParent" + RelationshipsPVP_SetIconPosition(0, 0, 1) + db.icon.point = "CENTER" + db.icon.relPoint = "CENTER" + db.icon.x = 0 + db.icon.y = 0 + db.icon.parent = "UIParent" end db.panel = { point = "CENTER", x = 0, y = 0 } @@ -880,6 +961,7 @@ end function RelationshipsPVP_OnLoad() this:RegisterEvent("PLAYER_LOGIN") this:RegisterEvent("PLAYER_ENTERING_WORLD") + this:RegisterEvent("PLAYER_LOGOUT") this:RegisterEvent("UPDATE_BATTLEFIELD_STATUS") this:RegisterEvent("UPDATE_BATTLEFIELD_SCORE") this:RegisterEvent("PLAYER_DEAD") @@ -934,6 +1016,12 @@ function RelationshipsPVP_SavePanelPos() end function RelationshipsPVP_OnEvent(event) + if event == "PLAYER_LOGOUT" then + RelationshipsPVP_SaveIconPos() + SavePanelPos() + return + end + if event == "PLAYER_LOGIN" or event == "PLAYER_ENTERING_WORLD" then EnsureDB() RestoreIconPos() diff --git a/RelationshipsPVP.xml b/RelationshipsPVP.xml index 50b9a50..3c5d587 100644 --- a/RelationshipsPVP.xml +++ b/RelationshipsPVP.xml @@ -383,11 +383,8 @@ if icon and icon.SetTexCoord then icon:SetTexCoord(0.08, 0.92, 0.08, 0.92) end - this:SetScript("OnDragStart", function() this:StartMoving() end) - this:SetScript("OnDragStop", function() - this:StopMovingOrSizing() - RelationshipsPVP_SaveIconPos() - end) + this:SetScript("OnDragStart", function() RelationshipsPVP_StartIconDrag() end) + this:SetScript("OnDragStop", function() RelationshipsPVP_StopIconDrag() end) if RelationshipsPVPFrame:IsVisible() then