+1
-1
@@ -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
@@ -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
|
||||||
|
|||||||
+3
-3
@@ -104,17 +104,17 @@ function BagScanner:Initialize()
|
|||||||
-- Create event frame for bag updates
|
-- Create event frame for bag updates
|
||||||
local eventFrame = CreateFrame("Frame")
|
local eventFrame = CreateFrame("Frame")
|
||||||
self.eventFrame = eventFrame
|
self.eventFrame = eventFrame
|
||||||
|
|
||||||
-- Register bag update events
|
-- Register bag update events
|
||||||
eventFrame:RegisterEvent("BAG_UPDATE")
|
eventFrame:RegisterEvent("BAG_UPDATE")
|
||||||
eventFrame:RegisterEvent("BAG_UPDATE_DELAYED")
|
eventFrame:RegisterEvent("BAG_UPDATE_DELAYED")
|
||||||
|
|
||||||
eventFrame:SetScript("OnEvent", function()
|
eventFrame:SetScript("OnEvent", function()
|
||||||
if event == "BAG_UPDATE" or event == "BAG_UPDATE_DELAYED" then
|
if event == "BAG_UPDATE" or event == "BAG_UPDATE_DELAYED" then
|
||||||
addon:Debug("Bag update detected, saving data...")
|
addon:Debug("Bag update detected, saving data...")
|
||||||
self:SaveToDatabase()
|
self:SaveToDatabase()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
addon:Debug("Bag scanner initialized with auto-save")
|
addon:Debug("Bag scanner initialized with auto-save")
|
||||||
end
|
end
|
||||||
@@ -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
|
||||||
|
|||||||
+1529
-1436
File diff suppressed because it is too large
Load Diff
+5
-11
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
+297
-81
@@ -1,8 +1,6 @@
|
|||||||
-- 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
|
||||||
local buttonPool = {}
|
local buttonPool = {}
|
||||||
local nextButtonID = 1
|
local nextButtonID = 1
|
||||||
@@ -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
|
||||||
@@ -561,4 +777,4 @@ function Guda_ReleaseAllButtons()
|
|||||||
button:Hide()
|
button:Hide()
|
||||||
button:ClearAllPoints()
|
button:ClearAllPoints()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
+9
-16
@@ -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>
|
||||||
@@ -16,9 +16,8 @@
|
|||||||
</Anchors>
|
</Anchors>
|
||||||
</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>
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
Reference in New Issue
Block a user