--[[ itemFrame.lua An guild bank item slot container --]] local Bagnon = LibStub('AceAddon-3.0'):GetAddon('Bagnon') local ItemFrame = Bagnon.Classy:New('Frame') ItemFrame:Hide() Bagnon.GuildItemFrame = ItemFrame --[[ Extreme Constants! ]]-- ItemFrame.ITEM_SIZE = 39 --[[ Constructor ]]-- local function throttledUpdater_OnUpdate(self, elapsed) local p = self:GetParent() if p:NeedsLayout() then p:Layout() end self:Hide() end function ItemFrame:New(frameID, parent) local f = self:Bind(CreateFrame('Frame', nil, parent)) f.itemSlots = {} f.throttledUpdater = CreateFrame('Frame', nil, f) f.throttledUpdater:SetScript('OnUpdate', throttledUpdater_OnUpdate) f:SetFrameID(frameID) f:SetScript('OnSizeChanged', f.OnSizeChanged) f:SetScript('OnEvent', f.OnEvent) f:SetScript('OnShow', f.OnShow) f:SetScript('OnHide', f.OnHide) return f end --[[ Messages ]]-- function ItemFrame:OnEvent(event, ...) local action = self[event] if action then action(self, event, ...) end end function ItemFrame:GUILDBANKBAGSLOTS_CHANGED(event, ...) self:ReloadAllItemSlots() end function ItemFrame:ITEM_FRAME_SPACING_UPDATE(msg, frameID, spacing) if self:GetFrameID() == frameID then self:RequestLayout() end end function ItemFrame:ITEM_FRAME_COLUMNS_UPDATE(msg, frameID, columns) if self:GetFrameID() == frameID then self:RequestLayout() end end function ItemFrame:HandleGlobalItemEvent(msg, ...) for i, item in self:GetAllItemSlots() do item:HandleEvent(msg, ...) end end --[[ Frame Events ]]-- function ItemFrame:OnShow() self:UpdateEverything() end function ItemFrame:OnHide() self:UpdateEvents() end function ItemFrame:OnSizeChanged() self:SendMessage('ITEM_FRAME_SIZE_CHANGE', self:GetFrameID()) end --[[ Update Methods ]]-- function ItemFrame:UpdateEverything() self:UpdateEvents() if self:IsVisible() then self:ReloadAllItemSlots() self:RequestLayout() end end function ItemFrame:UpdateEvents() self:UnregisterAllEvents() self:UnregisterAllMessages() if self:IsVisible() then self:RegisterEvent('GUILDBANKBAGSLOTS_CHANGED') self:RegisterMessage('ITEM_FRAME_SPACING_UPDATE') self:RegisterMessage('ITEM_FRAME_COLUMNS_UPDATE') self:RegisterMessage('TEXT_SEARCH_UPDATE', 'HandleGlobalItemEvent') self:RegisterMessage('BAG_SEARCH_UPDATE', 'HandleGlobalItemEvent') self:RegisterMessage('ITEM_HIGHLIGHT_QUEST_UPDATE', 'HandleGlobalItemEvent') self:RegisterMessage('ITEM_HIGHLIGHT_QUALITY_UPDATE', 'HandleGlobalItemEvent') self:RegisterMessage('ITEM_HIGHLIGHT_OPACITY_UPDATE', 'HandleGlobalItemEvent') self:RegisterMessage('SHOW_EMPTY_ITEM_SLOT_TEXTURE_UPDATE', 'HandleGlobalItemEvent') self:RegisterMessage('ITEM_SLOT_COLOR_UPDATE', 'HandleGlobalItemEvent') self:RegisterMessage('ITEM_SLOT_COLOR_ENABLED_UPDATE', 'HandleGlobalItemEvent') end end --[[ Item Slot Management ]]-- --if an item is not assigned to the given slotIndex, then add an item function ItemFrame:AddItemSlot(slot) if not self:GetItemSlot(slot) then local itemSlot = self:NewItemSlot(slot) self.itemSlots[slot] = itemSlot self:RequestLayout() end end function ItemFrame:NewItemSlot(slot) return Bagnon.GuildItemSlot:New(self:GetCurrentTab(), slot, self:GetFrameID(), self) end --returns the item slot assigned to the given slotIndex function ItemFrame:GetItemSlot(slot) return self.itemSlots[slot] end function ItemFrame:GetAllItemSlots() return ipairs(self.itemSlots) end --remove all unused item slots from the frame --add all missing slots to the frame --update all existing slots on the frame --if slots have been added or removed, then request a layout update function ItemFrame:ReloadAllItemSlots() local changed = false local currentTab = self:GetCurrentTab() for slot = 1, self:GetCurrentTabSize() do local itemSlot = self:GetItemSlot(slot) if not itemSlot then self:AddItemSlot(slot) changed = true else itemSlot:SetSlot(currentTab, slot) end end if changed then self:RequestLayout() end end --[[ Layout Methods ]]-- --arranges itemSlots on the ItemFrame, and adjusts size to fit --it should be noted that the guild bank is wacky in that items go down a column function ItemFrame:Layout() self.needsLayout = nil local numItems = self:GetCurrentTabSize() local numColumns = math.min(self:NumColumns(), numItems) local numRows = math.floor(numItems / numColumns + 0.5) local spacing = self:GetSpacing() local effItemSize = self.ITEM_SIZE + spacing local row, col = 0, 1 for i, itemSlot in self:GetAllItemSlots() do row = row + 1 if row > numRows then row = 1 col = col + 1 end itemSlot:ClearAllPoints() itemSlot:SetPoint('TOPLEFT', self, 'TOPLEFT', effItemSize * (col - 1), -effItemSize * (row - 1)) end local width = effItemSize * col - spacing local height = effItemSize * numRows - spacing self:SetWidth(width) self:SetHeight(height) end --request a layout update on this frame function ItemFrame:RequestLayout() self.needsLayout = true self.throttledUpdater:Show() end --returns true if the frame should have its layout updated, and false otherwise function ItemFrame:NeedsLayout() return self.needsLayout end --[[ Frame Properties ]]-- --frameID function ItemFrame:SetFrameID(frameID) if self:GetFrameID() ~= frameID then self.frameID = frameID self:UpdateEverything() end end function ItemFrame:GetFrameID() return self.frameID end --frame settings function ItemFrame:GetSettings() return Bagnon.FrameSettings:Get(self:GetFrameID()) end --layout info function ItemFrame:NumColumns() return self:GetSettings():GetItemFrameColumns() end function ItemFrame:GetSpacing() return self:GetSettings():GetItemFrameSpacing() end --guild bank info function ItemFrame:GetCurrentTab() return GetCurrentGuildBankTab() or 0 end function ItemFrame:GetCurrentTabSize() return 98 end