changeset 146:86564b5cbbff

Added bag button support
author Flick <flickerstreak@gmail.com>
date Thu, 30 Apr 2009 16:51:43 +0000
parents 42cade25d40d
children 901c91dc1bf2
files classes/BagButton.lua classes/Bar.lua classes/classes.xml locale/enUS.lua modules/Bag.lua modules/modules.xml
diffstat 6 files changed, 634 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/classes/BagButton.lua	Thu Apr 30 16:51:43 2009 +0000
@@ -0,0 +1,430 @@
+local ReAction = ReAction
+local L = ReAction.L
+local _G = _G
+local CreateFrame = CreateFrame
+local format = string.format
+local GetCVar = GetCVar
+local ContainerIDToInventoryID = ContainerIDToInventoryID
+local NUM_CONTAINER_FRAMES = NUM_CONTAINER_FRAMES
+local IsModifiedClick = IsModifiedClick
+local CursorHasItem = CursorHasItem
+local GetInventoryItemTexture = GetInventoryItemTexture
+local GetInventorySlotInfo = GetInventorySlotInfo
+local PickupBagFromSlot = PickupBagFromSlot
+local CursorCanGoInSlot = CursorCanGoInSlot
+
+ReAction:UpdateRevision("$Revision: 154 $")
+
+-- class declarations
+local Super    = ReAction.Button
+local BagBase  = setmetatable( { }, { __index = Super } )
+local Bag      = setmetatable( { }, { __index = BagBase } )
+local Backpack = setmetatable( { }, { __index = BagBase } )
+local Keyring  = setmetatable( { }, { __index = BagBase } )
+
+ReAction.Button.Bag = BagBase
+
+--
+-- Bag Button base class
+--
+
+function BagBase:New( idx, moduleConfig, bar, idHint )
+  local name = format("ReAction_%s_Bag_%d",bar:GetName(),idx)
+
+  -- use a variable private leaf implementation class
+  -- unlike traditional OO programming, we can initialize the leaf
+  -- class before initializing its derived class
+  local class = Bag
+  if idx == 1 then
+    class = Backpack
+  elseif idx == 6 then
+    class = Keyring
+  end
+  self = class:New(name,moduleConfig.buttons[bar:GetName()][idx], bar, idx)
+  self.moduleConfig = moduleConfig
+
+  local f = self:GetFrame()
+  local config = self:GetConfig()
+
+  -- set up the bag ID pool
+  self:SetActionIDPool("bag",6)
+  config.bagID = self:AcquireActionID(config.bagID, idHint, true)
+
+  -- non secure scripts
+  f:SetScript("OnEvent", function(frame, ...) self:OnEvent(...) end)
+  f:SetScript("OnEnter", function(frame) self:OnEnter() end)
+  f:SetScript("OnLeave", function(frame) self:OnLeave() end)
+  f:SetScript("OnReceiveDrag", function(frame, ...) self:OnReceiveDrag(...) end)
+  f:SetScript("OnClick", function(frame, ...) self:OnClick(...) end)
+
+  -- secure handlers
+  -- (none)
+
+  -- event registration
+  f:EnableMouse(true)
+  f:RegisterForClicks("LeftButtonUp","RightButtonUp")
+  f:RegisterEvent("UPDATE_BINDINGS")
+
+  -- frame setup
+  f:SetID(self:GetBagID())
+
+  if not f.hotkey then
+    local h = f:CreateFontString(name.."HotKey","ARTWORK","NumberFontNormalSmallGray")
+    h:SetWidth(36)
+    h:SetHeight(10)
+    h:SetJustifyH("RIGHT")
+    h:SetPoint("TOPLEFT",f,"TOPLEFT",-2,-2)
+    h:Show()
+    f.hotkey = h
+  end
+
+  if not _G[name.."ItemAnim"] then
+    local anim = CreateFrame("Model",name.."ItemAnim",f,"ItemAnimTemplate")
+    anim:SetPoint("BOTTOMRIGHT",f,"BOTTOMRIGHT",-10,0)
+    anim:Hide()
+  end
+
+  self.frames.count:SetDrawLayer("ARTWORK")
+
+  self.frames.hotkey = f.hotkey
+  self.frames.icon = _G[name.."IconTexture"]
+  self.frames.anim = _G[name.."ItemAnim"]
+
+  -- initial display
+  if ReAction:GetConfigMode() then
+    self:GetFrame():Show()
+  end
+
+  self:Refresh()
+
+  return self
+end
+
+function BagBase:GetModuleConfig()
+  -- this is the Bag module config structure,
+  -- not the config structure of the bar itself
+  return self.moduleConfig
+end
+
+function BagBase:GetActionID()
+  return self.config.bagID
+end
+
+function BagBase:GetBagID()
+  return self:GetActionID() - 1
+end
+
+function BagBase:Refresh()
+  Super.Refresh(self)
+  self:UpdateHotkey()
+  self:Update()
+end
+
+function BagBase:Update()
+  self:UpdateChecked()
+end
+
+function BagBase:UpdateChecked(force)
+  if force == nil then
+    for i=1, NUM_CONTAINER_FRAMES do
+      local c = _G["ContainerFrame"..i]
+      if c:GetID() == self:GetBagID() and c:IsShown() then
+        self:GetFrame():SetChecked(1)
+        return
+      end
+    end
+    self:GetFrame():SetChecked(0)
+  end
+  self:GetFrame():SetChecked(force)
+end
+
+function BagBase:OnEvent(evt, ...)
+  if self[evt] then
+    self[evt](self, ...)
+  end
+end
+
+function BagBase:OnEnter()
+  self:SetTooltip()
+end
+
+function BagBase:OnLeave()
+  GameTooltip:Hide()
+end
+
+function BagBase:UPDATE_BINDINGS()
+  self:UpdateHotkey()
+end
+
+
+--
+-- Bag Button class
+--
+function Bag:New(name, cfg, bar, idx)
+  self = Super.New(self, name, cfg, bar, idx, "ItemButtonTemplate" )
+
+  local f = self:GetFrame()
+
+  f:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight")
+
+  f:RegisterEvent("CURSOR_UPDATE")
+  f:RegisterEvent("UNIT_INVENTORY_CHANGED")
+  f:RegisterEvent("BAG_CLOSED")
+  f:SetScript("OnDragStart", function(frame, ...) self:OnDragStart(...) end)
+  f:RegisterForDrag("LeftButton")
+
+  -- attach to skinner
+  bar:SkinButton(self,
+    {
+      Icon = _G[name.."IconTexture"]
+    }
+  )
+
+  return self
+end
+
+function Bag:GetInventorySlot()
+  return ContainerIDToInventoryID(self:GetBagID())
+end
+
+function Bag:GetInventorySlotName()
+  return "Bag"..(self:GetBagID()-1).."Slot"
+end
+
+function Bag:SetTooltip()
+  GameTooltip:SetOwner(self:GetFrame(), "ANCHOR_LEFT")
+  if not GameTooltip:SetInventoryItem("player", self:GetInventorySlot()) then
+    GameTooltip:SetText(EQUIP_CONTAINER, 1.0, 1.0, 1.0)
+  end
+end
+
+function Bag:Update()
+	local texture = GetInventoryItemTexture("player", self:GetInventorySlot())
+	if texture then
+    self.frames.icon:SetTexture(texture)
+    self.frames.icon:Show()
+    self:GetFrame():SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
+	else
+    local _, bgTex = GetInventorySlotInfo(self:GetInventorySlotName())
+    self.frames.icon:SetTexture(bgTex)
+    self:GetFrame():SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
+	end
+  self:UpdateChecked()
+end
+
+function Bag:OnClick()
+  if IsModifiedClick("OPENALLBAGS") then
+    OpenAllBags()
+  else
+    if not PutItemInBag(self:GetInventorySlot()) then
+      ToggleBag(self:GetBagID())
+    end
+  end
+  self:UpdateChecked()
+end
+
+function Bag:OnReceiveDrag()
+  if CursorHasItem() then
+    PutItemInBag(self:GetInventorySlot())
+  end
+end
+
+function Bag:OnDragStart()
+  PickupBagFromSlot(self:GetInventorySlot())
+  self:Update()
+end
+
+function Bag:UNIT_INVENTORY_CHANGED(unit)
+  if unit == "player" then
+    self:Update()
+  end
+end
+
+function Bag:CURSOR_UPDATE()
+  if CursorCanGoInSlot(self:GetInventorySlot()) then
+    self:GetFrame():LockHighlight()
+  else
+    self:GetFrame():UnlockHighlight()
+  end
+end
+
+function Bag:BAG_CLOSED(bag)
+  if bag == self:GetBagID() then
+    self:Update()
+  end
+end
+
+
+--
+-- Backpack Button class
+--
+function Backpack:New(name, cfg, bar, idx)
+  self = Super.New(self, name, cfg, bar, idx, "ItemButtonTemplate" )
+
+  local f = self:GetFrame()
+  local icon = _G[name.."IconTexture"]
+  icon:SetTexture("Interface\\Buttons\\Button-Backpack-Up")
+  icon:Show()
+  f:SetCheckedTexture("Interface\\Buttons\\CheckButtonHilight")
+  f:RegisterEvent("PLAYER_ENTERING_WORLD");
+  f:RegisterEvent("CVAR_UPDATE");
+  f:SetScript("OnShow", function(frame, ...) self:OnShow(...) end)
+
+  -- attach to skinner
+  bar:SkinButton(self,
+    {
+      Icon = _G[name.."IconTexture"]
+    }
+  )
+
+  return self
+end
+
+function Backpack:Update()
+  self:UpdateFreeSlots()
+  self:UpdateChecked()
+end
+
+function Backpack:UpdateFreeSlots()
+  if GetCVar("displayFreeBagSlots") == "1" then
+    local total = 0
+    for i = BACKPACK_CONTAINER, NUM_BAG_SLOTS do
+      local free, family = GetContainerNumFreeSlots(i)
+      if family == 0 then
+        total = total + free
+      end
+    end
+
+    self.freeSlots = total
+    self.frames.count:SetText(format("(%s)", self.freeSlots))
+    self.frames.count:Show()
+  elseif self.frames.count:IsShown() then
+    self.frames.count:Hide()
+  end
+end
+
+function Backpack:SetTooltip()
+  GameTooltip:SetOwner(self:GetFrame(), "ANCHOR_LEFT")
+  GameTooltip:SetText(BACKPACK_TOOLTIP, 1.0, 1.0, 1.0)
+  GameTooltip:AddLine(string.format(NUM_FREE_SLOTS, (self.freeSlots or 0)))
+  GameTooltip:Show();
+end
+
+function Backpack:OnShow()
+  self:UpdateFreeSlots()
+end
+
+function Backpack:OnClick()
+  if IsModifiedClick("OPENALLBAGS") then
+    OpenAllBags()
+  else
+    if not PutItemInBackpack() then
+      ToggleBackpack()
+    end
+  end
+  self:UpdateChecked()
+end
+
+function Backpack:OnReceiveDrag()
+  if CursorHasItem() then
+    PutItemInBackpack()
+  end
+end
+
+function Backpack:PLAYER_ENTERING_WORLD()
+  self:CVAR_UPDATE("DISPLAY_FREE_BAG_SLOTS", GetCVar("displayFreeBagSlots"))
+end
+
+function Backpack:CVAR_UPDATE( cvar, value )
+  if cvar == "DISPLAY_FREE_BAG_SLOTS" then
+    if value == "1" then
+      self:GetFrame():RegisterEvent("BAG_UPDATE")
+    else
+      self:GetFrame():UnregisterEvent("BAG_UPDATE")
+    end
+    self:UpdateFreeSlots()
+  end
+end
+
+function Backpack:BAG_UPDATE(bag)
+  if bag >= BACKPACK_CONTAINER and bag <= NUM_BAG_SLOTS then
+    self:UpdateFreeSlots()
+  end
+end
+
+
+--
+-- Keyring Button class
+--
+function Keyring:New(name, cfg, bar, idx)
+  self = Super.New(self, name, cfg, bar, idx, "ItemButtonTemplate" )
+
+  local f = self:GetFrame()
+
+  f:SetWidth(18)
+  f:SetHeight(39)
+
+  local tex = f:GetNormalTexture()
+  tex:SetWidth(18)
+  tex:SetHeight(39)
+  tex:ClearAllPoints()
+  tex:SetPoint("CENTER")
+  
+  f:SetNormalTexture("Interface\\Buttons\\UI-Button-KeyRing")
+  f:SetHighlightTexture("Interface\\Buttons\\UI-Button-KeyRing-Highlight")
+  f:SetPushedTexture("Interface\\Buttons\\UI-Button-KeyRing-Down")
+  f:GetNormalTexture():SetTexCoord(0,0.5625,0,0.609375)
+  f:GetHighlightTexture():SetTexCoord(0,0.5625,0,0.609375)
+  f:GetPushedTexture():SetTexCoord(0,0.5625,0,0.609375)
+
+  if not HasKey() then
+    f:Hide()
+  end
+
+  -- DO NOT attach to skinner
+
+  return self
+end
+
+function Keyring:GetBagID()
+  return KEYRING_CONTAINER
+end
+
+function Keyring:Refresh()
+  local f = self:GetFrame()
+  self.bar:PlaceButton( self, f:GetHeight(), f:GetHeight() ) -- use height x height since it's an odd size
+  self:UpdateHotkey()
+  self:Update()
+end
+
+function Keyring:SetTooltip()
+  GameTooltip:SetOwner(self:GetFrame(), "ANCHOR_RIGHT");
+  GameTooltip:SetText(KEYRING, HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
+  GameTooltip:AddLine();
+end
+
+function Keyring:OnReceiveDrag()
+  if CursorHasItem() then
+    PutKeyInKeyRing()
+  end
+end
+
+function Keyring:OnClick()
+  if CursorHasItem() then
+    PutKeyInKeyRing()
+  else
+    ToggleKeyRing()
+  end
+  self:UpdateChecked()
+end
+
+function Keyring:ShowGridTemp(show)
+  if not HasKey() then
+    if show then 
+      self:GetFrame():Show()
+    else
+      self:GetFrame():Hide()
+    end
+  end
+end
+
--- a/classes/Bar.lua	Mon Apr 27 18:10:04 2009 +0000
+++ b/classes/Bar.lua	Thu Apr 30 16:51:43 2009 +0000
@@ -37,7 +37,7 @@
                         "SecureHandlerStateTemplate, SecureHandlerClickTemplate")
   f:SetFrameStrata("MEDIUM")
   f:SetWidth(self.width)
