flickerstreak@175: local addonName, addonTable = ... flickerstreak@175: local ReAction = addonTable.ReAction flickerstreak@146: local L = ReAction.L flickerstreak@146: local _G = _G flickerstreak@146: local CreateFrame = CreateFrame flickerstreak@146: local format = string.format flickerstreak@146: local GetCVar = GetCVar flickerstreak@146: local ContainerIDToInventoryID = ContainerIDToInventoryID flickerstreak@146: local NUM_CONTAINER_FRAMES = NUM_CONTAINER_FRAMES flickerstreak@146: local IsModifiedClick = IsModifiedClick flickerstreak@146: local CursorHasItem = CursorHasItem flickerstreak@146: local GetInventoryItemTexture = GetInventoryItemTexture flickerstreak@146: local GetInventorySlotInfo = GetInventorySlotInfo flickerstreak@146: local PickupBagFromSlot = PickupBagFromSlot flickerstreak@146: local CursorCanGoInSlot = CursorCanGoInSlot flickerstreak@146: flickerstreak@146: -- class declarations flickerstreak@146: local Super = ReAction.Button flickerstreak@146: local BagBase = setmetatable( { }, { __index = Super } ) flickerstreak@146: local Bag = setmetatable( { }, { __index = BagBase } ) flickerstreak@146: local Backpack = setmetatable( { }, { __index = BagBase } ) flickerstreak@146: local Keyring = setmetatable( { }, { __index = BagBase } ) flickerstreak@146: flickerstreak@146: ReAction.Button.Bag = BagBase flickerstreak@146: flickerstreak@146: -- flickerstreak@146: -- Bag Button base class flickerstreak@146: -- flickerstreak@146: flickerstreak@146: function BagBase:New( idx, moduleConfig, bar, idHint ) flickerstreak@146: local name = format("ReAction_%s_Bag_%d",bar:GetName(),idx) flickerstreak@146: flickerstreak@146: -- use a variable private leaf implementation class flickerstreak@146: -- unlike traditional OO programming, we can initialize the leaf flickerstreak@146: -- class before initializing its derived class flickerstreak@146: local class = Bag flickerstreak@146: if idx == 1 then flickerstreak@146: class = Backpack flickerstreak@146: elseif idx == 6 then flickerstreak@146: class = Keyring flickerstreak@146: end flickerstreak@146: self = class:New(name,moduleConfig.buttons[bar:GetName()][idx], bar, idx) flickerstreak@146: self.moduleConfig = moduleConfig flickerstreak@146: flickerstreak@146: local f = self:GetFrame() flickerstreak@146: local config = self:GetConfig() flickerstreak@146: flickerstreak@146: -- set up the bag ID pool flickerstreak@146: self:SetActionIDPool("bag",6) flickerstreak@146: config.bagID = self:AcquireActionID(config.bagID, idHint, true) flickerstreak@146: flickerstreak@146: -- non secure scripts flickerstreak@146: f:SetScript("OnEvent", function(frame, ...) self:OnEvent(...) end) flickerstreak@146: f:SetScript("OnEnter", function(frame) self:OnEnter() end) flickerstreak@146: f:SetScript("OnLeave", function(frame) self:OnLeave() end) flickerstreak@146: f:SetScript("OnReceiveDrag", function(frame, ...) self:OnReceiveDrag(...) end) flickerstreak@146: f:SetScript("OnClick", function(frame, ...) self:OnClick(...) end) flickerstreak@146: flickerstreak@146: -- secure handlers flickerstreak@146: -- (none) flickerstreak@146: flickerstreak@146: -- event registration flickerstreak@146: f:EnableMouse(true) flickerstreak@146: f:RegisterForClicks("LeftButtonUp","RightButtonUp") flickerstreak@146: f:RegisterEvent("UPDATE_BINDINGS") flickerstreak@146: flickerstreak@146: -- frame setup flickerstreak@146: f:SetID(self:GetBagID()) flickerstreak@146: flickerstreak@146: if not f.hotkey then flickerstreak@146: local h = f:CreateFontString(name.."HotKey","ARTWORK","NumberFontNormalSmallGray") flickerstreak@152: h:SetWidth(30) flickerstreak@146: h:SetHeight(10) flickerstreak@146: h:SetJustifyH("RIGHT") flickerstreak@146: h:SetPoint("TOPLEFT",f,"TOPLEFT",-2,-2) flickerstreak@146: h:Show() flickerstreak@146: f.hotkey = h flickerstreak@146: end flickerstreak@146: flickerstreak@146: if not _G[name.."ItemAnim"] then flickerstreak@146: local anim = CreateFrame("Model",name.."ItemAnim",f,"ItemAnimTemplate") flickerstreak@146: anim:SetPoint("BOTTOMRIGHT",f,"BOTTOMRIGHT",-10,0) flickerstreak@146: anim:Hide() flickerstreak@146: end flickerstreak@146: flickerstreak@152: if not f.border then flickerstreak@152: local b = f:CreateTexture(name.."Border","OVERLAY") flickerstreak@152: b:SetAllPoints() flickerstreak@152: b:SetWidth(f:GetWidth()*(62/36)) flickerstreak@152: b:SetHeight(f:GetHeight()*(62/36)) flickerstreak@152: b:SetTexture("Interface\\Buttons\UI-ActionButton-Border") flickerstreak@152: b:SetBlendMode("ADD") flickerstreak@152: b:Hide() flickerstreak@152: f.border = b flickerstreak@152: end flickerstreak@152: flickerstreak@146: self.frames.count:SetDrawLayer("ARTWORK") flickerstreak@146: flickerstreak@146: self.frames.hotkey = f.hotkey flickerstreak@152: self.frames.border = _G[name.."Border"] flickerstreak@146: self.frames.icon = _G[name.."IconTexture"] flickerstreak@146: self.frames.anim = _G[name.."ItemAnim"] flickerstreak@146: flickerstreak@146: -- initial display flickerstreak@146: if ReAction:GetConfigMode() then flickerstreak@146: self:GetFrame():Show() flickerstreak@146: end flickerstreak@146: flickerstreak@146: self:Refresh() flickerstreak@146: flickerstreak@146: return self flickerstreak@146: end flickerstreak@146: flickerstreak@146: function BagBase:GetModuleConfig() flickerstreak@146: -- this is the Bag module config structure, flickerstreak@146: -- not the config structure of the bar itself flickerstreak@146: return self.moduleConfig flickerstreak@146: end flickerstreak@146: flickerstreak@146: function BagBase:GetActionID() flickerstreak@146: return self.config.bagID flickerstreak@146: end flickerstreak@146: flickerstreak@146: function BagBase:GetBagID() flickerstreak@146: return self:GetActionID() - 1 flickerstreak@146: end flickerstreak@146: flickerstreak@146: function BagBase:Refresh() flickerstreak@146: Super.Refresh(self) flickerstreak@146: self:UpdateHotkey() flickerstreak@146: self:Update() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function BagBase:Update() flickerstreak@146: self:UpdateChecked() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function BagBase:UpdateChecked(force) flickerstreak@146: if force == nil then flickerstreak@146: for i=1, NUM_CONTAINER_FRAMES do flickerstreak@146: local c = _G["ContainerFrame"..i] flickerstreak@146: if c:GetID() == self:GetBagID() and c:IsShown() then flickerstreak@146: self:GetFrame():SetChecked(1) flickerstreak@146: return flickerstreak@146: end flickerstreak@146: end flickerstreak@146: self:GetFrame():SetChecked(0) flickerstreak@146: end flickerstreak@146: self:GetFrame():SetChecked(force) flickerstreak@146: end flickerstreak@146: flickerstreak@146: function BagBase:OnEvent(evt, ...) flickerstreak@146: if self[evt] then flickerstreak@146: self[evt](self, ...) flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: function BagBase:OnEnter() flickerstreak@146: self:SetTooltip() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function BagBase:OnLeave() flickerstreak@146: GameTooltip:Hide() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function BagBase:UPDATE_BINDINGS() flickerstreak@146: self:UpdateHotkey() flickerstreak@146: end flickerstreak@146: flickerstreak@146: flickerstreak@146: -- flickerstreak@146: -- Bag Button class flickerstreak@146: -- flickerstreak@146: function Bag:New(name, cfg, bar, idx) flickerstreak@146: self = Super.New(self, name, cfg, bar, idx, "ItemButtonTemplate" ) flickerstreak@146: flickerstreak@146: local f = self:GetFrame() flickerstreak@146: flickerstreak@146: f:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight") flickerstreak@146: flickerstreak@146: f:RegisterEvent("CURSOR_UPDATE") flickerstreak@151: f:RegisterEvent("BAG_UPDATE") flickerstreak@146: f:RegisterEvent("BAG_CLOSED") flickerstreak@146: f:SetScript("OnDragStart", function(frame, ...) self:OnDragStart(...) end) flickerstreak@146: f:RegisterForDrag("LeftButton") flickerstreak@146: flickerstreak@146: -- attach to skinner flickerstreak@146: bar:SkinButton(self, flickerstreak@146: { flickerstreak@146: Icon = _G[name.."IconTexture"] flickerstreak@146: } flickerstreak@146: ) flickerstreak@146: flickerstreak@146: return self flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Bag:GetInventorySlot() flickerstreak@146: return ContainerIDToInventoryID(self:GetBagID()) flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Bag:GetInventorySlotName() flickerstreak@146: return "Bag"..(self:GetBagID()-1).."Slot" flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Bag:SetTooltip() flickerstreak@146: GameTooltip:SetOwner(self:GetFrame(), "ANCHOR_LEFT") flickerstreak@146: if not GameTooltip:SetInventoryItem("player", self:GetInventorySlot()) then flickerstreak@146: GameTooltip:SetText(EQUIP_CONTAINER, 1.0, 1.0, 1.0) flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Bag:Update() flickerstreak@146: local texture = GetInventoryItemTexture("player", self:GetInventorySlot()) flickerstreak@146: if texture then flickerstreak@146: self.frames.icon:SetTexture(texture) flickerstreak@146: self.frames.icon:Show() flickerstreak@146: self:GetFrame():SetNormalTexture("Interface\\Buttons\\UI-Quickslot2") flickerstreak@146: else flickerstreak@146: local _, bgTex = GetInventorySlotInfo(self:GetInventorySlotName()) flickerstreak@146: self.frames.icon:SetTexture(bgTex) flickerstreak@146: self:GetFrame():SetNormalTexture("Interface\\Buttons\\UI-Quickslot") flickerstreak@146: end flickerstreak@146: self:UpdateChecked() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Bag:OnClick() flickerstreak@146: if IsModifiedClick("OPENALLBAGS") then flickerstreak@146: OpenAllBags() flickerstreak@146: else flickerstreak@146: if not PutItemInBag(self:GetInventorySlot()) then flickerstreak@146: ToggleBag(self:GetBagID()) flickerstreak@146: end flickerstreak@146: end flickerstreak@146: self:UpdateChecked() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Bag:OnReceiveDrag() flickerstreak@146: if CursorHasItem() then flickerstreak@146: PutItemInBag(self:GetInventorySlot()) flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Bag:OnDragStart() flickerstreak@146: PickupBagFromSlot(self:GetInventorySlot()) flickerstreak@146: self:Update() flickerstreak@146: end flickerstreak@146: flickerstreak@151: function Bag:BAG_UPDATE(bag) flickerstreak@151: if bag == self:GetBagID() then flickerstreak@146: self:Update() flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Bag:CURSOR_UPDATE() flickerstreak@146: if CursorCanGoInSlot(self:GetInventorySlot()) then flickerstreak@146: self:GetFrame():LockHighlight() flickerstreak@146: else flickerstreak@146: self:GetFrame():UnlockHighlight() flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Bag:BAG_CLOSED(bag) flickerstreak@146: if bag == self:GetBagID() then flickerstreak@146: self:Update() flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: flickerstreak@146: -- flickerstreak@146: -- Backpack Button class flickerstreak@146: -- flickerstreak@146: function Backpack:New(name, cfg, bar, idx) flickerstreak@146: self = Super.New(self, name, cfg, bar, idx, "ItemButtonTemplate" ) flickerstreak@146: flickerstreak@146: local f = self:GetFrame() flickerstreak@146: local icon = _G[name.."IconTexture"] flickerstreak@146: icon:SetTexture("Interface\\Buttons\\Button-Backpack-Up") flickerstreak@146: icon:Show() flickerstreak@146: f:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight") flickerstreak@146: f:RegisterEvent("PLAYER_ENTERING_WORLD"); flickerstreak@146: f:RegisterEvent("CVAR_UPDATE"); flickerstreak@146: f:SetScript("OnShow", function(frame, ...) self:OnShow(...) end) flickerstreak@146: flickerstreak@146: -- attach to skinner flickerstreak@146: bar:SkinButton(self, flickerstreak@146: { flickerstreak@146: Icon = _G[name.."IconTexture"] flickerstreak@146: } flickerstreak@146: ) flickerstreak@146: flickerstreak@146: return self flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Backpack:Update() flickerstreak@146: self:UpdateFreeSlots() flickerstreak@146: self:UpdateChecked() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Backpack:UpdateFreeSlots() flickerstreak@146: if GetCVar("displayFreeBagSlots") == "1" then flickerstreak@146: local total = 0 flickerstreak@146: for i = BACKPACK_CONTAINER, NUM_BAG_SLOTS do flickerstreak@146: local free, family = GetContainerNumFreeSlots(i) flickerstreak@146: if family == 0 then flickerstreak@146: total = total + free flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: self.freeSlots = total flickerstreak@146: self.frames.count:SetText(format("(%s)", self.freeSlots)) flickerstreak@146: self.frames.count:Show() flickerstreak@146: elseif self.frames.count:IsShown() then flickerstreak@146: self.frames.count:Hide() flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Backpack:SetTooltip() flickerstreak@146: GameTooltip:SetOwner(self:GetFrame(), "ANCHOR_LEFT") flickerstreak@146: GameTooltip:SetText(BACKPACK_TOOLTIP, 1.0, 1.0, 1.0) flickerstreak@146: GameTooltip:AddLine(string.format(NUM_FREE_SLOTS, (self.freeSlots or 0))) flickerstreak@146: GameTooltip:Show(); flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Backpack:OnShow() flickerstreak@146: self:UpdateFreeSlots() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Backpack:OnClick() flickerstreak@146: if IsModifiedClick("OPENALLBAGS") then flickerstreak@146: OpenAllBags() flickerstreak@146: else flickerstreak@146: if not PutItemInBackpack() then flickerstreak@146: ToggleBackpack() flickerstreak@146: end flickerstreak@146: end flickerstreak@146: self:UpdateChecked() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Backpack:OnReceiveDrag() flickerstreak@146: if CursorHasItem() then flickerstreak@146: PutItemInBackpack() flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Backpack:PLAYER_ENTERING_WORLD() flickerstreak@146: self:CVAR_UPDATE("DISPLAY_FREE_BAG_SLOTS", GetCVar("displayFreeBagSlots")) flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Backpack:CVAR_UPDATE( cvar, value ) flickerstreak@146: if cvar == "DISPLAY_FREE_BAG_SLOTS" then flickerstreak@146: if value == "1" then flickerstreak@146: self:GetFrame():RegisterEvent("BAG_UPDATE") flickerstreak@146: else flickerstreak@146: self:GetFrame():UnregisterEvent("BAG_UPDATE") flickerstreak@146: end flickerstreak@146: self:UpdateFreeSlots() flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Backpack:BAG_UPDATE(bag) flickerstreak@146: if bag >= BACKPACK_CONTAINER and bag <= NUM_BAG_SLOTS then flickerstreak@146: self:UpdateFreeSlots() flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: flickerstreak@146: -- flickerstreak@146: -- Keyring Button class flickerstreak@146: -- flickerstreak@146: function Keyring:New(name, cfg, bar, idx) flickerstreak@146: self = Super.New(self, name, cfg, bar, idx, "ItemButtonTemplate" ) flickerstreak@146: flickerstreak@146: local f = self:GetFrame() flickerstreak@146: flickerstreak@146: f:SetWidth(18) flickerstreak@146: f:SetHeight(39) flickerstreak@146: flickerstreak@146: local tex = f:GetNormalTexture() flickerstreak@146: tex:ClearAllPoints() flickerstreak@152: tex:SetAllPoints() flickerstreak@146: flickerstreak@146: f:SetNormalTexture("Interface\\Buttons\\UI-Button-KeyRing") flickerstreak@146: f:SetHighlightTexture("Interface\\Buttons\\UI-Button-KeyRing-Highlight") flickerstreak@146: f:SetPushedTexture("Interface\\Buttons\\UI-Button-KeyRing-Down") flickerstreak@146: f:GetNormalTexture():SetTexCoord(0,0.5625,0,0.609375) flickerstreak@146: f:GetHighlightTexture():SetTexCoord(0,0.5625,0,0.609375) flickerstreak@146: f:GetPushedTexture():SetTexCoord(0,0.5625,0,0.609375) flickerstreak@146: flickerstreak@146: if not HasKey() then flickerstreak@146: f:Hide() flickerstreak@146: end flickerstreak@146: flickerstreak@146: -- DO NOT attach to skinner flickerstreak@146: flickerstreak@146: return self flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Keyring:GetBagID() flickerstreak@146: return KEYRING_CONTAINER flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Keyring:Refresh() flickerstreak@146: local f = self:GetFrame() flickerstreak@146: self.bar:PlaceButton( self, f:GetHeight(), f:GetHeight() ) -- use height x height since it's an odd size flickerstreak@146: self:UpdateHotkey() flickerstreak@146: self:Update() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Keyring:SetTooltip() flickerstreak@146: GameTooltip:SetOwner(self:GetFrame(), "ANCHOR_RIGHT"); flickerstreak@146: GameTooltip:SetText(KEYRING, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b); flickerstreak@146: GameTooltip:AddLine(); flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Keyring:OnReceiveDrag() flickerstreak@146: if CursorHasItem() then flickerstreak@146: PutKeyInKeyRing() flickerstreak@146: end flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Keyring:OnClick() flickerstreak@146: if CursorHasItem() then flickerstreak@146: PutKeyInKeyRing() flickerstreak@146: else flickerstreak@146: ToggleKeyRing() flickerstreak@146: end flickerstreak@146: self:UpdateChecked() flickerstreak@146: end flickerstreak@146: flickerstreak@146: function Keyring:ShowGridTemp(show) flickerstreak@146: if not HasKey() then flickerstreak@146: if show then flickerstreak@146: self:GetFrame():Show() flickerstreak@146: else flickerstreak@146: self:GetFrame():Hide() flickerstreak@146: end flickerstreak@146: end flickerstreak@146: end flickerstreak@146: