Files
2026-08-05 15:54:45 +02:00

124 lines
4.5 KiB
Lua

-- TotemBar - minimap.lua
-- Hand-rolled minimap button (no LibDBIcon on 1.12). Orbits the minimap at a
-- saved angle, drag-repositions (angle persisted), left-click opens the
-- options panel, right-click toggles the bar. pfUI-safe: parent = Minimap,
-- name contains "Minimap", FrameStrata HIGH + level 9 (MEDIUM hides under
-- pfUI). /tb options is the guaranteed access path if pfUI collects/hides
-- the button. WoW-API file (parse-checked only).
TotemBar = TotemBar or {}
local button = nil
-- Custom icon sheet (tools/gen_icons.js, same texture ui.lua's
-- ICONS_TEXTURE points at): 4x4 grid of 128px cells, cell 7 = minimap
-- totem glyph (transparent backing). core/pulse.lua loads before this
-- file (see the .toc), so buildRingTexCoords is already available; built
-- once here at load, not per-tick.
local MINIMAP_ICON_TEXTURE = "Interface\\AddOns\\TotemBar\\textures\\icons"
local MINIMAP_ICON_CELL = 7
local minimapIconCoords = TotemBar.buildRingTexCoords(16, 4)
-- Repositions the button on its orbit for the given angle (degrees).
local function PlaceButton(angleDeg)
if not button then
return
end
local radius = (Minimap:GetWidth() / 2) + 5
local x, y = TotemBar.angleToOffset(angleDeg, radius)
button:ClearAllPoints()
button:SetPoint("CENTER", Minimap, "CENTER", x, y)
end
local function BuildMinimapButton()
if button then
return
end
local btn = CreateFrame("Button", "TotemBarMinimapButton", Minimap)
btn:SetWidth(33)
btn:SetHeight(33)
btn:SetFrameStrata("HIGH")
btn:SetFrameLevel(9)
local icon = btn:CreateTexture(nil, "ARTWORK")
icon:SetTexture(MINIMAP_ICON_TEXTURE)
local ic = minimapIconCoords[MINIMAP_ICON_CELL]
icon:SetTexCoord(ic.l, ic.r, ic.t, ic.b)
icon:SetWidth(20)
icon:SetHeight(20)
icon:SetPoint("CENTER", btn, "CENTER", 0, 0)
local border = btn:CreateTexture(nil, "OVERLAY")
border:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
-- Vanilla default-UI recipe (MiniMapTrackingButton in FrameXML): a 54px
-- border anchored TOPLEFT(0,0) on a 33px button. The ring is deliberately
-- off-centre WITHIN the texture, so it lands concentric with the icon at
-- this exact anchor/size - do NOT "centre" it (that pushes the ring off).
border:SetWidth(54)
border:SetHeight(54)
border:SetPoint("TOPLEFT", btn, "TOPLEFT", 0, 0)
btn:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
btn.angle = TotemBarDB.minimapAngle or 225
-- Drag (repositions around the orbit). Drag needs the movement threshold,
-- so a plain click still fires OnClick; the two coexist (verified 1.12
-- pattern).
btn:RegisterForDrag("LeftButton")
btn.isDragging = false
btn:SetScript("OnDragStart", function() this.isDragging = true end)
btn:SetScript("OnDragStop", function()
this.isDragging = false
TotemBarDB.minimapAngle = this.angle
end)
btn:SetScript("OnUpdate", function()
if not this.isDragging then
return
end
local mx, my = GetCursorPosition()
local scale = Minimap:GetEffectiveScale()
mx = mx / scale
my = my / scale
local cx, cy = Minimap:GetCenter()
this.angle = math.deg(math.atan2(my - cy, mx - cx))
PlaceButton(this.angle)
end)
-- Clicks: left = options, right = toggle bar.
btn:RegisterForClicks("LeftButtonUp", "RightButtonUp")
btn:SetScript("OnClick", function()
if arg1 == "RightButton" then
if TotemBar.ToggleBar then TotemBar.ToggleBar() end
else
if TotemBar.ToggleOptions then TotemBar.ToggleOptions() end
end
end)
btn:SetScript("OnEnter", function()
GameTooltip:SetOwner(this, "ANCHOR_LEFT")
GameTooltip:SetText("TotemBar")
GameTooltip:AddLine("Left-click: Options", 0.9, 0.9, 0.9)
GameTooltip:AddLine("Right-click: Toggle bar", 0.9, 0.9, 0.9)
GameTooltip:AddLine("Drag: reposition", 0.9, 0.9, 0.9)
GameTooltip:Show()
end)
btn:SetScript("OnLeave", function() GameTooltip:Hide() end)
button = btn
PlaceButton(btn.angle)
end
-- Build on ADDON_LOADED (SavedVariables are populated by then, same as the
-- bar). Guarded; never on PLAYER_ENTERING_WORLD (would re-run and leak
-- textures).
local ev = CreateFrame("Frame", "TotemBarMinimapEventFrame", UIParent)
ev:RegisterEvent("ADDON_LOADED")
ev:SetScript("OnEvent", function()
if event == "ADDON_LOADED" and arg1 == "TotemBar" then
BuildMinimapButton()
ev:UnregisterEvent("ADDON_LOADED")
end
end)