修复拾取界面点击无效问题 修复宠物训练界面不显示训练点问题 新增天赋分享到聊天界面 修复飞行界面无法关闭问题 修复术士宠物的显示问题 为天赋界面添加默认数据库支持 框架现在也可自主选择是否启用 玩家框架和目标框架可取消显示3D头像以及透明度修改 背包和银行也添加透明度自定义支持 优化tooltip性能和背包物品显示方式 修复布局模式在ui缩放后不能正常定位的问题 添加硬核模式危险和死亡的工会通报 添加拾取和已拾取的框体 等等
498 lines
17 KiB
Lua
498 lines
17 KiB
Lua
--------------------------------------------------------------------------------
|
|
-- Nanami-UI: Pet Stable Skin (PetStableSkin.lua)
|
|
-- Skins the Blizzard PetStableFrame with Nanami-UI theme
|
|
--------------------------------------------------------------------------------
|
|
|
|
SFrames = SFrames or {}
|
|
SFrames.PetStableSkin = {}
|
|
SFramesDB = SFramesDB or {}
|
|
|
|
local T = SFrames.ActiveTheme
|
|
local skinned = false
|
|
|
|
local function GetFont()
|
|
if SFrames and SFrames.GetFont then return SFrames:GetFont() end
|
|
return "Fonts\\ARIALN.TTF"
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Helpers
|
|
--------------------------------------------------------------------------------
|
|
local function NukeTextures(frame, exceptions)
|
|
local regions = { frame:GetRegions() }
|
|
for _, r in ipairs(regions) do
|
|
if r:IsObjectType("Texture") and not r.sfKeep then
|
|
local rName = r:GetName()
|
|
local skip = false
|
|
if exceptions and rName then
|
|
for _, exc in ipairs(exceptions) do
|
|
if string.find(rName, exc) then
|
|
skip = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if not skip then
|
|
r:SetTexture(nil)
|
|
r:SetAlpha(0)
|
|
r:Hide()
|
|
r.sfNuked = true
|
|
r:ClearAllPoints()
|
|
r:SetPoint("CENTER", UIParent, "CENTER", 9999, 9999)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function NukeChildTextures(frame)
|
|
local children = { frame:GetChildren() }
|
|
for _, child in ipairs(children) do
|
|
local cName = child:GetName() or ""
|
|
if string.find(cName, "Inset") or string.find(cName, "Bg") then
|
|
NukeTextures(child)
|
|
if child.SetBackdrop then child:SetBackdrop(nil) end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SetRoundBackdrop(frame)
|
|
frame:SetBackdrop({
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true, tileSize = 16, edgeSize = 14,
|
|
insets = { left = 3, right = 3, top = 3, bottom = 3 },
|
|
})
|
|
frame:SetBackdropColor(T.panelBg[1], T.panelBg[2], T.panelBg[3], T.panelBg[4])
|
|
frame:SetBackdropBorderColor(T.panelBorder[1], T.panelBorder[2], T.panelBorder[3], T.panelBorder[4])
|
|
end
|
|
|
|
local function CreateShadow(parent)
|
|
local s = CreateFrame("Frame", nil, parent)
|
|
s:SetPoint("TOPLEFT", parent, "TOPLEFT", -4, 4)
|
|
s:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", 4, -4)
|
|
s:SetBackdrop({
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true, tileSize = 16, edgeSize = 16,
|
|
insets = { left = 4, right = 4, top = 4, bottom = 4 },
|
|
})
|
|
s:SetBackdropColor(0, 0, 0, 0.45)
|
|
s:SetBackdropBorderColor(0, 0, 0, 0.6)
|
|
s:SetFrameLevel(math.max(0, parent:GetFrameLevel() - 1))
|
|
return s
|
|
end
|
|
|
|
local function MarkBackdropRegions(frame)
|
|
local regions = { frame:GetRegions() }
|
|
for _, r in ipairs(regions) do
|
|
if not r.sfNuked then r.sfKeep = true end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Slot styling (ItemButton-type pet slot buttons)
|
|
--------------------------------------------------------------------------------
|
|
local function StyleSlot(btn)
|
|
if not btn or btn.sfSkinned then return end
|
|
btn.sfSkinned = true
|
|
|
|
local bname = btn:GetName() or ""
|
|
|
|
local normalTex = _G[bname .. "NormalTexture"]
|
|
if normalTex then normalTex:SetAlpha(0) end
|
|
|
|
NukeTextures(btn, { "Icon", "Count" })
|
|
|
|
local iconTex = _G[bname .. "IconTexture"]
|
|
if iconTex then
|
|
iconTex:SetTexCoord(0.08, 0.92, 0.08, 0.92)
|
|
iconTex.sfKeep = true
|
|
end
|
|
|
|
local bg = btn:CreateTexture(nil, "BACKGROUND")
|
|
bg:SetTexture("Interface\\Tooltips\\UI-Tooltip-Background")
|
|
bg:SetAllPoints()
|
|
bg:SetVertexColor(T.slotBg[1], T.slotBg[2], T.slotBg[3], T.slotBg[4] or 0.8)
|
|
bg.sfKeep = true
|
|
|
|
local border = CreateFrame("Frame", nil, btn)
|
|
border:SetPoint("TOPLEFT", btn, "TOPLEFT", -2, 2)
|
|
border:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 2, -2)
|
|
border:SetBackdrop({
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
edgeSize = 10,
|
|
insets = { left = 2, right = 2, top = 2, bottom = 2 },
|
|
})
|
|
border:SetBackdropBorderColor(T.slotBorder[1], T.slotBorder[2], T.slotBorder[3], T.slotBorder[4])
|
|
btn.sfBorder = border
|
|
|
|
local origEnter = btn:GetScript("OnEnter")
|
|
local origLeave = btn:GetScript("OnLeave")
|
|
|
|
btn:SetScript("OnEnter", function()
|
|
if origEnter then origEnter() end
|
|
if this.sfBorder then
|
|
this.sfBorder:SetBackdropBorderColor(
|
|
T.slotHover[1], T.slotHover[2], T.slotHover[3], T.slotHover[4] or 1)
|
|
end
|
|
end)
|
|
|
|
btn:SetScript("OnLeave", function()
|
|
if origLeave then origLeave() end
|
|
if this.sfBorder then
|
|
this.sfBorder:SetBackdropBorderColor(
|
|
T.slotBorder[1], T.slotBorder[2], T.slotBorder[3], T.slotBorder[4])
|
|
end
|
|
end)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Close button styling
|
|
--------------------------------------------------------------------------------
|
|
local function StyleCloseButton(btn)
|
|
if not btn or btn.sfSkinned then return end
|
|
btn.sfSkinned = true
|
|
|
|
btn:SetWidth(22)
|
|
btn:SetHeight(22)
|
|
btn:ClearAllPoints()
|
|
btn:SetPoint("TOPRIGHT", btn:GetParent(), "TOPRIGHT", -6, -6)
|
|
|
|
if btn.GetNormalTexture and btn:GetNormalTexture() then
|
|
btn:GetNormalTexture():SetAlpha(0)
|
|
end
|
|
if btn.GetPushedTexture and btn:GetPushedTexture() then
|
|
btn:GetPushedTexture():SetAlpha(0)
|
|
end
|
|
if btn.GetHighlightTexture and btn:GetHighlightTexture() then
|
|
btn:GetHighlightTexture():SetAlpha(0)
|
|
end
|
|
|
|
btn:SetBackdrop({
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true, tileSize = 8, edgeSize = 8,
|
|
insets = { left = 2, right = 2, top = 2, bottom = 2 },
|
|
})
|
|
|
|
local cbg = { 0.5, 0.1, 0.1, 0.85 }
|
|
local cbd = { 0.6, 0.2, 0.2, 0.8 }
|
|
local cbgH = { 0.7, 0.15, 0.15, 1 }
|
|
local cbdH = { 0.9, 0.3, 0.3, 1 }
|
|
|
|
btn:SetBackdropColor(cbg[1], cbg[2], cbg[3], cbg[4])
|
|
btn:SetBackdropBorderColor(cbd[1], cbd[2], cbd[3], cbd[4])
|
|
|
|
local xLabel = btn:CreateFontString(nil, "OVERLAY")
|
|
xLabel:SetFont(GetFont(), 11, "OUTLINE")
|
|
xLabel:SetPoint("CENTER", 0, 0)
|
|
xLabel:SetText("X")
|
|
xLabel:SetTextColor(0.9, 0.8, 0.8)
|
|
|
|
local origEnter = btn:GetScript("OnEnter")
|
|
local origLeave = btn:GetScript("OnLeave")
|
|
|
|
btn:SetScript("OnEnter", function()
|
|
if origEnter then origEnter() end
|
|
this:SetBackdropColor(cbgH[1], cbgH[2], cbgH[3], cbgH[4])
|
|
this:SetBackdropBorderColor(cbdH[1], cbdH[2], cbdH[3], cbdH[4])
|
|
end)
|
|
|
|
btn:SetScript("OnLeave", function()
|
|
if origLeave then origLeave() end
|
|
this:SetBackdropColor(cbg[1], cbg[2], cbg[3], cbg[4])
|
|
this:SetBackdropBorderColor(cbd[1], cbd[2], cbd[3], cbd[4])
|
|
end)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- UIPanelButton styling (purchase button etc.)
|
|
--------------------------------------------------------------------------------
|
|
local function StyleActionButton(btn)
|
|
if not btn or btn.sfSkinned then return end
|
|
btn.sfSkinned = true
|
|
|
|
btn:SetBackdrop({
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true, tileSize = 16, edgeSize = 14,
|
|
insets = { left = 3, right = 3, top = 3, bottom = 3 },
|
|
})
|
|
|
|
local bg = T.btnBg
|
|
local bd = T.btnBorder
|
|
btn:SetBackdropColor(bg[1], bg[2], bg[3], bg[4])
|
|
btn:SetBackdropBorderColor(bd[1], bd[2], bd[3], bd[4])
|
|
|
|
if btn.GetNormalTexture and btn:GetNormalTexture() then
|
|
btn:GetNormalTexture():SetTexture(nil)
|
|
end
|
|
if btn.GetPushedTexture and btn:GetPushedTexture() then
|
|
btn:GetPushedTexture():SetTexture(nil)
|
|
end
|
|
if btn.GetHighlightTexture and btn:GetHighlightTexture() then
|
|
btn:GetHighlightTexture():SetAlpha(0)
|
|
end
|
|
if btn.GetDisabledTexture and btn:GetDisabledTexture() then
|
|
btn:GetDisabledTexture():SetTexture(nil)
|
|
end
|
|
|
|
local name = btn:GetName() or ""
|
|
for _, suffix in ipairs({ "Left", "Right", "Middle" }) do
|
|
local tex = _G[name .. suffix]
|
|
if tex then tex:SetAlpha(0); tex:Hide() end
|
|
end
|
|
|
|
local fs = btn:GetFontString()
|
|
if fs then
|
|
fs:SetFont(GetFont(), 11, "OUTLINE")
|
|
fs:SetTextColor(T.text[1], T.text[2], T.text[3])
|
|
end
|
|
|
|
local hoverBg = T.btnHoverBg
|
|
local hoverBd = T.btnHoverBd
|
|
|
|
local origEnter = btn:GetScript("OnEnter")
|
|
local origLeave = btn:GetScript("OnLeave")
|
|
|
|
btn:SetScript("OnEnter", function()
|
|
if origEnter then origEnter() end
|
|
this:SetBackdropColor(hoverBg[1], hoverBg[2], hoverBg[3], hoverBg[4])
|
|
this:SetBackdropBorderColor(hoverBd[1], hoverBd[2], hoverBd[3], hoverBd[4])
|
|
end)
|
|
|
|
btn:SetScript("OnLeave", function()
|
|
if origLeave then origLeave() end
|
|
this:SetBackdropColor(bg[1], bg[2], bg[3], bg[4])
|
|
this:SetBackdropBorderColor(bd[1], bd[2], bd[3], bd[4])
|
|
end)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Style all FontStrings on a frame with our themed font
|
|
--------------------------------------------------------------------------------
|
|
local function StyleFontStrings(frame, size, color)
|
|
local regions = { frame:GetRegions() }
|
|
local font = GetFont()
|
|
for _, r in ipairs(regions) do
|
|
if r:IsObjectType("FontString") then
|
|
r:SetFont(font, size or 11, "OUTLINE")
|
|
if color then
|
|
r:SetTextColor(color[1], color[2], color[3])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Main skin application
|
|
--------------------------------------------------------------------------------
|
|
local function ApplySkin()
|
|
if skinned then return end
|
|
if not PetStableFrame then return end
|
|
if SFramesDB.enablePetStable == false then return end
|
|
skinned = true
|
|
|
|
local frame = PetStableFrame
|
|
local font = GetFont()
|
|
|
|
-- 1) Remove Blizzard decorative textures from main frame
|
|
NukeTextures(frame, { "Icon", "Food", "Diet", "Selected" })
|
|
|
|
-- 2) Remove textures from sub-inset frames
|
|
NukeChildTextures(frame)
|
|
|
|
-- 3) Apply themed backdrop
|
|
SetRoundBackdrop(frame)
|
|
MarkBackdropRegions(frame)
|
|
|
|
-- 4) Shadow for depth (tagged so auto-compact ignores it)
|
|
local shadow = CreateShadow(frame)
|
|
shadow.sfOverlay = true
|
|
|
|
-- 5) Free drag support with position persistence
|
|
frame:SetMovable(true)
|
|
frame:EnableMouse(true)
|
|
frame:SetClampedToScreen(true)
|
|
frame:RegisterForDrag("LeftButton")
|
|
frame:SetScript("OnDragStart", function()
|
|
this:StartMoving()
|
|
end)
|
|
frame:SetScript("OnDragStop", function()
|
|
this:StopMovingOrSizing()
|
|
local point, _, relPoint, xOfs, yOfs = this:GetPoint()
|
|
SFramesDB.petStablePos = {
|
|
point = point, relPoint = relPoint,
|
|
x = xOfs, y = yOfs,
|
|
}
|
|
end)
|
|
|
|
-- 6) Title
|
|
local titleFS = PetStableFrameTitleText
|
|
if titleFS then
|
|
titleFS:SetFont(font, 13, "OUTLINE")
|
|
titleFS:SetTextColor(T.title[1], T.title[2], T.title[3])
|
|
titleFS.sfKeep = true
|
|
end
|
|
|
|
-- 7) Close button
|
|
if PetStableFrameCloseButton then
|
|
StyleCloseButton(PetStableFrameCloseButton)
|
|
end
|
|
|
|
-- 8) Style pet info FontStrings (try various naming patterns)
|
|
local infoFS = {
|
|
"PetStablePetName", "PetStableSelectedPetName",
|
|
"PetStablePetLevel", "PetStableSelectedPetLevel",
|
|
"PetStablePetFamily", "PetStableSelectedPetFamily",
|
|
"PetStablePetLoyalty", "PetStableSelectedPetLoyalty",
|
|
}
|
|
for _, n in ipairs(infoFS) do
|
|
local fs = _G[n]
|
|
if fs and fs.SetFont then
|
|
fs:SetFont(font, 11, "OUTLINE")
|
|
fs:SetTextColor(T.text[1], T.text[2], T.text[3])
|
|
end
|
|
end
|
|
|
|
local labelFS = {
|
|
"PetStableDietLabel", "PetStableTypeLabel",
|
|
"PetStableNameLabel", "PetStableLevelLabel",
|
|
"PetStableLoyaltyLabel", "PetStableFamilyLabel",
|
|
"PetStableDietText",
|
|
}
|
|
for _, n in ipairs(labelFS) do
|
|
local fs = _G[n]
|
|
if fs and fs.SetFont then
|
|
fs:SetFont(font, 10, "OUTLINE")
|
|
fs:SetTextColor(T.dimText[1], T.dimText[2], T.dimText[3])
|
|
end
|
|
end
|
|
|
|
-- Also style any remaining FontStrings on the main frame
|
|
StyleFontStrings(frame, 11, T.text)
|
|
|
|
-- 9) Current pet slot
|
|
if PetStableCurrentPet then
|
|
StyleSlot(PetStableCurrentPet)
|
|
end
|
|
|
|
-- 10) Stable slots (dynamic count for Turtle WoW, check up to 20)
|
|
for i = 1, 20 do
|
|
local slot = _G["PetStableStableSlot" .. i]
|
|
if slot then
|
|
StyleSlot(slot)
|
|
end
|
|
end
|
|
-- Alternate naming pattern
|
|
for i = 1, 20 do
|
|
local slot = _G["PetStableSlot" .. i]
|
|
if slot and not slot.sfSkinned then
|
|
StyleSlot(slot)
|
|
end
|
|
end
|
|
|
|
-- 11) Purchase button
|
|
if PetStablePurchaseButton then
|
|
StyleActionButton(PetStablePurchaseButton)
|
|
end
|
|
|
|
-- 12) Model frame background (tagged so auto-compact ignores it)
|
|
if PetStableModel then
|
|
local modelBg = CreateFrame("Frame", nil, frame)
|
|
modelBg.sfOverlay = true
|
|
modelBg:SetPoint("TOPLEFT", PetStableModel, "TOPLEFT", -3, 3)
|
|
modelBg:SetPoint("BOTTOMRIGHT", PetStableModel, "BOTTOMRIGHT", 3, -3)
|
|
modelBg:SetBackdrop({
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true, tileSize = 16, edgeSize = 10,
|
|
insets = { left = 2, right = 2, top = 2, bottom = 2 },
|
|
})
|
|
modelBg:SetBackdropColor(
|
|
T.modelBg[1], T.modelBg[2], T.modelBg[3], T.modelBg[4] or 0.5)
|
|
modelBg:SetBackdropBorderColor(
|
|
T.modelBorder[1], T.modelBorder[2], T.modelBorder[3], T.modelBorder[4])
|
|
modelBg:SetFrameLevel(math.max(0, PetStableModel:GetFrameLevel() - 1))
|
|
end
|
|
|
|
-- 13) Food/diet icons
|
|
for i = 1, 10 do
|
|
local food = _G["PetStableFood" .. i] or _G["PetStableDietIcon" .. i]
|
|
if food and food.SetTexCoord then
|
|
food:SetTexCoord(0.08, 0.92, 0.08, 0.92)
|
|
end
|
|
end
|
|
|
|
-- 14) Any additional child frames that look like insets
|
|
local insets = {
|
|
"PetStableLeftInset", "PetStableBottomInset",
|
|
"PetStableRightInset", "PetStableTopInset",
|
|
}
|
|
for _, iname in ipairs(insets) do
|
|
local inset = _G[iname]
|
|
if inset then
|
|
NukeTextures(inset)
|
|
if inset.SetBackdrop then inset:SetBackdrop(nil) end
|
|
end
|
|
end
|
|
|
|
-- 14b) Cleanup: only target known decorative inset/background children
|
|
local knownFrames = {}
|
|
if PetStableModel then knownFrames[PetStableModel] = true end
|
|
if PetStableFrameCloseButton then knownFrames[PetStableFrameCloseButton] = true end
|
|
if PetStablePurchaseButton then knownFrames[PetStablePurchaseButton] = true end
|
|
if PetStableCurrentPet then knownFrames[PetStableCurrentPet] = true end
|
|
for si = 1, 20 do
|
|
local ss = _G["PetStableStableSlot" .. si]
|
|
if ss then knownFrames[ss] = true end
|
|
local ps = _G["PetStableSlot" .. si]
|
|
if ps then knownFrames[ps] = true end
|
|
end
|
|
local allCh = { frame:GetChildren() }
|
|
for _, child in ipairs(allCh) do
|
|
if not knownFrames[child] and not child.sfSkinned
|
|
and not child.sfOverlay and not child.sfBorder then
|
|
local cName = child:GetName() or ""
|
|
if string.find(cName, "Inset") or string.find(cName, "Bg")
|
|
or string.find(cName, "Border") or string.find(cName, "Tab") then
|
|
NukeTextures(child)
|
|
if child.SetBackdrop then child:SetBackdrop(nil) end
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Restore saved position (runs every time the frame is shown)
|
|
--------------------------------------------------------------------------------
|
|
local function RestorePosition()
|
|
if not PetStableFrame then return end
|
|
if not SFramesDB.petStablePos then return end
|
|
local pos = SFramesDB.petStablePos
|
|
PetStableFrame:ClearAllPoints()
|
|
PetStableFrame:SetPoint(pos.point, UIParent, pos.relPoint, pos.x, pos.y)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Event-driven skin application + position restore
|
|
--------------------------------------------------------------------------------
|
|
local eventFrame = CreateFrame("Frame")
|
|
eventFrame:RegisterEvent("PET_STABLE_SHOW")
|
|
eventFrame:SetScript("OnEvent", function()
|
|
if event == "PET_STABLE_SHOW" then
|
|
ApplySkin()
|
|
RestorePosition()
|
|
end
|
|
end)
|
|
|
|
if PetStableFrame then
|
|
local origOnShow = PetStableFrame:GetScript("OnShow")
|
|
PetStableFrame:SetScript("OnShow", function()
|
|
if origOnShow then origOnShow() end
|
|
ApplySkin()
|
|
RestorePosition()
|
|
end)
|
|
end
|