Merge pull request #2 from

bug fixing
This commit is contained in:
Vati
2025-11-22 04:36:57 +04:00
committed by GitHub
11 changed files with 2069 additions and 1679 deletions
+1 -1
View File
@@ -117,7 +117,7 @@ end
-- Get current player's full name -- Get current player's full name
function DB:GetPlayerFullName() function DB:GetPlayerFullName()
return playerName return playerName .. "-" .. playerRealm
end end
-- Get current character data -- Get current character data
+69 -12
View File
@@ -218,6 +218,8 @@ function Tooltip:AddInventoryInfo(tooltip, link)
local totalCount = totalBags + totalBank + totalEquipped local totalCount = totalBags + totalBank + totalEquipped
if hasAnyItems then if hasAnyItems then
-- Top padding above the Inventory block (~10-12px visually)
tooltip:AddLine(" ") tooltip:AddLine(" ")
-- Inventory label in exact bag frame title color -- Inventory label in exact bag frame title color
@@ -263,8 +265,8 @@ function Tooltip:AddInventoryInfo(tooltip, link)
tooltip:AddDoubleLine(displayName, countText, r, g, b, 1.0, 1.0, 1.0) tooltip:AddDoubleLine(displayName, countText, r, g, b, 1.0, 1.0, 1.0)
end end
-- Add small gap between inventory data and vendor sell price -- Bottom padding below the Inventory block (~10-12px visually)
tooltip:AddLine(" ") --tooltip:AddLine(" ")
tooltip:Show() tooltip:Show()
end end
@@ -275,6 +277,32 @@ function Tooltip:Initialize()
-- Helper function to defer vendor money so we can insert our Inventory block above it -- Helper function to defer vendor money so we can insert our Inventory block above it
local Orig_SetTooltipMoney = SetTooltipMoney local Orig_SetTooltipMoney = SetTooltipMoney
-- Move the tooltip money frame(s) vertically to fine-tune their position under our custom block
local function AdjustMoneyFrames(tooltip, yOffset)
if not tooltip or not tooltip.GetName then return end
local baseName = tooltip:GetName()
if not baseName then return end
-- Collect potential money frame names used by WoW tooltips
local candidates = {}
-- Primary money frame
tinsert(candidates, baseName .. "MoneyFrame")
-- Sometimes multiple money frames are created with numeric suffixes
for i = 1, 8 do
tinsert(candidates, baseName .. "MoneyFrame" .. i)
tinsert(candidates, baseName .. "SmallMoneyFrame" .. i)
end
for i = 1, getn(candidates) do
local f = getglobal(candidates[i])
if f and f:IsShown() and f.GetPoint then
local point, relTo, relPoint, xOfs, yOfs = f:GetPoint(1)
if point then
f:SetPoint(point, relTo, relPoint, xOfs or 0, (yOfs or 0) + (yOffset or 0))
end
end
end
end
local function WithDeferredMoney(tooltip, buildFunc) local function WithDeferredMoney(tooltip, buildFunc)
local queue = {} local queue = {}
-- Temporarily override global SetTooltipMoney -- Temporarily override global SetTooltipMoney
@@ -295,30 +323,59 @@ function Tooltip:Initialize()
local q = queue[i] local q = queue[i]
Orig_SetTooltipMoney(q[1], q[2], q[3], q[4], q[5], q[6], q[7]) Orig_SetTooltipMoney(q[1], q[2], q[3], q[4], q[5], q[6], q[7])
end end
-- Add ~5px more space below the Inventory block by reducing the upward nudge from 15px to 10px
--AdjustMoneyFrames(tooltip, 12)
return ret return ret
end end
-- Hook SetBagItem -- Hook SetBagItem
local oldSetBagItem = GameTooltip.SetBagItem local oldSetBagItem = GameTooltip.SetBagItem
local oldSetInventoryItem = GameTooltip.SetInventoryItem
function GameTooltip:SetBagItem(bag, slot) function GameTooltip:SetBagItem(bag, slot)
return WithDeferredMoney(self, function() return WithDeferredMoney(self, function()
local ret = oldSetBagItem(self, bag, slot) local bankFrame = getglobal("BankFrame")
local link = GetContainerItemLink(bag, slot) if bag == -1 and bankFrame and bankFrame:IsVisible() then
if link then local invSlot = BankButtonIDToInvSlotID(slot)
Tooltip:AddInventoryInfo(self, link) if invSlot then
-- Use the inventory item method for bank main bag
local ret = oldSetInventoryItem(self, "player", invSlot)
local link = GetInventoryItemLink("player", invSlot)
if link then
Tooltip:AddInventoryInfo(self, link)
end
return ret
end
return nil
else
local ret = oldSetBagItem(self, bag, slot)
local link = GetContainerItemLink(bag, slot)
if link then
Tooltip:AddInventoryInfo(self, link)
end
return ret
end end
return ret
end) end)
end end
-- Hook SetHyperlink for chat links -- Hook SetHyperlink for hyperlinks from chat and cached links
local oldSetHyperlink = GameTooltip.SetHyperlink local oldSetHyperlink = GameTooltip.SetHyperlink
function GameTooltip:SetHyperlink(link) function GameTooltip:SetHyperlink(link)
return WithDeferredMoney(self, function() return WithDeferredMoney(self, function()
local ret = oldSetHyperlink(self, link) local _, _, inner = string.find(link or "", "|H(.+)|h")
if link and strfind(link, "item:") then local forwarded = link
Tooltip:AddInventoryInfo(self, link) local itemLinkForCounts = link
if inner then
forwarded = inner
if strfind(inner, "^item:") then
itemLinkForCounts = inner
end
end end
local ret = oldSetHyperlink(self, forwarded)
if itemLinkForCounts and strfind(itemLinkForCounts, "item:") then
Tooltip:AddInventoryInfo(self, itemLinkForCounts)
end
return ret return ret
end) end)
end end
+1 -2
View File
@@ -2,7 +2,7 @@
## Title: Guda ## Title: Guda
## Notes: All-in-one bag and bank addon for Turtle WoW ## Notes: All-in-one bag and bank addon for Turtle WoW
## Author: Vati ## Author: Vati
## Version: 1.1.2 ## Version: 1.1.3
## SavedVariables: Guda_DB ## SavedVariables: Guda_DB
## SavedVariablesPerCharacter: Guda_CharDB ## SavedVariablesPerCharacter: Guda_CharDB
@@ -25,7 +25,6 @@ Sorting\SortEngine.lua
UI\ItemButton.lua UI\ItemButton.lua
UI\BagFrame.lua UI\BagFrame.lua
UI\BankFrame.lua UI\BankFrame.lua
UI\MoneyDisplay.lua
UI\SettingsPopup.lua UI\SettingsPopup.lua
UI\ItemButton.xml UI\ItemButton.xml
+1526 -1433
View File
File diff suppressed because it is too large Load Diff
+5 -11
View File
@@ -193,7 +193,7 @@
</OnClick> </OnClick>
<OnEnter> <OnEnter>
GameTooltip:SetOwner(this, "ANCHOR_TOP") GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:SetText("View Other Characters") GameTooltip:SetText("My Characters")
GameTooltip:Show() GameTooltip:Show()
</OnEnter> </OnEnter>
<OnLeave> <OnLeave>
@@ -638,7 +638,8 @@
<!-- Container for item buttons --> <!-- Container for item buttons -->
<Frame name="$parent_ItemContainer" enableMouse="true"> <!-- Set enableMouse to false so it does not intercept drag/drop meant for child item buttons -->
<Frame name="$parent_ItemContainer" enableMouse="false">
<Size> <Size>
<AbsDimension x="400" y="480"/> <AbsDimension x="400" y="480"/>
</Size> </Size>
@@ -654,15 +655,8 @@
</TileSize> </TileSize>
<Color r="0" g="0" b="0" a="0.5"/> <Color r="0" g="0" b="0" a="0.5"/>
</Backdrop> </Backdrop>
<Scripts> <!-- Note: with enableMouse=false, OnMouseDown/OnReceiveDrag here would not fire;
<OnMouseDown> child item buttons will handle mouse events directly. -->
-- Clear search focus when clicking in item area
local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox")
if searchBox then
searchBox:ClearFocus()
end
</OnMouseDown>
</Scripts>
</Frame> </Frame>
</Frames> </Frames>
+141 -58
View File
@@ -10,6 +10,9 @@ local currentViewChar = nil
local searchText = "" local searchText = ""
local isReadOnlyMode = false -- Track if viewing saved bank (read-only) or live bank (interactive) local isReadOnlyMode = false -- Track if viewing saved bank (read-only) or live bank (interactive)
local hiddenBankBags = {} -- Track which bank bags are hidden (bagID -> true/false) local hiddenBankBags = {} -- Track which bank bags are hidden (bagID -> true/false)
local bankBagParents = {} -- Parent frames per bank bag (same approach as BagFrame)
-- Global click catcher for clearing bank search focus
local bankClickCatcher = nil
-- OnLoad -- OnLoad
function Guda_BankFrame_OnLoad(self) function Guda_BankFrame_OnLoad(self)
@@ -20,6 +23,21 @@ function Guda_BankFrame_OnLoad(self)
searchBox:SetTextColor(0.5, 0.5, 0.5, 1) searchBox:SetTextColor(0.5, 0.5, 0.5, 1)
end end
-- Create invisible full-screen frame to catch clicks outside the bank frame while typing in search
if not bankClickCatcher then
bankClickCatcher = CreateFrame("Frame", "Guda_BankClickCatcher", UIParent)
bankClickCatcher:SetFrameStrata("BACKGROUND")
bankClickCatcher:SetAllPoints(UIParent)
bankClickCatcher:EnableMouse(true)
bankClickCatcher:Hide()
bankClickCatcher:SetScript("OnMouseDown", function()
if Guda_BankFrame_ClearSearch then
Guda_BankFrame_ClearSearch()
end
end)
end
end end
-- OnShow -- OnShow
@@ -47,22 +65,6 @@ function Guda_BankFrame_OnShow(self)
BankFrame:Update() BankFrame:Update()
end end
-- OnHide
function Guda_BankFrame_OnHide(self)
-- Only release buttons that belong to this frame
local itemContainer = getglobal("Guda_BankFrame_ItemContainer")
if itemContainer then
-- Hide only the buttons that are children of this container
local children = { itemContainer:GetChildren() }
for _, child in ipairs(children) do
if child.hasItem ~= nil then -- It's an item button
child:Hide()
child:ClearAllPoints()
end
end
end
end
-- Toggle visibility -- Toggle visibility
function BankFrame:Toggle() function BankFrame:Toggle()
if Guda_BankFrame:IsShown() then if Guda_BankFrame:IsShown() then
@@ -86,20 +88,45 @@ function BankFrame:ShowCurrentCharacter()
self:Update() self:Update()
end end
-- Update lock states of existing buttons (lightweight, used during drag)
function BankFrame:UpdateLockStates()
for _, bankBagParent in pairs(bankBagParents) do
if bankBagParent then
local buttons = { bankBagParent:GetChildren() }
for _, button in ipairs(buttons) do
if button.hasItem ~= nil and button:IsShown() and button.bagID and button.slotID then
-- Get live lock state
local _, _, locked = GetContainerItemInfo(button.bagID, button.slotID)
-- Update desaturation (gray out locked items)
if not button.otherChar and not button.isReadOnly and SetItemButtonDesaturated then
SetItemButtonDesaturated(button, locked, 0.5, 0.5, 0.5)
end
end
end
end
end
end
-- Update display -- Update display
function BankFrame:Update() function BankFrame:Update()
if not Guda_BankFrame:IsShown() then if not Guda_BankFrame:IsShown() then
return return
end end
-- Only release buttons that belong to this frame -- If cursor is holding an item (mid-drag), only update lock states, don't rebuild UI
local itemContainer = getglobal("Guda_BankFrame_ItemContainer") if CursorHasItem and CursorHasItem() then
if itemContainer then self:UpdateLockStates()
local children = { itemContainer:GetChildren() } return
for _, child in ipairs(children) do end
if child.hasItem ~= nil then -- It's an item button
child:Hide() -- Mark all existing buttons as not in use (we'll mark active ones during display)
child:ClearAllPoints() for _, bankBagParent in pairs(bankBagParents) do
if bankBagParent then
local buttons = { bankBagParent:GetChildren() }
for _, button in ipairs(buttons) do
if button.hasItem ~= nil then
button.inUse = false
end
end end
end end
end end
@@ -120,7 +147,7 @@ function BankFrame:Update()
bankData = addon.Modules.DB:GetCharacterBank(currentViewChar) bankData = addon.Modules.DB:GetCharacterBank(currentViewChar)
isOtherChar = true isOtherChar = true
charName = currentViewChar charName = currentViewChar
getglobal("Guda_BankFrame_Title"):SetText("Bank - " .. currentViewChar) getglobal("Guda_BankFrame_Title"):SetText(currentViewChar .. "'s Bank")
else else
-- Viewing current character's bank -- Viewing current character's bank
if bankIsOpen then if bankIsOpen then
@@ -128,12 +155,12 @@ function BankFrame:Update()
bankData = addon.Modules.BankScanner:ScanBank() bankData = addon.Modules.BankScanner:ScanBank()
-- Use current character's name for the title -- Use current character's name for the title
local playerName = addon.Modules.DB:GetPlayerFullName() local playerName = addon.Modules.DB:GetPlayerFullName()
getglobal("Guda_BankFrame_Title"):SetText("Bank - " .. playerName) getglobal("Guda_BankFrame_Title"):SetText(playerName .. "'s Bank")
else else
-- Bank is closed - use saved data (read-only mode) -- Bank is closed - use saved data (read-only mode)
local playerName = addon.Modules.DB:GetPlayerFullName() local playerName = addon.Modules.DB:GetPlayerFullName()
bankData = addon.Modules.DB:GetCharacterBank(playerName) bankData = addon.Modules.DB:GetCharacterBank(playerName)
getglobal("Guda_BankFrame_Title"):SetText("Bank - " .. playerName) getglobal("Guda_BankFrame_Title"):SetText(playerName .. "'s Bank")
end end
end end
@@ -144,6 +171,19 @@ function BankFrame:Update()
-- Update bank slots info -- Update bank slots info
self:UpdateBankSlotsInfo(bankData, isOtherChar) self:UpdateBankSlotsInfo(bankData, isOtherChar)
-- Clean up unused buttons AFTER display is complete (prevents drag/drop issues)
for _, bankBagParent in pairs(bankBagParents) do
if bankBagParent then
local buttons = { bankBagParent:GetChildren() }
for _, button in ipairs(buttons) do
if button.hasItem ~= nil and not button.inUse then
button:Hide()
button:ClearAllPoints()
end
end
end
end
end end
-- Display items -- Display items
@@ -180,13 +220,26 @@ function BankFrame:DisplayItems(bankData, isOtherChar, charName)
-- Check if item matches search filter -- Check if item matches search filter
local matchesFilter = self:PassesSearchFilter(itemData) local matchesFilter = self:PassesSearchFilter(itemData)
local button = Guda_GetItemButton(itemContainer) -- Ensure a per-bag parent frame exists and carries the bag ID
local bankBagParent
if not bankBagParents[bagID] then
bankBagParents[bagID] = CreateFrame("Frame", "Guda_BankFrame_BankBagParent"..bagID, itemContainer)
bankBagParents[bagID]:SetAllPoints(itemContainer)
if bankBagParents[bagID].SetID then
bankBagParents[bagID]:SetID(bagID)
end
end
bankBagParent = bankBagParents[bagID]
local button = Guda_GetItemButton(bankBagParent)
-- Ensure this is NOT a bag slot button -- Ensure this is NOT a bag slot button
if button.isBagSlot then if button.isBagSlot then
break break
end end
button.inUse = true -- Mark this button as actively in use
-- Position button -- Position button
local xPos = x + (col * (buttonSize + spacing)) local xPos = x + (col * (buttonSize + spacing))
local yPos = y - (row * (buttonSize + spacing)) local yPos = y - (row * (buttonSize + spacing))
@@ -522,6 +575,27 @@ function Guda_BankFrame_OnSearchChanged(self)
end end
end end
-- Clear bank search and restore placeholder
function Guda_BankFrame_ClearSearch()
local searchBox = getglobal("Guda_BankFrame_SearchBar_SearchBox")
if searchBox then
searchBox:SetText("Search bank...")
searchBox:SetTextColor(0.5, 0.5, 0.5, 1)
if searchBox.ClearFocus then searchBox:ClearFocus() end
end
-- Reset search state
searchText = ""
-- Update display
BankFrame:Update()
-- Hide click catcher if present
if bankClickCatcher and bankClickCatcher.Hide then
bankClickCatcher:Hide()
end
end
-- Sort button handler with auto-repeat and smart pass calculation -- Sort button handler with auto-repeat and smart pass calculation
function Guda_BankFrame_Sort() function Guda_BankFrame_Sort()
if isReadOnlyMode or currentViewChar then if isReadOnlyMode or currentViewChar then
@@ -861,6 +935,12 @@ function BankFrame:Initialize()
-- Show current character's bank in interactive mode -- Show current character's bank in interactive mode
currentViewChar = nil currentViewChar = nil
-- Hide BagFrame to prevent button overlap
local bagFrame = getglobal("Guda_BagFrame")
if bagFrame and bagFrame:IsShown() then
bagFrame:Hide()
end
-- Show and update custom bank frame -- Show and update custom bank frame
local customBankFrame = getglobal("Guda_BankFrame") local customBankFrame = getglobal("Guda_BankFrame")
if customBankFrame then if customBankFrame then
@@ -1170,46 +1250,49 @@ end
-- Highlight all item slots belonging to a specific bank bag by dimming others -- Highlight all item slots belonging to a specific bank bag by dimming others
function Guda_BankFrame_HighlightBagSlots(bagID) function Guda_BankFrame_HighlightBagSlots(bagID)
local itemContainer = getglobal("Guda_BankFrame_ItemContainer") -- Buttons are parented under per-bag parents, not directly under the item container
if not itemContainer then local highlightCount, dimCount = 0, 0
return
end
local highlightCount = 0 for _, bankBagParent in pairs(bankBagParents) do
local dimCount = 0 if bankBagParent then
local children = { bankBagParent:GetChildren() }
-- Iterate through all children (item buttons) for _, button in ipairs(children) do
local children = { itemContainer:GetChildren() } if button and button:IsShown() and button.hasItem ~= nil and not button.isBagSlot then
for _, button in ipairs(children) do if button.bagID == bagID then
-- Check if this is an item button button:SetAlpha(1.0)
if button.hasItem ~= nil and button:IsShown() and not button.isBagSlot then highlightCount = highlightCount + 1
if button.bagID == bagID then else
-- This button belongs to the hovered bag - keep it bright button:SetAlpha(0.25)
button:SetAlpha(1.0) dimCount = dimCount + 1
highlightCount = highlightCount + 1 end
else end
-- This button belongs to a different bag - dim it
button:SetAlpha(0.25)
dimCount = dimCount + 1
end end
end end
end end
addon:Debug(string.format("BankFrame HighlightBagSlots: Highlighted %d slots, dimmed %d slots for bagID %d", highlightCount, dimCount, bagID)) if addon and addon.Debug then
addon:Debug(string.format("BankFrame HighlightBagSlots: Highlighted %d slots, dimmed %d slots for bagID %d", highlightCount, dimCount, bagID))
end
end end
-- Clear all highlighting by restoring full opacity to all slots -- Clear all highlighting by restoring full opacity to all slots
function Guda_BankFrame_ClearHighlightedSlots() function Guda_BankFrame_ClearHighlightedSlots()
local itemContainer = getglobal("Guda_BankFrame_ItemContainer") -- Restore alpha to search-filter state (pfUI style). If no search, full opacity.
if not itemContainer then return end local searchActive = BankFrame and BankFrame.IsSearchActive and BankFrame:IsSearchActive()
-- Iterate through all children (item buttons) for _, bankBagParent in pairs(bankBagParents) do
local children = { itemContainer:GetChildren() } if bankBagParent then
for _, button in ipairs(children) do local children = { bankBagParent:GetChildren() }
-- Check if this is an item button for _, button in ipairs(children) do
if button.hasItem ~= nil and button:IsShown() and not button.isBagSlot then if button and button:IsShown() and button.hasItem ~= nil and not button.isBagSlot then
-- Restore full opacity if searchActive and BankFrame and BankFrame.PassesSearchFilter then
button:SetAlpha(1.0) local matches = BankFrame:PassesSearchFilter(button.itemData)
button:SetAlpha(matches and 1.0 or 0.25)
else
button:SetAlpha(1.0)
end
end
end
end end
end end
end end
+14 -2
View File
@@ -240,7 +240,7 @@
</OnClick> </OnClick>
<OnEnter> <OnEnter>
GameTooltip:SetOwner(this, "ANCHOR_TOP") GameTooltip:SetOwner(this, "ANCHOR_TOP")
GameTooltip:SetText("View Other Characters' Bank") GameTooltip:SetText("View Bank")
GameTooltip:Show() GameTooltip:Show()
</OnEnter> </OnEnter>
<OnLeave> <OnLeave>
@@ -286,8 +286,14 @@
this:SetText("") this:SetText("")
this:SetTextColor(1, 1, 1, 1) this:SetTextColor(1, 1, 1, 1)
end end
-- Show bank click catcher to detect clicks outside bank while typing
local cc = getglobal("Guda_BankClickCatcher")
if cc then cc:Show() end
</OnEditFocusGained> </OnEditFocusGained>
<OnEditFocusLost> <OnEditFocusLost>
-- Hide bank click catcher when focus is lost
local cc = getglobal("Guda_BankClickCatcher")
if cc then cc:Hide() end
if this:GetText() == "" then if this:GetText() == "" then
this:SetText("Search bank...") this:SetText("Search bank...")
this:SetTextColor(0.5, 0.5, 0.5, 1) this:SetTextColor(0.5, 0.5, 0.5, 1)
@@ -302,6 +308,8 @@
this:SetTextColor(0.5, 0.5, 0.5, 1) this:SetTextColor(0.5, 0.5, 0.5, 1)
this:ClearFocus() this:ClearFocus()
Guda_BankFrame_OnSearchChanged(this) Guda_BankFrame_OnSearchChanged(this)
local cc = getglobal("Guda_BankClickCatcher")
if cc then cc:Hide() end
</OnEscapePressed> </OnEscapePressed>
</Scripts> </Scripts>
</EditBox> </EditBox>
@@ -595,7 +603,11 @@
Guda_BankFrame_OnShow(this) Guda_BankFrame_OnShow(this)
</OnShow> </OnShow>
<OnHide> <OnHide>
Guda_BankFrame_OnHide(this) Guda_BankFrame:Hide()
-- Close the actual Blizzard bank too
if BankFrame and BankFrame:IsShown() then
CloseBankFrame()
end
</OnHide> </OnHide>
<OnMouseDown> <OnMouseDown>
-- Clear search box focus when clicking on bank frame -- Clear search box focus when clicking on bank frame
+295 -79
View File
@@ -1,6 +1,4 @@
-- Guda Item Button -- Local alias to the addon root table (must be defined before any usages below)
-- Handles item button display and interaction
local addon = Guda local addon = Guda
-- Item button pool -- Item button pool
@@ -11,6 +9,8 @@ local nextButtonID = 1
local scanTooltip = CreateFrame("GameTooltip", "Guda_QuestScanTooltip", nil, "GameTooltipTemplate") local scanTooltip = CreateFrame("GameTooltip", "Guda_QuestScanTooltip", nil, "GameTooltipTemplate")
scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE") scanTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
-- (rollback) no custom drag-source tracking or target resolution; rely on Blizzard handlers
-- Check if an item is a quest item by scanning its tooltip -- Check if an item is a quest item by scanning its tooltip
local function IsQuestItem(bagID, slotID) local function IsQuestItem(bagID, slotID)
if not bagID or not slotID then return false end if not bagID or not slotID then return false end
@@ -108,30 +108,172 @@ function Guda_ItemButton_OnLoad(self)
iconFrame:Hide() iconFrame:Hide()
self.questIcon = iconFrame self.questIcon = iconFrame
end end
-- Ensure the item button sits above its container backdrop and is mouse-enabled
local parent = self:GetParent()
if parent and parent.GetFrameLevel then
-- Place button above parent backdrop/mouse layer to reliably receive drops
local parentLevel = parent:GetFrameLevel()
if parentLevel and self:GetFrameLevel() <= parentLevel + 1 then
self:SetFrameLevel(parentLevel + 2)
end
end
-- Enable mouse and register for drag/drop (crucial for Classic/Vanilla WoW)
if self.EnableMouse then
self:EnableMouse(true)
end
if self.RegisterForDrag then
self:RegisterForDrag("LeftButton")
end
if self.RegisterForClicks then
self:RegisterForClicks("LeftButtonUp", "RightButtonUp")
end
end
-- Update the Blizzard cooldown overlay on this item button
function Guda_ItemButton_UpdateCooldown(self)
-- Only show cooldowns for live items of the current character
if not self or self.isReadOnly or self.otherChar then return end
local cooldown = getglobal(self:GetName().."Cooldown") or self.cooldown
if not cooldown then return end
if not self.hasItem or not self.bagID or not self.slotID then
cooldown:Hide()
return
end
local start, duration, enable = GetContainerItemCooldown(self.bagID, self.slotID)
if start and duration and duration > 0 and enable == 1 then
if CooldownFrame_SetTimer then
CooldownFrame_SetTimer(cooldown, start, duration, enable)
elseif CooldownFrame_Set then
-- Some clients expose CooldownFrame_Set instead
CooldownFrame_Set(cooldown, start, duration, enable)
else
-- Fallback: show the frame if API missing
cooldown:Show()
end
else
cooldown:Hide()
end
end 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)
self.bagID = bagID self.bagID = bagID
self.slotID = slotID self.slotID = slotID
-- Also set the Blizzard slot ID for compatibility with ContainerFrameItemButtonTemplate behavior
if self.SetID and slotID then
self:SetID(slotID)
end
self.itemData = itemData self.itemData = itemData
self.isBank = isBank or false self.isBank = isBank or false
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
-- Re-register for drag/drop every time (crucial for button reuse in Classic/Vanilla)
if not self.isReadOnly and not self.otherChar then
if self.RegisterForDrag then
self:RegisterForDrag("LeftButton")
end
if self.RegisterForClicks then
self:RegisterForClicks("LeftButtonUp", "RightButtonUp")
end
if self.EnableMouse then
self:EnableMouse(true)
end
else
-- Disable drag for read-only or other character items
if self.RegisterForDrag then
self:RegisterForDrag() -- Clear drag registration
end
if self.EnableMouse then
self:EnableMouse(true) -- Still enable mouse for tooltips
end
end
-- Default to true if not specified (for non-filtered displays) -- Default to true if not specified (for non-filtered displays)
if matchesFilter == nil then if matchesFilter == nil then
matchesFilter = true matchesFilter = true
end end
local countText = getglobal(self:GetName().."_Count") -- Use Blizzard's default count fontstring (ContainerFrameItemButtonTemplate creates $parentCount)
local countText = getglobal(self:GetName().."Count")
local emptySlotBg = getglobal(self:GetName().."_EmptySlotBg") local emptySlotBg = getglobal(self:GetName().."_EmptySlotBg")
-- Apply icon size setting -- Apply icon size setting (nil-safe)
local iconSize = Guda.Modules.DB:GetSetting("iconSize") or addon.Constants.BUTTON_SIZE local iconSize = 37
if addon and addon.Modules and addon.Modules.DB and addon.Modules.DB.GetSetting then
iconSize = addon.Modules.DB:GetSetting("iconSize") or iconSize
elseif Guda and Guda.Modules and Guda.Modules.DB and Guda.Modules.DB.GetSetting then
iconSize = Guda.Modules.DB:GetSetting("iconSize") or iconSize
end
if addon and addon.Constants and addon.Constants.BUTTON_SIZE then
iconSize = iconSize or addon.Constants.BUTTON_SIZE
end
self:SetWidth(iconSize) self:SetWidth(iconSize)
self:SetHeight(iconSize) self:SetHeight(iconSize)
-- In live mode (readOnly=false), query real-time game state instead of cached DB
-- In read-only mode (readOnly=true), use cached itemData from DB
local displayTexture, displayCount
if not self.isReadOnly then
-- LIVE MODE: Always query game state directly, never use cached itemData
local liveTexture, liveCount = GetContainerItemInfo(bagID, slotID)
if liveTexture then
displayTexture = liveTexture
displayCount = liveCount
self.hasItem = true
else
-- No item in this slot (even if itemData has cached data)
self.hasItem = false
end
else
-- READ-ONLY MODE: Use cached itemData from DB (can't query other characters)
if itemData and itemData.texture then
displayTexture = itemData.texture
displayCount = itemData.count
self.hasItem = true
else
self.hasItem = false
end
end
-- Apply the determined texture and count
if self.hasItem then
if SetItemButtonTexture then SetItemButtonTexture(self, displayTexture) end
if SetItemButtonCount then SetItemButtonCount(self, displayCount or 1) end
if emptySlotBg then emptySlotBg:Hide() end
-- Update cooldown overlay for live items
if not self.isReadOnly and Guda_ItemButton_UpdateCooldown then
Guda_ItemButton_UpdateCooldown(self)
end
else
-- Fully clear all item button state for empty slots
if SetItemButtonTexture then SetItemButtonTexture(self, nil) end
if SetItemButtonCount then SetItemButtonCount(self, 0) end
if SetItemButtonDesaturated then SetItemButtonDesaturated(self, false) end
-- Ensure cooldown overlay is hidden for empty slots
local cooldown = getglobal(self:GetName().."Cooldown") or self.cooldown
if cooldown and cooldown.Hide then cooldown:Hide() end
-- Also clear the icon texture directly
local iconTexture = getglobal(self:GetName().."IconTexture")
if not iconTexture then
iconTexture = getglobal(self:GetName().."Icon") or self.icon or self.Icon
end
if iconTexture then
iconTexture:SetTexture(nil)
iconTexture:Hide()
end
if emptySlotBg then emptySlotBg:Show() end
end
-- Resize empty slot background to match icon size (slightly larger to ensure coverage) -- Resize empty slot background to match icon size (slightly larger to ensure coverage)
if emptySlotBg then if emptySlotBg then
emptySlotBg:ClearAllPoints() emptySlotBg:ClearAllPoints()
@@ -190,7 +332,12 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
-- Apply icon font size setting to stack count text -- Apply icon font size setting to stack count text
if countText and countText.GetFont then if countText and countText.GetFont then
local font, _, flags = countText:GetFont() local font, _, flags = countText:GetFont()
local fontSize = Guda.Modules.DB:GetSetting("iconFontSize") or 12 local fontSize = 12
if addon and addon.Modules and addon.Modules.DB and addon.Modules.DB.GetSetting then
fontSize = addon.Modules.DB:GetSetting("iconFontSize") or fontSize
elseif Guda and Guda.Modules and Guda.Modules.DB and Guda.Modules.DB.GetSetting then
fontSize = Guda.Modules.DB:GetSetting("iconFontSize") or fontSize
end
countText:SetFont(font, fontSize, flags) countText:SetFont(font, fontSize, flags)
-- Adjust count text position based on icon size for better alignment -- Adjust count text position based on icon size for better alignment
@@ -204,16 +351,28 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
end end
end end
if itemData then -- Get live metadata if in live mode (quality, link, lock status)
self.hasItem = true local itemQuality, itemLink, isLocked
if not self.isReadOnly and bagID and slotID and self.hasItem then
-- Query live game state for metadata
local _, _, locked, quality = GetContainerItemInfo(bagID, slotID)
itemLink = GetContainerItemLink(bagID, slotID)
itemQuality = quality
isLocked = locked
elseif itemData then
-- Use cached metadata from database
itemQuality = itemData.quality
itemLink = itemData.link
isLocked = itemData.locked
end
-- Set icon if self.hasItem then
SetItemButtonTexture(self, itemData.texture) -- Icon already set above based on mode (live vs cached)
-- Gray out locked items (being traded, mailed, or auctioned) - BagShui style -- Gray out locked items (being traded, mailed, or auctioned) - BagShui style
-- Don't desaturate items from other characters since they're read-only anyway -- Don't desaturate items from other characters since they're read-only anyway
if not self.otherChar and not self.isReadOnly then if not self.otherChar and not self.isReadOnly then
SetItemButtonDesaturated(self, itemData.locked, 0.5, 0.5, 0.5) SetItemButtonDesaturated(self, isLocked, 0.5, 0.5, 0.5)
end end
-- Hide NormalTexture for filled slots (pfUI style) -- Hide NormalTexture for filled slots (pfUI style)
@@ -238,9 +397,9 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
self:SetAlpha(0.25) self:SetAlpha(0.25)
end end
-- Set count -- Set count (use displayCount which was determined above based on mode)
if itemData.count and itemData.count > 1 then if displayCount and displayCount > 1 then
countText:SetText(itemData.count) countText:SetText(displayCount)
countText:Show() countText:Show()
else else
countText:Hide() countText:Hide()
@@ -252,10 +411,16 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
-- Special border for keyring items (cyan/blue) -- Special border for keyring items (cyan/blue)
self.qualityBorder:SetBackdropBorderColor(0.2, 0.8, 1.0, 1) self.qualityBorder:SetBackdropBorderColor(0.2, 0.8, 1.0, 1)
self.qualityBorder:Show() self.qualityBorder:Show()
elseif itemData.quality and itemData.link then elseif itemQuality and itemLink then
-- Check settings to determine if we should show borders -- Check settings to determine if we should show borders (nil-safe)
local showEquipmentBorder = addon.Modules.DB:GetSetting("showQualityBorderEquipment") local showEquipmentBorder, showOtherBorder
local showOtherBorder = addon.Modules.DB:GetSetting("showQualityBorderOther") if addon and addon.Modules and addon.Modules.DB and addon.Modules.DB.GetSetting then
showEquipmentBorder = addon.Modules.DB:GetSetting("showQualityBorderEquipment")
showOtherBorder = addon.Modules.DB:GetSetting("showQualityBorderOther")
elseif Guda and Guda.Modules and Guda.Modules.DB and Guda.Modules.DB.GetSetting then
showEquipmentBorder = Guda.Modules.DB:GetSetting("showQualityBorderEquipment")
showOtherBorder = Guda.Modules.DB:GetSetting("showQualityBorderOther")
end
-- Default to true if settings not found -- Default to true if settings not found
if showEquipmentBorder == nil then if showEquipmentBorder == nil then
@@ -265,15 +430,25 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
showOtherBorder = true showOtherBorder = true
end end
-- Check if item is equipment -- Check if item is equipment (nil-safe)
local isEquipment = addon.Modules.Utils:IsEquipment(itemData.link) local isEquipment = false
if addon and addon.Modules and addon.Modules.Utils and addon.Modules.Utils.IsEquipment then
isEquipment = addon.Modules.Utils:IsEquipment(itemLink)
elseif Guda and Guda.Modules and Guda.Modules.Utils and Guda.Modules.Utils.IsEquipment then
isEquipment = Guda.Modules.Utils:IsEquipment(itemLink)
end
-- Determine if we should show the border based on item type and settings -- Determine if we should show the border based on item type and settings
local shouldShowBorder = (isEquipment and showEquipmentBorder) or (not isEquipment and showOtherBorder) local shouldShowBorder = (isEquipment and showEquipmentBorder) or (not isEquipment and showOtherBorder)
if shouldShowBorder then if shouldShowBorder then
-- Show colored border for all items (Poor, Common, Uncommon, Rare, Epic, etc.) -- Show colored border for all items (Poor, Common, Uncommon, Rare, Epic, etc.)
local r, g, b = addon.Modules.Utils:GetQualityColor(itemData.quality) local r, g, b = 1, 1, 1
if addon and addon.Modules and addon.Modules.Utils and addon.Modules.Utils.GetQualityColor then
r, g, b = addon.Modules.Utils:GetQualityColor(itemQuality)
elseif Guda and Guda.Modules and Guda.Modules.Utils and Guda.Modules.Utils.GetQualityColor then
r, g, b = Guda.Modules.Utils:GetQualityColor(itemQuality)
end
self.qualityBorder:SetBackdropBorderColor(r, g, b, 1) self.qualityBorder:SetBackdropBorderColor(r, g, b, 1)
self.qualityBorder:Show() self.qualityBorder:Show()
else else
@@ -417,51 +592,64 @@ end
-- OnEnter handler (show tooltip) -- OnEnter handler (show tooltip)
function Guda_ItemButton_OnEnter(self) function Guda_ItemButton_OnEnter(self)
-- Highlight the corresponding bag button in the footer (works for empty and filled slots) -- 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
Guda_BankFrame_HighlightBagButton(self.bagID) Guda_BankFrame_HighlightBagButton(self.bagID)
else else
-- Regular bag item - highlight bag button -- Regular bag item - highlight bag button
Guda_BagFrame_HighlightBagButton(self.bagID) Guda_BagFrame_HighlightBagButton(self.bagID)
end end
end end
-- Early return for empty slots (no tooltip needed) -- Early return for empty slots (no tooltip needed)
if not self.hasItem or not self.itemData then if not self.hasItem or not self.itemData then
return return
end end
GameTooltip:SetOwner(self, "ANCHOR_RIGHT") GameTooltip:SetOwner(UIParent, "ANCHOR_NONE")
-- important position of tooltip
GameTooltip:SetPoint("BOTTOMRIGHT", self, "TOPLEFT", 10, 0)
-- For bank items, use the item link directly since SetBagItem might not work for bank bags if self.otherChar or self.isReadOnly then
if self.isBank and self.itemData.link then GameTooltip.GudaViewedCharacter = self.otherChar
-- Extract hyperlink from item link: |cFFFFFFFF|Hitem:1234:0:0:0|h[Name]|h|r -> item:1234:0:0:0 if self.itemData and self.itemData.link then
local _, _, hyperlink = strfind(self.itemData.link, "|H(.+)|h") GameTooltip:SetHyperlink(self.itemData.link)
if hyperlink then else
GameTooltip:SetHyperlink(hyperlink) GameTooltip:Hide()
else return
-- Fallback to SetBagItem end
GameTooltip:SetBagItem(self.bagID, self.slotID) -- Special handling for bank main bag when bank might be closed
end elseif self.isBank and self.bagID == -1 then
else local bankFrame = getglobal("BankFrame")
-- For regular bags, use SetBagItem as normal if bankFrame and bankFrame:IsVisible() then
GameTooltip:SetBagItem(self.bagID, self.slotID) -- Bank is open - use SetBagItem which will trigger inventory slot handling
end GameTooltip:SetBagItem(self.bagID, self.slotID)
elseif self.itemData and self.itemData.link then
GameTooltip:Show() -- Bank is closed - use cached link
GameTooltip:SetHyperlink(self.itemData.link)
-- Handle merchant sell cursor (same approach as BagShui) end
if MerchantFrame:IsShown() and not self.isBank and not self.otherChar and self.hasItem then else
ShowContainerSellCursor(self.bagID, self.slotID) -- For live mode: use SetBagItem for all bags
else GameTooltip:SetBagItem(self.bagID, self.slotID)
ResetCursor() end
end GameTooltip:Show()
-- Handle merchant sell cursor (same approach as BagShui)
if MerchantFrame:IsShown() and not self.isBank and not self.otherChar and self.hasItem then
ShowContainerSellCursor(self.bagID, self.slotID)
else
ResetCursor()
end
end end
-- OnLeave handler -- OnLeave handler
function Guda_ItemButton_OnLeave(self) function Guda_ItemButton_OnLeave(self)
-- Clear any viewed character hint on the tooltip when leaving
if GameTooltip and GameTooltip.GudaViewedCharacter then
GameTooltip.GudaViewedCharacter = nil
end
GameTooltip:Hide() GameTooltip:Hide()
ResetCursor() ResetCursor()
@@ -484,6 +672,11 @@ function Guda_ItemButton_OnDragStart(self, button)
-- Only allow left button drag -- Only allow left button drag
if button == "LeftButton" and self.hasItem then if button == "LeftButton" and self.hasItem then
-- Ensure the global click catcher doesn't intercept the drag/drop
local cc = getglobal and getglobal("Guda_ClickCatcher")
if cc and cc.Hide and cc:IsShown() then
cc:Hide()
end
PickupContainerItem(self.bagID, self.slotID) PickupContainerItem(self.bagID, self.slotID)
end end
end end
@@ -497,6 +690,30 @@ function Guda_ItemButton_OnReceiveDrag(self)
-- Place the item being dragged -- Place the item being dragged
PickupContainerItem(self.bagID, self.slotID) PickupContainerItem(self.bagID, self.slotID)
-- Trigger UI update after drop completes (was skipped during drag)
if addon and addon.Modules and addon.Modules.BagFrame then
addon.Modules.BagFrame:Update()
end
end
-- Handle mouse-up to emulate Blizzard drop behavior on 1.12 where OnReceiveDrag may not always fire
-- (rollback) no custom OnMouseUp; rely on Blizzard default
-- OnMouseDown handler - pick up item when pressing mouse button (classic pattern)
-- (rollback) no custom OnMouseDown; rely on Blizzard default
-- OnDragStop handler (optional cleanup)
function Guda_ItemButton_OnDragStop(self)
-- Reset cursor to default to avoid lingering special cursors
if ResetCursor then
ResetCursor()
end
-- Trigger UI update after drag completes (was skipped during drag)
if addon and addon.Modules and addon.Modules.BagFrame then
addon.Modules.BagFrame:Update()
end
end end
-- Stack split callback (called by StackSplitFrame) -- Stack split callback (called by StackSplitFrame)
@@ -509,44 +726,43 @@ end
-- OnClick handler -- OnClick handler
function Guda_ItemButton_OnClick(self, button) function Guda_ItemButton_OnClick(self, button)
-- Don't allow interaction with other characters' items or in read-only mode -- Don't allow interaction with other characters' items or in read-only mode
if self.otherChar or self.isReadOnly then if self.otherChar or self.isReadOnly then return end
return
end
-- Set the split callback -- Set the split callback
self.SplitStack = ItemButton_SplitStack self.SplitStack = ItemButton_SplitStack
-- Handle modified clicks first -- Modified clicks
if IsShiftKeyDown() then if IsShiftKeyDown() then
if button == "LeftButton" and self.hasItem then if button == "LeftButton" and self.hasItem then
-- Get live count and link
local _, count = GetContainerItemInfo(self.bagID, self.slotID)
local itemLink = GetContainerItemLink(self.bagID, self.slotID)
-- Shift+Left Click on stackable item: Show split stack dialog -- Shift+Left Click on stackable item: Show split stack dialog
if self.itemData and self.itemData.count and self.itemData.count > 1 then if count and count > 1 then
-- Get the actual stack count from the container OpenStackSplitFrame(count, self, "BOTTOMRIGHT", "TOPRIGHT")
local _, count = GetContainerItemInfo(self.bagID, self.slotID) return
if count and count > 1 then
-- Open the stack split frame (positioned to the left)
OpenStackSplitFrame(count, self, "BOTTOMRIGHT", "TOPRIGHT")
return
end
end end
-- If not stackable or only 1 item, link to chat -- If not stackable or only 1 item, link to chat
if self.itemData and self.itemData.link and ChatFrameEditBox:IsVisible() then if itemLink and ChatFrameEditBox:IsVisible() then
ChatFrameEditBox:Insert(self.itemData.link) ChatFrameEditBox:Insert(itemLink)
end end
end end
return return
elseif IsControlKeyDown() then elseif IsControlKeyDown() then
-- Ctrl+Click: Dress up (if applicable) -- Ctrl+Click: Dress up (if applicable)
if self.hasItem and self.itemData and self.itemData.link then if self.hasItem then
DressUpItemLink(self.itemData.link) local itemLink = GetContainerItemLink(self.bagID, self.slotID)
if itemLink then
DressUpItemLink(itemLink)
end
end end
return return
end end
-- Normal clicks - handle item pickup/placement
if button == "LeftButton" then if button == "LeftButton" then
-- Pick up or place item -- Left clicks are handled by MouseDown/MouseUp to prevent instant self-drop.
PickupContainerItem(self.bagID, self.slotID) return
elseif button == "RightButton" then elseif button == "RightButton" then
-- Right click: Use item (only if slot has an item) -- Right click: Use item (only if slot has an item)
if self.hasItem then if self.hasItem then
+8 -15
View File
@@ -1,7 +1,7 @@
<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/"> <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/">
<!-- Item Button Template --> <!-- Item Button Template (inherit Blizzard container item button for classic behavior/skins) -->
<Button name="Guda_ItemButtonTemplate" virtual="true" inherits="ItemButtonTemplate"> <Button name="Guda_ItemButtonTemplate" virtual="true" inherits="ContainerFrameItemButtonTemplate">
<Size> <Size>
<AbsDimension x="37" y="37"/> <AbsDimension x="37" y="37"/>
</Size> </Size>
@@ -17,8 +17,7 @@
</Texture> </Texture>
</Layer> </Layer>
<!-- Custom item count (this intentionally co-exists with Blizzard's $parentCount in rollback state) -->
<!-- Item count -->
<Layer level="OVERLAY"> <Layer level="OVERLAY">
<FontString name="$parent_Count" inherits="NumberFontNormal" justifyH="RIGHT"> <FontString name="$parent_Count" inherits="NumberFontNormal" justifyH="RIGHT">
<Anchors> <Anchors>
@@ -34,9 +33,12 @@
<Scripts> <Scripts>
<OnLoad> <OnLoad>
-- Our visual setup
Guda_ItemButton_OnLoad(this) Guda_ItemButton_OnLoad(this)
this:RegisterForDrag("LeftButton") -- Ensure Blizzard default container item button behavior is active
this:RegisterForClicks("LeftButtonUp", "RightButtonUp") if ContainerFrameItemButton_OnLoad then
ContainerFrameItemButton_OnLoad()
end
</OnLoad> </OnLoad>
<OnEnter> <OnEnter>
Guda_ItemButton_OnEnter(this) Guda_ItemButton_OnEnter(this)
@@ -44,15 +46,6 @@
<OnLeave> <OnLeave>
Guda_ItemButton_OnLeave(this) Guda_ItemButton_OnLeave(this)
</OnLeave> </OnLeave>
<OnClick>
Guda_ItemButton_OnClick(this, arg1)
</OnClick>
<OnDragStart>
Guda_ItemButton_OnDragStart(this, arg1)
</OnDragStart>
<OnReceiveDrag>
Guda_ItemButton_OnReceiveDrag(this)
</OnReceiveDrag>
</Scripts> </Scripts>
</Button> </Button>
-57
View File
@@ -1,57 +0,0 @@
-- Guda Money Display
-- Handles money display in UI
local addon = Guda
local MoneyDisplay = {}
addon.Modules.MoneyDisplay = MoneyDisplay
-- Create a money display frame
function MoneyDisplay:CreateDisplay(parent, x, y)
local frame = CreateFrame("Frame", nil, parent)
frame:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
frame:SetWidth(200)
frame:SetHeight(20)
-- Gold text
frame.gold = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
frame.gold:SetPoint("LEFT", frame, "LEFT", 0, 0)
-- Silver text
frame.silver = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
frame.silver:SetPoint("LEFT", frame.gold, "RIGHT", 2, 0)
-- Copper text
frame.copper = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
frame.copper:SetPoint("LEFT", frame.silver, "RIGHT", 2, 0)
return frame
end
-- Update money display
function MoneyDisplay:Update(frame, copper)
if not frame or not copper then
return
end
local gold = math.floor(copper / 10000)
local silver = math.floor(mod(copper, 10000) / 100)
local bronze = mod(copper, 100)
if gold > 0 then
frame.gold:SetText(gold .. "|cFFFFD700g|r")
frame.gold:Show()
else
frame.gold:Hide()
end
if silver > 0 or gold > 0 then
frame.silver:SetText(silver .. "|cFFC0C0C0s|r")
frame.silver:Show()
else
frame.silver:Hide()
end
frame.copper:SetText(bronze .. "|cFFFF6600c|r")
frame.copper:Show()
end