Bags.lua 88.7 KB
Newer Older
Azilroka's avatar
Azilroka committed
1
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
2 3 4
local B = E:GetModule('Bags')
local TT = E:GetModule('Tooltip')
local Skins = E:GetModule('Skins')
Simpy's avatar
Simpy committed
5
local Search = E.Libs.ItemSearch
6

Simpy's avatar
Simpy committed
7
--Lua functions1
8
local _G = _G
Rubgrsch's avatar
Rubgrsch committed
9
local type, ipairs, pairs, unpack, select, assert, pcall = type, ipairs, pairs, unpack, select, assert, pcall
Simpy's avatar
Simpy committed
10 11 12
local tinsert, tremove, twipe, tmaxn = tinsert, tremove, wipe, table.maxn
local floor, ceil, abs = floor, ceil, abs
local format, sub = format, strsub
Simpy's avatar
Simpy committed
13
local tonumber = tonumber
14
--WoW API / Variables
15 16
local BankFrameItemButton_Update = BankFrameItemButton_Update
local BankFrameItemButton_UpdateLocked = BankFrameItemButton_UpdateLocked
17 18 19 20
local CloseBag, CloseBackpack, CloseBankFrame = CloseBag, CloseBackpack, CloseBankFrame
local ContainerIDToInventoryID = ContainerIDToInventoryID
local CooldownFrame_Set = CooldownFrame_Set
local CreateFrame = CreateFrame
21 22
local DeleteCursorItem = DeleteCursorItem
local DepositReagentBank = DepositReagentBank
Merathilis's avatar
Merathilis committed
23
local GameTooltip_Hide = GameTooltip_Hide
24
local GetBackpackAutosortDisabled = GetBackpackAutosortDisabled
25
local GetBackpackCurrencyInfo = GetBackpackCurrencyInfo
26
local GetBagSlotFlag = GetBagSlotFlag
27
local GetBankAutosortDisabled = GetBankAutosortDisabled
28
local GetBankBagSlotFlag = GetBankBagSlotFlag
29
local GetContainerItemCooldown = GetContainerItemCooldown
Merathilis's avatar
Merathilis committed
30
local GetContainerItemID = GetContainerItemID
31
local GetContainerItemInfo = GetContainerItemInfo
32 33 34 35 36
local GetContainerItemLink = GetContainerItemLink
local GetContainerItemQuestInfo = GetContainerItemQuestInfo
local GetContainerNumFreeSlots = GetContainerNumFreeSlots
local GetContainerNumSlots = GetContainerNumSlots
local GetCurrencyLink = GetCurrencyLink
37
local GetCurrentGuildBankTab = GetCurrentGuildBankTab
Simpy's avatar
Simpy committed
38
local GetCVarBool = GetCVarBool
39
local GetGuildBankItemLink = GetGuildBankItemLink
40
local GetGuildBankTabInfo = GetGuildBankTabInfo
41 42
local GetItemInfo = GetItemInfo
local GetItemQualityColor = GetItemQualityColor
43 44 45
local GetMoney = GetMoney
local GetNumBankSlots = GetNumBankSlots
local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
Simpy's avatar
Simpy committed
46
local HandleModifiedItemClick = HandleModifiedItemClick
47
local IsBagOpen, IsOptionFrameOpen = IsBagOpen, IsOptionFrameOpen
48
local IsInventoryItemProfessionBag = IsInventoryItemProfessionBag
49 50 51 52 53
local IsModifiedClick = IsModifiedClick
local IsReagentBankUnlocked = IsReagentBankUnlocked
local IsShiftKeyDown, IsControlKeyDown = IsShiftKeyDown, IsControlKeyDown
local PickupContainerItem = PickupContainerItem
local PlaySound = PlaySound
54
local PutItemInBackpack = PutItemInBackpack
Blazeflack's avatar
Blazeflack committed
55
local PutItemInBag = PutItemInBag
56
local SetBackpackAutosortDisabled = SetBackpackAutosortDisabled
57
local SetBagSlotFlag = SetBagSlotFlag
58
local SetBankAutosortDisabled = SetBankAutosortDisabled
59
local SetBankBagSlotFlag = SetBankBagSlotFlag
Simpy's avatar
Simpy committed
60
local SetInsertItemsLeftToRight = SetInsertItemsLeftToRight
61
local SetItemButtonCount = SetItemButtonCount
62
local SetItemButtonDesaturated = SetItemButtonDesaturated
63 64
local SetItemButtonTexture = SetItemButtonTexture
local SetItemButtonTextureVertexColor = SetItemButtonTextureVertexColor
65 66
local SortBags = SortBags
local SortBankBags = SortBankBags
67 68 69
local SortReagentBankBags = SortReagentBankBags
local StaticPopup_Show = StaticPopup_Show
local ToggleFrame = ToggleFrame
70
local UseContainerItem = UseContainerItem
Simpy's avatar
Simpy committed
71 72 73 74 75 76 77 78

local C_AzeriteEmpoweredItem_IsAzeriteEmpoweredItemByID = C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItemByID
local C_Item_CanScrapItem = C_Item.CanScrapItem
local C_Item_DoesItemExist = C_Item.DoesItemExist
local C_NewItems_IsNewItem = C_NewItems.IsNewItem
local C_NewItems_RemoveNewItem = C_NewItems.RemoveNewItem
local C_Timer_After = C_Timer.After
local CreateAnimationGroup = CreateAnimationGroup
Simpy's avatar
Simpy committed
79
local hooksecurefunc = hooksecurefunc
80 81

