-- Guda Bag Frame -- Main bag viewing UI local addon = Guda local BagFrame = {} addon.Modules.BagFrame = BagFrame local currentViewChar = nil -- nil = current character local searchText = "" local itemButtons = {} -- Global click catcher for clearing search focus local clickCatcher = nil -- Get player race icon path (using racial ability icons) function Guda_GetPlayerRaceIcon() local _, race = UnitRace("player") -- Use racial ability icons that exist in vanilla local raceIcons = { Human = "Interface\\Icons\\Spell_Magic_PolymorphPig", Dwarf = "Interface\\Icons\\Spell_Shadow_UnholyFrenzy", NightElf = "Interface\\Icons\\Spell_Nature_Invisibility", Gnome = "Interface\\Icons\\Ability_Repair", Orc = "Interface\\Icons\\Ability_Racial_BloodRage", Undead = "Interface\\Icons\\Spell_Shadow_RaiseDead", Tauren = "Interface\\Icons\\Ability_Thunderclap", Troll = "Interface\\Icons\\Ability_Racial_Avatar", } return raceIcons[race] or "Interface\\Icons\\INV_Misc_GroupNeedMore" end -- OnLoad function Guda_BagFrame_OnLoad(self) -- Set up search box placeholder local searchBox = getglobal(self:GetName().."_SearchBar_SearchBox") if searchBox then searchBox:SetText("Search, try ~equipment") searchBox:SetTextColor(0.5, 0.5, 0.5, 1) end -- Create invisible full-screen frame to catch clicks outside bag if not clickCatcher then clickCatcher = CreateFrame("Frame", "Guda_ClickCatcher", UIParent) clickCatcher:SetFrameStrata("BACKGROUND") clickCatcher:SetAllPoints(UIParent) clickCatcher:EnableMouse(true) clickCatcher:Hide() clickCatcher:SetScript("OnMouseDown", function() local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox") if searchBox then searchBox:ClearFocus() end end) end addon:Debug("Bag frame loaded") end -- OnShow function Guda_BagFrame_OnShow(self) -- Save bag data when opening bags addon.Modules.BagScanner:SaveToDatabase() addon.Modules.MoneyTracker:Update() -- Restore saved position if it exists (only if saved as BOTTOMRIGHT) if addon and addon.Modules and addon.Modules.DB then local pos = addon.Modules.DB:GetSetting("bagFramePosition") if pos and pos.point == "BOTTOMRIGHT" and pos.x and pos.y then self:ClearAllPoints() self:SetPoint("BOTTOMRIGHT", "UIParent", "BOTTOMRIGHT", pos.x, pos.y) end end -- Set lock state when frame is shown (ensures all child frames are loaded) if BagFrame.UpdateLockState then BagFrame:UpdateLockState() end BagFrame:Update() end -- OnHide function Guda_BagFrame_OnHide(self) -- Release buttons Guda_ReleaseAllButtons() end -- Toggle visibility function BagFrame:Toggle() if Guda_BagFrame:IsShown() then Guda_BagFrame:Hide() else Guda_BagFrame:Show() end end -- Show specific character's bags function BagFrame:ShowCharacter(fullName) currentViewChar = fullName self:Update() end -- Show current character function BagFrame:ShowCurrentCharacter() currentViewChar = nil self:Update() end -- Update display function BagFrame:Update() if not Guda_BagFrame:IsShown() then return end -- Clear existing buttons Guda_ReleaseAllButtons() local bagData local isOtherChar = false local charName = "" local titleFont = getglobal("Guda_BagFrame_Title") local displayName if currentViewChar then -- Viewing another character bagData = addon.Modules.DB:GetCharacterBags(currentViewChar) isOtherChar = true charName = currentViewChar local dash = string.find(currentViewChar, "-") if dash then displayName = string.sub(currentViewChar, 1, dash - 1) else displayName = currentViewChar end else -- Viewing current character bagData = addon.Modules.BagScanner:ScanBags() displayName = UnitName("player") or "Character" end if titleFont and displayName then titleFont:SetText(string.format("%s's Bags", displayName)) end -- Display items self:DisplayItems(bagData, isOtherChar, charName) -- Update money self:UpdateMoney() end -- Display items function BagFrame:DisplayItems(bagData, isOtherChar, charName) local x, y = 10, -10 local row = 0 local col = 0 local buttonSize = addon.Modules.DB:GetSetting("iconSize") or addon.Constants.BUTTON_SIZE local spacing = addon.Modules.DB:GetSetting("iconSpacing") or addon.Constants.BUTTON_SPACING local perRow = addon.Modules.DB:GetSetting("bagColumns") or 10 local itemContainer = getglobal("Guda_BagFrame_ItemContainer") for _, bagID in ipairs(addon.Constants.BAGS) do local bag = bagData[bagID] -- Get slot count for this bag local numSlots if isOtherChar and bag and bag.numSlots then -- Use stored slot count for other characters numSlots = bag.numSlots else -- Use current character's bag slot count numSlots = addon.Modules.Utils:GetBagSlotCount(bagID) end -- Only show bags that have slots if numSlots and numSlots > 0 then -- Iterate through ALL slots (1 to numSlots) to show empty slots too for slot = 1, numSlots do local itemData = bag and bag.slots and bag.slots[slot] or nil -- Check if item matches search filter local matchesFilter = self:PassesSearchFilter(itemData) local button = Guda_GetItemButton(itemContainer) -- Position button local xPos = x + (col * (buttonSize + spacing)) local yPos = y - (row * (buttonSize + spacing)) button:ClearAllPoints() button:SetPoint("TOPLEFT", itemContainer, "TOPLEFT", xPos, yPos) -- Set item data with filter match info Guda_ItemButton_SetItem(button, bagID, slot, itemData, false, isOtherChar and charName or nil, matchesFilter) table.insert(itemButtons, button) -- Advance position col = col + 1 if col >= perRow then col = 0 row = row + 1 end end end end -- Resize frame dynamically based on content self:ResizeFrame(row, col, perRow) end -- Resize frame based on number of rows and columns function BagFrame:ResizeFrame(currentRow, currentCol, columns) local buttonSize = addon.Modules.DB:GetSetting("iconSize") or addon.Constants.BUTTON_SIZE local spacing = addon.Modules.DB:GetSetting("iconSpacing") or addon.Constants.BUTTON_SPACING -- Calculate actual number of rows used local totalRows = currentRow + 1 -- Ensure at least 1 row if totalRows < 1 then totalRows = 1 end -- Calculate required dimensions based on columns local containerWidth = (columns * (buttonSize + spacing)) + 20 local containerHeight = (totalRows * (buttonSize + spacing)) + 20 local frameWidth = containerWidth + 20 local frameHeight = containerHeight + 115 -- Title (40) + search (30) + footer (45) -- Minimum sizes if containerWidth < 200 then containerWidth = 200 frameWidth = 220 end if containerHeight < 150 then containerHeight = 150 end if frameHeight < 250 then frameHeight = 250 end -- Maximum sizes if containerWidth > 800 then containerWidth = 800 frameWidth = 820 end if containerHeight > 600 then containerHeight = 600 end if frameHeight > 800 then frameHeight = 800 end -- Resize frames local bagFrame = getglobal("Guda_BagFrame") local itemContainer = getglobal("Guda_BagFrame_ItemContainer") if bagFrame then bagFrame:SetWidth(frameWidth) bagFrame:SetHeight(frameHeight) -- Always use BOTTOMRIGHT anchor to make frame grow left bagFrame:ClearAllPoints() if addon and addon.Modules and addon.Modules.DB then local pos = addon.Modules.DB:GetSetting("bagFramePosition") -- Only use saved position if it was saved as BOTTOMRIGHT if pos and pos.point == "BOTTOMRIGHT" and pos.x and pos.y then bagFrame:SetPoint("BOTTOMRIGHT", "UIParent", "BOTTOMRIGHT", pos.x, pos.y) else -- Default position: bottom right corner bagFrame:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -50, 100) end else -- Fallback to default if DB not available bagFrame:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -50, 100) end end if itemContainer then itemContainer:SetWidth(containerWidth) itemContainer:SetHeight(containerHeight) end -- Resize search bar and toolbar to match container width local searchBar = getglobal("Guda_BagFrame_SearchBar") if searchBar then searchBar:SetWidth(containerWidth) end local toolbar = getglobal("Guda_BagFrame_Toolbar") if toolbar then toolbar:SetWidth(containerWidth) end end -- Check if search is currently active function BagFrame:IsSearchActive() return searchText and searchText ~= "" and searchText ~= "Search, try ~equipment" end -- Check if item passes search filter (pfUI style) function BagFrame:PassesSearchFilter(itemData) -- If no search text, everything matches if not self:IsSearchActive() then return true end -- Empty slots don't match when searching (pfUI style - they get dimmed) if not itemData then return false end -- Get item name from itemData.name or parse from link local itemName = itemData.name if not itemName and itemData.link then -- Parse name from item link: |cffffffff|Hitem:...|h[Item Name]|h|r local _, _, name = string.find(itemData.link, "%[(.+)%]") itemName = name if not self.warnedAboutParsing then addon:Print("DEBUG: Had to parse item name from link: " .. (itemName or "FAILED")) self.warnedAboutParsing = true end end if not itemName then if not self.warnedAboutNoName then addon:Print("DEBUG: Item has no name and no link! texture = " .. tostring(itemData.texture)) self.warnedAboutNoName = true end return false end -- Case-insensitive search in item name itemName = string.lower(itemName) local search = string.lower(searchText) -- Check if item name contains search text local matches = string.find(itemName, search, 1, true) ~= nil -- Debug: print first match found if matches and not self.foundFirstMatch then addon:Print("DEBUG: Found match! Item: '" .. itemName .. "' matches search: '" .. searchText .. "'") self.foundFirstMatch = true end return matches end function BagFrame:UpdateMoney() local moneyFrame = getglobal("Guda_BagFrame_MoneyFrame") if not moneyFrame then addon:Debug("MoneyFrame not found! Checking parent...") addon:Debug("Guda_BagFrame exists: " .. tostring(getglobal("Guda_BagFrame") ~= nil)) -- Try to create it manually self:CreateMoneyFrame() moneyFrame = getglobal("Guda_BagFrame_MoneyFrame") end if moneyFrame then MoneyFrame_Update("Guda_BagFrame_MoneyFrame", GetMoney()) moneyFrame:Show() -- Ensure tooltip overlay exists self:EnsureMoneyTooltipOverlay() -- Also add tooltip to toolbar empty space self:SetupToolbarTooltip() else addon:Debug("Still couldn't find or create MoneyFrame!") end end function BagFrame:CreateMoneyFrame() local moneyFrame = CreateFrame("Frame", "Guda_BagFrame_MoneyFrame", Guda_BagFrame, "SmallMoneyFrameTemplate") moneyFrame:SetPoint("BOTTOMRIGHT", Guda_BagFrame, "BOTTOMRIGHT", -15, 10) moneyFrame:SetWidth(180) moneyFrame:SetHeight(35) addon:Debug("MoneyFrame created via CreateMoneyFrame") end -- Setup tooltip on toolbar empty space function BagFrame:SetupToolbarTooltip() local toolbar = getglobal("Guda_BagFrame_Toolbar") if not toolbar then return end -- Only set up once if toolbar.tooltipSetup then return end -- Get the existing OnEnter script (if any) local originalOnEnter = toolbar:GetScript("OnEnter") -- Set new OnEnter that shows money tooltip toolbar:SetScript("OnEnter", function() -- Call original if it exists if originalOnEnter then originalOnEnter() end -- Show money tooltip addon:Debug("Toolbar OnEnter - showing money tooltip") Guda_BagFrame_MoneyOnEnter(getglobal("Guda_BagFrame_MoneyFrame")) end) -- Set OnLeave to hide tooltip toolbar:SetScript("OnLeave", function() addon:Debug("Toolbar OnLeave - hiding tooltip") GameTooltip:Hide() end) toolbar.tooltipSetup = true addon:Debug("Toolbar tooltip handlers set up") end -- Create transparent overlay for money tooltip function BagFrame:EnsureMoneyTooltipOverlay() local overlayName = "Guda_BagFrame_MoneyTooltipOverlay" local overlay = getglobal(overlayName) if not overlay then local moneyFrame = getglobal("Guda_BagFrame_MoneyFrame") if not moneyFrame then return end -- Create transparent overlay frame overlay = CreateFrame("Frame", overlayName, moneyFrame) overlay:SetAllPoints(moneyFrame) overlay:SetFrameLevel(moneyFrame:GetFrameLevel() + 1) overlay:EnableMouse(true) -- Set tooltip handlers on overlay overlay:SetScript("OnEnter", function() addon:Debug("Money overlay OnEnter triggered") Guda_BagFrame_MoneyOnEnter(moneyFrame) end) overlay:SetScript("OnLeave", function() addon:Debug("Money overlay OnLeave triggered") GameTooltip:Hide() end) -- Forward drag events to bag frame (if not locked) overlay:SetScript("OnMouseDown", function() local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox") if searchBox then searchBox:ClearFocus() end local bagFrame = getglobal("Guda_BagFrame") local isLocked = addon.Modules.DB and addon.Modules.DB:GetSetting("lockBags") if bagFrame and not isLocked and arg1 == "LeftButton" then bagFrame:StartMoving() end end) overlay:SetScript("OnMouseUp", function() local bagFrame = getglobal("Guda_BagFrame") local isLocked = addon.Modules.DB and addon.Modules.DB:GetSetting("lockBags") if bagFrame and not isLocked then bagFrame:StopMovingOrSizing() SaveBagFramePosition() end end) addon:Debug("Money tooltip overlay created") end overlay:Show() end -- Money frame OnLoad handler function Guda_BagFrame_MoneyFrame_OnLoad(self) addon:Debug("MoneyFrame OnLoad called for: " .. self:GetName()) -- Set tooltip handlers on all money denomination buttons local buttons = {"GoldButton", "SilverButton", "CopperButton"} for _, buttonName in ipairs(buttons) do local fullName = self:GetName() .. buttonName local button = getglobal(fullName) addon:Debug("Looking for button: " .. fullName .. " - Found: " .. tostring(button ~= nil)) if button then button:SetScript("OnEnter", function() addon:Debug("Money button OnEnter triggered") Guda_BagFrame_MoneyOnEnter(this:GetParent()) end) button:SetScript("OnLeave", function() GameTooltip:Hide() end) end end -- Also try setting handlers directly on the parent frame addon:Debug("Setting handlers on parent frame as fallback") self:EnableMouse(true) self:SetScript("OnEnter", function() addon:Debug("Parent frame OnEnter triggered") Guda_BagFrame_MoneyOnEnter(this) end) self:SetScript("OnLeave", function() GameTooltip:Hide() end) end -- Money tooltip handler function Guda_BagFrame_MoneyOnEnter(self) if not self then return end -- Anchor tooltip to TOPRIGHT - aligns tooltip's right edge with money container's right edge GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT", 0, 0) GameTooltip:ClearLines() -- Get all characters and total local chars = addon.Modules.DB:GetAllCharacters(true) local totalMoney = addon.Modules.DB:GetTotalMoney(true) -- Header with faction/realm total - use colored money GameTooltip:AddLine( "Faction/realm-wide gold: " .. addon.Modules.Utils:FormatMoney(totalMoney, false, true), 1, 0.82, 0 ) GameTooltip:AddLine(" ") -- List each character with class-colored names for _, char in ipairs(chars) do -- Get class color from WoW's built-in table using English class token local classToken = char.classToken local classColor = classToken and (CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[classToken] local colorR, colorG, colorB = 0.7, 0.7, 0.7 if classColor then colorR, colorG, colorB = classColor.r, classColor.g, classColor.b end -- Create colored name local coloredName = addon.Modules.Utils:ColorText(char.name, colorR, colorG, colorB) GameTooltip:AddLine( coloredName .. ": " .. addon.Modules.Utils:FormatMoney(char.money or 0, false, true) ) end GameTooltip:Show() end -- Character dropdown management local characterDropdown = nil -- Toggle character dropdown function Guda_BagFrame_ToggleCharacterDropdown(button) if characterDropdown and characterDropdown:IsShown() then characterDropdown:Hide() return end if not characterDropdown then -- Create dropdown frame characterDropdown = CreateFrame("Frame", "Guda_CharacterDropdown", UIParent) characterDropdown:SetFrameStrata("DIALOG") characterDropdown:SetWidth(200) characterDropdown:SetBackdrop({ bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true, tileSize = 16, edgeSize = 16, insets = { left = 4, right = 4, top = 4, bottom = 4 } }) characterDropdown:SetBackdropColor(0, 0, 0, 0.95) characterDropdown:EnableMouse(true) characterDropdown:Hide() characterDropdown.buttons = {} end -- Position dropdown below the button characterDropdown:ClearAllPoints() characterDropdown:SetPoint("TOPLEFT", button, "BOTTOMLEFT", 0, -2) -- Clear existing buttons for _, btn in ipairs(characterDropdown.buttons) do btn:Hide() end characterDropdown.buttons = {} -- Get all characters local chars = addon.Modules.DB:GetAllCharacters(true) -- Add "Current Character" option at the top local yOffset = -8 local currentCharButton = CreateFrame("Button", nil, characterDropdown) currentCharButton:SetWidth(188) currentCharButton:SetHeight(20) currentCharButton:SetPoint("TOP", characterDropdown, "TOP", 0, yOffset) -- Button background on hover local currentCharBg = currentCharButton:CreateTexture(nil, "BACKGROUND") currentCharBg:SetAllPoints() currentCharBg:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") currentCharBg:SetBlendMode("ADD") currentCharBg:SetAlpha(0) -- Button text local currentCharText = currentCharButton:CreateFontString(nil, "ARTWORK", "GameFontHighlight") currentCharText:SetPoint("LEFT", currentCharButton, "LEFT", 8, 0) currentCharText:SetText("Current Character") -- Button scripts currentCharButton:SetScript("OnEnter", function() currentCharBg:SetAlpha(0.3) end) currentCharButton:SetScript("OnLeave", function() currentCharBg:SetAlpha(0) end) currentCharButton:SetScript("OnClick", function() addon.Modules.BagFrame:ShowCurrentCharacter() characterDropdown:Hide() end) table.insert(characterDropdown.buttons, currentCharButton) yOffset = yOffset - 20 -- Add separator local separator = characterDropdown:CreateTexture(nil, "ARTWORK") separator:SetHeight(1) separator:SetWidth(180) separator:SetPoint("TOP", characterDropdown, "TOP", 0, yOffset) separator:SetTexture(1, 1, 1, 0.2) yOffset = yOffset - 4 -- Get current player's full name for comparison local currentPlayerFullName = addon.Modules.DB:GetPlayerFullName() -- Add character buttons for _, char in ipairs(chars) do -- Capture variables in local scope for closure local charFullName = char.fullName local charName = char.name local charMoney = char.money or 0 local charClassToken = char.classToken local isCurrentChar = (charFullName == currentPlayerFullName) local charButton = CreateFrame("Button", nil, characterDropdown) charButton:SetWidth(188) charButton:SetHeight(20) charButton:SetPoint("TOP", characterDropdown, "TOP", 0, yOffset) -- Button background on hover local charBg = charButton:CreateTexture(nil, "BACKGROUND") charBg:SetAllPoints() charBg:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight") charBg:SetBlendMode("ADD") charBg:SetAlpha(0) -- Get class color local classColor = charClassToken and RAID_CLASS_COLORS[charClassToken] local r, g, b = 1, 1, 1 if classColor then r, g, b = classColor.r, classColor.g, classColor.b end -- Button text local charText = charButton:CreateFontString(nil, "ARTWORK", "GameFontHighlight") charText:SetPoint("LEFT", charButton, "LEFT", 8, 0) charText:SetText(charName) charText:SetTextColor(r, g, b) -- Money text local moneyText = charButton:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall") moneyText:SetPoint("RIGHT", charButton, "RIGHT", -8, 0) moneyText:SetText(addon.Modules.Utils:FormatMoney(charMoney)) moneyText:SetTextColor(0.7, 0.7, 0.7) -- Button scripts charButton:SetScript("OnEnter", function() charBg:SetAlpha(0.3) end) charButton:SetScript("OnLeave", function() charBg:SetAlpha(0) end) charButton:SetScript("OnClick", function() if charFullName then if isCurrentChar then -- Clicking current character - show current live view addon.Modules.BagFrame:ShowCurrentCharacter() else -- Clicking different character - show their stored bags addon.Modules.BagFrame:ShowCharacter(charFullName) end characterDropdown:Hide() else addon:Print("Error: Character fullName is nil") end end) table.insert(characterDropdown.buttons, charButton) yOffset = yOffset - 20 end -- Set dropdown height based on content characterDropdown:SetHeight(math.abs(yOffset) + 8) -- Show dropdown characterDropdown:Show() end -- Hide dropdown when clicking elsewhere local function HideCharacterDropdown() if characterDropdown then characterDropdown:Hide() end end -- Search changed handler function Guda_BagFrame_OnSearchChanged(self) local text = self:GetText() -- Ignore placeholder text if text == "Search, try ~equipment" then text = "" end if text ~= searchText then searchText = text BagFrame.foundFirstMatch = false -- Reset debug flags BagFrame.warnedAboutParsing = false BagFrame.warnedAboutNoName = false addon:Print("Search text changed to: '" .. (searchText or "empty") .. "'") BagFrame:Update() end end -- Sort button handler function Guda_BagFrame_Sort() if currentViewChar then addon:Print("Cannot sort another character's bags!") return end addon.Modules.SortEngine:SortBags() -- Update after a delay to allow items to move local frame = CreateFrame("Frame") local elapsed = 0 frame:SetScript("OnUpdate", function() elapsed = elapsed + arg1 if elapsed >= 0.5 then frame:SetScript("OnUpdate", nil) BagFrame:Update() end end) end -- Hook to default bag opening local function HookDefaultBags() -- Override ToggleBackpack local originalToggleBackpack = ToggleBackpack function ToggleBackpack() BagFrame:Toggle() end -- Override OpenAllBags local originalOpenAllBags = OpenAllBags function OpenAllBags() Guda_BagFrame:Show() end -- Override CloseAllBags local originalCloseAllBags = CloseAllBags function CloseAllBags() Guda_BagFrame:Hide() end end -- Save bag frame position (always as BOTTOMRIGHT) local function SaveBagFramePosition() local frame = getglobal("Guda_BagFrame") if not frame or not addon or not addon.Modules or not addon.Modules.DB then return end -- Always save as BOTTOMRIGHT coordinates local right = frame:GetRight() local bottom = frame:GetBottom() local screenWidth = GetScreenWidth() if right and bottom and screenWidth then local xOffset = right - screenWidth local yOffset = bottom addon.Modules.DB:SetSetting("bagFramePosition", { point = "BOTTOMRIGHT", x = xOffset, y = yOffset }) end end -- Update lock state (controls whether frame is draggable) function BagFrame:UpdateLockState() -- Safety check: ensure addon and modules exist if not addon or not addon.Modules then return end local frame = getglobal("Guda_BagFrame") if not frame then return end -- Check if DB module is available if not addon.Modules.DB or not addon.Modules.DB.GetSetting then return end local success, isLocked = pcall(function() return addon.Modules.DB:GetSetting("lockBags") end) if not success then return end if isLocked == nil then isLocked = false end -- Get draggable areas local toolbar = getglobal("Guda_BagFrame_Toolbar") local moneyFrame = getglobal("Guda_BagFrame_MoneyFrame") local itemContainer = getglobal("Guda_BagFrame_ItemContainer") if isLocked then -- Disable dragging on main frame if frame.SetScript then frame:SetScript("OnMouseDown", function() local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox") if searchBox then searchBox:ClearFocus() end end) frame:SetScript("OnMouseUp", nil) end -- Disable dragging on toolbar if toolbar and toolbar.SetScript then toolbar:SetScript("OnMouseDown", function() local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox") if searchBox then searchBox:ClearFocus() end end) toolbar:SetScript("OnMouseUp", nil) end -- Disable dragging on money frame (preserve tooltip handlers on child buttons) if moneyFrame and moneyFrame.SetScript then moneyFrame:SetScript("OnMouseDown", function() local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox") if searchBox then searchBox:ClearFocus() end end) moneyFrame:SetScript("OnMouseUp", nil) end -- Disable dragging on item container if itemContainer and itemContainer.SetScript then itemContainer:SetScript("OnMouseDown", function() local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox") if searchBox then searchBox:ClearFocus() end end) itemContainer:SetScript("OnMouseUp", nil) end else -- Enable dragging on main frame if frame and frame.SetScript then frame:SetScript("OnMouseDown", function() local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox") if searchBox then searchBox:ClearFocus() end local bagFrame = getglobal("Guda_BagFrame") if bagFrame and arg1 == "LeftButton" then bagFrame:StartMoving() end end) frame:SetScript("OnMouseUp", function() local bagFrame = getglobal("Guda_BagFrame") if bagFrame then bagFrame:StopMovingOrSizing() SaveBagFramePosition() end end) end -- Enable dragging on toolbar (title area) if toolbar and toolbar.SetScript then toolbar:SetScript("OnMouseDown", function() local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox") if searchBox then searchBox:ClearFocus() end local bagFrame = getglobal("Guda_BagFrame") if bagFrame and arg1 == "LeftButton" then bagFrame:StartMoving() end end) toolbar:SetScript("OnMouseUp", function() local bagFrame = getglobal("Guda_BagFrame") if bagFrame then bagFrame:StopMovingOrSizing() SaveBagFramePosition() end end) end -- Enable dragging on money frame (preserve tooltip handlers on child buttons) if moneyFrame and moneyFrame.SetScript then moneyFrame:SetScript("OnMouseDown", function() local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox") if searchBox then searchBox:ClearFocus() end local bagFrame = getglobal("Guda_BagFrame") if bagFrame and arg1 == "LeftButton" then bagFrame:StartMoving() end end) moneyFrame:SetScript("OnMouseUp", function() local bagFrame = getglobal("Guda_BagFrame") if bagFrame then bagFrame:StopMovingOrSizing() SaveBagFramePosition() end end) end -- Enable dragging on item container if itemContainer and itemContainer.SetScript then itemContainer:SetScript("OnMouseDown", function() local searchBox = getglobal("Guda_BagFrame_SearchBar_SearchBox") if searchBox then searchBox:ClearFocus() end local bagFrame = getglobal("Guda_BagFrame") if bagFrame and arg1 == "LeftButton" then bagFrame:StartMoving() end end) itemContainer:SetScript("OnMouseUp", function() local bagFrame = getglobal("Guda_BagFrame") if bagFrame then bagFrame:StopMovingOrSizing() SaveBagFramePosition() end end) end end end -- Initialize function BagFrame:Initialize() -- Hook default bag functions HookDefaultBags() -- Update on bag changes addon.Modules.Events:OnBagUpdate(function() if not currentViewChar then BagFrame:Update() end end, "BagFrame") -- Update on money changes addon.Modules.Events:OnMoneyChanged(function() BagFrame:UpdateMoney() end, "BagFrame") -- Hide character dropdown when clicking on bag frame local bagFrame = getglobal("Guda_BagFrame") if bagFrame then local originalOnMouseDown = bagFrame:GetScript("OnMouseDown") bagFrame:SetScript("OnMouseDown", function() HideCharacterDropdown() if originalOnMouseDown then originalOnMouseDown() end end) end addon:Debug("Bag frame initialized") end