-  f:SetWidth(self.height)
+  f:SetHeight(self.height)
   f:SetAlpha(config.alpha or 1.0)
   f:Show()
   f:EnableMouse(false)
--- a/classes/classes.xml	Mon Apr 27 18:10:04 2009 +0000
+++ b/classes/classes.xml	Thu Apr 30 16:51:43 2009 +0000
@@ -9,5 +9,6 @@
 <Script file="ActionButton.lua"/>
 <Script file="PetActionButton.lua"/>
 <Script file="StanceButton.lua"/>
+<Script file="BagButton.lua"/>
 
 </Ui>
\ No newline at end of file
--- a/locale/enUS.lua	Mon Apr 27 18:10:04 2009 +0000
+++ b/locale/enUS.lua	Thu Apr 30 16:51:43 2009 +0000
@@ -189,6 +189,9 @@
 "Hide Auras",
 "Do not show Paladin Auras as stances",
 
+-- Bag
+"Bag Bar",
+
 -- ConfigUI
 "Center",
 "Left",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/Bag.lua	Thu Apr 30 16:51:43 2009 +0000
@@ -0,0 +1,198 @@
+--[[
+  ReAction Bag button module
+
+--]]
+
+-- local imports
+local ReAction = ReAction
+local L = ReAction.L
+local _G = _G
+
+-- Bag button 
+local Button = ReAction.Button.Bag
+
+-- module declaration
+local moduleID = "Bag"
+local module = ReAction:NewModule( moduleID
+  -- mixins go here
+)
+
+-- libraries
+local KB = LibStub("LibKeyBound-1.0")
+
+-- handlers
+function module:OnInitialize()
+  self.db = ReAction.db:RegisterNamespace( moduleID,
+    {
+      profile = { 
+        buttons = { }
+      }
+    }
+  )
+
+  self.buttons = { }
+
+  ReAction.RegisterCallback(self, "OnCreateBar", "OnRefreshBar")
+  ReAction.RegisterCallback(self, "OnDestroyBar")
+  ReAction.RegisterCallback(self, "OnRefreshBar")
+  ReAction.RegisterCallback(self, "OnEraseBar")
+  ReAction.RegisterCallback(self, "OnRenameBar")
+  ReAction.RegisterCallback(self, "OnConfigModeChanged")
+
+  KB.RegisterCallback(self, "LIBKEYBOUND_ENABLED")
+  KB.RegisterCallback(self, "LIBKEYBOUND_DISABLED")
+  KB.RegisterCallback(self, "LIBKEYBOUND_MODE_COLOR_CHANGED","LIBKEYBOUND_ENABLED")
+end
+
+function module:OnEnable()
+  ReAction:RegisterBarType(L["Bag Bar"], 
+    { 
+      type = moduleID ,
+      defaultButtonSize = 30,
+      defaultBarRows = 1,
+      defaultBarCols = 6,
+      defaultBarSpacing = 4
+    })
+end
+
+function module:OnDisable()
+  ReAction:UnregisterBarType(L["Bag Bar"])
+end
+
+function module:OnDestroyBar(event, bar, name)
+  local btns = self.buttons[bar]
+  if btns then
+    for _,b in pairs(btns) do
+      if b then
+        b:Destroy()
+      end
+    end
+    self.buttons[bar] = nil
+  end
+end
+
+function module:OnRefreshBar(event, bar, name)
+  if bar.config.type == moduleID then
+    local btns = self.buttons[bar]
+    if btns == nil then
+      btns = { }
+      self.buttons[bar] = btns
+    end
+    local profile = self.db.profile
+    if profile.buttons[name] == nil then
+      profile.buttons[name] = {}
+    end
+    local btnCfg = profile.buttons[name]
+
+    local r, c = bar:GetButtonGrid()
+    local n = r*c
+    for i = 1, n do
+      if btnCfg[i] == nil then
+        btnCfg[i] = {}
+      end
+      if btns[i] == nil then
+        local success, r = pcall(Button.New,Button,i,profile,bar,i>1 and btnCfg[i-1].bagID)
+        if success and r then
+          btns[i] = r
+          bar:AddButton(i,r)
+        else
+          n = i - 1
+          bar:ClipNButtons(n)
+          break
+        end
+      end
+      btns[i]:Refresh()
+    end
+    for i = n+1, #btns do
+      if btns[i] then
+        bar:RemoveButton(btns[i])
+        btns[i] = btns[i]:Destroy()
+        if btnCfg[i] then
+          btnCfg[i] = nil
+        end
+      end
+    end
+  end
+
+end
+
+function module:OnEraseBar(event, bar, name)
+  self.db.profile.buttons[name] = nil
+end
+
+function module:OnRenameBar(event, bar, oldName, newName)
+  local b = self.db.profile.buttons
+  b[newname], b[oldname] = b[oldname], nil
+end
+
+function module:OnConfigModeChanged(event, mode)
+  for bar in pairs(self.buttons) do
+    for b in bar:IterateButtons() do
+      b:UpdateActionIDLabel(mode)
+    end
+  end
+end
+
+function module:LIBKEYBOUND_ENABLED(evt)
+  for _, buttons in pairs(self.buttons) do
+    for _, b in pairs(buttons) do
+      b:SetKeybindMode(true)
+    end
+  end
+end
+
+function module:LIBKEYBOUND_DISABLED(evt)
+  for _, buttons in pairs(self.buttons) do
+    for _, b in pairs(buttons) do
+      b:SetKeybindMode(false)
+    end
+  end
+end
+
+function module:RefreshAll()
+  for bar in pairs(self.buttons) do
+    self:OnRefreshBar(nil,bar,bar:GetName())
+  end
+end
+
+
+-- hook some functions to propagate to our bag buttons
+hooksecurefunc("Disable_BagButtons", 
+  function()
+    for _, buttons in pairs(module.buttons) do
+      for _, b in pairs(buttons) do
+        local f = b:GetFrame()
+        f:Disable()
+        SetDesaturation(b.frames.icon,1)
+      end
+    end
+  end)
+
+hooksecurefunc("Enable_BagButtons",
+  function()
+    for _, buttons in pairs(module.buttons) do
+      for _, b in pairs(buttons) do
+        local f = b:GetFrame()
+        f:Enable()
+        SetDesaturation(b.frames.icon,nil)
+      end
+    end
+  end)
+
+hooksecurefunc("ContainerFrame_OnHide",
+  function()
+    for _, buttons in pairs(module.buttons) do
+      for _, b in pairs(buttons) do
+        b:Update()
+      end
+    end
+  end)
+
+hooksecurefunc("ContainerFrame_OnShow",
+  function()
+    for _, buttons in pairs(module.buttons) do
+      for _, b in pairs(buttons) do
+        b:Update()
+      end
+    end
+  end)
--- a/modules/modules.xml	Mon Apr 27 18:10:04 2009 +0000
+++ b/modules/modules.xml	Thu Apr 30 16:51:43 2009 +0000
@@ -9,5 +9,6 @@
 <Script file="Action.lua"/>
 <Script file="PetAction.lua"/>
 <Script file="Stance.lua"/>
+<Script file="Bag.lua"/>
 
 </Ui>
\ No newline at end of file