local BAG_FILTER_ASSIGN_TO = BAG_FILTER_ASSIGN_TO
82 83
local BAG_FILTER_CLEANUP = BAG_FILTER_CLEANUP
local BAG_FILTER_IGNORE = BAG_FILTER_IGNORE
84
local BAG_FILTER_LABELS = BAG_FILTER_LABELS
85
local CONTAINER_OFFSET_X, CONTAINER_OFFSET_Y = CONTAINER_OFFSET_X, CONTAINER_OFFSET_Y
86
local CONTAINER_SCALE = CONTAINER_SCALE
87
local CONTAINER_SPACING, VISIBLE_CONTAINER_SPACING = CONTAINER_SPACING, VISIBLE_CONTAINER_SPACING
88
local CONTAINER_WIDTH = CONTAINER_WIDTH
89 90 91
local IG_BACKPACK_CLOSE = SOUNDKIT.IG_BACKPACK_CLOSE
local IG_BACKPACK_OPEN = SOUNDKIT.IG_BACKPACK_OPEN
local LE_BAG_FILTER_FLAG_EQUIPMENT = LE_BAG_FILTER_FLAG_EQUIPMENT
92
local LE_BAG_FILTER_FLAG_IGNORE_CLEANUP = LE_BAG_FILTER_FLAG_IGNORE_CLEANUP
93
local LE_BAG_FILTER_FLAG_JUNK = LE_BAG_FILTER_FLAG_JUNK
Azilroka's avatar
Azilroka committed
94
local LE_ITEM_QUALITY_COMMON = LE_ITEM_QUALITY_COMMON
Simpy's avatar
Simpy committed
95
local LE_ITEM_QUALITY_POOR = LE_ITEM_QUALITY_POOR
96 97 98
local MAX_CONTAINER_ITEMS = MAX_CONTAINER_ITEMS
local MAX_WATCHED_TOKENS = MAX_WATCHED_TOKENS
local NUM_BAG_FRAMES = NUM_BAG_FRAMES
99
local NUM_BAG_SLOTS = NUM_BAG_SLOTS
100
local NUM_BANKGENERIC_SLOTS = NUM_BANKGENERIC_SLOTS
101
local NUM_CONTAINER_FRAMES = NUM_CONTAINER_FRAMES
102
local NUM_LE_BAG_FILTER_FLAGS = NUM_LE_BAG_FILTER_FLAGS
103
local REAGENTBANK_CONTAINER = REAGENTBANK_CONTAINER
Simpy's avatar
Simpy committed
104 105
local REAGENTBANK_PURCHASE_TEXT = REAGENTBANK_PURCHASE_TEXT
local SEARCH = SEARCH
106
-- GLOBALS: ElvUIBags, ElvUIBagMover, ElvUIBankMover, ElvUIReagentBankFrame, ElvUIReagentBankFrameItem1
107

Simpy's avatar
Simpy committed
108
local MATCH_ITEM_LEVEL = ITEM_LEVEL:gsub('%%d', '(%%d+)')
109

110
local ElvUIAssignBagDropdown
111
local SEARCH_STRING = ""
112
local BAG_FILTER_ICONS = {
Simpy's avatar
Simpy committed
113 114 115
	[_G.LE_BAG_FILTER_FLAG_EQUIPMENT] = "Interface\\ICONS\\INV_Chest_Plate10",
	[_G.LE_BAG_FILTER_FLAG_CONSUMABLES] = "Interface\\ICONS\\INV_Potion_93",
	[_G.LE_BAG_FILTER_FLAG_TRADE_GOODS] = "Interface\\ICONS\\INV_Fabric_Silk_02",
116 117
}

118
function B:GetContainerFrame(arg)
Simpy's avatar
Simpy committed
119
	if type(arg) == 'boolean' and (arg == true) then
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
		return self.BankFrame;
	elseif type(arg) == 'number' then
		if self.BankFrame then
			for _, bagID in ipairs(self.BankFrame.BagIDs) do
				if bagID == arg then
					return self.BankFrame;
				end
			end
		end
	end

	return self.BagFrame;
end

function B:Tooltip_Show()
Simpy's avatar
Simpy committed
135
	local GameTooltip = _G.GameTooltip
136 137 138 139 140
	GameTooltip:SetOwner(self);
	GameTooltip:ClearLines()
	GameTooltip:AddLine(self.ttText)

	if self.ttText2 then
141 142 143 144 145 146
		if self.ttText2desc then
			GameTooltip:AddLine(' ')
			GameTooltip:AddDoubleLine(self.ttText2, self.ttText2desc, 1, 1, 1)
		else
			GameTooltip:AddLine(self.ttText2)
		end
147 148 149 150 151 152
	end

	GameTooltip:Show()
end

function B:DisableBlizzard()
Simpy's avatar
Simpy committed
153
	_G.BankFrame:UnregisterAllEvents();
154 155 156 157 158 159 160 161 162 163 164

	for i=1, NUM_CONTAINER_FRAMES do
		_G['ContainerFrame'..i]:Kill();
	end
end

function B:SearchReset()
	SEARCH_STRING = ""
end

function B:IsSearching()
165
	return (SEARCH_STRING ~= "" and SEARCH_STRING ~= SEARCH)
166 167 168 169
end

function B:UpdateSearch()
	if self.Instructions then self.Instructions:SetShown(self:GetText() == "") end
Simpy's avatar
Simpy committed
170

171 172 173
	local MIN_REPEAT_CHARACTERS = 3;
	local searchString = self:GetText();
	local prevSearchString = SEARCH_STRING;
Rubgrsch's avatar
Rubgrsch committed
174
	if #searchString > MIN_REPEAT_CHARACTERS then
Simpy's avatar
Simpy committed
175
		local repeatChar = true
176
		for i=1, MIN_REPEAT_CHARACTERS, 1 do
Simpy's avatar
Simpy committed
177 178 179
			if sub(searchString,(0-i), (0-i)) ~= sub(searchString,(-1-i),(-1-i)) then
				repeatChar = false
				break
180 181
			end
		end
Simpy's avatar
Simpy committed
182 183

		if repeatChar then
184
			B:ResetAndClear()
Simpy's avatar
Simpy committed
185
			return
186 187 188 189 190 191 192 193 194 195 196 197
		end
	end

	--Keep active search term when switching between bank and reagent bank
	if searchString == SEARCH and prevSearchString ~= "" then
		searchString = prevSearchString
	elseif searchString == SEARCH then
		searchString = ''
	end

	SEARCH_STRING = searchString

198
	B:RefreshSearch()
199 200 201 202
	B:SetGuildBankSearch(SEARCH_STRING);
end

function B:OpenEditbox()
203 204 205 206
	self.BagFrame.detail:Hide()
	self.BagFrame.editBox:Show()
	self.BagFrame.editBox:SetText(SEARCH)
	self.BagFrame.editBox:HighlightText()
207 208 209
end

function B:ResetAndClear()
Azilroka's avatar
Azilroka committed
210 211
	B.BagFrame.editBox:SetText(SEARCH)
	B.BagFrame.editBox:ClearFocus()
212

Azilroka's avatar
Azilroka committed
213 214 215 216 217
	if B.BankFrame then
		B.BankFrame.editBox:SetText(SEARCH)
		B.BankFrame.editBox:ClearFocus()
	end

218 219 220 221
	B:SearchReset();
end

function B:SetSearch(query)
Rubgrsch's avatar
Rubgrsch committed
222
	local empty = #(query:gsub(' ', '')) == 0
223 224 225
	local method = Search.Matches
	if Search.Filters.tipPhrases.keywords[query] then
		method = Search.TooltipPhrase
226
		query = Search.Filters.tipPhrases.keywords[query]
227 228
	end

229 230 231 232 233
	for _, bagFrame in pairs(self.BagFrames) do
		for _, bagID in ipairs(bagFrame.BagIDs) do
			for slotID = 1, GetContainerNumSlots(bagID) do
				local _, _, _, _, _, _, link = GetContainerItemInfo(bagID, slotID);
				local button = bagFrame.Bags[bagID][slotID];
Rubgrsch's avatar
Rubgrsch committed
234
				local success, result = pcall(method, Search, link, query)
235
				if empty or (success and result) then
236
					SetItemButtonDesaturated(button, button.locked or button.junkDesaturate);
237
					button.searchOverlay:Hide();
238 239 240
					button:SetAlpha(1);
				else
					SetItemButtonDesaturated(button, 1);
241 242
					button.searchOverlay:Show();
					button:SetAlpha(0.5);
243 244 245 246 247
				end
			end
		end
	end

248
	if ElvUIReagentBankFrameItem1 then
Simpy's avatar
Simpy committed
249
		for slotID = 1, B.REAGENTBANK_SIZE do
250 251
			local _, _, _, _, _, _, link = GetContainerItemInfo(REAGENTBANK_CONTAINER, slotID);
			local button = _G["ElvUIReagentBankFrameItem"..slotID]
252
			local success, result = pcall(method, Search, link, query)
Simpy's avatar
Simpy committed
253
			if empty or (success and result) then
254
				SetItemButtonDesaturated(button, button.locked or button.junkDesaturate);
255
				button.searchOverlay:Hide();
256 257 258
				button:SetAlpha(1);
			else
				SetItemButtonDesaturated(button, 1);
259 260
				button.searchOverlay:Show();
				button:SetAlpha(0.5);
261 262 263 264 265 266
			end
		end
	end
end

function B:SetGuildBankSearch(query)
Rubgrsch's avatar
Rubgrsch committed
267
	local empty = #(query:gsub(' ', '')) == 0
268 269 270
	local method = Search.Matches
	if Search.Filters.tipPhrases.keywords[query] then
		method = Search.TooltipPhrase
271
		query = Search.Filters.tipPhrases.keywords[query]
272 273
	end

Simpy's avatar
Simpy committed
274
	if _G.GuildBankFrame and _G.GuildBankFrame:IsShown() then
275 276 277 278
		local tab = GetCurrentGuildBankTab()
		local _, _, isViewable = GetGuildBankTabInfo(tab)

		if isViewable then
Simpy's avatar
Simpy committed
279
			for slotID = 1, _G.MAX_GUILDBANK_SLOTS_PER_TAB do
280 281 282 283 284 285 286
				local link = GetGuildBankItemLink(tab, slotID)
				--A column goes from 1-14, e.g. GuildBankColumn1Button14 (slotID 14) or GuildBankColumn2Button3 (slotID 17)
				local col = ceil(slotID / 14)
				local btn = (slotID % 14)
				if col == 0 then col = 1 end
				if btn == 0 then btn = 14 end
				local button = _G["GuildBankColumn"..col.."Button"..btn]
Rubgrsch's avatar
Rubgrsch committed
287
				local success, result = pcall(method, Search, link, query)
Simpy's avatar
Simpy committed
288
				if empty or (success and result) then
289
					SetItemButtonDesaturated(button, button.locked or button.junkDesaturate);
290
					button.searchOverlay:Hide();
291 292 293
					button:SetAlpha(1);
				else
					SetItemButtonDesaturated(button, 1);
294 295
					button.searchOverlay:Show();
					button:SetAlpha(0.5);
296 297 298 299 300 301 302
				end
			end
		end
	end
end

