聊天重做前缓存

This commit is contained in:
rucky
2026-04-09 09:46:47 +08:00
parent 6e18269bfd
commit e915bbd74a
39 changed files with 8501 additions and 2308 deletions

778
ConsumableUI.lua Normal file
View File

@@ -0,0 +1,778 @@
--------------------------------------------------------------------------------
-- Nanami-UI: ConsumableUI.lua
-- 食物药剂百科窗口
--------------------------------------------------------------------------------
SFrames = SFrames or {}
SFrames.ConsumableUI = SFrames.ConsumableUI or {}
local CUI = SFrames.ConsumableUI
local FRAME_W = 600
local FRAME_H = 500
local HEADER_H = 34
local FILTER_H = 28
local ROLE_H = 28
local COL_H = 22
local ROW_H = 20
local MAX_ROWS = 18
local SIDE_PAD = 10
local COL_CAT_W = 86
local COL_NAME_W = 168
local COL_EFF_W = 232
local COL_DUR_W = 76
local S = {
frame = nil,
searchBox = nil,
searchText = "",
activeRole = "全部",
rows = {},
tabBtns = {},
displayList = {},
filteredCount = 0,
scrollOffset = 0,
scrollMax = 0,
summaryFS = nil,
emptyFS = nil,
scrollBar = nil,
}
local function GetTheme()
local base = {
panelBg = { 0.07, 0.07, 0.10, 0.96 },
panelBorder = { 0.35, 0.30, 0.40, 1.00 },
headerBg = { 0.10, 0.10, 0.14, 1.00 },
text = { 0.92, 0.88, 0.95 },
dimText = { 0.55, 0.50, 0.58 },
gold = { 1.00, 0.82, 0.40 },
slotBg = { 0.10, 0.10, 0.14, 0.90 },
slotBorder = { 0.30, 0.28, 0.35, 0.80 },
slotSelected = { 0.80, 0.60, 1.00 },
divider = { 0.28, 0.26, 0.32, 0.80 },
rowAlt = { 0.11, 0.10, 0.15, 0.60 },
green = { 0.40, 0.90, 0.50 },
}
if SFrames and SFrames.ActiveTheme then
for key, value in pairs(SFrames.ActiveTheme) do
base[key] = value
end
end
return base
end
local function GetFont()
return SFrames and SFrames.GetFont and SFrames:GetFont()
or "Fonts\\ARIALN.TTF"
end
local function ApplyBackdrop(frame, bg, border)
local theme = GetTheme()
local backdropBg = bg or theme.panelBg
local backdropBorder = border or theme.panelBorder
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(backdropBg[1], backdropBg[2], backdropBg[3], backdropBg[4] or 0.96)
frame:SetBackdropBorderColor(
backdropBorder[1],
backdropBorder[2],
backdropBorder[3],
backdropBorder[4] or 1.00
)
end
local function SetDivider(parent, y, rightPadding)
local theme = GetTheme()
local divider = parent:CreateTexture(nil, "ARTWORK")
divider:SetTexture("Interface\\Buttons\\WHITE8X8")
divider:SetHeight(1)
divider:SetPoint("TOPLEFT", parent, "TOPLEFT", SIDE_PAD, y)
divider:SetPoint("TOPRIGHT", parent, "TOPRIGHT", -(SIDE_PAD + (rightPadding or 0)), y)
divider:SetVertexColor(theme.divider[1], theme.divider[2], theme.divider[3], theme.divider[4] or 0.8)
end
local function Utf8DisplayWidth(value)
local width = 0
local index = 1
local len = string.len(value or "")
while index <= len do
local byte = string.byte(value, index)
if byte < 128 then
width = width + 7
index = index + 1
elseif byte < 224 then
width = width + 7
index = index + 2
elseif byte < 240 then
width = width + 11
index = index + 3
else
width = width + 11
index = index + 4
end
end
return width
end
local function GetDatabase()
local db = SFrames and SFrames.ConsumableDB
if not db then
return nil
end
if db.groups then
return db
end
return {
groups = db,
roleOrder = nil,
categoryOrder = nil,
summary = nil,
generatedAt = nil,
}
end
local function GetGroups()
local db = GetDatabase()
return db and db.groups or nil
end
local function CountAllItems(groups)
local count = 0
for _, group in ipairs(groups or {}) do
count = count + table.getn(group.items or {})
end
return count
end
local function CountAllCategories(groups)
local seen = {}
local count = 0
for _, group in ipairs(groups or {}) do
for _, item in ipairs(group.items or {}) do
if item.cat and item.cat ~= "" and not seen[item.cat] then
seen[item.cat] = true
count = count + 1
end
end
end
return count
end
local function BuildRoleList()
local db = GetDatabase()
local roles = { "全部" }
local seen = { ["全部"] = true }
if not db or not db.groups then
return roles
end
if db.roleOrder then
for _, role in ipairs(db.roleOrder) do
if role and role ~= "" and not seen[role] then
seen[role] = true
table.insert(roles, role)
end
end
end
for _, group in ipairs(db.groups) do
if group.role and group.role ~= "" and not seen[group.role] then
seen[group.role] = true
table.insert(roles, group.role)
end
end
return roles
end
local function RoleMatches(group)
if S.activeRole == "全部" then
return true
end
return group.role == S.activeRole
end
local function ItemMatches(item)
if S.searchText == "" then
return true
end
local query = string.lower(S.searchText)
return string.find(string.lower(item.name or ""), query, 1, true)
or string.find(string.lower(item.effect or ""), query, 1, true)
or string.find(string.lower(item.cat or ""), query, 1, true)
end
function CUI:RefreshSummary()
if not S.summaryFS then
return
end
local db = GetDatabase()
local groups = db and db.groups or {}
local summary = db and db.summary or nil
local roleCount = (summary and summary.roleCount) or table.getn(groups)
local categoryCount = (summary and summary.categoryCount) or CountAllCategories(groups)
local totalCount = (summary and summary.itemCount) or CountAllItems(groups)
local text = string.format("%d 定位 / %d 类别 / %d 条", roleCount, categoryCount, totalCount)
if S.activeRole ~= "全部" or S.searchText ~= "" then
text = string.format("当前筛出 %d 条,数据库共 %d 条", S.filteredCount or 0, totalCount)
end
if db and db.generatedAt then
text = text .. " · 更新于 " .. db.generatedAt
end
S.summaryFS:SetText(text)
end
function CUI:Filter()
S.displayList = {}
S.filteredCount = 0
local groups = GetGroups()
if not groups then
S.scrollOffset = 0
S.scrollMax = 0
self:RefreshSummary()
return
end
for _, group in ipairs(groups) do
if RoleMatches(group) then
local matched = {}
for _, item in ipairs(group.items or {}) do
if ItemMatches(item) then
table.insert(matched, item)
end
end
if table.getn(matched) > 0 then
table.insert(S.displayList, {
isHeader = true,
group = group,
count = table.getn(matched),
})
for _, item in ipairs(matched) do
table.insert(S.displayList, {
isHeader = false,
item = item,
})
end
S.filteredCount = S.filteredCount + table.getn(matched)
end
end
end
S.scrollOffset = 0
S.scrollMax = math.max(0, table.getn(S.displayList) - MAX_ROWS)
self:RefreshSummary()
end
local function UpdateScrollbar()
local scrollBar = S.scrollBar
if not scrollBar then
return
end
local total = table.getn(S.displayList)
if total <= MAX_ROWS then
scrollBar:Hide()
return
end
scrollBar:Show()
local trackHeight = scrollBar:GetHeight()
local thumbHeight = math.max(20, math.floor(trackHeight * MAX_ROWS / total + 0.5))
local percent = 0
if S.scrollMax > 0 then
percent = S.scrollOffset / S.scrollMax
end
local thumbY = math.floor((trackHeight - thumbHeight) * percent + 0.5)
if scrollBar.thumb then
scrollBar.thumb:SetHeight(thumbHeight)
scrollBar.thumb:SetPoint("TOP", scrollBar, "TOP", 0, -thumbY)
end
end
function CUI:Render()
local theme = GetTheme()
local total = table.getn(S.displayList)
local visibleItemIndex = 0
for i = 1, MAX_ROWS do
local row = S.rows[i]
if not row then
break
end
local displayIndex = S.scrollOffset + i
local entry = S.displayList[displayIndex]
if entry then
row:Show()
if entry.isHeader then
local headerText = entry.group.detail or entry.group.role or "未命名分组"
if entry.count and entry.count > 0 then
headerText = string.format("%s (%d)", headerText, entry.count)
end
row.catFS:SetText(headerText)
row.catFS:SetTextColor(
entry.group.color and entry.group.color[1] or theme.gold[1],
entry.group.color and entry.group.color[2] or theme.gold[2],
entry.group.color and entry.group.color[3] or theme.gold[3]
)
row.catFS:SetWidth(COL_CAT_W + COL_NAME_W + COL_EFF_W + COL_DUR_W - 10)
row.catFS:SetPoint("TOPLEFT", row, "TOPLEFT", 6, -3)
row.nameFS:SetText("")
row.effFS:SetText("")
row.durFS:SetText("")
row:SetBackdrop({
bgFile = "Interface\\Buttons\\WHITE8X8",
tile = false,
tileSize = 0,
edgeSize = 0,
})
row:SetBackdropColor(theme.headerBg[1], theme.headerBg[2], theme.headerBg[3], 0.85)
row.entry = nil
else
local item = entry.item
visibleItemIndex = visibleItemIndex + 1
row:SetBackdrop({
bgFile = "Interface\\Buttons\\WHITE8X8",
tile = false,
tileSize = 0,
edgeSize = 0,
})
if math.mod(visibleItemIndex, 2) == 0 then
row:SetBackdropColor(theme.rowAlt[1], theme.rowAlt[2], theme.rowAlt[3], theme.rowAlt[4] or 0.6)
else
row:SetBackdropColor(theme.slotBg[1], theme.slotBg[2], theme.slotBg[3], 0.0)
end
row.catFS:SetWidth(COL_CAT_W - 8)
row.catFS:SetText(item.cat or "")
row.catFS:SetTextColor(theme.dimText[1], theme.dimText[2], theme.dimText[3])
row.catFS:SetPoint("TOPLEFT", row, "TOPLEFT", 6, -3)
if item.id and item.id > 0 then
row.nameFS:SetTextColor(theme.gold[1], theme.gold[2], theme.gold[3])
else
row.nameFS:SetTextColor(theme.text[1], theme.text[2], theme.text[3])
end
row.nameFS:SetText(item.name or "")
row.effFS:SetText(item.effect or "")
row.effFS:SetTextColor(theme.text[1], theme.text[2], theme.text[3])
row.durFS:SetText(item.duration or "")
row.durFS:SetTextColor(theme.dimText[1], theme.dimText[2], theme.dimText[3])
row.entry = item
end
else
row:Hide()
row.entry = nil
end
end
if S.emptyFS then
if total == 0 then
S.emptyFS:SetText("没有匹配到条目,试试更短的关键词或切回“全部”。")
S.emptyFS:Show()
else
S.emptyFS:Hide()
end
end
UpdateScrollbar()
end
local function RefreshTabs()
local theme = GetTheme()
for _, button in ipairs(S.tabBtns or {}) do
local active = (button.roleName == S.activeRole)
if active then
button:SetBackdropBorderColor(
theme.slotSelected[1],
theme.slotSelected[2],
theme.slotSelected[3],
1.00
)
button.fs:SetTextColor(
theme.slotSelected[1],
theme.slotSelected[2],
theme.slotSelected[3]
)
else
button:SetBackdropBorderColor(
theme.slotBorder[1],
theme.slotBorder[2],
theme.slotBorder[3],
theme.slotBorder[4] or 0.8
)
button.fs:SetTextColor(theme.dimText[1], theme.dimText[2], theme.dimText[3])
end
end
end
local function BuildColumnLabel(parent, text, x, width)
local font = GetFont()
local theme = GetTheme()
local fs = parent:CreateFontString(nil, "OVERLAY")
fs:SetFont(font, 10, "OUTLINE")
fs:SetTextColor(theme.dimText[1], theme.dimText[2], theme.dimText[3])
fs:SetPoint("TOPLEFT", parent, "TOPLEFT", x, -4)
fs:SetWidth(width)
fs:SetJustifyH("LEFT")
fs:SetText(text)
return fs
end
function CUI:Build()
local theme = GetTheme()
local font = GetFont()
local frame = CreateFrame("Frame", "NanamiConsumableFrame", UIParent)
S.frame = frame
frame:SetWidth(FRAME_W)
frame:SetHeight(FRAME_H)
frame:SetPoint("CENTER", UIParent, "CENTER", 60, 20)
frame:SetFrameStrata("HIGH")
frame:SetToplevel(true)
frame:EnableMouse(true)
frame:SetMovable(true)
frame:RegisterForDrag("LeftButton")
frame:SetScript("OnDragStart", function() this:StartMoving() end)
frame:SetScript("OnDragStop", function() this:StopMovingOrSizing() end)
frame:EnableMouseWheel(true)
frame:SetScript("OnMouseWheel", function()
if arg1 > 0 then
S.scrollOffset = math.max(0, S.scrollOffset - 1)
else
S.scrollOffset = math.min(S.scrollMax, S.scrollOffset + 1)
end
CUI:Render()
end)
ApplyBackdrop(frame)
tinsert(UISpecialFrames, "NanamiConsumableFrame")
local header = CreateFrame("Frame", nil, frame)
header:SetPoint("TOPLEFT", 0, 0)
header:SetPoint("TOPRIGHT", 0, 0)
header:SetHeight(HEADER_H)
header:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8" })
header:SetBackdropColor(theme.headerBg[1], theme.headerBg[2], theme.headerBg[3], theme.headerBg[4] or 1.0)
local titleFS = header:CreateFontString(nil, "OVERLAY")
titleFS:SetFont(font, 13, "OUTLINE")
titleFS:SetPoint("LEFT", header, "LEFT", SIDE_PAD + 4, 0)
titleFS:SetText("食物药剂百科")
titleFS:SetTextColor(theme.gold[1], theme.gold[2], theme.gold[3])
local closeBtn = CreateFrame("Button", nil, header)
closeBtn:SetWidth(20)
closeBtn:SetHeight(20)
closeBtn:SetPoint("TOPRIGHT", header, "TOPRIGHT", -8, -7)
local closeTex = closeBtn:CreateTexture(nil, "ARTWORK")
closeTex:SetTexture("Interface\\AddOns\\Nanami-UI\\img\\icon")
closeTex:SetTexCoord(0.25, 0.375, 0, 0.125)
closeTex:SetAllPoints()
closeTex:SetVertexColor(theme.dimText[1], theme.dimText[2], theme.dimText[3])
closeBtn:SetScript("OnClick", function() frame:Hide() end)
closeBtn:SetScript("OnEnter", function() closeTex:SetVertexColor(1, 0.6, 0.7) end)
closeBtn:SetScript("OnLeave", function()
closeTex:SetVertexColor(theme.dimText[1], theme.dimText[2], theme.dimText[3])
end)
SetDivider(frame, -HEADER_H, 16)
local filterY = -(HEADER_H + 6)
local searchFrame = CreateFrame("Frame", nil, frame)
searchFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", SIDE_PAD, filterY)
searchFrame:SetWidth(212)
searchFrame:SetHeight(FILTER_H - 4)
searchFrame:SetBackdrop({
bgFile = "Interface\\Buttons\\WHITE8X8",
edgeFile = "Interface\\Buttons\\WHITE8X8",
tile = false,
tileSize = 0,
edgeSize = 1,
insets = { left = 1, right = 1, top = 1, bottom = 1 },
})
searchFrame:SetBackdropColor(0.05, 0.05, 0.08, 0.90)
searchFrame:SetBackdropBorderColor(theme.panelBorder[1], theme.panelBorder[2], theme.panelBorder[3], 0.80)
local searchBox = CreateFrame("EditBox", "NanamiConsumableSearch", searchFrame)
searchBox:SetPoint("TOPLEFT", searchFrame, "TOPLEFT", 4, -3)
searchBox:SetPoint("BOTTOMRIGHT", searchFrame, "BOTTOMRIGHT", -4, 3)
searchBox:SetFont(font, 11)
searchBox:SetAutoFocus(false)
searchBox:SetMaxLetters(40)
searchBox:EnableMouse(true)
S.searchBox = searchBox
local hintFS = searchFrame:CreateFontString(nil, "OVERLAY")
hintFS:SetFont(font, 10, "OUTLINE")
hintFS:SetPoint("LEFT", searchFrame, "LEFT", 6, 0)
hintFS:SetText("搜索名称 / 效果 / 类别")
hintFS:SetTextColor(theme.dimText[1], theme.dimText[2], theme.dimText[3])
searchBox:SetScript("OnTextChanged", function()
local text = this:GetText() or ""
S.searchText = text
if text == "" then
hintFS:Show()
else
hintFS:Hide()
end
CUI:Filter()
CUI:Render()
end)
searchBox:SetScript("OnEditFocusGained", function() hintFS:Hide() end)
searchBox:SetScript("OnEditFocusLost", function()
if (this:GetText() or "") == "" then
hintFS:Show()
end
end)
searchBox:SetScript("OnEscapePressed", function() this:ClearFocus() end)
local summaryFS = frame:CreateFontString(nil, "OVERLAY")
summaryFS:SetFont(font, 10, "OUTLINE")
summaryFS:SetPoint("LEFT", searchFrame, "RIGHT", 12, 0)
summaryFS:SetPoint("RIGHT", frame, "RIGHT", -36, filterY - 12)
summaryFS:SetJustifyH("RIGHT")
summaryFS:SetTextColor(theme.dimText[1], theme.dimText[2], theme.dimText[3])
summaryFS:SetText("")
S.summaryFS = summaryFS
local tabX = SIDE_PAD
local tabY = filterY - FILTER_H
S.tabBtns = {}
for _, roleName in ipairs(BuildRoleList()) do
local tabW = Utf8DisplayWidth(roleName) + 14
if tabX + tabW > FRAME_W - SIDE_PAD then
tabX = SIDE_PAD
tabY = tabY - (ROLE_H - 4) - 2
end
local button = CreateFrame("Button", nil, frame)
button:SetWidth(tabW)
button:SetHeight(ROLE_H - 4)
button:SetPoint("TOPLEFT", frame, "TOPLEFT", tabX, tabY)
button:SetBackdrop({
bgFile = "Interface\\Buttons\\WHITE8X8",
edgeFile = "Interface\\Buttons\\WHITE8X8",
tile = false,
tileSize = 0,
edgeSize = 1,
insets = { left = 1, right = 1, top = 1, bottom = 1 },
})
button:SetBackdropColor(theme.slotBg[1], theme.slotBg[2], theme.slotBg[3], 0.80)
button:SetBackdropBorderColor(theme.slotBorder[1], theme.slotBorder[2], theme.slotBorder[3], 0.80)
local buttonFS = button:CreateFontString(nil, "OVERLAY")
buttonFS:SetFont(font, 10, "OUTLINE")
buttonFS:SetPoint("CENTER", button, "CENTER", 0, 0)
buttonFS:SetText(roleName)
buttonFS:SetTextColor(theme.dimText[1], theme.dimText[2], theme.dimText[3])
button.fs = buttonFS
button.roleName = roleName
button:SetScript("OnClick", function()
S.activeRole = this.roleName
RefreshTabs()
CUI:Filter()
CUI:Render()
end)
button:SetScript("OnEnter", function()
if this.roleName ~= S.activeRole then
this:SetBackdropBorderColor(theme.text[1], theme.text[2], theme.text[3], 0.60)
end
end)
button:SetScript("OnLeave", function()
if this.roleName ~= S.activeRole then
this:SetBackdropBorderColor(theme.slotBorder[1], theme.slotBorder[2], theme.slotBorder[3], 0.80)
end
end)
table.insert(S.tabBtns, button)
tabX = tabX + tabW + 3
end
RefreshTabs()
local listStartY = tabY - ROLE_H + 2
SetDivider(frame, listStartY, 16)
local colY = listStartY - 2
local colHeader = CreateFrame("Frame", nil, frame)
colHeader:SetPoint("TOPLEFT", frame, "TOPLEFT", SIDE_PAD, colY)
colHeader:SetWidth(FRAME_W - SIDE_PAD * 2 - 14)
colHeader:SetHeight(COL_H)
colHeader:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8" })
colHeader:SetBackdropColor(theme.headerBg[1], theme.headerBg[2], theme.headerBg[3], 0.70)
BuildColumnLabel(colHeader, "类别", 4, COL_CAT_W)
BuildColumnLabel(colHeader, "名称", COL_CAT_W + 4, COL_NAME_W)
BuildColumnLabel(colHeader, "效果", COL_CAT_W + COL_NAME_W + 4, COL_EFF_W)
BuildColumnLabel(colHeader, "时长", COL_CAT_W + COL_NAME_W + COL_EFF_W + 4, COL_DUR_W)
local rowAreaY = colY - COL_H - 1
local rowAreaH = FRAME_H - (-rowAreaY) - 8
local scrollWidth = 10
local scrollBar = CreateFrame("Frame", nil, frame)
scrollBar:SetWidth(scrollWidth)
scrollBar:SetHeight(rowAreaH)
scrollBar:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -4, rowAreaY)
scrollBar:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8" })
scrollBar:SetBackdropColor(theme.slotBg[1], theme.slotBg[2], theme.slotBg[3], 0.40)
local scrollThumb = scrollBar:CreateTexture(nil, "OVERLAY")
scrollThumb:SetTexture("Interface\\Buttons\\WHITE8X8")
scrollThumb:SetWidth(scrollWidth - 2)
scrollThumb:SetHeight(40)
scrollThumb:SetPoint("TOP", scrollBar, "TOP", 0, 0)
scrollThumb:SetVertexColor(theme.slotSelected[1], theme.slotSelected[2], theme.slotSelected[3], 0.60)
scrollBar.thumb = scrollThumb
S.scrollBar = scrollBar
local rowWidth = FRAME_W - SIDE_PAD * 2 - scrollWidth - 6
for i = 1, MAX_ROWS do
local rowY = rowAreaY - (i - 1) * ROW_H
local row = CreateFrame("Button", nil, frame)
row:SetWidth(rowWidth)
row:SetHeight(ROW_H)
row:SetPoint("TOPLEFT", frame, "TOPLEFT", SIDE_PAD, rowY)
local catFS = row:CreateFontString(nil, "OVERLAY")
catFS:SetFont(font, 9, "OUTLINE")
catFS:SetPoint("TOPLEFT", row, "TOPLEFT", 6, -3)
catFS:SetWidth(COL_CAT_W - 8)
catFS:SetJustifyH("LEFT")
row.catFS = catFS
local nameFS = row:CreateFontString(nil, "OVERLAY")
nameFS:SetFont(font, 9, "OUTLINE")
nameFS:SetPoint("TOPLEFT", row, "TOPLEFT", COL_CAT_W + 4, -3)
nameFS:SetWidth(COL_NAME_W - 4)
nameFS:SetJustifyH("LEFT")
row.nameFS = nameFS
local effFS = row:CreateFontString(nil, "OVERLAY")
effFS:SetFont(font, 9, "OUTLINE")
effFS:SetPoint("TOPLEFT", row, "TOPLEFT", COL_CAT_W + COL_NAME_W + 4, -3)
effFS:SetWidth(COL_EFF_W - 4)
effFS:SetJustifyH("LEFT")
row.effFS = effFS
local durFS = row:CreateFontString(nil, "OVERLAY")
durFS:SetFont(font, 9, "OUTLINE")
durFS:SetPoint("TOPLEFT", row, "TOPLEFT", COL_CAT_W + COL_NAME_W + COL_EFF_W + 4, -3)
durFS:SetWidth(COL_DUR_W - 2)
durFS:SetJustifyH("LEFT")
row.durFS = durFS
local highlight = row:CreateTexture(nil, "HIGHLIGHT")
highlight:SetTexture("Interface\\Buttons\\WHITE8X8")
highlight:SetAllPoints()
highlight:SetVertexColor(1, 1, 1, 0.07)
highlight:SetBlendMode("ADD")
row:SetScript("OnEnter", function()
local entry = this.entry
if not entry then
return
end
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
if entry.id and entry.id > 0 then
GameTooltip:SetHyperlink("item:" .. entry.id .. ":0:0:0")
GameTooltip:AddLine("Shift+点击可发送物品链接", 0.55, 0.55, 0.60)
else
GameTooltip:SetText(entry.name or "", 1, 0.82, 0.40)
if entry.effect and entry.effect ~= "" then
GameTooltip:AddLine(entry.effect, 0.80, 0.80, 0.80)
end
if entry.duration and entry.duration ~= "" then
GameTooltip:AddLine("持续时间: " .. entry.duration, 0.55, 0.55, 0.60)
end
end
GameTooltip:Show()
end)
row:SetScript("OnLeave", function() GameTooltip:Hide() end)
row:SetScript("OnClick", function()
local entry = this.entry
if not entry then
return
end
if IsShiftKeyDown() and entry.id and entry.id > 0 then
local _, link = GetItemInfo(entry.id)
if link and ChatFrameEditBox then
ChatFrameEditBox:Show()
ChatFrameEditBox:Insert(link)
end
end
end)
row:Hide()
S.rows[i] = row
end
local emptyFS = frame:CreateFontString(nil, "OVERLAY")
emptyFS:SetFont(font, 11, "OUTLINE")
emptyFS:SetPoint("CENTER", frame, "CENTER", 0, -28)
emptyFS:SetTextColor(theme.dimText[1], theme.dimText[2], theme.dimText[3])
emptyFS:SetText("")
emptyFS:Hide()
S.emptyFS = emptyFS
end
function CUI:Toggle()
if S.frame and S.frame:IsShown() then
S.frame:Hide()
return
end
if not S.frame then
self:Build()
end
self:Filter()
self:Render()
S.frame:Show()
end
function CUI:Hide()
if S.frame then
S.frame:Hide()
end
end