1309 lines
48 KiB
Lua
1309 lines
48 KiB
Lua
--------------------------------------------------------------------------------
|
|
-- Nanami-UI: Quest Log Skin (QuestLogSkin.lua)
|
|
-- Reskins the default QuestLogFrame with Nanami-UI styled interface
|
|
-- Maintains full compatibility with pfquest and other quest addons
|
|
--------------------------------------------------------------------------------
|
|
|
|
SFrames = SFrames or {}
|
|
SFrames.QuestLogSkin = {}
|
|
local QLS = SFrames.QuestLogSkin
|
|
SFramesDB = SFramesDB or {}
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Theme (Pink Cat-Paw)
|
|
--------------------------------------------------------------------------------
|
|
local T = SFrames.Theme:Extend({
|
|
objectiveComplete = { 0.45, 0.90, 0.45 },
|
|
objectiveIncomplete = { 0.85, 0.78, 0.70 },
|
|
tagElite = { 1.0, 0.65, 0.20 },
|
|
tagDungeon = { 0.40, 0.70, 1.0 },
|
|
tagRaid = { 0.70, 0.45, 1.0 },
|
|
tagPvP = { 0.90, 0.30, 0.30 },
|
|
tagComplete = { 0.40, 0.90, 0.40 },
|
|
})
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Layout
|
|
--------------------------------------------------------------------------------
|
|
local FRAME_W = 595
|
|
local LIST_W = 250
|
|
local DETAIL_PAD = 8
|
|
local HEADER_H = 30
|
|
local BOTTOM_H = 36
|
|
local INNER_PAD = 6
|
|
local SCROLL_W = 14
|
|
local LIST_BTN_W = LIST_W - INNER_PAD * 2 - SCROLL_W - 4
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- State
|
|
--------------------------------------------------------------------------------
|
|
local skinApplied = false
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- 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)
|
|
local s = CreateFrame("Frame", nil, parent)
|
|
s:SetPoint("TOPLEFT", parent, "TOPLEFT", -4, 4)
|
|
s:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", 4, -4)
|
|
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.6)
|
|
s:SetBackdropBorderColor(0, 0, 0, 0.45)
|
|
return s
|
|
end
|
|
|
|
local function StripTextures(frame)
|
|
if not frame then return end
|
|
local regions = { frame:GetRegions() }
|
|
for i = 1, table.getn(regions) do
|
|
local region = regions[i]
|
|
if region and region.SetTexture and not region._nanamiKeep then
|
|
local drawLayer = region.GetDrawLayer and region:GetDrawLayer()
|
|
if drawLayer == "BACKGROUND" or drawLayer == "BORDER" or drawLayer == "ARTWORK" then
|
|
region:SetTexture(nil)
|
|
region:SetAlpha(0)
|
|
region:Hide()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function StripAllTextures(frame)
|
|
if not frame then return end
|
|
local regions = { frame:GetRegions() }
|
|
for i = 1, table.getn(regions) do
|
|
local region = regions[i]
|
|
if region and region.SetTexture and not region._nanamiKeep then
|
|
region:SetTexture(nil)
|
|
region:SetAlpha(0)
|
|
region:Hide()
|
|
end
|
|
end
|
|
end
|
|
|
|
local function StripNormalTexture(btn)
|
|
if not btn or not btn.GetNormalTexture then return end
|
|
local nt = btn:GetNormalTexture()
|
|
if nt then nt:SetTexture(nil); nt:SetAlpha(0) end
|
|
end
|
|
|
|
local function StripPushedTexture(btn)
|
|
if not btn or not btn.GetPushedTexture then return end
|
|
local pt = btn:GetPushedTexture()
|
|
if pt then pt:SetTexture(nil); pt:SetAlpha(0) end
|
|
end
|
|
|
|
local function StripHighlightTexture(btn)
|
|
if not btn or not btn.GetHighlightTexture then return end
|
|
local ht = btn:GetHighlightTexture()
|
|
if ht then ht:SetTexture(nil); ht:SetAlpha(0) end
|
|
end
|
|
|
|
local function StripDisabledTexture(btn)
|
|
if not btn or not btn.GetDisabledTexture then return end
|
|
local dt = btn:GetDisabledTexture()
|
|
if dt then dt:SetTexture(nil); dt:SetAlpha(0) end
|
|
end
|
|
|
|
local QUALITY_COLORS = {
|
|
[0] = { 0.62, 0.62, 0.62 }, [1] = { 1, 1, 1 },
|
|
[2] = { 0.12, 1, 0 }, [3] = { 0.0, 0.44, 0.87 },
|
|
[4] = { 0.64, 0.21, 0.93 }, [5] = { 1, 0.5, 0 },
|
|
}
|
|
|
|
local LINK_QUALITY_MAP = {
|
|
["9d9d9d"] = 0, ["ffffff"] = 1, ["1eff00"] = 2,
|
|
["0070dd"] = 3, ["a335ee"] = 4, ["ff8000"] = 5,
|
|
["e6cc80"] = 6,
|
|
}
|
|
|
|
local function QualityFromLink(link)
|
|
if not link then return nil end
|
|
local _, _, hex = string.find(link, "|c(%x%x%x%x%x%x%x%x)|")
|
|
if hex and string.len(hex) == 8 then
|
|
local color = string.lower(string.sub(hex, 3, 8))
|
|
return LINK_QUALITY_MAP[color]
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function GetQuestGreenRange()
|
|
local level = UnitLevel("player") or 60
|
|
if level <= 5 then return 0 end
|
|
if level <= 39 then return math.floor(level / 10) + 5 end
|
|
return math.floor(level / 5) + 1 + 8
|
|
end
|
|
|
|
local function GetDiffColor(level)
|
|
local pLvl = UnitLevel("player") or 60
|
|
local diff = (level or pLvl) - pLvl
|
|
if diff >= 5 then return 1, 0.10, 0.10
|
|
elseif diff >= 3 then return 1, 0.50, 0.25
|
|
elseif diff >= -2 then return 1, 1, 0
|
|
elseif diff >= -GetQuestGreenRange() then return 0.25, 0.75, 0.25
|
|
else return 0.50, 0.50, 0.50
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Scrollbar Skinning
|
|
--------------------------------------------------------------------------------
|
|
local function SkinScrollBar(scrollBarName)
|
|
local sb = _G[scrollBarName]
|
|
if not sb then return end
|
|
StripAllTextures(sb)
|
|
|
|
local track = sb:CreateTexture(nil, "BACKGROUND")
|
|
track:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
track:SetVertexColor(T.scrollTrack[1], T.scrollTrack[2], T.scrollTrack[3], T.scrollTrack[4])
|
|
track:SetWidth(6)
|
|
track:SetPoint("TOP", sb, "TOP", 0, -16)
|
|
track:SetPoint("BOTTOM", sb, "BOTTOM", 0, 16)
|
|
|
|
local thumb = sb:GetThumbTexture()
|
|
if thumb then
|
|
thumb:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
thumb:SetVertexColor(T.scrollThumb[1], T.scrollThumb[2], T.scrollThumb[3], T.scrollThumb[4])
|
|
thumb:SetWidth(6)
|
|
thumb:SetHeight(40)
|
|
end
|
|
|
|
for _, suffix in ipairs({"ScrollUpButton", "ScrollDownButton"}) do
|
|
local b = _G[scrollBarName .. suffix]
|
|
if b then
|
|
StripAllTextures(b)
|
|
StripNormalTexture(b)
|
|
StripPushedTexture(b)
|
|
StripDisabledTexture(b)
|
|
StripHighlightTexture(b)
|
|
b:SetWidth(6)
|
|
b:SetHeight(6)
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Action Button Skinning
|
|
--------------------------------------------------------------------------------
|
|
local btnDisabledBg = { 0.08, 0.04, 0.06, 0.60 }
|
|
local btnDisabledBd = { 0.22, 0.14, 0.18, 0.40 }
|
|
local btnDisabledText = { 0.35, 0.25, 0.30 }
|
|
|
|
local function RefreshButtonDisabledLook(btn)
|
|
if not btn then return end
|
|
local disabled = false
|
|
if btn.IsEnabled then
|
|
local ok, result = pcall(btn.IsEnabled, btn)
|
|
if ok then disabled = not result end
|
|
end
|
|
if disabled then
|
|
SetRoundBackdrop(btn, btnDisabledBg, btnDisabledBd)
|
|
if btn.GetFontString then
|
|
local fs = btn:GetFontString()
|
|
if fs then fs:SetTextColor(btnDisabledText[1], btnDisabledText[2], btnDisabledText[3]) end
|
|
end
|
|
else
|
|
SetRoundBackdrop(btn, T.btnBg, T.btnBorder)
|
|
if btn.GetFontString then
|
|
local fs = btn:GetFontString()
|
|
if fs then fs:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3]) end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SkinActionButton(btn)
|
|
if not btn or btn._nanamiActionSkinned then return end
|
|
btn._nanamiActionSkinned = true
|
|
StripAllTextures(btn)
|
|
StripNormalTexture(btn)
|
|
StripPushedTexture(btn)
|
|
StripHighlightTexture(btn)
|
|
SetRoundBackdrop(btn, T.btnBg, T.btnBorder)
|
|
|
|
if btn.GetFontString then
|
|
local fs = btn:GetFontString()
|
|
if fs then
|
|
fs:SetFont(GetFont(), 11, "OUTLINE")
|
|
fs:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3])
|
|
end
|
|
end
|
|
|
|
local origEnter = btn:GetScript("OnEnter")
|
|
btn:SetScript("OnEnter", function()
|
|
local disabled = false
|
|
if this.IsEnabled then
|
|
local ok, r = pcall(this.IsEnabled, this)
|
|
if ok then disabled = not r end
|
|
end
|
|
if disabled then
|
|
if origEnter then origEnter() end
|
|
return
|
|
end
|
|
SetRoundBackdrop(this, T.btnHoverBg, T.btnHoverBd)
|
|
if this.GetFontString then
|
|
local tfs = this:GetFontString()
|
|
if tfs then tfs:SetTextColor(T.btnActiveText[1], T.btnActiveText[2], T.btnActiveText[3]) end
|
|
end
|
|
if origEnter then origEnter() end
|
|
end)
|
|
local origLeave = btn:GetScript("OnLeave")
|
|
btn:SetScript("OnLeave", function()
|
|
local disabled = false
|
|
if this.IsEnabled then
|
|
local ok, r = pcall(this.IsEnabled, this)
|
|
if ok then disabled = not r end
|
|
end
|
|
if disabled then
|
|
RefreshButtonDisabledLook(this)
|
|
if origLeave then origLeave() end
|
|
return
|
|
end
|
|
SetRoundBackdrop(this, T.btnBg, T.btnBorder)
|
|
if this.GetFontString then
|
|
local tfs = this:GetFontString()
|
|
if tfs then tfs:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3]) end
|
|
end
|
|
if origLeave then origLeave() end
|
|
end)
|
|
btn:SetScript("OnMouseDown", function()
|
|
local disabled = false
|
|
if this.IsEnabled then
|
|
local ok, r = pcall(this.IsEnabled, this)
|
|
if ok then disabled = not r end
|
|
end
|
|
if disabled then return end
|
|
SetRoundBackdrop(this, T.btnDownBg, T.btnBorder)
|
|
end)
|
|
btn:SetScript("OnMouseUp", function()
|
|
local disabled = false
|
|
if this.IsEnabled then
|
|
local ok, r = pcall(this.IsEnabled, this)
|
|
if ok then disabled = not r end
|
|
end
|
|
if disabled then return end
|
|
SetRoundBackdrop(this, T.btnHoverBg, T.btnHoverBd)
|
|
end)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Reward Item Skinning
|
|
--------------------------------------------------------------------------------
|
|
local function SkinRewardItem(btn)
|
|
if not btn or btn._nanamiSkinned then return end
|
|
btn._nanamiSkinned = true
|
|
|
|
local bname = btn:GetName() or ""
|
|
|
|
local iconTex = _G[bname .. "IconTexture"]
|
|
if iconTex then iconTex._nanamiKeep = true end
|
|
|
|
StripAllTextures(btn)
|
|
StripNormalTexture(btn)
|
|
SetRoundBackdrop(btn, T.rewardBg, T.rewardBorder)
|
|
|
|
if iconTex then
|
|
iconTex:SetTexCoord(0.08, 0.92, 0.08, 0.92)
|
|
iconTex:ClearAllPoints()
|
|
iconTex:SetPoint("LEFT", btn, "LEFT", 4, 0)
|
|
iconTex:SetWidth(30); iconTex:SetHeight(30)
|
|
iconTex:SetAlpha(1)
|
|
iconTex:Show()
|
|
end
|
|
local nameFrame = _G[bname .. "NameFrame"]
|
|
if nameFrame then nameFrame:SetTexture(nil); nameFrame:SetAlpha(0) end
|
|
local nameText = _G[bname .. "Name"]
|
|
if nameText then
|
|
nameText:SetFont(GetFont(), 11, "OUTLINE")
|
|
nameText:SetTextColor(T.nameText[1], T.nameText[2], T.nameText[3])
|
|
end
|
|
local countText = _G[bname .. "Count"]
|
|
if countText then countText:SetFont(GetFont(), 10, "OUTLINE") end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Quest Log Item Quality Coloring
|
|
--------------------------------------------------------------------------------
|
|
local function GetQuestLogItemQuality(itemType, index)
|
|
if itemType == "choice" and GetQuestLogChoiceInfo then
|
|
local ok, name, tex, num, q, usable = pcall(GetQuestLogChoiceInfo, index)
|
|
if ok and q and q > 0 then return q end
|
|
elseif itemType == "reward" and GetQuestLogRewardInfo then
|
|
local ok, name, tex, num, q, usable = pcall(GetQuestLogRewardInfo, index)
|
|
if ok and q and q > 0 then return q end
|
|
end
|
|
if GetQuestLogItemLink then
|
|
local ok, link = pcall(GetQuestLogItemLink, itemType, index)
|
|
if ok and link then
|
|
local q = QualityFromLink(link)
|
|
if q then return q end
|
|
if GetItemInfo then
|
|
local ok2, _, _, iq = pcall(GetItemInfo, link)
|
|
if ok2 and iq and iq > 0 then return iq end
|
|
end
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function ApplyQuestLogItemQuality()
|
|
local choiceIdx = 0
|
|
local rewardIdx = 0
|
|
for i = 1, 10 do
|
|
local item = _G["QuestLogItem" .. i]
|
|
if not item or not item:IsVisible() then break end
|
|
|
|
local bname = item:GetName() or ""
|
|
local nameText = _G[bname .. "Name"]
|
|
if not nameText then break end
|
|
|
|
local itemType = item.type
|
|
local idx = 0
|
|
if itemType == "choice" then
|
|
choiceIdx = choiceIdx + 1
|
|
idx = choiceIdx
|
|
elseif itemType == "reward" then
|
|
rewardIdx = rewardIdx + 1
|
|
idx = rewardIdx
|
|
else
|
|
break
|
|
end
|
|
|
|
local quality = GetQuestLogItemQuality(itemType, idx)
|
|
local qc = quality and QUALITY_COLORS[quality]
|
|
if qc and quality >= 2 then
|
|
nameText:SetTextColor(qc[1], qc[2], qc[3])
|
|
item:SetBackdropBorderColor(qc[1], qc[2], qc[3], 0.8)
|
|
elseif qc and quality == 1 then
|
|
nameText:SetTextColor(T.nameText[1], T.nameText[2], T.nameText[3])
|
|
item:SetBackdropBorderColor(T.rewardBorder[1], T.rewardBorder[2], T.rewardBorder[3], T.rewardBorder[4])
|
|
else
|
|
nameText:SetTextColor(T.nameText[1], T.nameText[2], T.nameText[3])
|
|
item:SetBackdropBorderColor(T.rewardBorder[1], T.rewardBorder[2], T.rewardBorder[3], T.rewardBorder[4])
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Tag Color for elite/dungeon/raid/pvp/complete
|
|
--------------------------------------------------------------------------------
|
|
local function GetTagColor(tagText)
|
|
if not tagText or tagText == "" then return nil end
|
|
local t = string.lower(tagText)
|
|
if string.find(t, "elite") or string.find(t, "精英") then
|
|
return T.tagElite
|
|
elseif string.find(t, "dungeon") or string.find(t, "地下城") then
|
|
return T.tagDungeon
|
|
elseif string.find(t, "raid") or string.find(t, "团队") then
|
|
return T.tagRaid
|
|
elseif string.find(t, "pvp") then
|
|
return T.tagPvP
|
|
elseif string.find(t, "complete") or string.find(t, "完成") then
|
|
return T.tagComplete
|
|
end
|
|
return T.dimText
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Main Frame Skinning
|
|
--------------------------------------------------------------------------------
|
|
local function SkinMainFrame()
|
|
local f = QuestLogFrame
|
|
if not f then return end
|
|
|
|
-- Resize frame to remove excess right-side space
|
|
f:SetWidth(FRAME_W)
|
|
|
|
StripTextures(f)
|
|
SetRoundBackdrop(f, T.panelBg, T.panelBorder)
|
|
CreateShadow(f)
|
|
|
|
for _, pName in ipairs({"QuestLogFramePortrait", "QuestLogPortrait"}) do
|
|
local p = _G[pName]
|
|
if p then p:SetTexture(nil); p:SetAlpha(0); p:Hide() end
|
|
end
|
|
|
|
local titleText = QuestLogTitleText
|
|
if titleText then
|
|
titleText:SetFont(GetFont(), 14, "OUTLINE")
|
|
titleText:SetTextColor(T.gold[1], T.gold[2], T.gold[3])
|
|
titleText:ClearAllPoints()
|
|
titleText:SetPoint("LEFT", f, "TOPLEFT", 14, -15)
|
|
end
|
|
|
|
-- Quest count to top-right
|
|
local questCount = QuestLogQuestCount
|
|
if questCount then
|
|
questCount:SetFont(GetFont(), 11, "OUTLINE")
|
|
questCount:SetTextColor(T.countText[1], T.countText[2], T.countText[3])
|
|
questCount:ClearAllPoints()
|
|
questCount:SetPoint("RIGHT", f, "TOPRIGHT", -30, -15)
|
|
end
|
|
|
|
local closeBtn = _G["QuestLogFrameCloseButton"]
|
|
if closeBtn then
|
|
closeBtn:ClearAllPoints()
|
|
closeBtn:SetPoint("TOPRIGHT", f, "TOPRIGHT", -2, -2)
|
|
closeBtn:SetWidth(22); closeBtn:SetHeight(22)
|
|
closeBtn:SetFrameLevel(f:GetFrameLevel() + 10)
|
|
end
|
|
|
|
-- Make frame draggable and respond to ESC
|
|
if UIPanelWindows then
|
|
UIPanelWindows["QuestLogFrame"] = nil
|
|
end
|
|
table.insert(UISpecialFrames, "QuestLogFrame")
|
|
f:SetMovable(true)
|
|
f:EnableMouse(true)
|
|
f:SetClampedToScreen(true)
|
|
f:RegisterForDrag("LeftButton")
|
|
f:SetScript("OnDragStart", function() this:StartMoving() end)
|
|
f:SetScript("OnDragStop", function() this:StopMovingOrSizing() end)
|
|
|
|
-- Header separator
|
|
local sep = f:CreateTexture(nil, "ARTWORK")
|
|
sep:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
sep:SetHeight(1)
|
|
sep:SetPoint("TOPLEFT", f, "TOPLEFT", 8, -HEADER_H)
|
|
sep:SetPoint("TOPRIGHT", f, "TOPRIGHT", -8, -HEADER_H)
|
|
sep:SetVertexColor(T.sepColor[1], T.sepColor[2], T.sepColor[3], T.sepColor[4])
|
|
|
|
-- Bottom separator
|
|
local bsep = f:CreateTexture(nil, "ARTWORK")
|
|
bsep:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
bsep:SetHeight(1)
|
|
bsep:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 8, BOTTOM_H)
|
|
bsep:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -8, BOTTOM_H)
|
|
bsep:SetVertexColor(T.sepColor[1], T.sepColor[2], T.sepColor[3], T.sepColor[4])
|
|
|
|
-- Detect and preserve Turtle WoW translate / ? buttons
|
|
-- Also find any unrecognized buttons and ensure they remain visible
|
|
local knownPrefixes = {
|
|
"QuestLogTitle", "QuestLogFrame", "QuestLogCollapseAll",
|
|
"QuestLogTrack", "QuestFramePush", "pfQuest",
|
|
}
|
|
local function isKnownButton(child)
|
|
if child._nanamiPfSkinned or child._nanamiBottomBtn
|
|
or child._nanamiActionSkinned then return true end
|
|
local cname = child:GetName() or ""
|
|
if cname == "" then return false end
|
|
for ki = 1, table.getn(knownPrefixes) do
|
|
if string.find(cname, knownPrefixes[ki]) then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
f._skinExtraButtons = function()
|
|
local searchParents = {}
|
|
table.insert(searchParents, f)
|
|
local dc = _G["QuestLogDetailScrollFrameChildFrame"]
|
|
or _G["QuestLogDetailScrollFrameChild"]
|
|
if dc then table.insert(searchParents, dc) end
|
|
local ds = QuestLogDetailScrollFrame
|
|
if ds then table.insert(searchParents, ds) end
|
|
|
|
local detailLevel = (f._nanamiDetailPanel and f._nanamiDetailPanel:GetFrameLevel()) or (f:GetFrameLevel() + 2)
|
|
|
|
for pi = 1, table.getn(searchParents) do
|
|
local parent = searchParents[pi]
|
|
if parent and parent.GetChildren then
|
|
local children = { parent:GetChildren() }
|
|
for ci = 1, table.getn(children) do
|
|
local child = children[ci]
|
|
if child and child.GetObjectType then
|
|
local objType = child:GetObjectType()
|
|
if objType == "Button" and not isKnownButton(child) then
|
|
-- Ensure button is visible above detailPanel
|
|
if child:GetFrameLevel() <= detailLevel then
|
|
child:SetFrameLevel(detailLevel + 3)
|
|
end
|
|
child:Show()
|
|
SkinPfQuestButton(child)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Also search for globally named Turtle WoW translate buttons
|
|
for _, gname in ipairs({
|
|
"QuestTranslateButton", "QuestLogTranslateButton",
|
|
"QuestInfoTranslateButton", "TurtleTranslateButton",
|
|
"QuestTranslationButton", "QuestHelpButton",
|
|
}) do
|
|
local gb = _G[gname]
|
|
if gb and gb.GetObjectType and not gb._nanamiPfSkinned then
|
|
gb:Show()
|
|
if gb:GetFrameLevel() <= detailLevel then
|
|
gb:SetFrameLevel(detailLevel + 3)
|
|
end
|
|
SkinPfQuestButton(gb)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Quest List Panel Skinning
|
|
--------------------------------------------------------------------------------
|
|
local function SkinQuestList()
|
|
local listFrame = QuestLogListScrollFrame
|
|
if not listFrame then return end
|
|
local f = QuestLogFrame
|
|
|
|
local listPanel = CreateFrame("Frame", nil, f)
|
|
listPanel:SetPoint("TOPLEFT", f, "TOPLEFT", DETAIL_PAD, -(HEADER_H + 2))
|
|
listPanel:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", DETAIL_PAD, BOTTOM_H + 2)
|
|
listPanel:SetWidth(LIST_W)
|
|
SetRoundBackdrop(listPanel, T.listBg, T.listBorder)
|
|
listPanel:SetFrameLevel(f:GetFrameLevel() + 1)
|
|
f._nanamiListPanel = listPanel
|
|
|
|
listFrame:ClearAllPoints()
|
|
listFrame:SetPoint("TOPLEFT", listPanel, "TOPLEFT", INNER_PAD, -INNER_PAD)
|
|
listFrame:SetPoint("BOTTOMRIGHT", listPanel, "BOTTOMRIGHT", -(SCROLL_W + INNER_PAD), 4)
|
|
listFrame:SetWidth(LIST_W - INNER_PAD * 2 - SCROLL_W)
|
|
|
|
StripTextures(listFrame)
|
|
SkinScrollBar("QuestLogListScrollFrameScrollBar")
|
|
|
|
local collapseAll = QuestLogCollapseAllButton
|
|
if collapseAll then
|
|
StripNormalTexture(collapseAll)
|
|
StripPushedTexture(collapseAll)
|
|
StripHighlightTexture(collapseAll)
|
|
end
|
|
|
|
local highlight = _G["QuestLogHighlightFrame"]
|
|
if highlight then
|
|
StripAllTextures(highlight)
|
|
highlight:SetBackdrop({
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
tile = true, tileSize = 16,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 },
|
|
})
|
|
highlight:SetBackdropColor(T.questSelected[1], T.questSelected[2], T.questSelected[3], T.questSelected[4])
|
|
|
|
local hlBar = highlight:CreateTexture(nil, "OVERLAY")
|
|
hlBar:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
hlBar:SetWidth(3)
|
|
hlBar:SetPoint("TOPLEFT", highlight, "TOPLEFT", 0, 0)
|
|
hlBar:SetPoint("BOTTOMLEFT", highlight, "BOTTOMLEFT", 0, 0)
|
|
hlBar:SetVertexColor(T.questSelBar[1], T.questSelBar[2], T.questSelBar[3], T.questSelBar[4])
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Quest Detail Panel Skinning
|
|
--------------------------------------------------------------------------------
|
|
local function SkinQuestDetail()
|
|
local detailFrame = QuestLogDetailScrollFrame
|
|
if not detailFrame then return end
|
|
local f = QuestLogFrame
|
|
|
|
local DETAIL_W = FRAME_W - LIST_W - DETAIL_PAD * 2 - 4
|
|
|
|
local detailPanel = CreateFrame("Frame", nil, f)
|
|
detailPanel:SetPoint("TOPLEFT", f, "TOPLEFT", LIST_W + DETAIL_PAD + 4, -(HEADER_H + 2))
|
|
detailPanel:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -DETAIL_PAD, BOTTOM_H + 2)
|
|
SetRoundBackdrop(detailPanel, T.detailBg, T.detailBorder)
|
|
detailPanel:SetFrameLevel(f:GetFrameLevel() + 1)
|
|
f._nanamiDetailPanel = detailPanel
|
|
|
|
detailFrame:ClearAllPoints()
|
|
detailFrame:SetPoint("TOPLEFT", detailPanel, "TOPLEFT", INNER_PAD, -INNER_PAD)
|
|
detailFrame:SetPoint("BOTTOMRIGHT", detailPanel, "BOTTOMRIGHT", -(SCROLL_W + INNER_PAD), INNER_PAD)
|
|
detailFrame:SetFrameLevel(detailPanel:GetFrameLevel() + 2)
|
|
|
|
StripTextures(detailFrame)
|
|
SkinScrollBar("QuestLogDetailScrollFrameScrollBar")
|
|
|
|
local contentW = DETAIL_W - INNER_PAD * 2 - SCROLL_W - 6
|
|
local detailChild = _G["QuestLogDetailScrollFrameChildFrame"]
|
|
or _G["QuestLogDetailScrollFrameChild"]
|
|
if detailChild and contentW > 100 then
|
|
detailChild:SetWidth(contentW)
|
|
end
|
|
|
|
if QuestLogNoQuestsText then
|
|
QuestLogNoQuestsText:SetFont(GetFont(), 13)
|
|
QuestLogNoQuestsText:SetTextColor(T.dimText[1], T.dimText[2], T.dimText[3])
|
|
end
|
|
if EmptyQuestLogFrame then
|
|
StripTextures(EmptyQuestLogFrame)
|
|
local et = _G["EmptyQuestLogFrameText"]
|
|
if et then
|
|
et:SetFont(GetFont(), 13)
|
|
et:SetTextColor(T.dimText[1], T.dimText[2], T.dimText[3])
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Bottom Buttons Skinning
|
|
--------------------------------------------------------------------------------
|
|
local function SkinBottomButtons()
|
|
local f = QuestLogFrame
|
|
local btnW = math.floor((FRAME_W - 40) / 3)
|
|
if btnW > 120 then btnW = 120 end
|
|
if btnW < 80 then btnW = 80 end
|
|
|
|
local abandonBtn = QuestLogFrameAbandonButton
|
|
if abandonBtn then
|
|
SkinActionButton(abandonBtn)
|
|
abandonBtn:SetHeight(24)
|
|
abandonBtn:ClearAllPoints()
|
|
abandonBtn:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 12, 6)
|
|
abandonBtn:SetWidth(btnW)
|
|
abandonBtn._nanamiBottomBtn = true
|
|
end
|
|
|
|
local shareBtn = _G["QuestLogFramePushQuestButton"] or _G["QuestFramePushQuestButton"]
|
|
if shareBtn then
|
|
SkinActionButton(shareBtn)
|
|
shareBtn:SetHeight(24)
|
|
shareBtn:ClearAllPoints()
|
|
shareBtn:SetPoint("BOTTOM", f, "BOTTOM", 0, 6)
|
|
shareBtn:SetWidth(btnW)
|
|
shareBtn._nanamiBottomBtn = true
|
|
shareBtn._nanamiOrigText = nil
|
|
if shareBtn.GetFontString then
|
|
local fs = shareBtn:GetFontString()
|
|
if fs then shareBtn._nanamiOrigText = fs:GetText() end
|
|
end
|
|
|
|
shareBtn._nanamiRefreshShare = function(sb)
|
|
if not sb then return end
|
|
local canShare = GetQuestLogPushable and GetQuestLogPushable()
|
|
local fs = sb.GetFontString and sb:GetFontString()
|
|
if not canShare then
|
|
SetRoundBackdrop(sb, btnDisabledBg, btnDisabledBd)
|
|
if fs then
|
|
fs:SetTextColor(btnDisabledText[1], btnDisabledText[2], btnDisabledText[3])
|
|
end
|
|
else
|
|
SetRoundBackdrop(sb, T.btnBg, T.btnBorder)
|
|
if fs then
|
|
fs:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3])
|
|
end
|
|
end
|
|
end
|
|
|
|
shareBtn._nanamiRefreshShare(shareBtn)
|
|
|
|
local sharePoll = CreateFrame("Frame", nil, shareBtn)
|
|
sharePoll._t = 0
|
|
sharePoll:SetScript("OnUpdate", function()
|
|
this._t = (this._t or 0) + (arg1 or 0)
|
|
if this._t < 1.0 then return end
|
|
this._t = 0
|
|
local sb = this:GetParent()
|
|
if sb and sb._nanamiRefreshShare then sb._nanamiRefreshShare(sb) end
|
|
end)
|
|
end
|
|
|
|
-- Search for exit button by multiple names and text content
|
|
local exitBtn = nil
|
|
for _, eName in ipairs({
|
|
"QuestLogFrameExitButton", "QuestLogExitButton",
|
|
"QuestLogCancelButton", "QuestLogCloseButton",
|
|
"QuestLogFrameCancelButton",
|
|
}) do
|
|
if _G[eName] then exitBtn = _G[eName]; break end
|
|
end
|
|
|
|
-- Fallback: find any bottom button with "退出"/"Exit"/"Close" text
|
|
if not exitBtn then
|
|
local children = { f:GetChildren() }
|
|
for ci = 1, table.getn(children) do
|
|
local child = children[ci]
|
|
if child and child.GetObjectType and child:GetObjectType() == "Button"
|
|
and child.GetFontString then
|
|
local cfs = child:GetFontString()
|
|
if cfs then
|
|
local txt = cfs:GetText()
|
|
if txt and (string.find(txt, "退出") or string.find(txt, "Exit")
|
|
or string.find(txt, "Close") or string.find(txt, "关闭")) then
|
|
exitBtn = child
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if exitBtn then
|
|
SkinActionButton(exitBtn)
|
|
exitBtn:SetHeight(24)
|
|
exitBtn:ClearAllPoints()
|
|
exitBtn:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -12, 6)
|
|
exitBtn:SetWidth(btnW)
|
|
exitBtn._nanamiBottomBtn = true
|
|
end
|
|
|
|
-- Also skin any other unskinned bottom-area buttons (Turtle WoW additions)
|
|
local children = { f:GetChildren() }
|
|
for ci = 1, table.getn(children) do
|
|
local child = children[ci]
|
|
if child and child.GetObjectType and child:GetObjectType() == "Button"
|
|
and not child._nanamiBottomBtn and not child._nanamiPfSkinned
|
|
and not child._nanamiActionSkinned then
|
|
-- Check if this button is near the bottom of the frame
|
|
local point = child.GetPoint and child:GetPoint()
|
|
if point and (point == "BOTTOMLEFT" or point == "BOTTOMRIGHT" or point == "BOTTOM") then
|
|
if child.GetFontString then
|
|
local cfs = child:GetFontString()
|
|
if cfs then
|
|
local txt = cfs:GetText()
|
|
if txt and txt ~= "" then
|
|
SkinActionButton(child)
|
|
child._nanamiBottomBtn = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Quest List Entries Restyling
|
|
--------------------------------------------------------------------------------
|
|
local function GetHighlightAnchorBtn()
|
|
local hl = _G["QuestLogHighlightFrame"]
|
|
if hl and hl.IsVisible and hl:IsVisible() and hl.GetPoint then
|
|
local ok, _, anchor = pcall(hl.GetPoint, hl)
|
|
if ok and anchor then return anchor end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function StyleQuestListEntries()
|
|
local numEntries, numQuests = 0, 0
|
|
if GetNumQuestLogEntries then
|
|
numEntries, numQuests = GetNumQuestLogEntries()
|
|
end
|
|
local questsDisplayed = QUESTS_DISPLAYED or 22
|
|
local hlBtn = GetHighlightAnchorBtn()
|
|
|
|
for i = 1, questsDisplayed do
|
|
local btn = _G["QuestLogTitle" .. i]
|
|
if not btn then break end
|
|
|
|
if not btn._nanamiSkinned then
|
|
StripPushedTexture(btn)
|
|
|
|
local nt = _G["QuestLogTitle" .. i .. "NormalText"]
|
|
if nt then nt:SetFont(GetFont(), 11) end
|
|
local tg = _G["QuestLogTitle" .. i .. "Tag"]
|
|
if tg then tg:SetFont(GetFont(), 10, "OUTLINE") end
|
|
|
|
local origHL = btn:GetHighlightTexture()
|
|
if origHL then
|
|
origHL:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
origHL:SetVertexColor(T.questHover[1], T.questHover[2], T.questHover[3], T.questHover[4])
|
|
origHL:SetAllPoints(btn)
|
|
origHL:SetBlendMode("ADD")
|
|
end
|
|
|
|
btn._nanamiCollapse = btn:CreateFontString(nil, "OVERLAY")
|
|
btn._nanamiCollapse:SetFont(GetFont(), 12, "OUTLINE")
|
|
btn._nanamiCollapse:SetPoint("LEFT", btn, "LEFT", 2, 0)
|
|
btn._nanamiCollapse:SetTextColor(T.collapseIcon[1], T.collapseIcon[2], T.collapseIcon[3])
|
|
btn._nanamiCollapse:Hide()
|
|
|
|
btn._nanamiTrackBar = btn:CreateTexture(nil, "OVERLAY")
|
|
btn._nanamiTrackBar:SetTexture("Interface\\Buttons\\WHITE8X8")
|
|
btn._nanamiTrackBar:SetWidth(3)
|
|
btn._nanamiTrackBar:SetPoint("TOPRIGHT", btn, "TOPRIGHT", 0, 0)
|
|
btn._nanamiTrackBar:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 0, 0)
|
|
btn._nanamiTrackBar:SetVertexColor(T.trackBar[1], T.trackBar[2], T.trackBar[3], 1)
|
|
btn._nanamiTrackBar:Hide()
|
|
|
|
btn._nanamiTrackLabel = btn:CreateFontString(nil, "OVERLAY")
|
|
btn._nanamiTrackLabel:SetFont(GetFont(), 9, "OUTLINE")
|
|
btn._nanamiTrackLabel:SetPoint("RIGHT", btn, "RIGHT", -6, 0)
|
|
btn._nanamiTrackLabel:SetTextColor(T.trackBar[1], T.trackBar[2], T.trackBar[3], 1)
|
|
btn._nanamiTrackLabel:Hide()
|
|
|
|
local gmFS = _G["QuestLogTitle" .. i .. "GroupMates"]
|
|
if gmFS and gmFS.SetFont then
|
|
gmFS:SetFont(GetFont(), 10, "OUTLINE")
|
|
end
|
|
|
|
btn._nanamiSkinned = true
|
|
end
|
|
|
|
btn:SetWidth(LIST_BTN_W)
|
|
|
|
local normalText = _G["QuestLogTitle" .. i .. "NormalText"]
|
|
local tagFS = _G["QuestLogTitle" .. i .. "Tag"]
|
|
|
|
if btn:IsVisible() and normalText then
|
|
normalText:SetWidth(LIST_BTN_W - 30)
|
|
|
|
local questIndex = btn.questLogIndex
|
|
local isSelected = (btn == hlBtn) and not btn.isHeader
|
|
|
|
if btn.isHeader then
|
|
normalText:SetTextColor(T.zoneHeader[1], T.zoneHeader[2], T.zoneHeader[3])
|
|
if btn._nanamiCollapse then
|
|
local collapsed = false
|
|
if btn.IsExpanded then
|
|
collapsed = not btn:IsExpanded()
|
|
elseif btn.IsCollapsed then
|
|
collapsed = btn:IsCollapsed()
|
|
end
|
|
local ntex = btn.GetNormalTexture and btn:GetNormalTexture()
|
|
if ntex then
|
|
local tex = ntex.GetTexture and ntex:GetTexture()
|
|
if tex then
|
|
tex = string.lower(tex)
|
|
if string.find(tex, "plus") or string.find(tex, "expand") then
|
|
collapsed = true
|
|
elseif string.find(tex, "minus") or string.find(tex, "collapse") then
|
|
collapsed = false
|
|
end
|
|
end
|
|
ntex:SetAlpha(0)
|
|
end
|
|
btn._nanamiCollapse:SetText(collapsed and "+" or "-")
|
|
btn._nanamiCollapse:Show()
|
|
end
|
|
if btn._nanamiTrackBar then btn._nanamiTrackBar:Hide() end
|
|
if btn._nanamiTrackLabel then btn._nanamiTrackLabel:Hide() end
|
|
if tagFS then tagFS:SetText("") end
|
|
else
|
|
local diffR, diffG, diffB
|
|
if questIndex and GetQuestLogTitle then
|
|
local _, level = GetQuestLogTitle(questIndex)
|
|
if level and level > 0 then
|
|
if GetQuestDifficultyColor then
|
|
local c = GetQuestDifficultyColor(level)
|
|
if c then diffR, diffG, diffB = c.r, c.g, c.b end
|
|
end
|
|
if not diffR then
|
|
diffR, diffG, diffB = GetDiffColor(level)
|
|
end
|
|
end
|
|
end
|
|
if diffR then
|
|
normalText:SetTextColor(diffR, diffG, diffB)
|
|
elseif btn.GetTextColor then
|
|
local cr, cg, cb = btn:GetTextColor()
|
|
if cr then normalText:SetTextColor(cr, cg, cb) end
|
|
end
|
|
|
|
if isSelected then
|
|
normalText:SetTextColor(1, 1, 1)
|
|
end
|
|
|
|
if btn._nanamiCollapse then btn._nanamiCollapse:Hide() end
|
|
|
|
local check = _G["QuestLogTitle" .. i .. "Check"]
|
|
local isTracked = check and check.IsVisible and check:IsVisible()
|
|
if btn._nanamiTrackBar then
|
|
if isTracked then btn._nanamiTrackBar:Show() else btn._nanamiTrackBar:Hide() end
|
|
end
|
|
if btn._nanamiTrackLabel then btn._nanamiTrackLabel:Hide() end
|
|
if check then
|
|
if isTracked then
|
|
check:SetVertexColor(T.trackBar[1], T.trackBar[2], T.trackBar[3], 1)
|
|
check:SetWidth(14)
|
|
check:SetHeight(14)
|
|
else
|
|
check:SetWidth(12)
|
|
check:SetHeight(12)
|
|
end
|
|
end
|
|
|
|
if tagFS then
|
|
local tagText = tagFS:GetText()
|
|
if tagText and tagText ~= "" then
|
|
if isSelected then
|
|
tagFS:SetTextColor(1, 1, 1)
|
|
elseif diffR then
|
|
tagFS:SetTextColor(diffR, diffG, diffB)
|
|
elseif btn.GetTextColor then
|
|
local cr, cg, cb = btn:GetTextColor()
|
|
if cr then tagFS:SetTextColor(cr, cg, cb) end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- check icon is handled in the tracking section above
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Quest Detail Text Restyling
|
|
--------------------------------------------------------------------------------
|
|
local function StyleQuestDetailText()
|
|
local titleFS = _G["QuestLogQuestTitle"]
|
|
if titleFS then
|
|
titleFS:SetFont(GetFont(), 14, "OUTLINE")
|
|
titleFS:SetTextColor(T.gold[1], T.gold[2], T.gold[3])
|
|
end
|
|
|
|
local descFS = _G["QuestLogQuestDescription"]
|
|
if descFS then
|
|
descFS:SetFont(GetFont(), 12)
|
|
descFS:SetTextColor(T.bodyText[1], T.bodyText[2], T.bodyText[3])
|
|
end
|
|
|
|
local objectivesTitle = _G["QuestLogObjectivesText"]
|
|
if objectivesTitle then
|
|
objectivesTitle:SetFont(GetFont(), 12)
|
|
objectivesTitle:SetTextColor(T.sectionTitle[1], T.sectionTitle[2], T.sectionTitle[3])
|
|
end
|
|
|
|
local descTitle = _G["QuestLogDescriptionTitle"]
|
|
if descTitle then
|
|
descTitle:SetFont(GetFont(), 12, "OUTLINE")
|
|
descTitle:SetTextColor(T.sectionTitle[1], T.sectionTitle[2], T.sectionTitle[3])
|
|
end
|
|
|
|
for i = 1, 20 do
|
|
local objFS = _G["QuestLogObjective" .. i]
|
|
if not objFS then break end
|
|
objFS:SetFont(GetFont(), 11)
|
|
local text = objFS:GetText()
|
|
if text then
|
|
local _, _, done, needed = string.find(text, "(%d+)/(%d+)")
|
|
if done and needed and tonumber(done) >= tonumber(needed) then
|
|
objFS:SetTextColor(T.objectiveComplete[1], T.objectiveComplete[2], T.objectiveComplete[3])
|
|
else
|
|
objFS:SetTextColor(T.objectiveIncomplete[1], T.objectiveIncomplete[2], T.objectiveIncomplete[3])
|
|
end
|
|
end
|
|
end
|
|
|
|
local styledTexts = {
|
|
"QuestLogRewardTitleText", "QuestLogHeaderText",
|
|
"QuestLogItemChooseText", "QuestLogItemReceiveText",
|
|
"QuestLogSpellLearnText",
|
|
}
|
|
for _, name in ipairs(styledTexts) do
|
|
local fs = _G[name]
|
|
if fs then
|
|
fs:SetFont(GetFont(), 11, "OUTLINE")
|
|
fs:SetTextColor(T.sectionTitle[1], T.sectionTitle[2], T.sectionTitle[3])
|
|
end
|
|
end
|
|
|
|
local rewardMoney = _G["QuestLogRequiredMoneyText"]
|
|
if rewardMoney then rewardMoney:SetFont(GetFont(), 11) end
|
|
|
|
local timerText = _G["QuestLogTimerText"]
|
|
if timerText then
|
|
timerText:SetFont(GetFont(), 11, "OUTLINE")
|
|
timerText:SetTextColor(T.gold[1], T.gold[2], T.gold[3])
|
|
end
|
|
|
|
for i = 1, 10 do
|
|
local item = _G["QuestLogItem" .. i]
|
|
if item then SkinRewardItem(item) end
|
|
end
|
|
|
|
ApplyQuestLogItemQuality()
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- pfquest Button Detection & Styling
|
|
--------------------------------------------------------------------------------
|
|
local pfquestSkinned = false
|
|
|
|
local function SkinPfQuestButton(btn)
|
|
if not btn or btn._nanamiPfSkinned then return end
|
|
btn._nanamiPfSkinned = true
|
|
StripAllTextures(btn)
|
|
StripNormalTexture(btn)
|
|
StripPushedTexture(btn)
|
|
StripHighlightTexture(btn)
|
|
SetRoundBackdrop(btn, T.btnBg, T.btnBorder)
|
|
|
|
if btn.GetFontString then
|
|
local fs = btn:GetFontString()
|
|
if fs then
|
|
fs:SetFont(GetFont(), 10, "OUTLINE")
|
|
fs:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3])
|
|
end
|
|
end
|
|
|
|
local origEnter = btn:GetScript("OnEnter")
|
|
btn:SetScript("OnEnter", function()
|
|
SetRoundBackdrop(this, T.btnHoverBg, T.btnHoverBd)
|
|
if this.GetFontString then
|
|
local tfs = this:GetFontString()
|
|
if tfs then tfs:SetTextColor(T.btnActiveText[1], T.btnActiveText[2], T.btnActiveText[3]) end
|
|
end
|
|
if origEnter then origEnter() end
|
|
end)
|
|
local origLeave = btn:GetScript("OnLeave")
|
|
btn:SetScript("OnLeave", function()
|
|
SetRoundBackdrop(this, T.btnBg, T.btnBorder)
|
|
if this.GetFontString then
|
|
local tfs = this:GetFontString()
|
|
if tfs then tfs:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3]) end
|
|
end
|
|
if origLeave then origLeave() end
|
|
end)
|
|
end
|
|
|
|
local function IsPfQuestButtonText(text)
|
|
if not text then return false end
|
|
return string.find(text, "show") or string.find(text, "hide")
|
|
or string.find(text, "clean") or string.find(text, "reset")
|
|
or string.find(text, "Show") or string.find(text, "Hide")
|
|
or string.find(text, "Clean") or string.find(text, "Reset")
|
|
or string.find(text, "显示") or string.find(text, "隐藏")
|
|
or string.find(text, "清空") or string.find(text, "重置")
|
|
end
|
|
|
|
local function TrySkinPfQuestButtons()
|
|
local pfBtns = {}
|
|
|
|
for _, name in ipairs({
|
|
"pfQuestShow", "pfQuestHide", "pfQuestClean", "pfQuestReset",
|
|
"pfQuest.show", "pfQuest.hide", "pfQuest.clean", "pfQuest.reset",
|
|
}) do
|
|
local btn = _G[name]
|
|
if btn then
|
|
SkinPfQuestButton(btn)
|
|
table.insert(pfBtns, btn)
|
|
end
|
|
end
|
|
|
|
if pfQuest and pfQuest.buttons then
|
|
for _, btn in pairs(pfQuest.buttons) do
|
|
if type(btn) == "table" and btn.GetObjectType then
|
|
SkinPfQuestButton(btn)
|
|
table.insert(pfBtns, btn)
|
|
end
|
|
end
|
|
end
|
|
|
|
local detailChild = _G["QuestLogDetailScrollFrameChildFrame"]
|
|
or _G["QuestLogDetailScrollFrameChild"]
|
|
if detailChild and detailChild.GetChildren then
|
|
local children = { detailChild:GetChildren() }
|
|
for idx = 1, table.getn(children) do
|
|
local child = children[idx]
|
|
if child and child.GetObjectType and child:GetObjectType() == "Button" and child.GetFontString then
|
|
local fs = child:GetFontString()
|
|
if fs then
|
|
local text = fs:GetText()
|
|
if IsPfQuestButtonText(text) then
|
|
SkinPfQuestButton(child)
|
|
table.insert(pfBtns, child)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Resize pfquest buttons to fit within the detail content area (keep original positions)
|
|
local contentW = FRAME_W - LIST_W - DETAIL_PAD * 2 - 4 - INNER_PAD * 2 - SCROLL_W - 6
|
|
local btnCount = table.getn(pfBtns)
|
|
if btnCount > 0 and contentW > 100 then
|
|
local gap = 2
|
|
local pfBtnW = math.floor((contentW - gap * (btnCount - 1)) / btnCount)
|
|
if pfBtnW < 50 then pfBtnW = 50 end
|
|
for bi = 1, btnCount do
|
|
local btn = pfBtns[bi]
|
|
if btn and btn.SetWidth then
|
|
btn:SetWidth(pfBtnW)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Quest Tracker Button Skinning
|
|
--------------------------------------------------------------------------------
|
|
local function SkinQuestTrackButton()
|
|
for _, bname in ipairs({
|
|
"QuestLogTrack", "QuestLogFrameTrackButton", "QuestLogTrackButton",
|
|
}) do
|
|
local trackBtn = _G[bname]
|
|
if trackBtn then
|
|
trackBtn:Hide()
|
|
trackBtn:SetAlpha(0)
|
|
trackBtn:SetWidth(1)
|
|
trackBtn:SetHeight(1)
|
|
trackBtn:ClearAllPoints()
|
|
trackBtn:SetPoint("TOPLEFT", QuestLogFrame, "TOPLEFT", -9999, 0)
|
|
end
|
|
end
|
|
for _, tname in ipairs({
|
|
"QuestLogTrackText", "QuestLogTrackButtonText",
|
|
"QuestLogTrackHighlight",
|
|
}) do
|
|
local t = _G[tname]
|
|
if t then
|
|
t:Hide()
|
|
if t.SetAlpha then t:SetAlpha(0) end
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Hooks
|
|
--------------------------------------------------------------------------------
|
|
local function ClampHighlightWidth()
|
|
local hl = _G["QuestLogHighlightFrame"]
|
|
if hl and hl.IsVisible and hl:IsVisible() then
|
|
hl:SetWidth(LIST_BTN_W)
|
|
end
|
|
end
|
|
|
|
local function EnforceListScrollSize()
|
|
local lf = QuestLogListScrollFrame
|
|
local f = QuestLogFrame
|
|
if not lf or not f or not f._nanamiListPanel then return end
|
|
local panelH = f._nanamiListPanel:GetHeight()
|
|
if panelH and panelH > 50 then
|
|
lf:SetHeight(panelH - INNER_PAD - 4)
|
|
end
|
|
end
|
|
|
|
local function InstallHooks()
|
|
local origUpdate = QuestLog_Update
|
|
if origUpdate then
|
|
QuestLog_Update = function()
|
|
origUpdate()
|
|
if QuestLogFrame then QuestLogFrame:SetWidth(FRAME_W) end
|
|
EnforceListScrollSize()
|
|
StyleQuestListEntries()
|
|
ClampHighlightWidth()
|
|
if not pfquestSkinned then
|
|
pfquestSkinned = true
|
|
TrySkinPfQuestButtons()
|
|
end
|
|
end
|
|
end
|
|
|
|
local origSetSelection = QuestLog_SetSelection
|
|
if origSetSelection then
|
|
QuestLog_SetSelection = function(index)
|
|
origSetSelection(index)
|
|
EnforceListScrollSize()
|
|
StyleQuestListEntries()
|
|
ClampHighlightWidth()
|
|
StyleQuestDetailText()
|
|
TrySkinPfQuestButtons()
|
|
if QuestLogFrame and QuestLogFrame._skinExtraButtons then
|
|
QuestLogFrame._skinExtraButtons()
|
|
end
|
|
local sb = _G["QuestLogFramePushQuestButton"] or _G["QuestFramePushQuestButton"]
|
|
if sb and sb._nanamiRefreshShare then sb._nanamiRefreshShare(sb) end
|
|
end
|
|
end
|
|
|
|
local origUpdateDetails = QuestLog_UpdateQuestDetails
|
|
if origUpdateDetails then
|
|
QuestLog_UpdateQuestDetails = function(doNotShow)
|
|
origUpdateDetails(doNotShow)
|
|
StyleQuestDetailText()
|
|
TrySkinPfQuestButtons()
|
|
if QuestLogFrame and QuestLogFrame._skinExtraButtons then
|
|
QuestLogFrame._skinExtraButtons()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Initialize
|
|
--------------------------------------------------------------------------------
|
|
function QLS:Initialize()
|
|
if skinApplied then return end
|
|
if not QuestLogFrame then return end
|
|
skinApplied = true
|
|
|
|
SkinMainFrame()
|
|
SkinQuestList()
|
|
SkinQuestDetail()
|
|
SkinBottomButtons()
|
|
SkinQuestTrackButton()
|
|
InstallHooks()
|
|
|
|
local origOnShow = QuestLogFrame:GetScript("OnShow")
|
|
QuestLogFrame:SetScript("OnShow", function()
|
|
if origOnShow then origOnShow() end
|
|
QuestLogFrame:SetWidth(FRAME_W)
|
|
EnforceListScrollSize()
|
|
StyleQuestListEntries()
|
|
ClampHighlightWidth()
|
|
StyleQuestDetailText()
|
|
if not pfquestSkinned then
|
|
pfquestSkinned = true
|
|
TrySkinPfQuestButtons()
|
|
end
|
|
if QuestLogFrame._skinExtraButtons then
|
|
QuestLogFrame._skinExtraButtons()
|
|
end
|
|
end)
|
|
|
|
-- Delayed pfquest + translate button detection
|
|
local pfCheck = CreateFrame("Frame", nil, QuestLogFrame)
|
|
pfCheck._e = 0; pfCheck._n = 0
|
|
pfCheck:SetScript("OnUpdate", function()
|
|
this._e = (this._e or 0) + (arg1 or 0)
|
|
if this._e < 0.5 then return end
|
|
this._e = 0
|
|
this._n = (this._n or 0) + 1
|
|
TrySkinPfQuestButtons()
|
|
if QuestLogFrame._skinExtraButtons then
|
|
QuestLogFrame._skinExtraButtons()
|
|
end
|
|
if this._n >= 8 then this:SetScript("OnUpdate", nil) end
|
|
end)
|
|
|
|
if QuestLogFrame:IsVisible() then
|
|
StyleQuestListEntries()
|
|
StyleQuestDetailText()
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Bootstrap
|
|
--------------------------------------------------------------------------------
|
|
local bootstrap = CreateFrame("Frame")
|
|
bootstrap:RegisterEvent("PLAYER_LOGIN")
|
|
bootstrap:SetScript("OnEvent", function()
|
|
if event == "PLAYER_LOGIN" then
|
|
if SFramesDB.enableQuestLogSkin == nil then
|
|
SFramesDB.enableQuestLogSkin = true
|
|
end
|
|
if SFramesDB.enableQuestLogSkin ~= false then
|
|
QLS:Initialize()
|
|
end
|
|
end
|
|
end)
|