function B:UpdateItemLevelDisplay()
Simpy's avatar
Simpy committed
303
	if E.private.bags.enable ~= true then return end
304 305 306 307 308
	for _, bagFrame in pairs(self.BagFrames) do
		for _, bagID in ipairs(bagFrame.BagIDs) do
			for slotID = 1, GetContainerNumSlots(bagID) do
				local slot = bagFrame.Bags[bagID][slotID]
				if slot and slot.itemLevel then
Azilroka's avatar
Azilroka committed
309
					slot.itemLevel:FontTemplate(E.Libs.LSM:Fetch("font", E.db.bags.itemLevelFont), E.db.bags.itemLevelFontSize, E.db.bags.itemLevelFontOutline)
310 311 312
				end
			end
		end
Simpy's avatar
Simpy committed
313

314 315 316 317 318 319 320
		if bagFrame.UpdateAllSlots then
			bagFrame:UpdateAllSlots()
		end
	end
end

function B:UpdateCountDisplay()
Simpy's avatar
Simpy committed
321
	if E.private.bags.enable ~= true then return end
322 323 324 325 326 327 328
	local color = E.db.bags.countFontColor

	for _, bagFrame in pairs(self.BagFrames) do
		for _, bagID in ipairs(bagFrame.BagIDs) do
			for slotID = 1, GetContainerNumSlots(bagID) do
				local slot = bagFrame.Bags[bagID][slotID]
				if slot and slot.Count then
Azilroka's avatar
Azilroka committed
329
					slot.Count:FontTemplate(E.Libs.LSM:Fetch("font", E.db.bags.countFont), E.db.bags.countFontSize, E.db.bags.countFontOutline)
330 331 332 333
					slot.Count:SetTextColor(color.r, color.g, color.b)
				end
			end
		end
Simpy's avatar
Simpy committed
334

335 336 337 338
		if bagFrame.UpdateAllSlots then
			bagFrame:UpdateAllSlots()
		end
	end
339 340

	--Reagent Bank
341
	if self.BankFrame and self.BankFrame.reagentFrame then
Simpy's avatar
Simpy committed
342
		for i = 1, B.REAGENTBANK_SIZE do
343
			local slot = self.BankFrame.reagentFrame.slots[i]
344
			if slot then
Azilroka's avatar
Azilroka committed
345
				slot.Count:FontTemplate(E.Libs.LSM:Fetch("font", E.db.bags.countFont), E.db.bags.countFontSize, E.db.bags.countFontOutline)
346 347 348
				slot.Count:SetTextColor(color.r, color.g, color.b)
				self:UpdateReagentSlot(i)
			end
349
		end
350
	end
351 352 353 354 355 356 357 358 359 360 361 362
end

function B:UpdateBagTypes(isBank)
	local f = self:GetContainerFrame(isBank);
	for _, bagID in ipairs(f.BagIDs) do
		if f.Bags[bagID] then
			f.Bags[bagID].type = select(2, GetContainerNumFreeSlots(bagID));
		end
	end
end

function B:UpdateAllBagSlots()
Simpy's avatar
Simpy committed
363
	if E.private.bags.enable ~= true then return end
364 365 366 367 368 369 370 371

	for _, bagFrame in pairs(self.BagFrames) do
		if bagFrame.UpdateAllSlots then
			bagFrame:UpdateAllSlots()
		end
	end
end

372 373 374 375
local function IsItemEligibleForItemLevelDisplay(classID, subClassID, equipLoc, rarity)
	if ((classID == 3 and subClassID == 11) --Artifact Relics
		or (equipLoc ~= nil and equipLoc ~= "" and equipLoc ~= "INVTYPE_BAG" and equipLoc ~= "INVTYPE_QUIVER" and equipLoc ~= "INVTYPE_TABARD"))
		and (rarity and rarity > 1) then
Rubgrsch's avatar
Rubgrsch committed
376

377 378 379 380 381 382
		return true
	end

	return false
end

383
local UpdateItemUpgradeIcon;
384
local ITEM_UPGRADE_CHECK_TIME = 0.5;
385
local function UpgradeCheck_OnUpdate(self, elapsed)
386
	self.timeSinceUpgradeCheck = self.timeSinceUpgradeCheck + elapsed;
Rubgrsch's avatar
Rubgrsch committed
387

Simpy's avatar
Simpy committed
388
	if self.timeSinceUpgradeCheck >= ITEM_UPGRADE_CHECK_TIME then
389 390 391 392 393 394 395
		UpdateItemUpgradeIcon(self);
	end
end

function UpdateItemUpgradeIcon(slot)
	if not E.db.bags.upgradeIcon then
		slot.UpgradeIcon:SetShown(false);
396
		slot:SetScript("OnUpdate", nil);
397 398 399 400
		return
	end

	slot.timeSinceUpgradeCheck = 0;
Rubgrsch's avatar
Rubgrsch committed
401

402
	local itemIsUpgrade = _G.IsContainerItemAnUpgrade(slot:GetParent():GetID(), slot:GetID());
403
	if itemIsUpgrade == nil then -- nil means not all the data was available to determine if this is an upgrade.
404 405 406 407 408 409 410 411
		slot.UpgradeIcon:SetShown(false);
		slot:SetScript("OnUpdate", UpgradeCheck_OnUpdate);
	else
		slot.UpgradeIcon:SetShown(itemIsUpgrade);
		slot:SetScript("OnUpdate", nil);
	end
end

Rubgrsch's avatar
Rubgrsch committed
412
local function UpdateItemScrapIcon(slot)
413 414
	if not E.db.bags.scrapIcon then
		slot.ScrapIcon:SetShown(false)
415
		return
