forked from Dusk/ShaguTweaks-ClassicAPI
- The map keeps the scale picked with Ctrl+Mousewheel (saved per character, .4 to 2). It was reset to .85 on every open and by the Turtle WoW maximize wrapper. - The title bar drags the window: on Turtle the title sits 17 units above the frame, so the frame's click area now extends over it. - With OctoBus loaded, a Transports button left of the Continent dropdown runs OctoBus' own toggle. Its window is lifted above the map while both are open and restored when the map closes. - New Loot History module (/loothistory), ported from brues-code/pfUI and rebuilt with stock 1.12 widgets, on ClassicAPI's C_LootHistory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019W3rwusM4i1CYaHQAYixJ7
232 lines
7.9 KiB
Lua
232 lines
7.9 KiB
Lua
local _G = ShaguTweaks.GetGlobalEnv()
|
|
local T = ShaguTweaks.T
|
|
local API = ShaguTweaks.API
|
|
local HookScript = ShaguTweaks.HookScript
|
|
|
|
local module = ShaguTweaks:register({
|
|
title = T["WorldMap Window"],
|
|
description = T["Turns the world map into a movable window. The map can be scaled with <Ctrl> + Mousewheel."],
|
|
expansions = { ["vanilla"] = true },
|
|
category = T["Minimap & World Map"],
|
|
enabled = true,
|
|
})
|
|
|
|
local DEFAULT_SCALE = .85
|
|
local MIN_SCALE, MAX_SCALE = .4, 2
|
|
|
|
local function AddSpecialFrame(name)
|
|
for i = 1, table.getn(UISpecialFrames) do
|
|
if UISpecialFrames[i] == name then return end
|
|
end
|
|
table.insert(UISpecialFrames, name)
|
|
end
|
|
|
|
-- The scale chosen with Ctrl + Mousewheel is saved per character, so the map
|
|
-- reopens (and survives a reload) at the size it was left at.
|
|
local function GetSavedScale()
|
|
local scale = ShaguTweaks_config and tonumber(ShaguTweaks_config["WorldMapScale"])
|
|
if not scale then return DEFAULT_SCALE end
|
|
if scale < MIN_SCALE then return MIN_SCALE end
|
|
if scale > MAX_SCALE then return MAX_SCALE end
|
|
return scale
|
|
end
|
|
|
|
local function SaveScale(scale)
|
|
if not ShaguTweaks_config then return end
|
|
ShaguTweaks_config["WorldMapScale"] = scale
|
|
end
|
|
|
|
-- Turtle WoW Compatibility re-applies the window layout after Turtle's own
|
|
-- WorldMapFrame_Maximize and uses this instead of a fixed scale.
|
|
ShaguTweaks.GetWorldMapScale = GetSavedScale
|
|
|
|
-- The window's title bar is drawn above the frame's top edge (Turtle places
|
|
-- the title 17 units above it), so clicks there missed the frame and only
|
|
-- the dropdown row could be dragged. Extend the frame's clickable area up to
|
|
-- the top of the title. The close and minimize buttons are child frames on
|
|
-- a higher level, so they keep their clicks.
|
|
local TITLE_MARGIN = 6
|
|
|
|
local function TitleHeightAboveFrame()
|
|
local title = WorldMapFrameTitle
|
|
if not title then return 0 end
|
|
|
|
-- Prefer the anchor: exact, and valid before the layout is computed.
|
|
local count = title.GetNumPoints and title:GetNumPoints() or 1
|
|
for i = 1, count do
|
|
local point, relativeTo, relativePoint, _, y = title:GetPoint(i)
|
|
if point == "TOP" and relativeTo == WorldMapFrame
|
|
and (relativePoint == nil or relativePoint == "TOP") and y then
|
|
return y
|
|
end
|
|
end
|
|
|
|
local frameTop, titleTop = WorldMapFrame:GetTop(), title:GetTop()
|
|
if frameTop and titleTop then return titleTop - frameTop end
|
|
return 0
|
|
end
|
|
|
|
local function UpdateDragArea()
|
|
local extra = TitleHeightAboveFrame()
|
|
if extra > 0 then
|
|
extra = math.floor(extra + TITLE_MARGIN + .5)
|
|
if extra > 40 then extra = 40 end
|
|
else
|
|
extra = 0
|
|
end
|
|
|
|
WorldMapFrame:SetHitRectInsets(0, 0, -extra, 0)
|
|
end
|
|
|
|
ShaguTweaks.UpdateWorldMapDragArea = UpdateDragArea
|
|
|
|
-- OctoBus (github.com/Phridgey/OctoBus) shows transport timers. When it is
|
|
-- loaded, add a "Transports" button in front of the Continent dropdown that
|
|
-- toggles its window, the same as a left-click on its minimap icon.
|
|
local function OctoBusAvailable()
|
|
return OctoBusPanel and SlashCmdList and SlashCmdList["OCTOBUS"] and true or false
|
|
end
|
|
|
|
local function CreateTransportsButton()
|
|
if module.transports or not OctoBusAvailable() then return end
|
|
if not WorldMapContinentDropDown or not WorldMapZoomOutButton then return end
|
|
|
|
local button = CreateFrame("Button", "ShaguTweaksWorldMapTransports", WorldMapFrame, "UIPanelButtonTemplate")
|
|
button:SetWidth(WorldMapZoomOutButton:GetWidth() or 110)
|
|
button:SetHeight(WorldMapZoomOutButton:GetHeight() or 22)
|
|
-- Mirror of the Zoom Out button, which sits 10 units into the zone
|
|
-- dropdown's transparent right edge and 3 units higher.
|
|
button:SetPoint("RIGHT", WorldMapContinentDropDown, "LEFT", 10, 3)
|
|
button:SetText(T["Transports"])
|
|
|
|
-- OctoBus' window lives on the MEDIUM strata, behind the full-screen map.
|
|
-- Lift it above the map while both are open (also when OctoBus opens it
|
|
-- by itself at a dock), and give it its own strata back afterwards.
|
|
local function RaisePanel()
|
|
if not WorldMapFrame:IsShown() or not OctoBusPanel:IsShown() then return end
|
|
if not module.panelStrata then
|
|
module.panelStrata = OctoBusPanel:GetFrameStrata()
|
|
end
|
|
OctoBusPanel:SetFrameStrata("FULLSCREEN_DIALOG")
|
|
end
|
|
|
|
local function RestorePanel()
|
|
if module.panelStrata then
|
|
OctoBusPanel:SetFrameStrata(module.panelStrata)
|
|
module.panelStrata = nil
|
|
end
|
|
end
|
|
|
|
HookScript(WorldMapFrame, "OnShow", RaisePanel)
|
|
HookScript(WorldMapFrame, "OnHide", RestorePanel)
|
|
HookScript(OctoBusPanel, "OnShow", RaisePanel)
|
|
|
|
button:SetScript("OnClick", function()
|
|
-- OctoBus' "/ob" without arguments is the same toggle as its icon.
|
|
SlashCmdList["OCTOBUS"]("")
|
|
RaisePanel()
|
|
end)
|
|
|
|
button:SetScript("OnEnter", function()
|
|
GameTooltip:SetOwner(this, "ANCHOR_BOTTOM")
|
|
GameTooltip:SetText(T["Transports"])
|
|
GameTooltip:AddLine(T["Shows or hides the OctoBus transport timers."], 1, 1, 1, 1)
|
|
GameTooltip:Show()
|
|
end)
|
|
button:SetScript("OnLeave", function() GameTooltip:Hide() end)
|
|
|
|
module.transports = button
|
|
end
|
|
|
|
module.enable = function(self)
|
|
-- Only advertise the window as active after the delayed compatibility check.
|
|
-- Turtle WoW consumes this flag instead of looking at config alone.
|
|
ShaguTweaks.WorldMapWindowActive = nil
|
|
|
|
-- Reuse one initialization frame so repeated enable() calls cannot stack
|
|
-- PLAYER_ENTERING_WORLD handlers or duplicate WorldMapFrame hooks.
|
|
if not self.delay then
|
|
self.delay = CreateFrame("Frame")
|
|
end
|
|
|
|
local delay = self.delay
|
|
delay:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
delay:SetScript("OnEvent", function()
|
|
-- Do not touch the stock world-map controls at all when a dedicated map
|
|
-- addon owns them. Run this before replacing ToggleWorldMap or adding hooks.
|
|
if Cartographer or METAMAP_TITLE then
|
|
ShaguTweaks.WorldMapWindowActive = nil
|
|
this:UnregisterAllEvents()
|
|
this:Hide()
|
|
return
|
|
end
|
|
|
|
ShaguTweaks.WorldMapWindowActive = true
|
|
AddSpecialFrame("WorldMapFrame")
|
|
|
|
-- Window mode requires a direct Show/Hide toggle instead of the stock
|
|
-- full-screen panel toggle. Install it only after the compatibility check.
|
|
if not self.toggleInstalled then
|
|
self.toggleInstalled = true
|
|
function _G.ToggleWorldMap()
|
|
if WorldMapFrame:IsShown() then
|
|
WorldMapFrame:Hide()
|
|
else
|
|
WorldMapFrame:Show()
|
|
end
|
|
end
|
|
end
|
|
|
|
UIPanelWindows["WorldMapFrame"] = { area = "center" }
|
|
|
|
if not self.hooked then
|
|
self.hooked = true
|
|
|
|
HookScript(WorldMapFrame, "OnShow", function()
|
|
this:EnableKeyboard(false)
|
|
this:EnableMouseWheel(1)
|
|
WorldMapFrame:SetScale(GetSavedScale())
|
|
UpdateDragArea()
|
|
end)
|
|
|
|
HookScript(WorldMapFrame, "OnMouseWheel", function()
|
|
if API.IsShiftKeyDown() then
|
|
WorldMapFrame:SetAlpha(WorldMapFrame:GetAlpha() + arg1 / 10)
|
|
elseif API.IsControlKeyDown() then
|
|
local scale = WorldMapFrame:GetScale() + arg1 / 10
|
|
if scale < MIN_SCALE then scale = MIN_SCALE end
|
|
if scale > MAX_SCALE then scale = MAX_SCALE end
|
|
WorldMapFrame:SetScale(scale)
|
|
SaveScale(scale)
|
|
end
|
|
end)
|
|
|
|
HookScript(WorldMapFrame, "OnMouseDown", function()
|
|
WorldMapFrame:StartMoving()
|
|
end)
|
|
|
|
HookScript(WorldMapFrame, "OnMouseUp", function()
|
|
WorldMapFrame:StopMovingOrSizing()
|
|
end)
|
|
end
|
|
|
|
WorldMapFrame:SetMovable(true)
|
|
WorldMapFrame:EnableMouse(true)
|
|
|
|
WorldMapFrame:SetScale(GetSavedScale())
|
|
WorldMapFrame:ClearAllPoints()
|
|
WorldMapFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 30)
|
|
WorldMapFrame:SetWidth(WorldMapButton:GetWidth() + 15)
|
|
WorldMapFrame:SetHeight(WorldMapButton:GetHeight() + 55)
|
|
BlackoutWorld:Hide()
|
|
UpdateDragArea()
|
|
|
|
CreateTransportsButton()
|
|
|
|
-- Initialization is complete. Keeping this event registered would repeat
|
|
-- the full layout work on every loading screen and reset a moved window.
|
|
this:UnregisterAllEvents()
|
|
this:Hide()
|
|
end)
|
|
end
|