+1
-1
@@ -117,7 +117,7 @@ end
|
||||
|
||||
-- Get current player's full name
|
||||
function DB:GetPlayerFullName()
|
||||
return playerName
|
||||
return playerName .. "-" .. playerRealm
|
||||
end
|
||||
|
||||
-- Get current character data
|
||||
|
||||
+69
-12
@@ -218,6 +218,8 @@ function Tooltip:AddInventoryInfo(tooltip, link)
|
||||
local totalCount = totalBags + totalBank + totalEquipped
|
||||
|
||||
if hasAnyItems then
|
||||
|
||||
-- Top padding above the Inventory block (~10-12px visually)
|
||||
tooltip:AddLine(" ")
|
||||
|
||||
-- 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)
|
||||
end
|
||||
|
||||
-- Add small gap between inventory data and vendor sell price
|
||||
tooltip:AddLine(" ")
|
||||
-- Bottom padding below the Inventory block (~10-12px visually)
|
||||
--tooltip:AddLine(" ")
|
||||
|
||||
tooltip:Show()
|
||||
end
|
||||
@@ -275,6 +277,32 @@ function Tooltip:Initialize()
|
||||
|
||||
-- Helper function to defer vendor money so we can insert our Inventory block above it
|
||||
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 queue = {}
|
||||
-- Temporarily override global SetTooltipMoney
|
||||
@@ -295,30 +323,59 @@ function Tooltip:Initialize()
|
||||
local q = queue[i]
|
||||
Orig_SetTooltipMoney(q[1], q[2], q[3], q[4], q[5], q[6], q[7])
|
||||
end
|
||||
|
||||
-- Add ~5px more space below the Inventory block by reducing the upward nudge from 15px to 10px
|
||||
--AdjustMoneyFrames(tooltip, 12)
|
||||
return ret
|
||||
end
|
||||
|
||||
-- Hook SetBagItem
|
||||
local oldSetBagItem = GameTooltip.SetBagItem
|
||||
local oldSetInventoryItem = GameTooltip.SetInventoryItem
|
||||
function GameTooltip:SetBagItem(bag, slot)
|
||||
return WithDeferredMoney(self, function()
|
||||
local ret = oldSetBagItem(self, bag, slot)
|
||||
local link = GetContainerItemLink(bag, slot)
|
||||
if link then
|
||||
Tooltip:AddInventoryInfo(self, link)
|
||||
local bankFrame = getglobal("BankFrame")
|
||||
if bag == -1 and bankFrame and bankFrame:IsVisible() then
|
||||
local invSlot = BankButtonIDToInvSlotID(slot)
|
||||
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
|
||||
return ret
|
||||
end)
|
||||
end
|
||||
|
||||
-- Hook SetHyperlink for chat links
|
||||
local oldSetHyperlink = GameTooltip.SetHyperlink
|
||||
-- Hook SetHyperlink for hyperlinks from chat and cached links
|
||||
local oldSetHyperlink = GameTooltip.SetHyperlink
|
||||
function GameTooltip:SetHyperlink(link)
|
||||
return WithDeferredMoney(self, function()
|
||||
local ret = oldSetHyperlink(self, link)
|
||||
if link and strfind(link, "item:") then
|
||||
Tooltip:AddInventoryInfo(self, link)
|
||||
local _, _, inner = string.find(link or "", "|H(.+)|h")
|
||||
local forwarded = link
|
||||
local itemLinkForCounts = link
|
||||
if inner then
|
||||
forwarded = inner
|
||||
if strfind(inner, "^item:") then
|
||||
itemLinkForCounts = inner
|
||||
end
|
||||
end
|
||||
local ret = oldSetHyperlink(self, forwarded)
|
||||
if itemLinkForCounts and strfind(itemLinkForCounts, "item:") then
|
||||
Tooltip:AddInventoryInfo(self, itemLinkForCounts)
|
||||
end
|
||||
|
||||
return ret
|
||||
end)
|
||||
end
|
||||
|
||||
+3
-3
@@ -104,17 +104,17 @@ function BagScanner:Initialize()
|
||||
-- Create event frame for bag updates
|
||||
local eventFrame = CreateFrame("Frame")
|
||||
self.eventFrame = eventFrame
|
||||
|
||||
|
||||
-- Register bag update events
|
||||
eventFrame:RegisterEvent("BAG_UPDATE")
|
||||
eventFrame:RegisterEvent("BAG_UPDATE_DELAYED")
|
||||
|
||||
|
||||
eventFrame:SetScript("OnEvent", function()
|
||||
if event == "BAG_UPDATE" or event == "BAG_UPDATE_DELAYED" then
|
||||
addon:Debug("Bag update detected, saving data...")
|
||||
self:SaveToDatabase()
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
addon:Debug("Bag scanner initialized with auto-save")
|
||||
end
|
||||
@@ -2,7 +2,7 @@
|
||||
## Title: Guda
|
||||
## Notes: All-in-one bag and bank addon for Turtle WoW
|
||||
## Author: Vati
|
||||
## Version: 1.1.2
|
||||
## Version: 1.1.3
|
||||
## SavedVariables: Guda_DB
|
||||
## SavedVariablesPerCharacter: Guda_CharDB
|
||||
|
||||
@@ -25,7 +25,6 @@ Sorting\SortEngine.lua
|
||||
UI\ItemButton.lua
|
||||
UI\BagFrame.lua
|
||||
UI\BankFrame.lua
|
||||
UI\MoneyDisplay.lua
|
||||
UI\SettingsPopup.lua
|
||||
|
||||
UI\ItemButton.xml
|
||||
|
||||
+1529
-1436
File diff suppressed because it is too large
Load Diff
+5
-11
@@ -193,7 +193,7 @@
|
||||
</OnClick>
|
||||
<OnEnter>
|
||||
GameTooltip:SetOwner(this, "ANCHOR_TOP")
|
||||
GameTooltip:SetText("View Other Characters")
|
||||
GameTooltip:SetText("My Characters")
|
||||
GameTooltip:Show()
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
@@ -638,7 +638,8 @@
|
||||
|
||||
|
||||
<!-- 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>
|
||||
<AbsDimension x="400" y="480"/>
|
||||
</Size>
|
||||
@@ -654,15 +655,8 @@
|
||||
</TileSize>
|
||||
<Color r="0" g="0" b="0" a="0.5"/>
|
||||
</Backdrop>
|
||||
<Scripts>
|
||||
<OnMouseDown>
|
||||
-- Clear search focus when clicking in item area
|
||||
local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox")
|
||||
if searchBox then
|
||||
searchBox:ClearFocus()
|
||||
end
|
||||
</OnMouseDown>
|
||||
</Scripts>
|
||||
<!-- Note: with enableMouse=false, OnMouseDown/OnReceiveDrag here would not fire;
|
||||
child item buttons will handle mouse events directly. -->
|
||||
</Frame>
|
||||
</Frames>
|
||||
|
||||
|
||||
+141
-58
@@ -10,6 +10,9 @@ local currentViewChar = nil
|
||||
local searchText = ""
|
||||
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 bankBagParents = {} -- Parent frames per bank bag (same approach as BagFrame)
|
||||
-- Global click catcher for clearing bank search focus
|
||||
local bankClickCatcher = nil
|
||||
|
||||
-- OnLoad
|
||||
function Guda_BankFrame_OnLoad(self)
|
||||
@@ -20,6 +23,21 @@ function Guda_BankFrame_OnLoad(self)
|
||||
searchBox:SetTextColor(0.5, 0.5, 0.5, 1)
|
||||
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
|
||||
|
||||
-- OnShow
|
||||
@@ -47,22 +65,6 @@ function Guda_BankFrame_OnShow(self)
|
||||
BankFrame:Update()
|
||||
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
|
||||
function BankFrame:Toggle()
|
||||
if Guda_BankFrame:IsShown() then
|
||||
@@ -86,20 +88,45 @@ function BankFrame:ShowCurrentCharacter()
|
||||
self:Update()
|
||||
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
|
||||
function BankFrame:Update()
|
||||
if not Guda_BankFrame:IsShown() then
|
||||
return
|
||||
end
|
||||
|
||||
-- Only release buttons that belong to this frame
|
||||
local itemContainer = getglobal("Guda_BankFrame_ItemContainer")
|
||||
if itemContainer then
|
||||
local children = { itemContainer:GetChildren() }
|
||||
for _, child in ipairs(children) do
|
||||
if child.hasItem ~= nil then -- It's an item button
|
||||
child:Hide()
|
||||
child:ClearAllPoints()
|
||||
-- If cursor is holding an item (mid-drag), only update lock states, don't rebuild UI
|
||||
if CursorHasItem and CursorHasItem() then
|
||||
self:UpdateLockStates()
|
||||
return
|
||||
end
|
||||
|
||||
-- Mark all existing buttons as not in use (we'll mark active ones during display)
|
||||
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
|
||||
@@ -120,7 +147,7 @@ function BankFrame:Update()
|
||||
bankData = addon.Modules.DB:GetCharacterBank(currentViewChar)
|
||||
isOtherChar = true
|
||||
charName = currentViewChar
|
||||
getglobal("Guda_BankFrame_Title"):SetText("Bank - " .. currentViewChar)
|
||||
getglobal("Guda_BankFrame_Title"):SetText(currentViewChar .. "'s Bank")
|
||||
else
|
||||
-- Viewing current character's bank
|
||||
if bankIsOpen then
|
||||
@@ -128,12 +155,12 @@ function BankFrame:Update()
|
||||
bankData = addon.Modules.BankScanner:ScanBank()
|
||||
-- Use current character's name for the title
|
||||
local playerName = addon.Modules.DB:GetPlayerFullName()
|
||||
getglobal("Guda_BankFrame_Title"):SetText("Bank - " .. playerName)
|
||||
getglobal("Guda_BankFrame_Title"):SetText(playerName .. "'s Bank")
|
||||
else
|
||||
-- Bank is closed - use saved data (read-only mode)
|
||||
local playerName = addon.Modules.DB:GetPlayerFullName()
|
||||
bankData = addon.Modules.DB:GetCharacterBank(playerName)
|
||||
getglobal("Guda_BankFrame_Title"):SetText("Bank - " .. playerName)
|
||||
getglobal("Guda_BankFrame_Title"):SetText(playerName .. "'s Bank")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -144,6 +171,19 @@ function BankFrame:Update()
|
||||
|
||||
-- Update bank slots info
|
||||
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
|
||||
|
||||
-- Display items
|
||||
@@ -180,13 +220,26 @@ function BankFrame:DisplayItems(bankData, isOtherChar, charName)
|
||||
-- Check if item matches search filter
|
||||
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
|
||||
if button.isBagSlot then
|
||||
break
|
||||
end
|
||||
|
||||
button.inUse = true -- Mark this button as actively in use
|
||||
|
||||
-- Position button
|
||||
local xPos = x + (col * (buttonSize + spacing))
|
||||
local yPos = y - (row * (buttonSize + spacing))
|
||||
@@ -522,6 +575,27 @@ function Guda_BankFrame_OnSearchChanged(self)
|
||||
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
|
||||
function Guda_BankFrame_Sort()
|
||||
if isReadOnlyMode or currentViewChar then
|
||||
@@ -861,6 +935,12 @@ function BankFrame:Initialize()
|
||||
-- Show current character's bank in interactive mode
|
||||
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
|
||||
local customBankFrame = getglobal("Guda_BankFrame")
|
||||
if customBankFrame then
|
||||
@@ -1170,46 +1250,49 @@ end
|
||||
|
||||
-- Highlight all item slots belonging to a specific bank bag by dimming others
|
||||
function Guda_BankFrame_HighlightBagSlots(bagID)
|
||||
local itemContainer = getglobal("Guda_BankFrame_ItemContainer")
|
||||
if not itemContainer then
|
||||
return
|
||||
end
|
||||
-- Buttons are parented under per-bag parents, not directly under the item container
|
||||
local highlightCount, dimCount = 0, 0
|
||||
|
||||
local highlightCount = 0
|
||||
local dimCount = 0
|
||||
|
||||
-- Iterate through all children (item buttons)
|
||||
local children = { itemContainer:GetChildren() }
|
||||
for _, button in ipairs(children) do
|
||||
-- Check if this is an item button
|
||||
if button.hasItem ~= nil and button:IsShown() and not button.isBagSlot then
|
||||
if button.bagID == bagID then
|
||||
-- This button belongs to the hovered bag - keep it bright
|
||||
button:SetAlpha(1.0)
|
||||
highlightCount = highlightCount + 1
|
||||
else
|
||||
-- This button belongs to a different bag - dim it
|
||||
button:SetAlpha(0.25)
|
||||
dimCount = dimCount + 1
|
||||
for _, bankBagParent in pairs(bankBagParents) do
|
||||
if bankBagParent then
|
||||
local children = { bankBagParent:GetChildren() }
|
||||
for _, button in ipairs(children) do
|
||||
if button and button:IsShown() and button.hasItem ~= nil and not button.isBagSlot then
|
||||
if button.bagID == bagID then
|
||||
button:SetAlpha(1.0)
|
||||
highlightCount = highlightCount + 1
|
||||
else
|
||||
button:SetAlpha(0.25)
|
||||
dimCount = dimCount + 1
|
||||
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
|
||||
|
||||
-- Clear all highlighting by restoring full opacity to all slots
|
||||
function Guda_BankFrame_ClearHighlightedSlots()
|
||||
local itemContainer = getglobal("Guda_BankFrame_ItemContainer")
|
||||
if not itemContainer then return end
|
||||
-- Restore alpha to search-filter state (pfUI style). If no search, full opacity.
|
||||
local searchActive = BankFrame and BankFrame.IsSearchActive and BankFrame:IsSearchActive()
|
||||
|
||||
-- Iterate through all children (item buttons)
|
||||
local children = { itemContainer:GetChildren() }
|
||||
for _, button in ipairs(children) do
|
||||
-- Check if this is an item button
|
||||
if button.hasItem ~= nil and button:IsShown() and not button.isBagSlot then
|
||||
-- Restore full opacity
|
||||
button:SetAlpha(1.0)
|
||||
for _, bankBagParent in pairs(bankBagParents) do
|
||||
if bankBagParent then
|
||||
local children = { bankBagParent:GetChildren() }
|
||||
for _, button in ipairs(children) do
|
||||
if button and button:IsShown() and button.hasItem ~= nil and not button.isBagSlot then
|
||||
if searchActive and BankFrame and BankFrame.PassesSearchFilter then
|
||||
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
|
||||
|
||||
+14
-2
@@ -240,7 +240,7 @@
|
||||
</OnClick>
|
||||
<OnEnter>
|
||||
GameTooltip:SetOwner(this, "ANCHOR_TOP")
|
||||
GameTooltip:SetText("View Other Characters' Bank")
|
||||
GameTooltip:SetText("View Bank")
|
||||
GameTooltip:Show()
|
||||
</OnEnter>
|
||||
<OnLeave>
|
||||
@@ -286,8 +286,14 @@
|
||||
this:SetText("")
|
||||
this:SetTextColor(1, 1, 1, 1)
|
||||
end
|
||||
-- Show bank click catcher to detect clicks outside bank while typing
|
||||
local cc = getglobal("Guda_BankClickCatcher")
|
||||
if cc then cc:Show() end
|
||||
</OnEditFocusGained>
|
||||
<OnEditFocusLost>
|
||||
-- Hide bank click catcher when focus is lost
|
||||
local cc = getglobal("Guda_BankClickCatcher")
|
||||
if cc then cc:Hide() end
|
||||
if this:GetText() == "" then
|
||||
this:SetText("Search bank...")
|
||||
this:SetTextColor(0.5, 0.5, 0.5, 1)
|
||||
@@ -302,6 +308,8 @@
|
||||
this:SetTextColor(0.5, 0.5, 0.5, 1)
|
||||
this:ClearFocus()
|
||||
Guda_BankFrame_OnSearchChanged(this)
|
||||
local cc = getglobal("Guda_BankClickCatcher")
|
||||
if cc then cc:Hide() end
|
||||
</OnEscapePressed>
|
||||
</Scripts>
|
||||
</EditBox>
|
||||
@@ -595,7 +603,11 @@
|
||||
Guda_BankFrame_OnShow(this)
|
||||
</OnShow>
|
||||
<OnHide>
|
||||
Guda_BankFrame_OnHide(this)
|
||||
Guda_BankFrame:Hide()
|
||||
-- Close the actual Blizzard bank too
|
||||
if BankFrame and BankFrame:IsShown() then
|
||||
CloseBankFrame()
|
||||
end
|
||||
</OnHide>
|
||||
<OnMouseDown>
|
||||
-- Clear search box focus when clicking on bank frame
|
||||
|
||||
+297
-81
@@ -1,8 +1,6 @@
|
||||
-- Guda Item Button
|
||||
-- Handles item button display and interaction
|
||||
|
||||
-- Local alias to the addon root table (must be defined before any usages below)
|
||||
local addon = Guda
|
||||
|
||||
|
||||
-- Item button pool
|
||||
local buttonPool = {}
|
||||
local nextButtonID = 1
|
||||
@@ -11,6 +9,8 @@ local nextButtonID = 1
|
||||
local scanTooltip = CreateFrame("GameTooltip", "Guda_QuestScanTooltip", nil, "GameTooltipTemplate")
|
||||
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
|
||||
local function IsQuestItem(bagID, slotID)
|
||||
if not bagID or not slotID then return false end
|
||||
@@ -108,30 +108,172 @@ function Guda_ItemButton_OnLoad(self)
|
||||
iconFrame:Hide()
|
||||
self.questIcon = iconFrame
|
||||
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
|
||||
|
||||
-- Set item data
|
||||
function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCharName, matchesFilter, isReadOnly)
|
||||
self.bagID = bagID
|
||||
self.slotID = slotID
|
||||
-- Also set the Blizzard slot ID for compatibility with ContainerFrameItemButtonTemplate behavior
|
||||
if self.SetID and slotID then
|
||||
self:SetID(slotID)
|
||||
end
|
||||
self.itemData = itemData
|
||||
self.isBank = isBank or false
|
||||
self.otherChar = otherCharName
|
||||
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)
|
||||
if matchesFilter == nil then
|
||||
matchesFilter = true
|
||||
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")
|
||||
|
||||
-- Apply icon size setting
|
||||
local iconSize = Guda.Modules.DB:GetSetting("iconSize") or addon.Constants.BUTTON_SIZE
|
||||
-- Apply icon size setting (nil-safe)
|
||||
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: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)
|
||||
if emptySlotBg then
|
||||
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
|
||||
if countText and countText.GetFont then
|
||||
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)
|
||||
|
||||
-- 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
|
||||
|
||||
if itemData then
|
||||
self.hasItem = true
|
||||
-- Get live metadata if in live mode (quality, link, lock status)
|
||||
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
|
||||
SetItemButtonTexture(self, itemData.texture)
|
||||
if self.hasItem then
|
||||
-- Icon already set above based on mode (live vs cached)
|
||||
|
||||
-- Gray out locked items (being traded, mailed, or auctioned) - BagShui style
|
||||
-- Don't desaturate items from other characters since they're read-only anyway
|
||||
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
|
||||
|
||||
-- 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)
|
||||
end
|
||||
|
||||
-- Set count
|
||||
if itemData.count and itemData.count > 1 then
|
||||
countText:SetText(itemData.count)
|
||||
-- Set count (use displayCount which was determined above based on mode)
|
||||
if displayCount and displayCount > 1 then
|
||||
countText:SetText(displayCount)
|
||||
countText:Show()
|
||||
else
|
||||
countText:Hide()
|
||||
@@ -252,10 +411,16 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
||||
-- Special border for keyring items (cyan/blue)
|
||||
self.qualityBorder:SetBackdropBorderColor(0.2, 0.8, 1.0, 1)
|
||||
self.qualityBorder:Show()
|
||||
elseif itemData.quality and itemData.link then
|
||||
-- Check settings to determine if we should show borders
|
||||
local showEquipmentBorder = addon.Modules.DB:GetSetting("showQualityBorderEquipment")
|
||||
local showOtherBorder = addon.Modules.DB:GetSetting("showQualityBorderOther")
|
||||
elseif itemQuality and itemLink then
|
||||
-- Check settings to determine if we should show borders (nil-safe)
|
||||
local showEquipmentBorder, showOtherBorder
|
||||
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
|
||||
if showEquipmentBorder == nil then
|
||||
@@ -265,15 +430,25 @@ function Guda_ItemButton_SetItem(self, bagID, slotID, itemData, isBank, otherCha
|
||||
showOtherBorder = true
|
||||
end
|
||||
|
||||
-- Check if item is equipment
|
||||
local isEquipment = addon.Modules.Utils:IsEquipment(itemData.link)
|
||||
-- Check if item is equipment (nil-safe)
|
||||
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
|
||||
local shouldShowBorder = (isEquipment and showEquipmentBorder) or (not isEquipment and showOtherBorder)
|
||||
|
||||
if shouldShowBorder then
|
||||
-- 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:Show()
|
||||
else
|
||||
@@ -417,51 +592,64 @@ end
|
||||
|
||||
-- OnEnter handler (show tooltip)
|
||||
function Guda_ItemButton_OnEnter(self)
|
||||
-- Highlight the corresponding bag button in the footer (works for empty and filled slots)
|
||||
if not self.otherChar and self.bagID then
|
||||
if self.isBank then
|
||||
-- Bank item - highlight bank bag button
|
||||
Guda_BankFrame_HighlightBagButton(self.bagID)
|
||||
else
|
||||
-- Regular bag item - highlight bag button
|
||||
Guda_BagFrame_HighlightBagButton(self.bagID)
|
||||
end
|
||||
end
|
||||
-- Highlight the corresponding bag button in the footer (works for empty and filled slots)
|
||||
if not self.otherChar and self.bagID then
|
||||
if self.isBank then
|
||||
-- Bank item - highlight bank bag button
|
||||
Guda_BankFrame_HighlightBagButton(self.bagID)
|
||||
else
|
||||
-- Regular bag item - highlight bag button
|
||||
Guda_BagFrame_HighlightBagButton(self.bagID)
|
||||
end
|
||||
end
|
||||
|
||||
-- Early return for empty slots (no tooltip needed)
|
||||
if not self.hasItem or not self.itemData then
|
||||
return
|
||||
end
|
||||
-- Early return for empty slots (no tooltip needed)
|
||||
if not self.hasItem or not self.itemData then
|
||||
return
|
||||
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.isBank and self.itemData.link then
|
||||
-- Extract hyperlink from item link: |cFFFFFFFF|Hitem:1234:0:0:0|h[Name]|h|r -> item:1234:0:0:0
|
||||
local _, _, hyperlink = strfind(self.itemData.link, "|H(.+)|h")
|
||||
if hyperlink then
|
||||
GameTooltip:SetHyperlink(hyperlink)
|
||||
else
|
||||
-- Fallback to SetBagItem
|
||||
GameTooltip:SetBagItem(self.bagID, self.slotID)
|
||||
end
|
||||
else
|
||||
-- For regular bags, use SetBagItem as normal
|
||||
GameTooltip:SetBagItem(self.bagID, self.slotID)
|
||||
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
|
||||
if self.otherChar or self.isReadOnly then
|
||||
GameTooltip.GudaViewedCharacter = self.otherChar
|
||||
if self.itemData and self.itemData.link then
|
||||
GameTooltip:SetHyperlink(self.itemData.link)
|
||||
else
|
||||
GameTooltip:Hide()
|
||||
return
|
||||
end
|
||||
-- Special handling for bank main bag when bank might be closed
|
||||
elseif self.isBank and self.bagID == -1 then
|
||||
local bankFrame = getglobal("BankFrame")
|
||||
if bankFrame and bankFrame:IsVisible() then
|
||||
-- Bank is open - use SetBagItem which will trigger inventory slot handling
|
||||
GameTooltip:SetBagItem(self.bagID, self.slotID)
|
||||
elseif self.itemData and self.itemData.link then
|
||||
-- Bank is closed - use cached link
|
||||
GameTooltip:SetHyperlink(self.itemData.link)
|
||||
end
|
||||
else
|
||||
-- For live mode: use SetBagItem for all bags
|
||||
GameTooltip:SetBagItem(self.bagID, self.slotID)
|
||||
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
|
||||
|
||||
|
||||
-- OnLeave handler
|
||||
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()
|
||||
ResetCursor()
|
||||
|
||||
@@ -484,6 +672,11 @@ function Guda_ItemButton_OnDragStart(self, button)
|
||||
|
||||
-- Only allow left button drag
|
||||
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)
|
||||
end
|
||||
end
|
||||
@@ -497,6 +690,30 @@ function Guda_ItemButton_OnReceiveDrag(self)
|
||||
|
||||
-- Place the item being dragged
|
||||
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
|
||||
|
||||
-- Stack split callback (called by StackSplitFrame)
|
||||
@@ -509,44 +726,43 @@ end
|
||||
-- OnClick handler
|
||||
function Guda_ItemButton_OnClick(self, button)
|
||||
-- Don't allow interaction with other characters' items or in read-only mode
|
||||
if self.otherChar or self.isReadOnly then
|
||||
return
|
||||
end
|
||||
if self.otherChar or self.isReadOnly then return end
|
||||
|
||||
-- Set the split callback
|
||||
self.SplitStack = ItemButton_SplitStack
|
||||
|
||||
-- Handle modified clicks first
|
||||
-- Modified clicks
|
||||
if IsShiftKeyDown() 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
|
||||
if self.itemData and self.itemData.count and self.itemData.count > 1 then
|
||||
-- Get the actual stack count from the container
|
||||
local _, count = GetContainerItemInfo(self.bagID, self.slotID)
|
||||
if count and count > 1 then
|
||||
-- Open the stack split frame (positioned to the left)
|
||||
OpenStackSplitFrame(count, self, "BOTTOMRIGHT", "TOPRIGHT")
|
||||
return
|
||||
end
|
||||
if count and count > 1 then
|
||||
OpenStackSplitFrame(count, self, "BOTTOMRIGHT", "TOPRIGHT")
|
||||
return
|
||||
end
|
||||
-- If not stackable or only 1 item, link to chat
|
||||
if self.itemData and self.itemData.link and ChatFrameEditBox:IsVisible() then
|
||||
ChatFrameEditBox:Insert(self.itemData.link)
|
||||
if itemLink and ChatFrameEditBox:IsVisible() then
|
||||
ChatFrameEditBox:Insert(itemLink)
|
||||
end
|
||||
end
|
||||
return
|
||||
elseif IsControlKeyDown() then
|
||||
-- Ctrl+Click: Dress up (if applicable)
|
||||
if self.hasItem and self.itemData and self.itemData.link then
|
||||
DressUpItemLink(self.itemData.link)
|
||||
if self.hasItem then
|
||||
local itemLink = GetContainerItemLink(self.bagID, self.slotID)
|
||||
if itemLink then
|
||||
DressUpItemLink(itemLink)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Normal clicks - handle item pickup/placement
|
||||
if button == "LeftButton" then
|
||||
-- Pick up or place item
|
||||
PickupContainerItem(self.bagID, self.slotID)
|
||||
-- Left clicks are handled by MouseDown/MouseUp to prevent instant self-drop.
|
||||
return
|
||||
elseif button == "RightButton" then
|
||||
-- Right click: Use item (only if slot has an item)
|
||||
if self.hasItem then
|
||||
@@ -561,4 +777,4 @@ function Guda_ReleaseAllButtons()
|
||||
button:Hide()
|
||||
button:ClearAllPoints()
|
||||
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/">
|
||||
|
||||
<!-- Item Button Template -->
|
||||
<Button name="Guda_ItemButtonTemplate" virtual="true" inherits="ItemButtonTemplate">
|
||||
<!-- Item Button Template (inherit Blizzard container item button for classic behavior/skins) -->
|
||||
<Button name="Guda_ItemButtonTemplate" virtual="true" inherits="ContainerFrameItemButtonTemplate">
|
||||
<Size>
|
||||
<AbsDimension x="37" y="37"/>
|
||||
</Size>
|
||||
@@ -16,9 +16,8 @@
|
||||
</Anchors>
|
||||
</Texture>
|
||||
</Layer>
|
||||
|
||||
|
||||
<!-- Item count -->
|
||||
|
||||
<!-- Custom item count (this intentionally co-exists with Blizzard's $parentCount in rollback state) -->
|
||||
<Layer level="OVERLAY">
|
||||
<FontString name="$parent_Count" inherits="NumberFontNormal" justifyH="RIGHT">
|
||||
<Anchors>
|
||||
@@ -34,9 +33,12 @@
|
||||
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
-- Our visual setup
|
||||
Guda_ItemButton_OnLoad(this)
|
||||
this:RegisterForDrag("LeftButton")
|
||||
this:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
||||
-- Ensure Blizzard default container item button behavior is active
|
||||
if ContainerFrameItemButton_OnLoad then
|
||||
ContainerFrameItemButton_OnLoad()
|
||||
end
|
||||
</OnLoad>
|
||||
<OnEnter>
|
||||
Guda_ItemButton_OnEnter(this)
|
||||
@@ -44,15 +46,6 @@
|
||||
<OnLeave>
|
||||
Guda_ItemButton_OnLeave(this)
|
||||
</OnLeave>
|
||||
<OnClick>
|
||||
Guda_ItemButton_OnClick(this, arg1)
|
||||
</OnClick>
|
||||
<OnDragStart>
|
||||
Guda_ItemButton_OnDragStart(this, arg1)
|
||||
</OnDragStart>
|
||||
<OnReceiveDrag>
|
||||
Guda_ItemButton_OnReceiveDrag(this)
|
||||
</OnReceiveDrag>
|
||||
</Scripts>
|
||||
</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