修复拾取界面点击无效问题 修复宠物训练界面不显示训练点问题 新增天赋分享到聊天界面 修复飞行界面无法关闭问题 修复术士宠物的显示问题 为天赋界面添加默认数据库支持 框架现在也可自主选择是否启用 玩家框架和目标框架可取消显示3D头像以及透明度修改 背包和银行也添加透明度自定义支持 优化tooltip性能和背包物品显示方式 修复布局模式在ui缩放后不能正常定位的问题 添加硬核模式危险和死亡的工会通报 添加拾取和已拾取的框体 等等
363 lines
13 KiB
Lua
363 lines
13 KiB
Lua
--------------------------------------------------------------------------------
|
|
-- Nanami-UI: Game Menu (GameMenu.lua)
|
|
-- Reskins the ESC menu (GameMenuFrame) with pink cat-paw theme
|
|
--------------------------------------------------------------------------------
|
|
|
|
SFrames.GameMenu = {}
|
|
|
|
local GM = SFrames.GameMenu
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Theme: Pink Cat-Paw
|
|
--------------------------------------------------------------------------------
|
|
local T = SFrames.ActiveTheme
|
|
|
|
local BUTTON_W = 170
|
|
local BUTTON_H = 26
|
|
local BUTTON_GAP = 5
|
|
local SIDE_PAD = 16
|
|
local HEADER_H = 32
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Helpers
|
|
--------------------------------------------------------------------------------
|
|
local function GetFont()
|
|
if SFrames and SFrames.GetFont then return SFrames:GetFont() end
|
|
return "Fonts\\ARIALN.TTF"
|
|
end
|
|
|
|
local function SetRoundBackdrop(frame, bgColor, borderColor)
|
|
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 },
|
|
})
|
|
local bg = bgColor or T.panelBg
|
|
local bd = borderColor or T.panelBorder
|
|
frame:SetBackdropColor(bg[1], bg[2], bg[3], bg[4] or 1)
|
|
frame:SetBackdropBorderColor(bd[1], bd[2], bd[3], bd[4] or 1)
|
|
end
|
|
|
|
local function CreateShadow(parent, size)
|
|
local s = CreateFrame("Frame", nil, parent)
|
|
local sz = size or 4
|
|
s:SetPoint("TOPLEFT", parent, "TOPLEFT", -sz, sz)
|
|
s:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", sz, -sz)
|
|
s:SetFrameLevel(math.max(parent:GetFrameLevel() - 1, 0))
|
|
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.55)
|
|
s:SetBackdropBorderColor(0, 0, 0, 0.4)
|
|
return s
|
|
end
|
|
|
|
local function HideTexture(tex)
|
|
if not tex then return end
|
|
if tex.SetTexture then tex:SetTexture(nil) end
|
|
if tex.SetAlpha then tex:SetAlpha(0) end
|
|
if tex.Hide then tex:Hide() end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Button Styling
|
|
--------------------------------------------------------------------------------
|
|
local MENU_BUTTON_ICONS = {
|
|
["GameMenuButtonContinue"] = "exit",
|
|
["GameMenuButtonUIOptions"] = "talent",
|
|
["GameMenuButtonKeybindings"] = "menu",
|
|
["GameMenuButtonRatings"] = "backpack",
|
|
["GameMenuButtonMacros"] = "ai",
|
|
["GameMenuButtonLogout"] = "close",
|
|
["GameMenuButtonQuit"] = "logout",
|
|
}
|
|
|
|
local function StyleMenuButton(btn)
|
|
if not btn or btn.nanamiStyled then return end
|
|
btn.nanamiStyled = true
|
|
|
|
HideTexture(btn:GetNormalTexture())
|
|
HideTexture(btn:GetPushedTexture())
|
|
HideTexture(btn:GetHighlightTexture())
|
|
HideTexture(btn:GetDisabledTexture())
|
|
|
|
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
|
|
|
|
SetRoundBackdrop(btn, T.btnBg, T.btnBorder)
|
|
btn:SetWidth(BUTTON_W)
|
|
btn:SetHeight(BUTTON_H)
|
|
|
|
local iconKey = MENU_BUTTON_ICONS[name]
|
|
local icoSize = 12
|
|
local gap = 4
|
|
local fs = btn:GetFontString()
|
|
if fs then
|
|
fs:SetFont(GetFont(), 11, "OUTLINE")
|
|
fs:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3])
|
|
fs:ClearAllPoints()
|
|
if iconKey and SFrames and SFrames.CreateIcon then
|
|
local ico = SFrames:CreateIcon(btn, iconKey, icoSize)
|
|
ico:SetDrawLayer("OVERLAY")
|
|
ico:SetVertexColor(T.btnText[1], T.btnText[2], T.btnText[3])
|
|
fs:SetPoint("CENTER", btn, "CENTER", (icoSize + gap) / 2, 0)
|
|
ico:SetPoint("RIGHT", fs, "LEFT", -gap, 0)
|
|
btn.nanamiIcon = ico
|
|
else
|
|
fs:SetPoint("CENTER", btn, "CENTER", 0, 0)
|
|
end
|
|
end
|
|
|
|
local origEnter = btn:GetScript("OnEnter")
|
|
local origLeave = btn:GetScript("OnLeave")
|
|
local origDown = btn:GetScript("OnMouseDown")
|
|
local origUp = btn:GetScript("OnMouseUp")
|
|
|
|
btn:SetScript("OnEnter", function()
|
|
if origEnter then origEnter() end
|
|
this:SetBackdropColor(T.btnHoverBg[1], T.btnHoverBg[2], T.btnHoverBg[3], T.btnHoverBg[4])
|
|
this:SetBackdropBorderColor(T.btnHoverBorder[1], T.btnHoverBorder[2], T.btnHoverBorder[3], T.btnHoverBorder[4])
|
|
local txt = this:GetFontString()
|
|
if txt then txt:SetTextColor(T.btnActiveText[1], T.btnActiveText[2], T.btnActiveText[3]) end
|
|
if this.nanamiIcon then this.nanamiIcon:SetVertexColor(T.btnActiveText[1], T.btnActiveText[2], T.btnActiveText[3]) end
|
|
end)
|
|
|
|
btn:SetScript("OnLeave", function()
|
|
if origLeave then origLeave() end
|
|
this:SetBackdropColor(T.btnBg[1], T.btnBg[2], T.btnBg[3], T.btnBg[4])
|
|
this:SetBackdropBorderColor(T.btnBorder[1], T.btnBorder[2], T.btnBorder[3], T.btnBorder[4])
|
|
local txt = this:GetFontString()
|
|
if txt then txt:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3]) end
|
|
if this.nanamiIcon then this.nanamiIcon:SetVertexColor(T.btnText[1], T.btnText[2], T.btnText[3]) end
|
|
end)
|
|
|
|
btn:SetScript("OnMouseDown", function()
|
|
if origDown then origDown() end
|
|
this:SetBackdropColor(T.btnDownBg[1], T.btnDownBg[2], T.btnDownBg[3], T.btnDownBg[4])
|
|
end)
|
|
|
|
btn:SetScript("OnMouseUp", function()
|
|
if origUp then origUp() end
|
|
this:SetBackdropColor(T.btnHoverBg[1], T.btnHoverBg[2], T.btnHoverBg[3], T.btnHoverBg[4])
|
|
end)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Create Settings Button
|
|
--------------------------------------------------------------------------------
|
|
local settingsBtn
|
|
|
|
local function CreateSettingsButton(parent)
|
|
if settingsBtn then return settingsBtn end
|
|
|
|
local btn = CreateFrame("Button", "GameMenuButtonNanamiUI", parent)
|
|
btn:SetWidth(BUTTON_W)
|
|
btn:SetHeight(BUTTON_H)
|
|
SetRoundBackdrop(btn, T.btnBg, T.btnBorder)
|
|
|
|
local icoSize = 14
|
|
local gap = 4
|
|
|
|
local fs = btn:CreateFontString(nil, "OVERLAY")
|
|
fs:SetFont(GetFont(), 11, "OUTLINE")
|
|
fs:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3])
|
|
fs:SetPoint("CENTER", btn, "CENTER", (icoSize + gap) / 2, 0)
|
|
fs:SetText("Nanami-UI 设置")
|
|
|
|
local ico = SFrames:CreateIcon(btn, "logo", icoSize)
|
|
ico:SetDrawLayer("OVERLAY")
|
|
ico:SetVertexColor(T.btnText[1], T.btnText[2], T.btnText[3])
|
|
ico:SetPoint("RIGHT", fs, "LEFT", -gap, 0)
|
|
btn.nanamiIcon = ico
|
|
|
|
btn:SetScript("OnClick", function()
|
|
HideUIPanel(GameMenuFrame)
|
|
if SFrames.ConfigUI and SFrames.ConfigUI.Build then
|
|
SFrames.ConfigUI:Build("ui")
|
|
end
|
|
end)
|
|
|
|
btn:SetScript("OnEnter", function()
|
|
this:SetBackdropColor(T.btnHoverBg[1], T.btnHoverBg[2], T.btnHoverBg[3], T.btnHoverBg[4])
|
|
this:SetBackdropBorderColor(T.btnHoverBorder[1], T.btnHoverBorder[2], T.btnHoverBorder[3], T.btnHoverBorder[4])
|
|
fs:SetTextColor(T.btnActiveText[1], T.btnActiveText[2], T.btnActiveText[3])
|
|
ico:SetVertexColor(T.btnActiveText[1], T.btnActiveText[2], T.btnActiveText[3])
|
|
end)
|
|
|
|
btn:SetScript("OnLeave", function()
|
|
this:SetBackdropColor(T.btnBg[1], T.btnBg[2], T.btnBg[3], T.btnBg[4])
|
|
this:SetBackdropBorderColor(T.btnBorder[1], T.btnBorder[2], T.btnBorder[3], T.btnBorder[4])
|
|
fs:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3])
|
|
ico:SetVertexColor(T.btnText[1], T.btnText[2], T.btnText[3])
|
|
end)
|
|
|
|
btn:SetScript("OnMouseDown", function()
|
|
this:SetBackdropColor(T.btnDownBg[1], T.btnDownBg[2], T.btnDownBg[3], T.btnDownBg[4])
|
|
end)
|
|
|
|
btn:SetScript("OnMouseUp", function()
|
|
this:SetBackdropColor(T.btnHoverBg[1], T.btnHoverBg[2], T.btnHoverBg[3], T.btnHoverBg[4])
|
|
end)
|
|
|
|
btn.nanamiStyled = true
|
|
settingsBtn = btn
|
|
return btn
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Known button priority order (covers vanilla + Turtle WoW extras)
|
|
--------------------------------------------------------------------------------
|
|
local BUTTON_ORDER = {
|
|
"GameMenuButtonContinue",
|
|
"__NANAMI_SETTINGS__",
|
|
"GameMenuButtonUIOptions",
|
|
"GameMenuButtonKeybindings",
|
|
"GameMenuButtonRatings",
|
|
"GameMenuButtonMacros",
|
|
"GameMenuButtonLogout",
|
|
"GameMenuButtonQuit",
|
|
}
|
|
|
|
local HIDDEN_BUTTONS = {
|
|
"GameMenuButtonOptions",
|
|
"GameMenuButtonSoundOptions",
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Frame Styling (called once at PLAYER_LOGIN, before first show)
|
|
--------------------------------------------------------------------------------
|
|
local styled = false
|
|
|
|
local function StyleGameMenuFrame()
|
|
if styled then return end
|
|
if not GameMenuFrame then return end
|
|
styled = true
|
|
|
|
-- Hide all default background textures and header text
|
|
local regions = { GameMenuFrame:GetRegions() }
|
|
for _, region in ipairs(regions) do
|
|
if region then
|
|
local otype = region:GetObjectType()
|
|
if otype == "Texture" then
|
|
region:SetTexture(nil)
|
|
region:SetAlpha(0)
|
|
region:Hide()
|
|
elseif otype == "FontString" then
|
|
region:SetAlpha(0)
|
|
region:Hide()
|
|
end
|
|
end
|
|
end
|
|
|
|
SetRoundBackdrop(GameMenuFrame, T.panelBg, T.panelBorder)
|
|
CreateShadow(GameMenuFrame, 5)
|
|
|
|
-- Title
|
|
local title = GameMenuFrame:CreateFontString(nil, "OVERLAY")
|
|
title:SetFont(GetFont(), 13, "OUTLINE")
|
|
title:SetTextColor(T.titleColor[1], T.titleColor[2], T.titleColor[3])
|
|
title:SetPoint("TOP", GameMenuFrame, "TOP", 0, -11)
|
|
title:SetText("Nanami-UI")
|
|
|
|
-- Create settings button
|
|
local sBt = CreateSettingsButton(GameMenuFrame)
|
|
|
|
-- Hide removed buttons (Video / Sound)
|
|
for _, name in ipairs(HIDDEN_BUTTONS) do
|
|
local btn = _G[name]
|
|
if btn then
|
|
btn:Hide()
|
|
btn:SetWidth(0.001)
|
|
btn:SetHeight(0.001)
|
|
btn:ClearAllPoints()
|
|
btn:SetPoint("TOPLEFT", GameMenuFrame, "TOPLEFT", 0, 0)
|
|
end
|
|
end
|
|
|
|
-- Build a lookup of known names for quick check
|
|
local knownSet = {}
|
|
for _, name in ipairs(BUTTON_ORDER) do
|
|
if name ~= "__NANAMI_SETTINGS__" then
|
|
knownSet[name] = true
|
|
end
|
|
end
|
|
for _, name in ipairs(HIDDEN_BUTTONS) do
|
|
knownSet[name] = true
|
|
end
|
|
|
|
-- Collect all child buttons that are NOT the settings button
|
|
local children = { GameMenuFrame:GetChildren() }
|
|
local unknownBtns = {}
|
|
for _, child in ipairs(children) do
|
|
if child and child:GetObjectType() == "Button" and child ~= sBt then
|
|
local cname = child:GetName()
|
|
if cname and not knownSet[cname] then
|
|
table.insert(unknownBtns, child)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Build final ordered button list from BUTTON_ORDER
|
|
local orderedBtns = {}
|
|
for _, name in ipairs(BUTTON_ORDER) do
|
|
if name == "__NANAMI_SETTINGS__" then
|
|
table.insert(orderedBtns, sBt)
|
|
else
|
|
local btn = _G[name]
|
|
if btn then
|
|
StyleMenuButton(btn)
|
|
table.insert(orderedBtns, btn)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Append unknown / Turtle WoW extra buttons before Logout & Quit
|
|
local insertBefore = table.getn(orderedBtns)
|
|
for i = table.getn(orderedBtns), 1, -1 do
|
|
local bname = orderedBtns[i]:GetName() or ""
|
|
if bname == "GameMenuButtonLogout" or bname == "GameMenuButtonQuit" then
|
|
insertBefore = i
|
|
else
|
|
break
|
|
end
|
|
end
|
|
for _, btn in ipairs(unknownBtns) do
|
|
StyleMenuButton(btn)
|
|
table.insert(orderedBtns, insertBefore, btn)
|
|
insertBefore = insertBefore + 1
|
|
end
|
|
|
|
-- Layout vertically
|
|
local numBtns = table.getn(orderedBtns)
|
|
local totalH = numBtns * BUTTON_H + (numBtns - 1) * BUTTON_GAP
|
|
local frameH = HEADER_H + SIDE_PAD + totalH + SIDE_PAD
|
|
local frameW = BUTTON_W + SIDE_PAD * 2
|
|
|
|
GameMenuFrame:SetWidth(frameW)
|
|
GameMenuFrame:SetHeight(frameH)
|
|
|
|
local startY = -(HEADER_H + SIDE_PAD)
|
|
for i, btn in ipairs(orderedBtns) do
|
|
btn:ClearAllPoints()
|
|
btn:SetPoint("TOP", GameMenuFrame, "TOP", 0, startY - (i - 1) * (BUTTON_H + BUTTON_GAP))
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Hook: style at login, BEFORE any show (avoids OnShow size-change issues)
|
|
--------------------------------------------------------------------------------
|
|
local hookFrame = CreateFrame("Frame")
|
|
hookFrame:RegisterEvent("PLAYER_LOGIN")
|
|
hookFrame:SetScript("OnEvent", function()
|
|
if GameMenuFrame then
|
|
StyleGameMenuFrame()
|
|
end
|
|
end)
|