feat: mailbox bug
This commit is contained in:
+113
@@ -1578,6 +1578,119 @@ local function HideCharacterDropdown()
|
||||
end
|
||||
end
|
||||
|
||||
-- Toggle mail dropdown
|
||||
function Guda_BagFrame_ToggleMailDropdown(button)
|
||||
-- Hide character dropdown if it's shown
|
||||
if characterDropdown and characterDropdown:IsShown() then
|
||||
characterDropdown:Hide()
|
||||
end
|
||||
|
||||
if bankDropdown and bankDropdown:IsShown() then
|
||||
bankDropdown:Hide()
|
||||
end
|
||||
|
||||
if mailDropdown and mailDropdown:IsShown() then
|
||||
mailDropdown:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
if not mailDropdown then
|
||||
-- Create dropdown frame
|
||||
mailDropdown = CreateFrame("Frame", "Guda_MailDropdown", UIParent)
|
||||
mailDropdown:SetFrameStrata("DIALOG")
|
||||
mailDropdown:SetWidth(200)
|
||||
mailDropdown:SetBackdrop({
|
||||
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
||||
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
|
||||
tile = true,
|
||||
tileSize = 16,
|
||||
edgeSize = 16,
|
||||
insets = { left = 4, right = 4, top = 4, bottom = 4 }
|
||||
})
|
||||
mailDropdown:SetBackdropColor(0, 0, 0, 0.95)
|
||||
mailDropdown:EnableMouse(true)
|
||||
mailDropdown:Hide()
|
||||
|
||||
mailDropdown.buttons = {}
|
||||
end
|
||||
|
||||
-- Position dropdown below the button
|
||||
mailDropdown:ClearAllPoints()
|
||||
mailDropdown:SetPoint("TOPLEFT", button, "BOTTOMLEFT", 0, -2)
|
||||
-- Clear existing buttons
|
||||
for _, btn in ipairs(mailDropdown.buttons) do
|
||||
btn:Hide()
|
||||
end
|
||||
mailDropdown.buttons = {}
|
||||
|
||||
-- Get all characters on current realm
|
||||
local chars = addon.Modules.DB:GetAllCharacters(false, true)
|
||||
|
||||
local yOffset = -8
|
||||
|
||||
-- Add character buttons
|
||||
for _, char in ipairs(chars) do
|
||||
-- Capture variables in local scope for closure
|
||||
local charFullName = char.fullName
|
||||
local charName = char.name
|
||||
local charClassToken = char.classToken
|
||||
|
||||
local charButton = CreateFrame("Button", nil, mailDropdown)
|
||||
charButton:SetWidth(188)
|
||||
charButton:SetHeight(20)
|
||||
charButton:SetPoint("TOP", mailDropdown, "TOP", 0, yOffset)
|
||||
|
||||
-- Button background on hover
|
||||
local charBg = charButton:CreateTexture(nil, "BACKGROUND")
|
||||
charBg:SetAllPoints()
|
||||
charBg:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
|
||||
charBg:SetBlendMode("ADD")
|
||||
charBg:SetAlpha(0)
|
||||
|
||||
-- Get class color
|
||||
local classColor = charClassToken and RAID_CLASS_COLORS[charClassToken]
|
||||
local r, g, b = 1, 1, 1
|
||||
if classColor then
|
||||
r, g, b = classColor.r, classColor.g, classColor.b
|
||||
end
|
||||
|
||||
-- Button text
|
||||
local charText = charButton:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
|
||||
charText:SetPoint("LEFT", charButton, "LEFT", 8, 0)
|
||||
charText:SetText(charName)
|
||||
charText:SetTextColor(r, g, b)
|
||||
|
||||
-- Button scripts
|
||||
charButton:SetScript("OnEnter", function()
|
||||
charBg:SetAlpha(0.3)
|
||||
end)
|
||||
charButton:SetScript("OnLeave", function()
|
||||
charBg:SetAlpha(0)
|
||||
end)
|
||||
charButton:SetScript("OnClick", function()
|
||||
if charFullName then
|
||||
-- Show mailbox for this character
|
||||
addon.Modules.MailboxFrame:ShowCharacter(charFullName)
|
||||
if not Guda_MailboxFrame:IsShown() then
|
||||
Guda_MailboxFrame:Show()
|
||||
end
|
||||
mailDropdown:Hide()
|
||||
else
|
||||
addon:Print("Error: Character fullName is nil")
|
||||
end
|
||||
end)
|
||||
|
||||
table.insert(mailDropdown.buttons, charButton)
|
||||
yOffset = yOffset - 20
|
||||
end
|
||||
|
||||
-- Set dropdown height based on content
|
||||
mailDropdown:SetHeight(math.abs(yOffset) + 8)
|
||||
|
||||
-- Show dropdown
|
||||
mailDropdown:Show()
|
||||
end
|
||||
|
||||
-- Toggle bank dropdown
|
||||
function Guda_BagFrame_ToggleBankDropdown(button)
|
||||
-- Hide character dropdown if it's shown
|
||||
|
||||
@@ -248,6 +248,52 @@
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<!-- Mail Button (header left, next to bank) -->
|
||||
<Button name="$parent_MailButton">
|
||||
<Size>
|
||||
<AbsDimension x="24" y="24"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT" relativePoint="RIGHT" relativeTo="$parent_BankButton">
|
||||
<Offset>
|
||||
<AbsDimension x="2" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parent_Icon">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER"/>
|
||||
</Anchors>
|
||||
<Color r="0.8" g="0.8" b="0.8"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
local icon = getglobal(this:GetName().."_Icon")
|
||||
if icon then
|
||||
icon:SetTexture("Interface\\Icons\\INV_Letter_15")
|
||||
end
|
||||
</OnLoad>
|
||||
<OnClick>
|
||||
Guda_BagFrame_ToggleMailDropdown(this)
|
||||
</OnClick>
|
||||
<OnEnter>
|
||||
GameTooltip:SetOwner(this, "ANCHOR_TOP")
|
||||
GameTooltip:SetText("View Mailbox")
|
||||
GameTooltip:Show()
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
GameTooltip:Hide()
|
||||
</OnLeave>
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<!-- Toolbar Container (for money tooltip and bag slots) -->
|
||||
<Frame name="$parent_Toolbar" enableMouse="true">
|
||||
<Size>
|
||||
|
||||
@@ -107,6 +107,52 @@
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<!-- Mail Button (header right, next to sort) -->
|
||||
<Button name="$parent_MailButton">
|
||||
<Size>
|
||||
<AbsDimension x="24" y="24"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="RIGHT" relativePoint="LEFT" relativeTo="$parent_SortButton">
|
||||
<Offset>
|
||||
<AbsDimension x="-2" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parent_Icon">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER"/>
|
||||
</Anchors>
|
||||
<Color r="0.8" g="0.8" b="0.8"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
local icon = getglobal(this:GetName().."_Icon")
|
||||
if icon then
|
||||
icon:SetTexture("Interface\\Icons\\INV_Letter_15")
|
||||
end
|
||||
</OnLoad>
|
||||
<OnClick>
|
||||
Guda_MailboxFrame:Toggle()
|
||||
</OnClick>
|
||||
<OnEnter>
|
||||
GameTooltip:SetOwner(this, "ANCHOR_TOP")
|
||||
GameTooltip:SetText("View Mailbox")
|
||||
GameTooltip:Show()
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
GameTooltip:Hide()
|
||||
</OnLeave>
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<!-- Settings Button (header right, next to close) -->
|
||||
<Button name="$parent_SettingsButton">
|
||||
<Size>
|
||||
|
||||
+33
-5
@@ -447,13 +447,18 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
||||
self.bagID = bagID
|
||||
self.slotID = slotID
|
||||
-- Also set the Blizzard slot ID for compatibility with ContainerFrameItemButtonTemplate behavior
|
||||
if self.SetID and slotID then
|
||||
self:SetID(slotID)
|
||||
-- ALWAYS set ID to something (0 if nil) to avoid leaking old IDs when button is reused
|
||||
if self.SetID then
|
||||
self:SetID(slotID or 0)
|
||||
end
|
||||
-- Explicitly set bag index to avoid Blizzard's ContainerFrameItemButton_OnEnter logic
|
||||
-- from picking up this button as part of a real bag.
|
||||
self.bagIndex = bagID or -100 -- Use an invalid bag index for non-bag buttons
|
||||
self.itemData = itemData
|
||||
self.isBank = isBank or false
|
||||
self.otherChar = otherCharName
|
||||
self.isReadOnly = isReadOnly or false -- Track if this is read-only mode
|
||||
self.isMail = false -- Clear mailbox flag by default
|
||||
|
||||
-- Re-register for drag/drop every time (crucial for button reuse in Classic/Vanilla)
|
||||
if not self.isReadOnly and not self.otherChar then
|
||||
@@ -538,7 +543,17 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
||||
|
||||
-- Apply the determined texture and count
|
||||
if self.hasItem then
|
||||
if SetItemButtonTexture then SetItemButtonTexture(self, displayTexture) end
|
||||
if SetItemButtonTexture then
|
||||
SetItemButtonTexture(self, displayTexture)
|
||||
end
|
||||
|
||||
-- Explicitly set and show icon texture as SetItemButtonTexture can be unreliable for custom paths in 1.12
|
||||
local iconTexture = getglobal(self:GetName().."IconTexture") or getglobal(self:GetName().."Icon") or self.icon or self.Icon
|
||||
if iconTexture and displayTexture then
|
||||
iconTexture:SetTexture(displayTexture)
|
||||
iconTexture:Show()
|
||||
end
|
||||
|
||||
if SetItemButtonCount then SetItemButtonCount(self, displayCount or 1) end
|
||||
if emptySlotBg then emptySlotBg:Hide() end
|
||||
-- Update cooldown overlay for live items
|
||||
@@ -625,6 +640,9 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
||||
-- For 1.12.1 compatibility, access textures using both methods and proper naming
|
||||
-- We'll set the NormalTexture later based on whether slot is empty or filled
|
||||
|
||||
-- ICON TEXTURE: Ensure we use the correct name ($parentIconTexture is standard)
|
||||
local iconTexture = getglobal(self:GetName().."IconTexture") or getglobal(self:GetName().."Icon") or self.icon or self.Icon
|
||||
|
||||
-- Pushed texture follows the button size/position
|
||||
local pushedTexture = getglobal(self:GetName().."PushedTexture")
|
||||
if not pushedTexture and self.GetPushedTexture then
|
||||
@@ -920,8 +938,8 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
||||
self.questIcon:ClearAllPoints()
|
||||
self.questIcon:SetPoint("TOPRIGHT", self, "TOPRIGHT", 1, 0)
|
||||
end
|
||||
else
|
||||
-- Hide icon for empty slots
|
||||
elseif not self.isMail then
|
||||
-- Hide icon for empty slots, but keep it for mailbox custom icons
|
||||
iconTexture:Hide()
|
||||
end
|
||||
end
|
||||
@@ -929,6 +947,16 @@ end
|
||||
|
||||
-- OnEnter handler (show tooltip)
|
||||
function Guda_ItemButton_OnEnter(self)
|
||||
-- DETACH from Blizzard's internal tooltip logic for mailbox items
|
||||
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 self.isBank then
|
||||
|
||||
@@ -0,0 +1,302 @@
|
||||
-- Mailbox Frame
|
||||
-- Mailbox viewing UI
|
||||
|
||||
local addon = Guda
|
||||
|
||||
local MailboxFrame = {}
|
||||
addon.Modules.MailboxFrame = MailboxFrame
|
||||
|
||||
local currentViewChar = nil
|
||||
local searchText = ""
|
||||
local isReadOnlyMode = true -- Mailbox is always read-only in this addon (viewing offline data)
|
||||
local itemButtons = {}
|
||||
local mailboxClickCatcher = nil
|
||||
|
||||
-- OnLoad
|
||||
function Guda_MailboxFrame_OnLoad(self)
|
||||
-- Set up initial backdrop
|
||||
addon:ApplyBackdrop(self, "DEFAULT_FRAME")
|
||||
|
||||
-- Set up search box placeholder
|
||||
local searchBox = getglobal(self:GetName().."_SearchBar_SearchBox")
|
||||
if searchBox then
|
||||
searchBox:SetText("Search mailbox...")
|
||||
searchBox:SetTextColor(0.5, 0.5, 0.5, 1)
|
||||
end
|
||||
|
||||
-- Create invisible full-screen frame to catch clicks outside the mailbox frame while typing in search
|
||||
if not mailboxClickCatcher then
|
||||
mailboxClickCatcher = CreateFrame("Frame", "Guda_MailboxClickCatcher", UIParent)
|
||||
mailboxClickCatcher:SetFrameStrata("BACKGROUND")
|
||||
mailboxClickCatcher:SetAllPoints(UIParent)
|
||||
mailboxClickCatcher:EnableMouse(true)
|
||||
mailboxClickCatcher:Hide()
|
||||
|
||||
mailboxClickCatcher:SetScript("OnMouseDown", function()
|
||||
if Guda_MailboxFrame_ClearSearch then
|
||||
Guda_MailboxFrame_ClearSearch()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- Clear search focus
|
||||
function Guda_MailboxFrame_ClearSearch()
|
||||
local searchBox = getglobal("Guda_MailboxFrame_SearchBar_SearchBox")
|
||||
if searchBox then
|
||||
searchBox:ClearFocus()
|
||||
end
|
||||
end
|
||||
|
||||
-- OnShow
|
||||
function Guda_MailboxFrame_OnShow(self)
|
||||
-- Apply frame transparency
|
||||
if Guda_ApplyBackgroundTransparency then
|
||||
Guda_ApplyBackgroundTransparency()
|
||||
end
|
||||
|
||||
MailboxFrame:Update()
|
||||
end
|
||||
|
||||
-- Toggle visibility
|
||||
function MailboxFrame:Toggle()
|
||||
if Guda_MailboxFrame:IsShown() then
|
||||
Guda_MailboxFrame:Hide()
|
||||
else
|
||||
Guda_MailboxFrame:Show()
|
||||
end
|
||||
end
|
||||
|
||||
-- Show specific character's mailbox
|
||||
function MailboxFrame:ShowCharacter(fullName)
|
||||
currentViewChar = fullName
|
||||
self:Update()
|
||||
end
|
||||
|
||||
-- Initialize module
|
||||
function MailboxFrame:Initialize()
|
||||
-- Register events if needed
|
||||
end
|
||||
|
||||
-- Update the mailbox frame
|
||||
function MailboxFrame:Update()
|
||||
if not Guda_MailboxFrame:IsShown() then return end
|
||||
|
||||
-- Determine which character to show
|
||||
local charFullName = currentViewChar or addon.Modules.DB:GetPlayerFullName()
|
||||
local mailboxData = addon.Modules.DB:GetCharacterMailbox(charFullName)
|
||||
|
||||
-- Extract character name from fullName
|
||||
local charName = charFullName
|
||||
local dashPos = string.find(charFullName, "-")
|
||||
if dashPos then
|
||||
charName = string.sub(charFullName, 1, dashPos - 1)
|
||||
end
|
||||
|
||||
getglobal("Guda_MailboxFrame_Title"):SetText(charName .. "'s Mailbox")
|
||||
|
||||
-- Filter items based on search text
|
||||
local filteredItems = {}
|
||||
for i, mail in ipairs(mailboxData) do
|
||||
local matchesSearch = true
|
||||
if searchText ~= "" then
|
||||
matchesSearch = false
|
||||
if mail.sender and string.find(string.lower(mail.sender), searchText) then
|
||||
matchesSearch = true
|
||||
elseif mail.subject and string.find(string.lower(mail.subject), searchText) then
|
||||
matchesSearch = true
|
||||
elseif mail.item and mail.item.name and string.find(string.lower(mail.item.name), searchText) then
|
||||
matchesSearch = true
|
||||
end
|
||||
end
|
||||
|
||||
if matchesSearch then
|
||||
table.insert(filteredItems, mail)
|
||||
end
|
||||
end
|
||||
|
||||
-- Display items
|
||||
self:DisplayItems(filteredItems, charFullName)
|
||||
|
||||
-- Update footer info
|
||||
local totalItems = table.getn(mailboxData)
|
||||
local displayedItems = table.getn(filteredItems)
|
||||
local footerText = string.format("Items: %d", totalItems)
|
||||
if searchText ~= "" then
|
||||
footerText = string.format("Filtered: %d / %d", displayedItems, totalItems)
|
||||
end
|
||||
getglobal("Guda_MailboxFrame_Footer_Text"):SetText(footerText)
|
||||
|
||||
-- Update money (total money in mailbox)
|
||||
local totalMoney = 0
|
||||
for _, mail in ipairs(mailboxData) do
|
||||
totalMoney = totalMoney + (mail.money or 0)
|
||||
end
|
||||
MoneyFrame_Update("Guda_MailboxFrame_MoneyFrame", totalMoney)
|
||||
end
|
||||
|
||||
-- Display mailbox items in a grid
|
||||
function MailboxFrame:DisplayItems(items, charFullName)
|
||||
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
|
||||
local buttonSize = 34
|
||||
local spacing = 2
|
||||
|
||||
-- Hide all existing buttons first
|
||||
for _, button in pairs(itemButtons) do
|
||||
button:Hide()
|
||||
button.inUse = false
|
||||
end
|
||||
|
||||
local row = 0
|
||||
local col = 0
|
||||
|
||||
for i, mail in ipairs(items) do
|
||||
local button = itemButtons[i]
|
||||
if not button then
|
||||
button = Guda_GetItemButton(container)
|
||||
itemButtons[i] = button
|
||||
end
|
||||
|
||||
-- Consistently set button size for the mailbox grid
|
||||
button:SetWidth(buttonSize)
|
||||
button:SetHeight(buttonSize)
|
||||
|
||||
button:ClearAllPoints()
|
||||
button:SetPoint("TOPLEFT", container, "TOPLEFT", col * (buttonSize + spacing), -row * (buttonSize + spacing))
|
||||
|
||||
-- Set button data
|
||||
button.isBank = false
|
||||
button.otherChar = charFullName
|
||||
button.isMail = true -- Custom flag for mailbox items
|
||||
button.inUse = true
|
||||
|
||||
if mail.item and (mail.item.texture or mail.item.link) then
|
||||
Guda_ItemButton_SetItem(button, nil, nil, mail.item, false, charFullName, true, true)
|
||||
-- Re-enforce size because SetItem overrides it with global settings
|
||||
button:SetWidth(buttonSize)
|
||||
button:SetHeight(buttonSize)
|
||||
button.isMail = true -- Re-apply after SetItem clears it
|
||||
else
|
||||
-- Use SetItem with nil itemData to clear the button properly first
|
||||
Guda_ItemButton_SetItem(button, nil, nil, nil, false, charFullName, true, true)
|
||||
button:SetWidth(buttonSize)
|
||||
button:SetHeight(buttonSize)
|
||||
button.isMail = true -- Re-apply after SetItem clears it
|
||||
|
||||
-- Then show our custom icon for money/mail
|
||||
button.itemData = nil
|
||||
local icon = getglobal(button:GetName().."IconTexture") or getglobal(button:GetName().."Icon")
|
||||
if icon then
|
||||
if (mail.money or 0) > 0 then
|
||||
icon:SetTexture("Interface\\Icons\\INV_Misc_Coin_01")
|
||||
elseif mail.packageIcon then
|
||||
icon:SetTexture(mail.packageIcon)
|
||||
else
|
||||
icon:SetTexture("Interface\\Icons\\INV_Letter_15")
|
||||
end
|
||||
icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
|
||||
icon:Show()
|
||||
end
|
||||
|
||||
if button.qualityBorder then button.qualityBorder:Hide() end
|
||||
end
|
||||
|
||||
-- Custom Tooltip for mail items
|
||||
button.mailData = mail -- Store data on button to avoid closure issues in Lua 5.0
|
||||
button.isMail = true -- Redundant set to be safe
|
||||
button:SetScript("OnEnter", function()
|
||||
-- Force detachment from Blizzard logic inside the closure as well
|
||||
if this.SetID then this:SetID(0) end
|
||||
this.isMail = true
|
||||
|
||||
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
|
||||
|
||||
-- Adjust container height
|
||||
local totalRows = row + (col > 0 and 1 or 0)
|
||||
container:SetHeight(math.max(420, totalRows * (buttonSize + spacing)))
|
||||
end
|
||||
|
||||
-- Search text changed
|
||||
function Guda_MailboxFrame_OnSearchTextChanged()
|
||||
local searchBox = getglobal("Guda_MailboxFrame_SearchBar_SearchBox")
|
||||
local text = searchBox:GetText()
|
||||
if text == "Search mailbox..." then
|
||||
searchText = ""
|
||||
else
|
||||
searchText = string.lower(text)
|
||||
end
|
||||
MailboxFrame:Update()
|
||||
end
|
||||
|
||||
-- Show character selection menu
|
||||
function Guda_MailboxFrame_ShowCharacterMenu()
|
||||
local characters = addon.Modules.DB:GetAllCharacters(true, true)
|
||||
local menu = {}
|
||||
|
||||
for i, char in ipairs(characters) do
|
||||
local charFullName = char.fullName
|
||||
table.insert(menu, {
|
||||
text = char.name,
|
||||
func = function() MailboxFrame:ShowCharacter(charFullName) end,
|
||||
checked = (currentViewChar == char.fullName or (not currentViewChar and char.fullName == addon.Modules.DB:GetPlayerFullName()))
|
||||
})
|
||||
end
|
||||
|
||||
-- EasyMenu is available in 1.12.1
|
||||
local menuFrame = CreateFrame("Frame", "Guda_MailboxCharacterMenu", UIParent, "UIDropDownMenuTemplate")
|
||||
EasyMenu(menu, menuFrame, "cursor", 0, 0, "MENU")
|
||||
end
|
||||
@@ -0,0 +1,244 @@
|
||||
<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/">
|
||||
|
||||
<!-- Mailbox Frame -->
|
||||
<Frame name="Guda_MailboxFrame" toplevel="true" movable="true" enableMouse="true" hidden="true" parent="UIParent">
|
||||
<Size>
|
||||
<AbsDimension x="420" y="540"/>
|
||||
</Size>
|
||||
|
||||
<Anchors>
|
||||
<Anchor point="CENTER" relativePoint="CENTER" relativeTo="UIParent">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
|
||||
<Backdrop bgFile="Interface\ChatFrame\ChatFrameBackground" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true">
|
||||
<BackgroundInsets>
|
||||
<AbsInset left="11" right="12" top="12" bottom="11"/>
|
||||
</BackgroundInsets>
|
||||
<TileSize>
|
||||
<AbsValue val="16"/>
|
||||
</TileSize>
|
||||
<EdgeSize>
|
||||
<AbsValue val="32"/>
|
||||
</EdgeSize>
|
||||
</Backdrop>
|
||||
|
||||
<Layers>
|
||||
<!-- Title at top -->
|
||||
<Layer level="ARTWORK">
|
||||
<FontString name="$parent_Title" inherits="GameFontNormalLarge">
|
||||
<Anchors>
|
||||
<Anchor point="TOP">
|
||||
<Offset>
|
||||
<AbsDimension x="0" y="-12"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
|
||||
<Frames>
|
||||
<!-- Close Button -->
|
||||
<Button name="$parent_CloseButton" inherits="UIPanelCloseButton">
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT">
|
||||
<Offset>
|
||||
<AbsDimension x="-16" y="-10"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick>
|
||||
Guda_MailboxFrame:Hide()
|
||||
</OnClick>
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<!-- Search Bar -->
|
||||
<Frame name="$parent_SearchBar" inherits="OptionFrameBoxTemplate">
|
||||
<Size>
|
||||
<AbsDimension x="250" y="32"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="20" y="-35"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Frames>
|
||||
<EditBox name="$parent_SearchBox" autoFocus="false" inherits="InputBoxTemplate">
|
||||
<Size>
|
||||
<AbsDimension x="240" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="5" y="0"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnTextChanged>
|
||||
Guda_MailboxFrame_OnSearchTextChanged()
|
||||
</OnTextChanged>
|
||||
<OnEscapePressed>
|
||||
this:ClearFocus()
|
||||
</OnEscapePressed>
|
||||
<OnEnterPressed>
|
||||
this:ClearFocus()
|
||||
</OnEnterPressed>
|
||||
<OnEditFocusGained>
|
||||
if this:GetText() == "Search mailbox..." then
|
||||
this:SetText("")
|
||||
this:SetTextColor(1, 1, 1, 1)
|
||||
end
|
||||
if Guda_MailboxClickCatcher then
|
||||
Guda_MailboxClickCatcher:Show()
|
||||
end
|
||||
</OnEditFocusGained>
|
||||
<OnEditFocusLost>
|
||||
if this:GetText() == "" then
|
||||
this:SetText("Search mailbox...")
|
||||
this:SetTextColor(0.5, 0.5, 0.5, 1)
|
||||
end
|
||||
if Guda_MailboxClickCatcher then
|
||||
Guda_MailboxClickCatcher:Hide()
|
||||
end
|
||||
</OnEditFocusLost>
|
||||
</Scripts>
|
||||
</EditBox>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
this:SetBackdropBorderColor(0.4, 0.4, 0.4)
|
||||
this:SetBackdropColor(0.15, 0.15, 0.15, 0.5)
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
|
||||
<!-- Character Selection Button -->
|
||||
<Button name="$parent_CharacterButton">
|
||||
<Size>
|
||||
<AbsDimension x="24" y="24"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT">
|
||||
<Offset>
|
||||
<AbsDimension x="-20" y="-40"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<Texture name="$parent_Icon">
|
||||
<Size>
|
||||
<AbsDimension x="20" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER"/>
|
||||
</Anchors>
|
||||
<Color r="0.8" g="0.8" b="0.8"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
local icon = getglobal(this:GetName().."_Icon")
|
||||
if icon then
|
||||
icon:SetTexture("Interface\\AddOns\\Guda\\Assets\\All_Characters")
|
||||
end
|
||||
</OnLoad>
|
||||
<OnClick>
|
||||
Guda_MailboxFrame_ShowCharacterMenu()
|
||||
</OnClick>
|
||||
<OnEnter>
|
||||
GameTooltip:SetOwner(this, "ANCHOR_TOP")
|
||||
GameTooltip:SetText("Switch Character")
|
||||
GameTooltip:Show()
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
GameTooltip:Hide()
|
||||
</OnLeave>
|
||||
</Scripts>
|
||||
</Button>
|
||||
|
||||
<!-- Scroll Frame for Items -->
|
||||
<ScrollFrame name="$parent_ScrollFrame" inherits="UIPanelScrollFrameTemplate">
|
||||
<Size>
|
||||
<AbsDimension x="360" y="420"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="20" y="-75"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<ScrollChild>
|
||||
<Frame name="Guda_MailboxFrame_ItemContainer">
|
||||
<Size>
|
||||
<AbsDimension x="360" y="420"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT"/>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
</ScrollChild>
|
||||
</ScrollFrame>
|
||||
|
||||
<!-- Footer for stats/info -->
|
||||
<Frame name="$parent_Footer">
|
||||
<Size>
|
||||
<AbsDimension x="380" y="20"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT">
|
||||
<Offset>
|
||||
<AbsDimension x="20" y="15"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString name="$parent_Text" inherits="GameFontHighlightSmall" justifyH="LEFT">
|
||||
<Anchors>
|
||||
<Anchor point="LEFT"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</Frame>
|
||||
|
||||
<Frame name="$parent_MoneyFrame" inherits="SmallMoneyFrameTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT">
|
||||
<Offset>
|
||||
<AbsDimension x="-15" y="10"/>
|
||||
</Offset>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Frame>
|
||||
</Frames>
|
||||
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
Guda_MailboxFrame_OnLoad(this)
|
||||
</OnLoad>
|
||||
<OnShow>
|
||||
Guda_MailboxFrame_OnShow(this)
|
||||
</OnShow>
|
||||
<OnMouseDown>
|
||||
this:StartMoving()
|
||||
</OnMouseDown>
|
||||
<OnMouseUp>
|
||||
this:StopMovingOrSizing()
|
||||
</OnMouseUp>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
</Ui>
|
||||
Reference in New Issue
Block a user