From c26b2cf3378aff5c49f7c35dbe4a0c7d189fb150 Mon Sep 17 00:00:00 2001 From: Crum Date: Mon, 8 Oct 2018 19:41:32 -0500 Subject: [PATCH] update bags and sort --- ElvUI/Modules/Bags/Bags.lua | 114 +++++++++++++++++++++++++++++------- ElvUI/Modules/Bags/Sort.lua | 37 ++++++++++-- 2 files changed, 124 insertions(+), 27 deletions(-) diff --git a/ElvUI/Modules/Bags/Bags.lua b/ElvUI/Modules/Bags/Bags.lua index 21943be..23d14a7 100644 --- a/ElvUI/Modules/Bags/Bags.lua +++ b/ElvUI/Modules/Bags/Bags.lua @@ -82,8 +82,12 @@ function B:Tooltip_Show() GameTooltip:AddLine(this.ttText) if this.ttText2 then - GameTooltip:AddLine(" ") - GameTooltip:AddDoubleLine(this.ttText2, this.ttText2desc, 1, 1, 1) + if self.ttText2desc then + GameTooltip:AddLine(" ") + GameTooltip:AddDoubleLine(self.ttText2, self.ttText2desc, 1, 1, 1) + else + GameTooltip:AddLine(self.ttText2) + end end GameTooltip:Show() @@ -125,6 +129,7 @@ function B:UpdateSearch() break end end + if repeatChar then B.ResetAndClear(this) return @@ -140,7 +145,7 @@ function B:UpdateSearch() SEARCH_STRING = searchString - B:SetSearch(SEARCH_STRING) + B:RefreshSearch() end function B:OpenEditbox() @@ -321,7 +326,22 @@ function B:UpdateBagSlots(bagID) if self.UpdateSlot then self:UpdateSlot(bagID, slotID) else - self:GetParent():UpdateSlot(bagID, slotID) + self:GetParent():GetParent():UpdateSlot(bagID, slotID) + end + end +end + +function B:RefreshSearch() + B:SetSearch(SEARCH_STRING) +end + +function B:SortingFadeBags(bagFrame) + if not (bagFrame and bagFrame.BagIDs) then return end + for _, bagID in ipairs(bagFrame.BagIDs) do + for slotID = 1, GetContainerNumSlots(bagID) do + local button = bagFrame.Bags[bagID][slotID] + SetItemButtonDesaturated(button, 1) + button:SetAlpha(0.5) end end end @@ -348,6 +368,11 @@ function B:UpdateAllSlots() self.Bags[bagID]:UpdateBagSlots(bagID) end end + + -- Refresh search in case we moved items around + if (not self.registerUpdate) and B:IsSearching() then + B:RefreshSearch() + end end function B:SetSlotAlphaForBag(f) @@ -460,14 +485,14 @@ function B:Layout(isBank) if not f.ContainerHolder[i] then if isBank then f.ContainerHolder[i] = CreateFrame("CheckButton", "ElvUIBankBag"..bagID - 4, f.ContainerHolder, "BankItemButtonBagTemplate") - f.ContainerHolder[i]:SetScript("OnClick", function() - local inventoryID = this:GetInventorySlot() + f.ContainerHolder[i]:SetScript("OnClick", function(holder) + local inventoryID = holder:GetInventorySlot() PutItemInBag(inventoryID) --Put bag on empty slot, or drop item in this bag end) else f.ContainerHolder[i] = CreateFrame("CheckButton", "ElvUIMainBag"..bagID.."Slot", f.ContainerHolder, "BagSlotButtonTemplate") - f.ContainerHolder[i]:SetScript("OnClick", function() - local id = this:GetID() + f.ContainerHolder[i]:SetScript("OnClick", function(holder) + local id = holder:GetID() PutItemInBag(id) --Put bag on empty slot, or drop item in this bag end) end @@ -478,6 +503,7 @@ function B:Layout(isBank) f.ContainerHolder[i]:SetNormalTexture("") f.ContainerHolder[i]:SetCheckedTexture("") f.ContainerHolder[i]:SetPushedTexture("") + f.ContainerHolder[i].id = isBank and bagID or bagID + 1 HookScript(f.ContainerHolder[i], "OnEnter", function() B.SetSlotAlphaForBag(this, f) end) HookScript(f.ContainerHolder[i], "OnLeave", function() B.ResetSlotAlphaForBags(this, f) end) @@ -516,10 +542,10 @@ function B:Layout(isBank) local numSlots = GetContainerNumSlots(bagID) if numSlots > 0 then if not f.Bags[bagID] then - f.Bags[bagID] = CreateFrame("Frame", f:GetName().."Bag"..bagID, f) + f.Bags[bagID] = CreateFrame("Frame", f:GetName().."Bag"..bagID, f.holderFrame) f.Bags[bagID]:SetID(bagID) f.Bags[bagID].UpdateBagSlots = B.UpdateBagSlots - -- f.Bags[bagID].UpdateSlot = UpdateSlot + f.Bags[bagID].UpdateSlot = UpdateSlot end f.Bags[bagID].numSlots = numSlots @@ -756,13 +782,13 @@ function B:OnEvent() --Refresh search in case we moved items around if B:IsSearching() then - B:SetSearch(SEARCH_STRING) + B:RefreshSearch() end elseif event == "BAG_UPDATE_COOLDOWN" then if not this:IsShown() then return end this:UpdateCooldowns() elseif event == "PLAYERBANKSLOTS_CHANGED" then - this:UpdateAllSlots() + this:UpdateAllSlots(-1) end end @@ -815,7 +841,7 @@ function B:GetGraysValue() end function B:VendorGrays(delete) - if (not MerchantFrame or not MerchantFrame:IsShown()) and not delete then + if not MerchantFrame or not MerchantFrame:IsShown() and not delete then E:Print(L["You must be at a vendor."]) return end @@ -875,13 +901,15 @@ function B:ContructContainerFrame(name, isBank) f:RegisterEvent("ITEM_UNLOCKED") f:RegisterEvent("BAG_UPDATE_COOLDOWN") f:RegisterEvent("BAG_UPDATE") - f:RegisterEvent("PLAYERBANKSLOTS_CHANGED") + + if isBank then + f:RegisterEvent("PLAYERBANKSLOTS_CHANGED") + end f:SetScript("OnEvent", B.OnEvent) f:Hide() f.isBank = isBank - f.bottomOffset = isBank and 8 or 28 f.topOffset = isBank and 45 or 50 f.BagIDs = isBank and {-1, 5, 6, 7, 8, 9, 10, 11} or {0, 1, 2, 3, 4} @@ -893,6 +921,7 @@ function B:ContructContainerFrame(name, isBank) f.mover = mover end + --Allow dragging the frame around f:SetMovable(true) f:RegisterForDrag("LeftButton", "RightButton") f:RegisterForClicks("AnyUp") @@ -923,13 +952,16 @@ function B:ContructContainerFrame(name, isBank) E:SetTemplate(f.ContainerHolder, "Transparent") f.ContainerHolder:Hide() + if isBank then + --Bag Text f.bagText = f:CreateFontString(nil, "OVERLAY") E:FontTemplate(f.bagText) E:Point(f.bagText, "BOTTOMRIGHT", f.holderFrame, "TOPRIGHT", -2, 4) f.bagText:SetJustifyH("RIGHT") f.bagText:SetText(L["Bank"]) + --Sort Button f.sortButton = CreateFrame("Button", name.."SortButton", f) E:Size(f.sortButton, 16 + E.Border) E:SetTemplate(f.sortButton) @@ -948,11 +980,19 @@ function B:ContructContainerFrame(name, isBank) f.sortButton.ttText = L["Sort Bags"] f.sortButton:SetScript("OnEnter", self.Tooltip_Show) f.sortButton:SetScript("OnLeave", self.Tooltip_Hide) - f.sortButton:SetScript("OnClick", function() B:CommandDecorator(B.SortBags, "bank")() end) + f.sortButton:SetScript("OnClick", function() + f:UnregisterAllEvents() --Unregister to prevent unnecessary updates + if not f.registerUpdate then + B:SortingFadeBags(f) + end + f.registerUpdate = true --Set variable that indicates this bag should be updated when sorting is done + B:CommandDecorator(B.SortBags, "bank")() + end) if E.db.bags.disableBankSort then f.sortButton:Disable() end + --Toggle Bags Button f.bagsButton = CreateFrame("Button", name.."BagsButton", f.holderFrame) E:Size(f.bagsButton, 16 + E.Border) E:SetTemplate(f.bagsButton) @@ -1008,6 +1048,7 @@ function B:ContructContainerFrame(name, isBank) end end) + --Search f.editBox = CreateFrame("EditBox", name.."EditBox", f) f.editBox:SetFrameLevel(f.editBox:GetFrameLevel() + 2) E:CreateBackdrop(f.editBox, "Default") @@ -1036,11 +1077,13 @@ function B:ContructContainerFrame(name, isBank) f.keyFrame.slots = {} f.keyFrame:Hide() + --Gold Text f.goldText = f:CreateFontString(nil, "OVERLAY") E:FontTemplate(f.goldText) E:Point(f.goldText, "BOTTOMRIGHT", f.holderFrame, "TOPRIGHT", -2, 4) f.goldText:SetJustifyH("RIGHT") + --Sort Button f.sortButton = CreateFrame("Button", name.."SortButton", f) E:Size(f.sortButton, 16 + E.Border) E:SetTemplate(f.sortButton) @@ -1059,11 +1102,19 @@ function B:ContructContainerFrame(name, isBank) f.sortButton.ttText = L["Sort Bags"] f.sortButton:SetScript("OnEnter", self.Tooltip_Show) f.sortButton:SetScript("OnLeave", self.Tooltip_Hide) - f.sortButton:SetScript("OnClick", function() B:CommandDecorator(B.SortBags, "bags")() end) + f.sortButton:SetScript("OnClick", function() + f:UnregisterAllEvents() --Unregister to prevent unnecessary updates + if not f.registerUpdate then + B:SortingFadeBags(f) + end + f.registerUpdate = true --Set variable that indicates this bag should be updated when sorting is done + B:CommandDecorator(B.SortBags, "bags")() + end) if E.db.bags.disableBagSort then f.sortButton:Disable() end + --Keyring Button f.keyButton = CreateFrame("Button", name.."KeyButton", f) E:Size(f.keyButton, 16 + E.Border) E:SetTemplate(f.keyButton) @@ -1080,6 +1131,7 @@ function B:ContructContainerFrame(name, isBank) f.keyButton:SetScript("OnLeave", self.Tooltip_Hide) f.keyButton:SetScript("OnClick", function() ToggleFrame(f.keyFrame) end) + --Bags Button f.bagsButton = CreateFrame("Button", name.."BagsButton", f) E:Size(f.bagsButton, 16 + E.Border) E:SetTemplate(f.bagsButton) @@ -1096,6 +1148,7 @@ function B:ContructContainerFrame(name, isBank) f.bagsButton:SetScript("OnLeave", self.Tooltip_Hide) f.bagsButton:SetScript("OnClick", function() ToggleFrame(f.ContainerHolder) end) + --Vendor Grays f.vendorGraysButton = CreateFrame("Button", nil, f.holderFrame) E:Size(f.vendorGraysButton, 16 + E.Border) E:SetTemplate(f.vendorGraysButton) @@ -1112,6 +1165,7 @@ function B:ContructContainerFrame(name, isBank) f.vendorGraysButton:SetScript("OnLeave", self.Tooltip_Hide) f.vendorGraysButton:SetScript("OnClick", B.VendorGrayCheck) + --Search f.editBox = CreateFrame("EditBox", name.."EditBox", f) f.editBox:SetFrameLevel(f.editBox:GetFrameLevel() + 2) E:CreateBackdrop(f.editBox, "Default") @@ -1144,6 +1198,7 @@ function B:ContructContainerFrame(name, isBank) bagButton:SetChecked(false) end end + if E.db.bags.clearSearchOnClose then B.ResetAndClear(f.editBox) end @@ -1160,8 +1215,7 @@ function B:ContructContainerFrame(name, isBank) end function B:ToggleBags(id) - --Closes a bag when inserting a new container.. - if id and GetContainerNumSlots(id) == 0 then return end + if id and (GetContainerNumSlots(id) == 0) then return end --Closes a bag when inserting a new container.. if self.BagFrame:IsShown() then self:CloseBags() @@ -1213,7 +1267,7 @@ end function B:OpenBags() self.BagFrame:Show() - self.BagFrame:UpdateAllSlots() + E:GetModule("Tooltip"):GameTooltip_SetDefaultAnchor(GameTooltip) end @@ -1232,9 +1286,11 @@ function B:OpenBank() self.BankFrame = self:ContructContainerFrame("ElvUI_BankContainerFrame", true) end + --Call :Layout first so all elements are created before we update self:Layout(true) + self.BankFrame:Show() - self.BankFrame:UpdateAllSlots() + self:OpenBags() end @@ -1260,6 +1316,7 @@ function B:updateContainerFrameAnchors() local screenWidth = GetScreenWidth() local containerScale = 1 local leftLimit = 0 + if BankFrame:IsShown() then leftLimit = BankFrame:GetRight() - 25 end @@ -1276,14 +1333,17 @@ function B:updateContainerFrameAnchors() local frameHeight for _, frameName in ipairs(ContainerFrame1.bags) do frameHeight = _G[frameName]:GetHeight() + if freeScreenHeight < frameHeight then -- Start a new column column = column + 1 leftMostPoint = screenWidth - (column * CONTAINER_WIDTH * containerScale) - xOffset freeScreenHeight = screenHeight - yOffset end + freeScreenHeight = freeScreenHeight - frameHeight - VISIBLE_CONTAINER_SPACING end + if leftMostPoint < leftLimit then containerScale = containerScale - 0.01 else @@ -1307,6 +1367,7 @@ function B:updateContainerFrameAnchors() for index, frameName in ipairs(ContainerFrame1.bags) do frame = _G[frameName] frame:SetScale(1) + if index == 1 then -- First bag frame:SetPoint("BOTTOMRIGHT", ElvUIBagMover, "BOTTOMRIGHT", E.Spacing, -E.Border) @@ -1326,6 +1387,7 @@ function B:updateContainerFrameAnchors() frame:SetPoint("BOTTOMRIGHT", ContainerFrame1.bags[index - 1], "TOPRIGHT", 0, CONTAINER_SPACING) bagsPerColumn = bagsPerColumn + 1 end + freeScreenHeight = freeScreenHeight - frame:GetHeight() - VISIBLE_CONTAINER_SPACING end end @@ -1333,6 +1395,7 @@ end function B:PostBagMove() if not E.private.bags.enable then return end + -- self refers to the mover (bag or bank) local x, y = self:GetCenter() local screenHeight = UIParent:GetTop() local screenWidth = UIParent:GetRight() @@ -1363,11 +1426,14 @@ end function B:Initialize() self:LoadBagBar() + --Bag Mover (We want it created even if Bags module is disabled, so we can use it for default bags too) local BagFrameHolder = CreateFrame("Frame", nil, E.UIParent) - E:Size(BagFrameHolder, 200, 22) + E:Width(BagFrameHolder, 200) + E:Height(BagFrameHolder, 22) BagFrameHolder:SetFrameLevel(BagFrameHolder:GetFrameLevel() + 400) if not E.private.bags.enable then + --Set a different default anchor E:Point(BagFrameHolder, "BOTTOMRIGHT", RightChatPanel, "BOTTOMRIGHT", -(E.Border*2), 22 + E.Border*4 - E.Spacing*2) E:CreateMover(BagFrameHolder, "ElvUIBagMover", L["Bag Mover"], nil, nil, B.PostBagMove) @@ -1379,15 +1445,18 @@ function B:Initialize() self.db = E.db.bags self.BagFrames = {} + --Bag Mover: Set default anchor point and create mover E:Point(BagFrameHolder, "BOTTOMRIGHT", RightChatPanel, "BOTTOMRIGHT", 0, 22 + E.Border*4 - E.Spacing*2) E:CreateMover(BagFrameHolder, "ElvUIBagMover", L["Bag Mover (Grow Up)"], nil, nil, B.PostBagMove) + --Bank Mover local BankFrameHolder = CreateFrame("Frame", nil, E.UIParent) E:Size(BankFrameHolder, 200, 22) E:Point(BankFrameHolder, "BOTTOMLEFT", LeftChatPanel, "BOTTOMLEFT", 0, 22 + E.Border*4 - E.Spacing*2) BankFrameHolder:SetFrameLevel(BankFrameHolder:GetFrameLevel() + 400) E:CreateMover(BankFrameHolder, "ElvUIBankMover", L["Bank Mover (Grow Up)"], nil, nil, B.PostBagMove) + --Set some variables on movers ElvUIBagMover.textGrowUp = L["Bag Mover (Grow Up)"] ElvUIBagMover.textGrowDown = L["Bag Mover (Grow Down)"] ElvUIBagMover.POINT = "BOTTOMRIGHT" @@ -1395,6 +1464,7 @@ function B:Initialize() ElvUIBankMover.textGrowDown = L["Bank Mover (Grow Down)"] ElvUIBankMover.POINT = "BOTTOMLEFT" + --Create Bag Frame self.BagFrame = self:ContructContainerFrame("ElvUI_ContainerFrame") --Hook onto Blizzard Functions diff --git a/ElvUI/Modules/Bags/Sort.lua b/ElvUI/Modules/Bags/Sort.lua index ccb794d..a94e9f6 100644 --- a/ElvUI/Modules/Bags/Sort.lua +++ b/ElvUI/Modules/Bags/Sort.lua @@ -5,7 +5,7 @@ local LIP = LibStub("ItemPrice-1.1"); --Cache global variables --Lua functions -local ipairs, pairs, pcall, tonumber, select, unpack = ipairs, pairs, pcall, tonumber, select, unpack +local ipairs, pairs, pcall, tonumber, select, unpack, pcall = ipairs, pairs, pcall, tonumber, select, unpack, pcall local getn, tinsert, tremove, tsort, twipe = table.getn, table.insert, table.remove, table.sort, table.wipe local floor, mod = math.floor, math.mod local band = bit.band @@ -460,6 +460,7 @@ local blackListQueries = {} local function buildBlacklist(arg) for entry in pairs(arg) do local itemName = GetItemInfo(entry) + if itemName then blackList[itemName] = true elseif entry ~= "" then @@ -549,7 +550,6 @@ function B.FillBags(from, to) tinsert(specialtyBags, bag) end end - if getn(specialtyBags) > 0 then B:Fill(from, specialtyBags) end @@ -637,13 +637,40 @@ function B:StartStacking() end end -function B:StopStacking(message) +local function RegisterUpdateDelayed() + local shouldUpdateFade + for _, bagFrame in pairs(B.BagFrames) do + if bagFrame.registerUpdate then + bagFrame:UpdateAllSlots() + bagFrame.registerUpdate = nil -- call update and re-register events, keep this after UpdateAllSlots + shouldUpdateFade = true -- we should refresh the bag search after sorting + bagFrame:RegisterEvent("ITEM_LOCK_CHANGED") + bagFrame:RegisterEvent("ITEM_UNLOCKED") + bagFrame:RegisterEvent("BAG_UPDATE_COOLDOWN") + bagFrame:RegisterEvent("BAG_UPDATE") + if bagFrame.isBank then + bagFrame:RegisterEvent("PLAYERBANKSLOTS_CHANGED") + end + end + end + if shouldUpdateFade then + B:RefreshSearch() -- this will clear the bag lock look during a sort + end +end + +function B:StopStacking(message, noUpdate) twipe(moves) twipe(moveTracker) moveRetries, lastItemID, lockStop, lastDestination, lastMove = 0, nil, nil, nil, nil, nil self.SortUpdateTimer:Hide() + if not noUpdate then + --Add a delayed update call, as BAG_UPDATE fires slightly delayed + -- and we don't want the last few unneeded updates to be catched + E:Delay(0.6, RegisterUpdateDelayed) + end + if message then E:Print(message) end @@ -762,7 +789,7 @@ function B:DoMoves() lastItemID = moveID tremove(moves, i) - if moves[i-1] then + if moves[i - 1] then WAIT_TIME = 0 return end @@ -785,7 +812,7 @@ end function B:CommandDecorator(func, groupsDefaults) return function(groups) if self.SortUpdateTimer:IsShown() then - B:StopStacking(L["Already Running.. Bailing Out!"]) + B:StopStacking(L["Already Running.. Bailing Out!"], true) return end