416 417
	end

Simpy's avatar
Simpy committed
418
	local itemLocation = _G.ItemLocation:CreateFromBagAndSlot(slot:GetParent():GetID(), slot:GetID())
419 420 421
	if not itemLocation then return end

	if itemLocation and itemLocation ~= "" then
422
		if (C_Item_DoesItemExist(itemLocation) and C_Item_CanScrapItem(itemLocation)) and E.db.bags.scrapIcon then
423 424 425 426 427 428 429
			slot.ScrapIcon:SetShown(itemLocation)
		else
			slot.ScrapIcon:SetShown(false)
		end
	end
end

430
function B:SCRAPPING_MACHINE_SHOW()
Simpy's avatar
:L  
Simpy committed
431
	E:Delay(0.1, B.Layout, B)
432 433 434
end

function B:SCRAPPING_MACHINE_CLOSE()
Simpy's avatar
:L  
Simpy committed
435
	E:Delay(0.1, B.Layout, B)
436 437
end

Simpy's avatar
Simpy committed
438
function B:NewItemGlowSlotSwitch(slot, show)
439
	if slot and slot.newItemGlow then
440
		if show then
441
			slot.newItemGlow:Show()
442 443 444

			local bank = slot:GetParent().isBank and B.BankFrame
			B:ShowItemGlow(bank or B.BagFrame, slot.newItemGlow)
445
		else
446
			slot.newItemGlow:Hide()
447 448 449 450 451

			-- also clear them on blizzard's side
			if slot.bagID and slot.slotID then
				C_NewItems_RemoveNewItem(slot.bagID, slot.slotID)
			end
452
		end
453 454 455
	end
end

456 457 458 459 460 461 462 463 464 465 466 467
function B:NewItemGlowBagClear(bagFrame)
	if not (bagFrame and bagFrame.BagIDs) then return end

	for _, bagID in ipairs(bagFrame.BagIDs) do
		for slotID = 1, GetContainerNumSlots(bagID) do
			if bagFrame.Bags[bagID][slotID] then
				B:NewItemGlowSlotSwitch(bagFrame.Bags[bagID][slotID])
			end
		end
	end
end

468 469 470 471 472 473
function B:HideSlotItemGlow()
	B:NewItemGlowSlotSwitch(self)
end

function B:CheckSlotNewItem(slot, bagID, slotID)
	B:NewItemGlowSlotSwitch(slot, C_NewItems_IsNewItem(bagID, slotID))
474 475
end

476 477 478 479 480
function B:UpdateSlot(bagID, slotID)
	if (self.Bags[bagID] and self.Bags[bagID].numSlots ~= GetContainerNumSlots(bagID)) or not self.Bags[bagID] or not self.Bags[bagID][slotID] then
		return;
	end

481
	local slot = self.Bags[bagID][slotID];
482 483
	local bagType = self.Bags[bagID].type;

484
	local assignedID = bagID
485 486
	local assignedBag = self.Bags[assignedID] and self.Bags[assignedID].assigned

Rubgrsch's avatar
Rubgrsch committed
487
	local texture, count, locked, rarity, readable, _, _, _, noValue = GetContainerItemInfo(bagID, slotID)
488
	slot.name, slot.rarity, slot.locked = nil, rarity, locked
489

490
	local clink = GetContainerItemLink(bagID, slotID)
491 492

	slot:Show();
Simpy's avatar
Simpy committed
493
	if slot.questIcon then
494 495
		slot.questIcon:Hide();
	end
Azilroka's avatar
Azilroka committed
496

Simpy's avatar
Simpy committed
497
	if slot.Azerite then
498
		slot.Azerite:Hide()
Darth Predator's avatar
Darth Predator committed
499
	end
500

501 502 503
	slot.isJunk = (slot.rarity and slot.rarity == LE_ITEM_QUALITY_POOR) and not noValue
	slot.junkDesaturate = slot.isJunk and E.db.bags.junkDesaturate

Simpy's avatar
Simpy committed
504
	if slot.JunkIcon then
505
		if slot.isJunk and E.db.bags.junkIcon then
506
			slot.JunkIcon:Show()
507 508 509 510 511
		else
			slot.JunkIcon:Hide()
		end
	end

512
	if slot.ScrapIcon then
513
		UpdateItemScrapIcon(slot)
514
	end
Azilroka's avatar
Azilroka committed
515

Merathilis's avatar
Merathilis committed
516
	slot:UpdateItemContextMatching() -- Blizzards way to highlight scrapable items if the Scrapping Machine Frame is open.
517

518 519 520 521 522
	if slot.UpgradeIcon then
		--Check if item is an upgrade and show/hide upgrade icon accordingly
		UpdateItemUpgradeIcon(slot)
	end

523 524
	slot.itemLevel:SetText('')
	slot.bindType:SetText('')
Azilroka's avatar
Azilroka committed
525

Simpy's avatar
Simpy committed
526 527 528 529
	local professionColors = B.ProfessionColors[bagType]
	local showItemLevel = B.db.itemLevel and clink and not professionColors
	local showBindType = B.db.showBindType and (slot.rarity and slot.rarity > LE_ITEM_QUALITY_COMMON)
	if showBindType or showItemLevel then
Simpy's avatar
Simpy committed
530
		E.ScanTooltip:SetOwner(_G.UIParent, "ANCHOR_NONE")
531 532 533 534 535
		if slot.GetInventorySlot then -- this fixes bank bagid -1
			E.ScanTooltip:SetInventoryItem("player", slot:GetInventorySlot())
		else
			E.ScanTooltip:SetBagItem(bagID, slotID)
		end
Simpy's avatar
Simpy committed
536
		E.ScanTooltip:Show()
