fix: mailbox tooltip

This commit is contained in:
Salikh Gurgenidze
2025-12-27 17:31:41 +04:00
parent 61bb1d9d8e
commit 6ca33c1c9f
5 changed files with 375 additions and 160 deletions
+25 -5
View File
@@ -95,6 +95,31 @@ function Utils:GetItemInfo(itemLink)
return nil return nil
end end
-- Create a hidden tooltip for scanning
local scanTooltip = CreateFrame("GameTooltip", "GudaBagScanTooltip", nil, "GameTooltipTemplate")
scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
-- Get item link from mailbox attachment (WoW 1.12.1 workaround)
function Utils:GetInboxItemLink(index, itemIndex)
-- In 1.12.1, GameTooltip:GetHyperlink() does not exist.
-- Actually, in 1.12.1, there's no official API to get the link from a mailbox item
-- if GetInboxItemLink(index) is not available (it's often NOT available in Vanilla).
-- Let's try to use GetItemInfo(name) as the primary way.
local name = GetInboxItem(index, itemIndex)
if name then
local _, link = GetItemInfo(name)
if link then
return link
end
end
-- Fallback: If we still don't have it, we might try to scan the tooltip for the name
-- but GetInboxItem already gave us the name.
return nil
end
-- Get quality color -- Get quality color
function Utils:GetQualityColor(quality) function Utils:GetQualityColor(quality)
local color = addon.Constants.QUALITY_COLORS[quality] or addon.Constants.QUALITY_COLORS[1] local color = addon.Constants.QUALITY_COLORS[quality] or addon.Constants.QUALITY_COLORS[1]
@@ -156,12 +181,7 @@ function Utils:FormatTimeAgo(timestamp)
end end
-- Create hidden tooltip for scanning (only once) -- Create hidden tooltip for scanning (only once)
local scanTooltip = nil
local function GetScanTooltip() local function GetScanTooltip()
if not scanTooltip then
scanTooltip = CreateFrame("GameTooltip", "GudaBagScanTooltip", nil, "GameTooltipTemplate")
scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
end
return scanTooltip return scanTooltip
end end
+44 -34
View File
@@ -27,42 +27,40 @@ end
-- Scan a single mail item -- Scan a single mail item
function MailboxScanner:ScanMailItem(index) function MailboxScanner:ScanMailItem(index)
-- GetInboxItem(index) returns: packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, hasItem, wasRead, wasReturned, textCreated, canReply, isGM -- GetInboxHeaderInfo(index) returns: packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, hasItem, wasRead, wasReturned, textCreated, canReply, isGM
local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, hasItem, wasRead, wasReturned, textCreated, canReply, isGM = GetInboxItem(index) local packageIcon, stationeryIcon, sender, subject, money, CODAmount, daysLeft, hasItem, wasRead, wasReturned, textCreated, canReply, isGM = GetInboxHeaderInfo(index)
local itemData = nil local items = {}
if hasItem then if hasItem then
addon:Debug("Scanning mail item %d", index) -- Turtle WoW supports up to 12 attachments per mail
-- In 1.12.1, GetInboxItemLink(index) returns the link -- GetInboxItem(index, itemIndex) returns: name, texture, count, quality, canUse
local itemLink = GetInboxItemLink(index) local name, texture, count, quality, canUse = GetInboxItem(index, itemIndex)
if name then
local itemLink = addon.Modules.Utils:GetInboxItemLink(index, itemIndex)
-- GetInboxItemInfo(index) returns: name, texture, count, quality, canUse local itemData = {
local infoName, infoTexture, infoCount, infoQuality, infoCanUse = GetInboxItemInfo(index) link = itemLink,
texture = texture or "Interface\\Icons\\INV_Misc_Bag_08",
count = count or 1,
quality = quality or 0,
name = name,
}
addon:Debug("Mail item %d: infoName=%s, infoTexture=%s", index, tostring(infoName), tostring(infoTexture)) -- If we have a link, try to get more detailed info
if itemLink then
-- Even if link is missing (not cached), we can store what we have from GetInboxItemInfo local itemName, link, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice = addon.Modules.Utils:GetItemInfo(itemLink)
itemData = { if itemName then
link = itemLink, itemData.name = itemName
texture = infoTexture or packageIcon or "Interface\\Icons\\INV_Misc_Bag_08", itemData.quality = itemQuality or itemData.quality
count = infoCount or 1, itemData.iLevel = iLevel
quality = infoQuality or 0, itemData.type = itemType
name = infoName or subject or "Unknown Item", itemData.class = itemCategory
} itemData.subclass = itemSubType
itemData.equipSlot = itemEquipLoc
-- If we have a link, try to get more detailed info if itemTexture then itemData.texture = itemTexture end
if itemLink then end
local itemName, link, itemQuality, iLevel, itemCategory, itemType, itemStackCount, itemSubType, itemTexture, itemEquipLoc, itemSellPrice = addon.Modules.Utils:GetItemInfo(itemLink) end
if itemName then table.insert(items, itemData)
itemData.name = itemName
itemData.quality = itemQuality or itemData.quality
itemData.iLevel = iLevel
itemData.type = itemType
itemData.class = itemCategory
itemData.subclass = itemSubType
itemData.equipSlot = itemEquipLoc
if itemTexture then itemData.texture = itemTexture end
end
end end
end end
@@ -72,8 +70,9 @@ function MailboxScanner:ScanMailItem(index)
money = money, money = money,
CODAmount = CODAmount, CODAmount = CODAmount,
daysLeft = daysLeft, daysLeft = daysLeft,
hasItem = hasItem, hasItem = (table.getn(items) > 0),
item = itemData, item = items[1],
items = items,
wasRead = wasRead, wasRead = wasRead,
packageIcon = packageIcon, packageIcon = packageIcon,
} }
@@ -111,6 +110,17 @@ function MailboxScanner:Initialize()
end) end)
end, "MailboxScanner") end, "MailboxScanner")
-- Register for GET_ITEM_INFO_RECEIVED to refresh if item data arrives
addon.Modules.Events:Register("GET_ITEM_INFO_RECEIVED", function()
if mailboxOpen then
addon:Debug("GET_ITEM_INFO_RECEIVED: Refreshing mailbox")
MailboxScanner:SaveToDatabase()
end
end, "MailboxScanner")
-- Register for UI_ERROR_MESSAGE to handle "item not found" situations if needed
-- (Some items might not be in cache and fail silently otherwise)
-- Mailbox closed -- Mailbox closed
addon.Modules.Events:OnMailClosed(function() addon.Modules.Events:OnMailClosed(function()
-- Final save on close -- Final save on close
+58 -13
View File
@@ -11,6 +11,8 @@ scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
-- Check if an item is a quest item by scanning its tooltip -- Check if an item is a quest item by scanning its tooltip
-- Check if an item is a quest item by scanning its tooltip and determine type -- Check if an item is a quest item by scanning its tooltip and determine type
local function IsQuestItem(bagID, slotID, isBank) local function IsQuestItem(bagID, slotID, isBank)
bagID = tonumber(bagID)
slotID = tonumber(slotID)
if not bagID or not slotID then return false end if not bagID or not slotID then return false end
scanTooltip:ClearLines() scanTooltip:ClearLines()
@@ -117,6 +119,8 @@ end
-- Scan tooltip for red text that is NOT a durability line -- Scan tooltip for red text that is NOT a durability line
local function IsItemUnusable(bagID, slotID, isBank) local function IsItemUnusable(bagID, slotID, isBank)
bagID = tonumber(bagID)
slotID = tonumber(slotID)
if not bagID or not slotID then return false end if not bagID or not slotID then return false end
-- Some clients require SetOwner before every SetBagItem/SetInventoryItem to populate lines -- Some clients require SetOwner before every SetBagItem/SetInventoryItem to populate lines
@@ -425,6 +429,10 @@ end
-- Set item data -- Set item data
function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCharName, matchesFilter, isReadOnly) function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCharName, matchesFilter, isReadOnly)
-- Proactively convert to number to avoid comparisons with strings in downstream functions
bagID = tonumber(bagID)
slotID = tonumber(slotID)
-- Proactively clear any previous cooldown overlay state before reassigning this pooled button -- Proactively clear any previous cooldown overlay state before reassigning this pooled button
do do
local cd = getglobal(self:GetName().."Cooldown") or self.cooldown local cd = getglobal(self:GetName().."Cooldown") or self.cooldown
@@ -459,6 +467,8 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
self.otherChar = otherCharName self.otherChar = otherCharName
self.isReadOnly = isReadOnly or false -- Track if this is read-only mode self.isReadOnly = isReadOnly or false -- Track if this is read-only mode
self.isMail = false -- Clear mailbox flag by default self.isMail = false -- Clear mailbox flag by default
self.mailIndex = nil
self.mailItemIndex = nil
-- Re-register for drag/drop every time (crucial for button reuse in Classic/Vanilla) -- Re-register for drag/drop every time (crucial for button reuse in Classic/Vanilla)
if not self.isReadOnly and not self.otherChar then if not self.isReadOnly and not self.otherChar then
@@ -486,6 +496,8 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
matchesFilter = true matchesFilter = true
end end
self.mailData = nil -- Clear mail metadata by default
-- Use Blizzard's default count fontstring (ContainerFrameItemButtonTemplate creates $parentCount) -- Use Blizzard's default count fontstring (ContainerFrameItemButtonTemplate creates $parentCount)
local countText = getglobal(self:GetName().."Count") local countText = getglobal(self:GetName().."Count")
local emptySlotBg = getglobal(self:GetName().."_EmptySlotBg") local emptySlotBg = getglobal(self:GetName().."_EmptySlotBg")
@@ -947,17 +959,7 @@ end
-- OnEnter handler (show tooltip) -- OnEnter handler (show tooltip)
function Guda_ItemButton_OnEnter(self) function Guda_ItemButton_OnEnter(self)
-- DETACH from Blizzard's internal tooltip logic for mailbox items -- Highlight the corresponding bag button in the footer (works for empty and filled slots)
if self.isMail or this.isMail or (this:GetParent() and this:GetParent():GetName() == "Guda_MailboxFrame_ItemContainer") then
return
end
-- Prevent Blizzard's ContainerFrameItemButton_OnEnter from running if it somehow got through
if not self.bagID or self.bagID == -100 then
return
end
-- Highlight the corresponding bag button in the footer (works for empty and filled slots)
if not self.otherChar and self.bagID then if not self.otherChar and self.bagID then
if self.isBank then if self.isBank then
-- Bank item - highlight bank bag button -- Bank item - highlight bank bag button
@@ -969,7 +971,7 @@ function Guda_ItemButton_OnEnter(self)
end end
-- Early return for empty slots (no tooltip needed) -- Early return for empty slots (no tooltip needed)
if not self.hasItem then if not self.hasItem and not self.isMail then
return return
end end
@@ -977,7 +979,50 @@ function Guda_ItemButton_OnEnter(self)
-- important position of tooltip -- important position of tooltip
GameTooltip:SetPoint("BOTTOMRIGHT", self, "TOPLEFT", 10, 0) GameTooltip:SetPoint("BOTTOMRIGHT", self, "TOPLEFT", 10, 0)
if self.otherChar or self.isReadOnly then -- Mailbox tooltip handling
if self.isMail then
local currentPlayerName = addon.Modules.DB:GetPlayerFullName()
if (not self.otherChar or self.otherChar == currentPlayerName) and self.mailIndex then
-- Live mailbox for current character
GameTooltip:SetInboxItem(self.mailIndex, self.mailItemIndex or 1)
elseif self.itemData and self.itemData.link then
-- Read-only / other character mailbox
GameTooltip.GudaViewedCharacter = self.otherChar
GameTooltip:SetHyperlink(self.itemData.link)
elseif self.itemData and self.itemData.name then
-- Money or generic mail
GameTooltip:AddLine(self.itemData.name, 1, 1, 1)
end
-- Add mailbox metadata if available
local mailData = self.mailData
if mailData then
-- If we already added a line (for money/generic), or SetHyperlink/SetInboxItem added lines,
-- we might want a separator if we're adding sender info.
if GameTooltip:NumLines() > 0 then
GameTooltip:AddLine(" ")
end
if mailData.sender then
GameTooltip:AddLine("From: " .. mailData.sender, 1, 1, 1)
end
if mailData.subject then
GameTooltip:AddLine("Subject: " .. mailData.subject, 1, 1, 0.8)
end
if (mailData.money or 0) > 0 and not (self.itemData and self.itemData.name == "Money") then
GameTooltip:AddLine("Money: " .. addon.Modules.Utils:FormatMoney(mailData.money), 1, 1, 1)
end
if (mailData.CODAmount or 0) > 0 then
GameTooltip:AddLine("COD: " .. addon.Modules.Utils:FormatMoney(mailData.CODAmount), 1, 0, 0)
end
if mailData.daysLeft then
GameTooltip:AddLine("Days left: " .. math.floor(mailData.daysLeft), 0.5, 0.5, 0.5)
end
end
GameTooltip:Show()
return
elseif self.otherChar or self.isReadOnly then
GameTooltip.GudaViewedCharacter = self.otherChar GameTooltip.GudaViewedCharacter = self.otherChar
if self.itemData and self.itemData.link then if self.itemData and self.itemData.link then
GameTooltip:SetHyperlink(self.itemData.link) GameTooltip:SetHyperlink(self.itemData.link)
+131 -104
View File
@@ -10,6 +10,9 @@ local currentViewChar = nil
local searchText = "" local searchText = ""
local isReadOnlyMode = true -- Mailbox is always read-only in this addon (viewing offline data) local isReadOnlyMode = true -- Mailbox is always read-only in this addon (viewing offline data)
local itemButtons = {} local itemButtons = {}
local mailboxRows = {}
local currentPage = 1
local ITEMS_PER_PAGE = 7
local mailboxClickCatcher = nil local mailboxClickCatcher = nil
-- OnLoad -- OnLoad
@@ -70,9 +73,23 @@ end
-- Show specific character's mailbox -- Show specific character's mailbox
function MailboxFrame:ShowCharacter(fullName) function MailboxFrame:ShowCharacter(fullName)
currentViewChar = fullName currentViewChar = fullName
currentPage = 1
self:Update() self:Update()
end end
-- Pagination
function MailboxFrame:NextPage()
currentPage = currentPage + 1
self:Update()
end
function MailboxFrame:PrevPage()
if currentPage > 1 then
currentPage = currentPage - 1
self:Update()
end
end
-- Initialize module -- Initialize module
function MailboxFrame:Initialize() function MailboxFrame:Initialize()
-- Register events if needed -- Register events if needed
@@ -105,13 +122,38 @@ function MailboxFrame:Update()
matchesSearch = true matchesSearch = true
elseif mail.subject and string.find(string.lower(mail.subject), searchText) then elseif mail.subject and string.find(string.lower(mail.subject), searchText) then
matchesSearch = true matchesSearch = true
elseif mail.items then
for _, item in ipairs(mail.items) do
if item.name and string.find(string.lower(item.name), searchText) then
matchesSearch = true
break
end
end
elseif mail.item and mail.item.name and string.find(string.lower(mail.item.name), searchText) then elseif mail.item and mail.item.name and string.find(string.lower(mail.item.name), searchText) then
matchesSearch = true matchesSearch = true
end end
end end
if matchesSearch then if matchesSearch then
table.insert(filteredItems, mail) -- Flatten mails with multiple items so they all show up in the grid
if mail.items and table.getn(mail.items) > 1 then
for itemIndex, item in ipairs(mail.items) do
local mailCopy = {}
for k, v in pairs(mail) do mailCopy[k] = v end
mailCopy.item = item
mailCopy.mailIndex = i
mailCopy.itemIndex = itemIndex
-- Clear items list in copy to avoid recursive flattening
mailCopy.items = nil
table.insert(filteredItems, mailCopy)
end
else
local mailCopy = {}
for k, v in pairs(mail) do mailCopy[k] = v end
mailCopy.mailIndex = i
mailCopy.itemIndex = 1
table.insert(filteredItems, mailCopy)
end
end end
end end
@@ -135,61 +177,76 @@ function MailboxFrame:Update()
MoneyFrame_Update("Guda_MailboxFrame_MoneyFrame", totalMoney) MoneyFrame_Update("Guda_MailboxFrame_MoneyFrame", totalMoney)
end end
-- Display mailbox items in a grid -- Display mailbox items in a list
function MailboxFrame:DisplayItems(items, charFullName) function MailboxFrame:DisplayItems(items, charFullName)
local container = getglobal("Guda_MailboxFrame_ItemContainer") local container = getglobal("Guda_MailboxFrame_ItemContainer")
-- Explicitly set container ID to -100 to avoid being picked up as a bag
if container.SetID then container:SetID(-100) end
local columns = 10 -- Hide all existing rows first
local buttonSize = 34 for _, row in pairs(mailboxRows) do
local spacing = 2 row:Hide()
-- Hide all existing buttons first
for _, button in pairs(itemButtons) do
button:Hide()
button.inUse = false
end end
local row = 0 local totalItems = table.getn(items)
local col = 0 local totalPages = math.max(1, math.ceil(totalItems / ITEMS_PER_PAGE))
for i, mail in ipairs(items) do if currentPage > totalPages then
local button = itemButtons[i] currentPage = totalPages
if not button then end
button = Guda_GetItemButton(container)
itemButtons[i] = button local startIndex = (currentPage - 1) * ITEMS_PER_PAGE + 1
local endIndex = math.min(startIndex + ITEMS_PER_PAGE - 1, totalItems)
local rowIndex = 1
for i = startIndex, endIndex do
local mail = items[i]
local row = mailboxRows[rowIndex]
if not row then
row = CreateFrame("Frame", "Guda_MailboxRow" .. rowIndex, container, "Guda_MailboxRowTemplate")
mailboxRows[rowIndex] = row
end end
-- Consistently set button size for the mailbox grid row:ClearAllPoints()
button:SetWidth(buttonSize) row:SetPoint("TOPLEFT", container, "TOPLEFT", 0, -(rowIndex - 1) * 55)
button:SetHeight(buttonSize)
button:ClearAllPoints() -- Fill row data
button:SetPoint("TOPLEFT", container, "TOPLEFT", col * (buttonSize + spacing), -row * (buttonSize + spacing)) getglobal(row:GetName() .. "_Sender"):SetText(mail.sender or "Unknown")
getglobal(row:GetName() .. "_Subject"):SetText(mail.subject or "No Subject")
-- Set button data local expireText = ""
button.isBank = false if mail.daysLeft then
button.otherChar = charFullName if mail.daysLeft < 1 then
button.isMail = true -- Custom flag for mailbox items expireText = string.format("|cffff0000%dh|r", math.floor(mail.daysLeft * 24))
button.inUse = true else
expireText = string.format("%dd", math.floor(mail.daysLeft))
end
end
getglobal(row:GetName() .. "_ExpireTime"):SetText(expireText)
-- Item Button
local itemButton = getglobal(row:GetName() .. "_ItemButton")
-- Re-assign shared namespace function if needed, but it should be available globally or via addon
itemButton.isBank = false
itemButton.otherChar = charFullName
itemButton.mailData = mail
itemButton.isMail = true
itemButton.mailIndex = mail.mailIndex
itemButton.mailItemIndex = mail.itemIndex or 1
if mail.item and (mail.item.texture or mail.item.link) then if mail.item and (mail.item.texture or mail.item.link) then
Guda_ItemButton_SetItem(button, nil, nil, mail.item, false, charFullName, true, true) Guda_ItemButton_SetItem(itemButton, nil, nil, mail.item, false, charFullName, true, true)
-- Re-enforce size because SetItem overrides it with global settings itemButton.isMail = true
button:SetWidth(buttonSize) itemButton.mailData = mail
button:SetHeight(buttonSize) itemButton.mailIndex = mail.mailIndex
button.isMail = true -- Re-apply after SetItem clears it itemButton.mailItemIndex = mail.itemIndex or 1
else else
-- Use SetItem with nil itemData to clear the button properly first Guda_ItemButton_SetItem(itemButton, nil, nil, nil, false, charFullName, true, true)
Guda_ItemButton_SetItem(button, nil, nil, nil, false, charFullName, true, true) itemButton.isMail = true
button:SetWidth(buttonSize) itemButton.mailData = mail
button:SetHeight(buttonSize) itemButton.mailIndex = mail.mailIndex
button.isMail = true -- Re-apply after SetItem clears it itemButton.mailItemIndex = 1
-- Then show our custom icon for money/mail local icon = getglobal(itemButton:GetName().."IconTexture") or getglobal(itemButton:GetName().."Icon")
button.itemData = nil
local icon = getglobal(button:GetName().."IconTexture") or getglobal(button:GetName().."Icon")
if icon then if icon then
if (mail.money or 0) > 0 then if (mail.money or 0) > 0 then
icon:SetTexture("Interface\\Icons\\INV_Misc_Coin_01") icon:SetTexture("Interface\\Icons\\INV_Misc_Coin_01")
@@ -201,73 +258,42 @@ function MailboxFrame:DisplayItems(items, charFullName)
icon:SetTexCoord(0.08, 0.92, 0.08, 0.92) icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
icon:Show() icon:Show()
end end
if itemButton.qualityBorder then itemButton.qualityBorder:Hide() end
if button.qualityBorder then button.qualityBorder:Hide() end
end end
-- Custom Tooltip for mail items -- Row Money Frame
button.mailData = mail -- Store data on button to avoid closure issues in Lua 5.0 local moneyFrame = getglobal(row:GetName() .. "_MoneyFrame")
button.isMail = true -- Redundant set to be safe if (mail.money or 0) > 0 then
button:SetScript("OnEnter", function() MoneyFrame_Update(moneyFrame:GetName(), mail.money)
-- Force detachment from Blizzard logic inside the closure as well moneyFrame:Show()
if this.SetID then this:SetID(0) end else
this.isMail = true moneyFrame:Hide()
local mailData = this.mailData
if not mailData then return end
-- Explicitly use GameTooltip:ClearLines() and SetOwner to ensure a clean tooltip
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
GameTooltip:ClearLines()
if mailData.item and mailData.item.link then
GameTooltip:SetHyperlink(mailData.item.link)
-- Add a gap if there's also sender/subject info to show
GameTooltip:AddLine(" ")
elseif mailData.item and mailData.item.name then
-- Fallback if we have item data but no link (e.g. not in cache yet)
GameTooltip:AddLine(mailData.item.name, 1, 1, 1)
GameTooltip:AddLine(" ")
end
GameTooltip:AddLine("From: " .. (mailData.sender or "Unknown"), 1, 1, 1)
GameTooltip:AddLine("Subject: " .. (mailData.subject or "No Subject"), 1, 1, 0.8)
if (mailData.money or 0) > 0 then
GameTooltip:AddLine("Money: " .. addon.Modules.Utils:FormatMoney(mailData.money), 1, 1, 1)
end
if (mailData.CODAmount or 0) > 0 then
GameTooltip:AddLine("COD: " .. addon.Modules.Utils:FormatMoney(mailData.CODAmount), 1, 0, 0)
end
if mailData.daysLeft then
GameTooltip:AddLine("Days left: " .. math.floor(mailData.daysLeft), 0.5, 0.5, 0.5)
end
GameTooltip:Show()
end)
button:SetScript("OnLeave", function()
GameTooltip:Hide()
end)
-- Mailbox is read-only, so no clicking/dragging
button:RegisterForClicks()
button:SetScript("OnClick", nil)
button:SetScript("OnDragStart", nil)
button:SetScript("OnReceiveDrag", nil)
button:Show()
col = col + 1
if col >= columns then
col = 0
row = row + 1
end end
row:Show()
rowIndex = rowIndex + 1
end end
-- Adjust container height -- Update pagination buttons
local totalRows = row + (col > 0 and 1 or 0) local prevBtn = getglobal("Guda_MailboxFrame_PrevPageButton")
container:SetHeight(math.max(420, totalRows * (buttonSize + spacing))) local nextBtn = getglobal("Guda_MailboxFrame_NextPageButton")
if currentPage > 1 then
prevBtn:Enable()
else
prevBtn:Disable()
end
if currentPage < totalPages then
nextBtn:Enable()
else
nextBtn:Disable()
end
-- Update page text in footer
local footerFontString = getglobal("Guda_MailboxFrame_Footer_Text")
local footerText = footerFontString:GetText() or ""
footerFontString:SetText(footerText .. " (Page " .. currentPage .. " of " .. totalPages .. ")")
end end
-- Search text changed -- Search text changed
@@ -279,6 +305,7 @@ function Guda_MailboxFrame_OnSearchTextChanged()
else else
searchText = string.lower(text) searchText = string.lower(text)
end end
currentPage = 1
MailboxFrame:Update() MailboxFrame:Update()
end end
+113
View File
@@ -1,6 +1,82 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" <Ui xmlns="http://www.blizzard.com/wow/ui/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/">
<!-- Mailbox Row Template -->
<Frame name="Guda_MailboxRowTemplate" virtual="true">
<Size>
<AbsDimension x="360" y="50"/>
</Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parent_Background">
<Anchors>
<Anchor point="TOPLEFT"/>
<Anchor point="BOTTOMRIGHT"/>
</Anchors>
<Color r="1" g="1" b="1" a="0.05"/>
</Texture>
</Layer>
<Layer level="ARTWORK">
<FontString name="$parent_Sender" inherits="GameFontNormal" justifyH="LEFT">
<Size>
<AbsDimension x="140" y="16"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="60" y="-8"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="$parent_Subject" inherits="GameFontHighlightSmall" justifyH="LEFT">
<Size>
<AbsDimension x="280" y="14"/>
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parent_Sender" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="-2"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
<FontString name="$parent_ExpireTime" inherits="GameFontDisableSmall" justifyH="RIGHT">
<Size>
<AbsDimension x="100" y="12"/>
</Size>
<Anchors>
<Anchor point="TOPRIGHT">
<Offset>
<AbsDimension x="-10" y="-8"/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="$parent_ItemButton" inherits="Guda_ItemButtonTemplate">
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT">
<Offset>
<AbsDimension x="10" y="0"/>
</Offset>
</Anchor>
</Anchors>
</Button>
<Frame name="$parent_MoneyFrame" inherits="SmallMoneyFrameTemplate">
<Anchors>
<Anchor point="BOTTOMRIGHT">
<Offset>
<AbsDimension x="-10" y="8"/>
</Offset>
</Anchor>
</Anchors>
</Frame>
</Frames>
</Frame>
<!-- Mailbox Frame --> <!-- Mailbox Frame -->
<Frame name="Guda_MailboxFrame" toplevel="true" movable="true" enableMouse="true" hidden="true" parent="UIParent"> <Frame name="Guda_MailboxFrame" toplevel="true" movable="true" enableMouse="true" hidden="true" parent="UIParent">
<Size> <Size>
@@ -224,6 +300,43 @@
</Anchor> </Anchor>
</Anchors> </Anchors>
</Frame> </Frame>
<!-- Pagination -->
<Button name="$parent_PrevPageButton" inherits="UIPanelButtonTemplate" text="Prev">
<Size>
<AbsDimension x="60" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOMLEFT">
<Offset>
<AbsDimension x="120" y="10"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Guda.Modules.MailboxFrame:PrevPage()
</OnClick>
</Scripts>
</Button>
<Button name="$parent_NextPageButton" inherits="UIPanelButtonTemplate" text="Next">
<Size>
<AbsDimension x="60" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOMRIGHT" relativeTo="$parent_MoneyFrame" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="-10" y="0"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
Guda.Modules.MailboxFrame:NextPage()
</OnClick>
</Scripts>
</Button>
</Frames> </Frames>
<Scripts> <Scripts>