204 lines
6.7 KiB
Lua
204 lines
6.7 KiB
Lua
local T = ShaguTweaks.T
|
|
|
|
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)
|
|
ShaguTweaks.ScheduleMinimapClamp()
|
|
|
|
-- BuffFrame is anchored to UIParent TOPRIGHT/TOPRIGHT x=-205 y=-13 by vanilla.
|
|
-- The C engine can restore these anchors after aura layout updates, 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.
|
|
if not self.enforcer then
|
|
self.enforcer = CreateFrame("Frame")
|
|
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
|