forked from Dusk/ShaguTweaks-ClassicAPI
237 lines
8.0 KiB
Lua
237 lines
8.0 KiB
Lua
local T = ShaguTweaks.T
|
|
local _G = ShaguTweaks.GetGlobalEnv()
|
|
|
|
local function FixLFTButtonDrag()
|
|
local button = _G.LFTMinimapButton
|
|
if not button or button.stEnlargedDragFix then return end
|
|
local stop = button:GetScript("OnDragStop")
|
|
if type(stop) ~= "function" then return end
|
|
button.stEnlargedDragFix = true
|
|
button:SetScript("OnDragStop", function(...)
|
|
local parent = button:GetParent()
|
|
local left, top = button:GetLeft(), button:GetTop()
|
|
local scale = button:GetScale()
|
|
stop(unpack(arg))
|
|
-- Turtle's handler detaches to UIParent without converting coordinates or
|
|
-- inherited scale. Keep the native parent/local scale (also across reloads)
|
|
-- and preserve the dropped screen position. Native reset remains untouched.
|
|
if parent == Minimap and button:GetParent() == UIParent then
|
|
button:SetParent(parent)
|
|
button:SetScale(scale)
|
|
if left and top then
|
|
button:ClearAllPoints()
|
|
button:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", left, top)
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
local module = ShaguTweaks:register({
|
|
title = T["Enlarged Minimap"],
|
|
description = T["Increases the minimap size and shifts buff icons left to prevent overlap."],
|
|
expansions = { ["vanilla"] = true },
|
|
category = T["Minimap & World Map"],
|
|
enabled = false,
|
|
order = 73,
|
|
config = {
|
|
["minimap.scale"] = 1.2,
|
|
}
|
|
})
|
|
|
|
local function EnsurePoint(frame, point, relativeTo, relativePoint, x, y)
|
|
if not frame then return end
|
|
|
|
local currentPoint, currentRelative, currentRelativePoint, currentX, currentY = frame:GetPoint(1)
|
|
if currentPoint == point and currentRelative == relativeTo
|
|
and currentRelativePoint == relativePoint and currentX == x and currentY == y then
|
|
return
|
|
end
|
|
|
|
frame:ClearAllPoints()
|
|
frame:SetPoint(point, relativeTo, relativePoint, x, y)
|
|
end
|
|
|
|
local function GetMoverState(group)
|
|
local state = ShaguTweaks.MovableUnitFramesState
|
|
if not state then return false, false end
|
|
|
|
local manual = state.manual and state.manual[group] and true or false
|
|
local dragging = state.dragging and state.dragging[group] and true or false
|
|
return manual, dragging
|
|
end
|
|
|
|
local function GetMovedPosition(key)
|
|
local config = ShaguTweaks_config and ShaguTweaks_config["MoveUnitframes"]
|
|
return config and config[key]
|
|
end
|
|
|
|
local function EnsureMovedPosition(frame, key)
|
|
local pos = GetMovedPosition(key)
|
|
if not frame or not pos or not pos[1] or not pos[2] then return end
|
|
|
|
EnsurePoint(frame, "TOPLEFT", UIParent, "BOTTOMLEFT", pos[1], pos[2])
|
|
end
|
|
|
|
-- Keep a moved/scaled minimap fully on screen without touching its saved
|
|
-- Movable Unit Frames position. Bounds are compared in physical screen space
|
|
-- because MinimapCluster can have a different effective scale than UIParent.
|
|
local function ClampMinimapToScreen()
|
|
local frame = MinimapCluster
|
|
if not frame or not UIParent then return end
|
|
|
|
local left = frame:GetLeft()
|
|
local right = frame:GetRight()
|
|
local top = frame:GetTop()
|
|
local bottom = frame:GetBottom()
|
|
if not left or not right or not top or not bottom then return end
|
|
|
|
local frameScale = frame:GetEffectiveScale()
|
|
local uiScale = UIParent:GetEffectiveScale()
|
|
if not frameScale or frameScale <= 0 or not uiScale or uiScale <= 0 then return end
|
|
|
|
local uiLeft = (UIParent:GetLeft() or 0) * uiScale
|
|
local uiRight = (UIParent:GetRight() or UIParent:GetWidth()) * uiScale
|
|
local uiTop = (UIParent:GetTop() or UIParent:GetHeight()) * uiScale
|
|
local uiBottom = (UIParent:GetBottom() or 0) * uiScale
|
|
|
|
local frameLeft = left * frameScale
|
|
local frameRight = right * frameScale
|
|
local frameTop = top * frameScale
|
|
local frameBottom = bottom * frameScale
|
|
|
|
local dx, dy = 0, 0
|
|
|
|
if frameLeft < uiLeft then
|
|
dx = uiLeft - frameLeft
|
|
elseif frameRight > uiRight then
|
|
dx = uiRight - frameRight
|
|
end
|
|
|
|
if frameBottom < uiBottom then
|
|
dy = uiBottom - frameBottom
|
|
elseif frameTop > uiTop then
|
|
dy = uiTop - frameTop
|
|
end
|
|
|
|
if dx == 0 and dy == 0 then return end
|
|
|
|
-- Anchor from the measured top-left so only the overflowing amount is moved.
|
|
-- This changes the live position only; the saved mover coordinates stay intact.
|
|
local newLeft = (frameLeft + dx - uiLeft) / frameScale
|
|
local newTop = (frameTop + dy - uiBottom) / frameScale
|
|
|
|
frame:ClearAllPoints()
|
|
frame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", newLeft, newTop)
|
|
end
|
|
|
|
-- Layout coordinates can lag one frame after SetScale()/SetPoint() on Vanilla.
|
|
-- Coalesce clamp requests into a single deferred pass with no permanent OnUpdate.
|
|
local minimapClampFrame = CreateFrame("Frame")
|
|
minimapClampFrame:Hide()
|
|
minimapClampFrame:SetScript("OnUpdate", function()
|
|
this:Hide()
|
|
ClampMinimapToScreen()
|
|
end)
|
|
|
|
ShaguTweaks.ScheduleMinimapClamp = function()
|
|
minimapClampFrame:Show()
|
|
end
|
|
|
|
module.enable = function(self)
|
|
local scale = module.config["minimap.scale"]
|
|
if scale < 1.0 then scale = 1.0 end
|
|
if scale > 2.0 then scale = 2.0 end
|
|
|
|
if MinimapCluster.SetClampedToScreen then
|
|
MinimapCluster:SetClampedToScreen(true)
|
|
end
|
|
|
|
MinimapCluster:SetScale(scale)
|
|
FixLFTButtonDrag()
|
|
ShaguTweaks.ScheduleMinimapClamp()
|
|
|
|
-- BuffFrame is anchored to UIParent TOPRIGHT/TOPRIGHT x=-205 y=-13 by vanilla.
|
|
-- The stock BuffFrame_Enchant_OnUpdate re-anchors BuffFrame on every frame,
|
|
-- so keep a lightweight per-frame verifier and only write when an anchor
|
|
-- actually moved.
|
|
local extra = MinimapCluster:GetWidth() * (scale - 1.0)
|
|
local targetX = -205 - extra
|
|
local targetY = -13
|
|
|
|
-- BuffButton16 is the anchor for the player debuff row in vanilla 1.12.
|
|
local debuffX = -205 - extra
|
|
local debuffY = -13 - 70
|
|
|
|
-- BuffButton8 ends the top buff row and can overlap an enlarged minimap.
|
|
local buffRowX = -205 - extra
|
|
local buffRowY = debuffY + 26
|
|
|
|
-- Reuse a single verifier if enable() is called again. This prevents stacked
|
|
-- OnUpdate frames from fighting over the same anchors.
|
|
-- The verifier is a child of BuffFrame, so it only runs while the stock
|
|
-- buffs are shown. Buff addons such as VCB hide BuffFrame and
|
|
-- TemporaryEnchantFrame; the stock per-frame re-anchoring
|
|
-- (BuffFrame_Enchant_OnUpdate on TemporaryEnchantFrame) stops with them,
|
|
-- and so does this check.
|
|
if not self.enforcer then
|
|
self.enforcer = CreateFrame("Frame", nil, BuffFrame)
|
|
end
|
|
local enforcer = self.enforcer
|
|
|
|
enforcer:SetScript("OnUpdate", function()
|
|
local buffsManual, buffsDragging = GetMoverState("buffs")
|
|
local debuffsManual, debuffsDragging = GetMoverState("debuffs")
|
|
local weaponManual, weaponDragging = GetMoverState("weapon")
|
|
|
|
-- Manually moved aura groups always win. While a group is actively being
|
|
-- dragged, do not write any anchor for it; once released, enforce the
|
|
-- saved user position instead of the Enlarged Minimap default.
|
|
if buffsManual then
|
|
if not buffsDragging then
|
|
EnsureMovedPosition(BuffButton0, "BuffButton0")
|
|
end
|
|
else
|
|
EnsurePoint(BuffFrame, "TOPRIGHT", UIParent, "TOPRIGHT", targetX, targetY)
|
|
|
|
if BuffButton8 then
|
|
EnsurePoint(BuffButton8, "TOPRIGHT", UIParent, "TOPRIGHT", buffRowX, buffRowY)
|
|
end
|
|
end
|
|
|
|
if debuffsManual then
|
|
if not debuffsDragging then
|
|
EnsureMovedPosition(BuffButton32, "BuffButton32")
|
|
end
|
|
elseif BuffButton16 then
|
|
EnsurePoint(BuffButton16, "TOPRIGHT", UIParent, "TOPRIGHT", debuffX, debuffY)
|
|
end
|
|
|
|
if weaponManual then
|
|
if not weaponDragging then
|
|
EnsureMovedPosition(TempEnchant1, "TempEnchant1")
|
|
|
|
if TempEnchant2 and TempEnchant1 then
|
|
EnsurePoint(TempEnchant2, "TOP", TempEnchant1, "BOTTOM", 0, -2)
|
|
end
|
|
end
|
|
else
|
|
-- Temporary enchant buttons are also restored by the stock aura layout.
|
|
-- Verify their anchors like the buff rows instead of clearing and setting
|
|
-- them unconditionally every frame.
|
|
if TempEnchant1 then
|
|
EnsurePoint(TempEnchant1, "TOPLEFT", BuffFrame, "TOPRIGHT", 5, 0)
|
|
end
|
|
|
|
if TempEnchant2 and TempEnchant1 then
|
|
EnsurePoint(TempEnchant2, "TOP", TempEnchant1, "BOTTOM", 0, -2)
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
module.disable = function(self)
|
|
if self.enforcer then
|
|
self.enforcer:SetScript("OnUpdate", nil)
|
|
end
|
|
end
|