Simpy's avatar
Simpy committed
537
	end
Azilroka's avatar
Azilroka committed
538

Simpy's avatar
Simpy committed
539 540
	if professionColors then
		local r, g, b = unpack(professionColors)
541
		slot.newItemGlow:SetVertexColor(r, g, b)
Simpy's avatar
Simpy committed
542
		slot:SetBackdropBorderColor(r, g, b)
Simpy's avatar
Simpy committed
543
		slot.ignoreBorderColors = true
Simpy's avatar
Simpy committed
544
	elseif clink then
545
		local name, _, itemRarity, _, _, _, _, _, itemEquipLoc, _, _, itemClassID, itemSubClassID = GetItemInfo(clink);
Rubgrsch's avatar
Rubgrsch committed
546
		slot.name = name
Simpy's avatar
Simpy committed
547

548 549 550
		local isQuestItem, questId, isActiveQuest = GetContainerItemQuestInfo(bagID, slotID);
		local r, g, b

551 552
		if slot.rarity or itemRarity then
			r, g, b = GetItemQualityColor(slot.rarity or itemRarity);
553 554
		end

Simpy's avatar
Simpy committed
555 556 557
		if showBindType or showItemLevel then
			local colorblind = GetCVarBool('colorblindmode')
			local canShowItemLevel = showItemLevel and IsItemEligibleForItemLevelDisplay(itemClassID, itemSubClassID, itemEquipLoc, slot.rarity)
558
			local itemLevelLines, bindTypeLines = colorblind and 4 or 3, colorblind and 8 or 7
Simpy's avatar
Simpy committed
559 560 561
			local iLvl, BoE, BoU --GetDetailedItemLevelInfo this api dont work for some time correctly for ilvl

			for i = 2, bindTypeLines do
Simpy's avatar
Simpy committed
562
				local line = _G["ElvUI_ScanTooltipTextLeft"..i]:GetText()
Simpy's avatar
Simpy committed
563 564
				if not line or line == "" then break end
				if canShowItemLevel and (i <= itemLevelLines) then
Simpy's avatar
Simpy committed
565
					local itemLevel = line:match(MATCH_ITEM_LEVEL)
Simpy's avatar
Simpy committed
566 567
					if itemLevel then iLvl = tonumber(itemLevel) end
				end
568 569 570 571 572
				if showBindType then
					-- as long as we check the ilvl first, we can savely break on these because they fall after ilvl
					if line == _G.ITEM_SOULBOUND or line == _G.ITEM_ACCOUNTBOUND or line == _G.ITEM_BNETACCOUNTBOUND then break end
					BoE, BoU = line == _G.ITEM_BIND_ON_EQUIP, line == _G.ITEM_BIND_ON_USE
				end
Simpy's avatar
Simpy committed
573 574
				if ((not showBindType) or (BoE or BoU)) and ((not canShowItemLevel) or iLvl) then
					break
Simpy's avatar
Simpy committed
575 576
				end
			end
Simpy's avatar
Simpy committed
577 578

			if BoE or BoU then
Rubgrsch's avatar
Rubgrsch committed
579
				slot.bindType:SetText(BoE and L["BoE"] or L["BoU"])
Azilroka's avatar
Azilroka committed
580
				slot.bindType:SetVertexColor(r, g, b)
Simpy's avatar
Simpy committed
581 582 583 584 585 586 587 588
			end

			if iLvl and iLvl >= B.db.itemLevelThreshold then
				slot.itemLevel:SetText(iLvl)
				if B.db.itemLevelCustomColorEnable then
					slot.itemLevel:SetTextColor(B.db.itemLevelCustomColor.r, B.db.itemLevelCustomColor.g, B.db.itemLevelCustomColor.b)
				else
					slot.itemLevel:SetTextColor(r, g, b)
589
				end
590 591 592 593 594
			end
		end

		-- color slot according to item quality
		if questId and not isActiveQuest then
Simpy's avatar
Simpy committed
595 596
			slot.newItemGlow:SetVertexColor(unpack(B.QuestColors.questStarter))
			slot:SetBackdropBorderColor(unpack(B.QuestColors.questStarter))
597
			slot.ignoreBorderColors = true
598 599 600 601
			if(slot.questIcon) then
				slot.questIcon:Show();
			end
		elseif questId or isQuestItem then
Simpy's avatar
Simpy committed
602 603
			slot.newItemGlow:SetVertexColor(unpack(B.QuestColors.questItem))
			slot:SetBackdropBorderColor(unpack(B.QuestColors.questItem))
604
			slot.ignoreBorderColors = true
Azilroka's avatar
Azilroka committed
605
		elseif B.db.qualityColors and slot.rarity and slot.rarity > LE_ITEM_QUALITY_COMMON then
606
			slot.newItemGlow:SetVertexColor(r, g, b);
607
			slot:SetBackdropBorderColor(r, g, b);
608
			slot.ignoreBorderColors = true
609
		elseif B.db.showAssignedColor and B.AssignmentColors[assignedBag] then
Simpy's avatar
Simpy committed
610
			local rr, gg, bb = unpack(B.AssignmentColors[assignedBag])
611
			slot.newItemGlow:SetVertexColor(rr, gg, bb)
Simpy's avatar
Simpy committed
612
			slot:SetBackdropBorderColor(rr, gg, bb)
613
			slot.ignoreBorderColors = true
614
		else
615 616 617
			local rr, gg, bb = unpack(E.media.bordercolor)
			slot.newItemGlow:SetVertexColor(rr, gg, bb)
			slot:SetBackdropBorderColor(rr, gg, bb)
618
			slot.ignoreBorderColors = nil
