init
This commit is contained in:
346
GameMenu.lua
Normal file
346
GameMenu.lua
Normal file
@@ -0,0 +1,346 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- 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",
|
||||
["GameMenuButtonOptions"] = "settings",
|
||||
["GameMenuButtonSoundOptions"] = "sound",
|
||||
["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__",
|
||||
"GameMenuButtonOptions",
|
||||
"GameMenuButtonSoundOptions",
|
||||
"GameMenuButtonUIOptions",
|
||||
"GameMenuButtonKeybindings",
|
||||
"GameMenuButtonRatings",
|
||||
"GameMenuButtonMacros",
|
||||
"GameMenuButtonLogout",
|
||||
"GameMenuButtonQuit",
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- 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)
|
||||
|
||||
-- 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
|
||||
|
||||
-- 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)
|
||||
Reference in New Issue
Block a user