|
|
|
@@ -134,6 +134,9 @@ local function MigrateSavedVariables()
|
|
|
|
|
if not SexyMap2DB.userPresets then
|
|
|
|
|
SexyMap2DB.userPresets = {}
|
|
|
|
|
end
|
|
|
|
|
if not SexyMap2DB.buttonPositions then
|
|
|
|
|
SexyMap2DB.buttonPositions = {}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Mark the current version so migration doesn't re-run needlessly
|
|
|
|
|
-- (but the checks above still protect against manually-edited bad data)
|
|
|
|
@@ -182,6 +185,7 @@ function CMap_OnEvent()
|
|
|
|
|
CUpdateMinimapVisibility()
|
|
|
|
|
CApplyMapScale()
|
|
|
|
|
CLoadArtwork()
|
|
|
|
|
CApplyButtonPositions()
|
|
|
|
|
SlashCmdList["CMAP"] = CMap_SlashCmdHandler
|
|
|
|
|
SLASH_CMAP1 = "/cm"
|
|
|
|
|
SLASH_CMAP2 = "/sm"
|
|
|
|
@@ -337,6 +341,152 @@ local function RestoreButtonPoints(frame)
|
|
|
|
|
hiddenBtnOrigPoints[frame] = nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- Persistent minimap button positions
|
|
|
|
|
-- ============================================
|
|
|
|
|
-- Minimap buttons are children of the (scaled) MinimapCluster / Minimap.
|
|
|
|
|
-- When the user drags one, we save its position in UIParent screen space
|
|
|
|
|
-- (i.e. multiplied by its effective scale, divided by UIParent effective
|
|
|
|
|
-- scale) so that changing the map scale later does NOT visually move the
|
|
|
|
|
-- button. On login we restore that same on-screen center regardless of
|
|
|
|
|
-- the current map scale.
|
|
|
|
|
|
|
|
|
|
-- Frames we have already made draggable / hooked (avoid double-hooking).
|
|
|
|
|
local dragEnabledButtons = {}
|
|
|
|
|
|
|
|
|
|
-- Save a frame's on-screen center to SavedVariables, keyed by frame name.
|
|
|
|
|
local function CSaveButtonScreenPos(frame)
|
|
|
|
|
if not frame or not frame.GetName or not frame.GetCenter then return end
|
|
|
|
|
local name = frame:GetName()
|
|
|
|
|
if not name or name == "" then return end
|
|
|
|
|
local x, y = frame:GetCenter()
|
|
|
|
|
if not x or not y then return end
|
|
|
|
|
local fScale = frame:GetEffectiveScale() or 1
|
|
|
|
|
local uScale = UIParent:GetEffectiveScale() or 1
|
|
|
|
|
if uScale == 0 then uScale = 1 end
|
|
|
|
|
-- Convert into UIParent-space (screen) coordinates.
|
|
|
|
|
local ux = x * fScale / uScale
|
|
|
|
|
local uy = y * fScale / uScale
|
|
|
|
|
if not SexyMap2DB.buttonPositions then
|
|
|
|
|
SexyMap2DB.buttonPositions = {}
|
|
|
|
|
end
|
|
|
|
|
SexyMap2DB.buttonPositions[name] = { x = ux, y = uy }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Restore a frame to its saved on-screen center, compensating for the
|
|
|
|
|
-- current parent scale so it lands in the same screen pixel.
|
|
|
|
|
local function CRestoreButtonScreenPos(frame)
|
|
|
|
|
if not frame or not frame.GetName or not frame.ClearAllPoints then return end
|
|
|
|
|
local name = frame:GetName()
|
|
|
|
|
if not name or name == "" then return end
|
|
|
|
|
if not SexyMap2DB.buttonPositions then return end
|
|
|
|
|
local saved = SexyMap2DB.buttonPositions[name]
|
|
|
|
|
if not saved or not saved.x or not saved.y then return end
|
|
|
|
|
local fScale = frame:GetEffectiveScale() or 1
|
|
|
|
|
if fScale == 0 then fScale = 1 end
|
|
|
|
|
local uScale = UIParent:GetEffectiveScale() or 1
|
|
|
|
|
-- Convert UIParent-space coords back into the frame's own coord space.
|
|
|
|
|
local fx = saved.x * uScale / fScale
|
|
|
|
|
local fy = saved.y * uScale / fScale
|
|
|
|
|
frame:ClearAllPoints()
|
|
|
|
|
frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", fx, fy)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- OnDragStart / OnDragStop handlers used by hooked buttons.
|
|
|
|
|
local function CButton_OnDragStart()
|
|
|
|
|
if this and this.StartMoving then
|
|
|
|
|
this:StartMoving()
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local function CButton_OnDragStop()
|
|
|
|
|
if this then
|
|
|
|
|
if this.StopMovingOrSizing then this:StopMovingOrSizing() end
|
|
|
|
|
CSaveButtonScreenPos(this)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Make a single frame movable + save on drag stop. Safe to call repeatedly.
|
|
|
|
|
local function CEnableDragForButton(frame)
|
|
|
|
|
if not frame or dragEnabledButtons[frame] then return end
|
|
|
|
|
-- Guard: must be a real Frame-derived object (not a Texture/FontString).
|
|
|
|
|
if type(frame) ~= "table" or not frame.GetObjectType then return end
|
|
|
|
|
local ok, objType = pcall(frame.GetObjectType, frame)
|
|
|
|
|
if not ok or not objType then return end
|
|
|
|
|
if objType ~= "Frame" and objType ~= "Button" and objType ~= "CheckButton" then return end
|
|
|
|
|
if not frame.GetScript or not frame.SetScript then return end
|
|
|
|
|
local name = frame:GetName()
|
|
|
|
|
if not name or name == "" then return end
|
|
|
|
|
if frame.SetMovable then frame:SetMovable(true) end
|
|
|
|
|
if frame.RegisterForDrag then frame:RegisterForDrag("LeftButton") end
|
|
|
|
|
local origStart = frame:GetScript("OnDragStart")
|
|
|
|
|
local origStop = frame:GetScript("OnDragStop")
|
|
|
|
|
frame:SetScript("OnDragStart", function()
|
|
|
|
|
if origStart then origStart() end
|
|
|
|
|
CButton_OnDragStart()
|
|
|
|
|
end)
|
|
|
|
|
frame:SetScript("OnDragStop", function()
|
|
|
|
|
CButton_OnDragStop()
|
|
|
|
|
if origStop then origStop() end
|
|
|
|
|
end)
|
|
|
|
|
dragEnabledButtons[frame] = true
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Iterate all current minimap side buttons: make them draggable and
|
|
|
|
|
-- restore any saved position. Called on login (after CApplyMapScale) and
|
|
|
|
|
-- again whenever the map scale changes.
|
|
|
|
|
function CApplyButtonPositions()
|
|
|
|
|
if not Minimap then return end
|
|
|
|
|
|
|
|
|
|
local excludeNames = {
|
|
|
|
|
["MinimapZoomIn"] = true,
|
|
|
|
|
["MinimapZoomOut"] = true,
|
|
|
|
|
["MinimapToggleButton"] = true,
|
|
|
|
|
["CMinimapBackdrop"] = true,
|
|
|
|
|
["MinimapPing"] = true,
|
|
|
|
|
["MiniMapPing"] = true,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-- Named side buttons
|
|
|
|
|
local namedFrames = {
|
|
|
|
|
"MiniMapTracking", "MiniMapTrackingButton", "MiniMapTrackingFrame",
|
|
|
|
|
"MiniMapMailFrame", "MiniMapMailBorder",
|
|
|
|
|
"MiniMapBattlefieldFrame", "MiniMapMeetingStoneFrame",
|
|
|
|
|
"MiniMapWorldMapButton", "MinimapVoiceChatFrame", "MiniMapLFGFrame",
|
|
|
|
|
"GameTimeFrame",
|
|
|
|
|
}
|
|
|
|
|
for _, n in ipairs(namedFrames) do
|
|
|
|
|
local f = _G[n]
|
|
|
|
|
if f then
|
|
|
|
|
CEnableDragForButton(f)
|
|
|
|
|
if SexyMap2DB.buttonPositions and SexyMap2DB.buttonPositions[n] then
|
|
|
|
|
CRestoreButtonScreenPos(f)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Any addon buttons parented to Minimap
|
|
|
|
|
local children = { Minimap:GetChildren() }
|
|
|
|
|
for _, frame in ipairs(children) do
|
|
|
|
|
local objType = frame:GetObjectType()
|
|
|
|
|
if objType == "Button" or objType == "CheckButton" then
|
|
|
|
|
local name = frame:GetName() or ""
|
|
|
|
|
if name ~= "" and not excludeNames[name]
|
|
|
|
|
and not string.find(name, "POI")
|
|
|
|
|
and not string.find(name, "[Qq]uest")
|
|
|
|
|
and not string.find(name, "^MinimapPin")
|
|
|
|
|
and not string.find(name, "^MiniMapPOI")
|
|
|
|
|
and not string.find(name, "[Pp]in%d")
|
|
|
|
|
then
|
|
|
|
|
CEnableDragForButton(frame)
|
|
|
|
|
if SexyMap2DB.buttonPositions and SexyMap2DB.buttonPositions[name] then
|
|
|
|
|
CRestoreButtonScreenPos(frame)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function CUpdateMinimapButtonsVisibility()
|
|
|
|
|
if SexyMap2DB.showMinimapButtons then
|
|
|
|
|
-- Show only the buttons we previously hid (preserves original visibility)
|
|
|
|
@@ -461,6 +611,10 @@ function CApplyMapScale()
|
|
|
|
|
|
|
|
|
|
-- Update border textures to match new minimap size
|
|
|
|
|
CUpdateBackdrop()
|
|
|
|
|
|
|
|
|
|
-- Re-place any user-positioned minimap buttons so they stay in the
|
|
|
|
|
-- same on-screen spot regardless of the new scale.
|
|
|
|
|
if CApplyButtonPositions then CApplyButtonPositions() end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function CUpdateZoneText()
|
|
|
|
|