619
		end
Azilroka's avatar
Azilroka committed
620 621

		if slot.Azerite and C_AzeriteEmpoweredItem_IsAzeriteEmpoweredItemByID(clink) then slot.Azerite:Show() end
622
	elseif B.db.showAssignedColor and B.AssignmentColors[assignedBag] then
Simpy's avatar
Simpy committed
623
		local rr, gg, bb = unpack(B.AssignmentColors[assignedBag])
624
		slot.newItemGlow:SetVertexColor(rr, gg, bb)
Simpy's avatar
Simpy committed
625
		slot:SetBackdropBorderColor(rr, gg, bb)
626
		slot.ignoreBorderColors = true
627
	else
628 629 630
		local rr, gg, bb = unpack(E.media.bordercolor)
		slot.newItemGlow:SetVertexColor(rr, gg, bb)
		slot:SetBackdropBorderColor(rr, gg, bb)
631
		slot.ignoreBorderColors = nil
632 633
	end

Simpy's avatar
Simpy committed
634
	E.ScanTooltip:Hide()
635 636 637 638

	if E.db.bags.newItemGlow then
		E:Delay(0.1, B.CheckSlotNewItem, B, slot, bagID, slotID)
	end
639

Simpy's avatar
Simpy committed
640
	if texture then
641 642
		local start, duration, enable = GetContainerItemCooldown(bagID, slotID)
		CooldownFrame_Set(slot.cooldown, start, duration, enable)
Simpy's avatar
Simpy committed
643
		if duration > 0 and enable == 0 then
644 645 646 647 648 649 650 651 652 653 654 655 656 657
			SetItemButtonTextureVertexColor(slot, 0.4, 0.4, 0.4);
		else
			SetItemButtonTextureVertexColor(slot, 1, 1, 1);
		end
		slot.hasItem = 1;
	else
		slot.cooldown:Hide()
		slot.hasItem = nil;
	end

	slot.readable = readable;

	SetItemButtonTexture(slot, texture);
	SetItemButtonCount(slot, count);
658
	SetItemButtonDesaturated(slot, slot.locked or slot.junkDesaturate);
659

Simpy's avatar
Simpy committed
660
	if _G.GameTooltip:GetOwner() == slot and not slot.hasItem then
661
		GameTooltip_Hide()
662 663 664 665
	end
end

function B:UpdateBagSlots(bagID)
666
	if bagID == REAGENTBANK_CONTAINER then
Simpy's avatar
Simpy committed
667
		for i=1, B.REAGENTBANK_SIZE do
668 669 670 671 672 673 674 675 676 677 678 679 680
			self:UpdateReagentSlot(i);
		end
	else
		for slotID = 1, GetContainerNumSlots(bagID) do
			if self.UpdateSlot then
				self:UpdateSlot(bagID, slotID);
			else
				self:GetParent():GetParent():UpdateSlot(bagID, slotID);
			end
		end
	end
end

681 682
function B:RefreshSearch()
	B:SetSearch(SEARCH_STRING)
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
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.searchOverlay:Show();
			button:SetAlpha(0.5);
		end
	end
end

698 699 700 701
function B:UpdateCooldowns()
	for _, bagID in ipairs(self.BagIDs) do
		for slotID = 1, GetContainerNumSlots(bagID) do
			local start, duration, enable = GetContainerItemCooldown(bagID, slotID)
702
			CooldownFrame_Set(self.Bags[bagID][slotID].cooldown, start, duration, enable, _, _)
703 704 705 706 707 708 709 710 711 712
		end
	end
end

function B:UpdateAllSlots()
	for _, bagID in ipairs(self.BagIDs) do
		if self.Bags[bagID] then
			self.Bags[bagID]:UpdateBagSlots(bagID);
		end
	end
Rubgrsch's avatar
Rubgrsch committed
713

714 715
	-- Refresh search in case we moved items around
	if (not self.registerUpdate) and B:IsSearching() then
716
		B:RefreshSearch()
Rubgrsch's avatar
Rubgrsch committed
717
	end
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750
end

function B:SetSlotAlphaForBag(f)
	for _, bagID in ipairs(f.BagIDs) do
		if f.Bags[bagID] then
			local numSlots = GetContainerNumSlots(bagID);
			for slotID = 1, numSlots do
				if f.Bags[bagID][slotID] then
					if bagID == self.id then
						f.Bags[bagID][slotID]:SetAlpha(1)
					else
						f.Bags[bagID][slotID]:SetAlpha(0.1)
					end
				end
			end
		end
	end
end

function B:ResetSlotAlphaForBags(f)
	for _, bagID in ipairs(f.BagIDs) do
		if f.Bags[bagID] then
			local numSlots = GetContainerNumSlots(bagID);
			for slotID = 1, numSlots do
				if f.Bags[bagID][slotID] then
					f.Bags[bagID][slotID]:SetAlpha(1)
				end
			end
		end
	end
end

function B:REAGENTBANK_PURCHASED()
751
	ElvUIReagentBankFrame.cover:Hide()
752 753
end

754 755 756 757
--Look at ContainerFrameFilterDropDown_Initialize in FrameXML/ContainerFrame.lua
function B:AssignBagFlagMenu()
	local holder = ElvUIAssignBagDropdown.holder
	ElvUIAssignBagDropdown.holder = nil
758

759
	if not (holder and holder.id) then return end
760

Simpy's avatar
Simpy committed
761
	local info = _G.UIDropDownMenu_CreateInfo()
762 763 764 765
	if holder.id > 0 and not IsInventoryItemProfessionBag("player", ContainerIDToInventoryID(holder.id)) then -- The actual bank has ID -1, backpack has ID 0, we want to make sure we're looking at a regular or bank bag
		info.text = BAG_FILTER_ASSIGN_TO
		info.isTitle = 1
		info.notCheckable = 1
Simpy's avatar
Simpy committed
766
		_G.UIDropDownMenu_AddButton(info)
767

768 769 770 771
		info.isTitle = nil
		info.notCheckable = nil
		info.tooltipWhileDisabled = 1
		info.tooltipOnButton = 1
772

773
		for i = LE_BAG_FILTER_FLAG_EQUIPMENT, NUM_LE_BAG_FILTER_FLAGS do
774 775
			if i ~= LE_BAG_FILTER_FLAG_JUNK then
				info.text = BAG_FILTER_LABELS[i]
776
				info.func = function(_, _, _, value)
777 778 779 780
					value = not value

					if holder.id > NUM_BAG_SLOTS then
						SetBankBagSlotFlag(holder.id - NUM_BAG_SLOTS, i, value)
781
					else
782
						SetBagSlotFlag(holder.id, i, value)
783
					end
784

785
					if (value) then
786 787 788 789
						holder.tempflag = i;
						holder.ElvUIFilterIcon.Icon:SetTexture(BAG_FILTER_ICONS[i]);
						holder.ElvUIFilterIcon.Icon:SetTexCoord(unpack(E.TexCoords));
						holder.ElvUIFilterIcon:Show();
790
					else
791 792
						holder.ElvUIFilterIcon:Hide();
						holder.tempflag = -1;
793
					end
794 795 796 797
				end

				if holder.tempflag then
					info.checked = holder.tempflag == i
798
				else
799 800
					if holder.id > NUM_BAG_SLOTS then
						info.checked = GetBankBagSlotFlag(holder.id - NUM_BAG_SLOTS, i)
801
					else
802
						info.checked = GetBagSlotFlag(holder.id, i)
803
					end
804
				end
805 806 807

				info.disabled = nil
				info.tooltipTitle = nil
Simpy's avatar
Simpy committed
808
				_G.UIDropDownMenu_AddButton(info)
809
			end
810 811 812 813 814 815
		end
	end

	info.text = BAG_FILTER_CLEANUP;
	info.isTitle = 1;
	info.notCheckable = 1;
Simpy's avatar
Simpy committed
816
	_G.UIDropDownMenu_AddButton(info);
817 818 819 820 821 822 823 824

	info.isTitle = nil;
	info.notCheckable = nil;
	info.isNotRadio = true;
	info.disabled = nil;

	info.text = BAG_FILTER_IGNORE;
	info.func = function(_, _, _, value)
825
		if (holder.id == -1) then
826
			SetBankAutosortDisabled(not value);
827
		elseif (holder.id == 0) then
828
			SetBackpackAutosortDisabled(not value);
829 830
		elseif (holder.id > NUM_BAG_SLOTS) then
			SetBankBagSlotFlag(holder.id - NUM_BAG_SLOTS, LE_BAG_FILTER_FLAG_IGNORE_CLEANUP, not value);
831
		else
832
			SetBagSlotFlag(holder.id, LE_BAG_FILTER_FLAG_IGNORE_CLEANUP, not value);
833 834
		end
	end;
835
	if (holder.id == -1) then
836
		info.checked = GetBankAutosortDisabled();
837
	elseif (holder.id == 0) then
838
		info.checked = GetBackpackAutosortDisabled();
839 840
	elseif (holder.id > NUM_BAG_SLOTS) then
		info.checked = GetBankBagSlotFlag(holder.id - NUM_BAG_SLOTS, LE_BAG_FILTER_FLAG_IGNORE_CLEANUP);
841
	else
842
		info.checked = GetBagSlotFlag(holder.id, LE_BAG_FILTER_FLAG_IGNORE_CLEANUP);
843
	end
Simpy's avatar
Simpy committed
844 845

	_G.UIDropDownMenu_AddButton(info);
846
end
847

848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
function B:GetBagAssignedInfo(holder)
	if not (holder and holder.id and holder.id > 0) then return end

	local inventoryID = ContainerIDToInventoryID(holder.id)
	if IsInventoryItemProfessionBag("player", inventoryID) then return end

	if holder.tempflag then
		holder.tempflag = nil --clear tempflag from AssignBagFlagMenu
	end

	local active, color
	for i = LE_BAG_FILTER_FLAG_EQUIPMENT, NUM_LE_BAG_FILTER_FLAGS do
		if i ~= LE_BAG_FILTER_FLAG_JUNK then --ignore this one
			if holder.id > NUM_BAG_SLOTS then
				active = GetBankBagSlotFlag(holder.id - NUM_BAG_SLOTS, i)
			else
				active = GetBagSlotFlag(holder.id, i)
			end

			if active then
				color = B.AssignmentColors[i]
				active = (color and i) or 0
				break
			end
		end
	end

	if not active then
		holder:SetBackdropBorderColor(unpack(E.media.bordercolor))
		holder.ignoreBorderColors = nil --restore these borders to be updated
	else
		holder:SetBackdropBorderColor(unpack(color or B.AssignmentColors[0]))
		holder.ignoreBorderColors = true --dont allow these border colors to update for now
		return active
	end
end

885
local function Container_OnShow(self)
886
	if self.id > 0 and not IsInventoryItemProfessionBag("player", ContainerIDToInventoryID(self.id)) then
887
		for i = LE_BAG_FILTER_FLAG_EQUIPMENT, NUM_LE_BAG_FILTER_FLAGS do
Rubgrsch's avatar
Cleanup  
Rubgrsch committed
888
			local active
Blazeflack's avatar