diff modules/ReAction_PossessBar/ReAction_PossessBar.lua @ 54:8b81d4b3e73d

Possess bar support (actions only)
author Flick <flickerstreak@gmail.com>
date Fri, 25 Apr 2008 22:13:02 +0000
parents
children b85118b61564
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ReAction_PossessBar/ReAction_PossessBar.lua	Fri Apr 25 22:13:02 2008 +0000
@@ -0,0 +1,298 @@
+--[[
+  ReAction Possess Bar (Mind Control/etc) button module.
+
+  Wraps the standard Action buttons 121-132 with an automatic show/hide
+  when mind control (etc) is active
+
+--]]
+
+-- local imports
+local ReAction = ReAction
+local L = ReAction.L
+local _G = _G
+local CreateFrame = CreateFrame
+
+-- module declaration
+local moduleID = "PossessBar"
+local module = ReAction:NewModule( moduleID )
+
+-- module methods
+function module:OnInitialize()
+  self.db = ReAction.db:RegisterNamespace( moduleID,
+    { 
+      profile = {
+        buttons = { }
+      }
+    }
+  )
+  self.buttons = { }
+
+  ReAction:RegisterOptions("global", self, {
+    hideEmptyPossess = {
+      type = "toggle",
+      name = L["Hide Empty Possess Bar Buttons"],
+      get  = function() return self.db.profile.hideEmptyButtons end,
+      set  = function(info, val) module:SetHideEmptyButtons(val) end,
+    }
+  })
+end
+
+function module:OnEnable()
+  ReAction:RegisterBarType(L["Possess Bar"], 
+    { 
+      type = moduleID,
+      defaultButtonSize = 36,
+      defaultBarRows = 1,
+      defaultBarCols = 12,
+      defaultBarSpacing = 3
+    })
+end
+
+function module:OnDisable()
+  ReAction:UnregisterBarType(L["Possess Bar"])
+end
+
+function module:ApplyToBar(bar)
+  if bar.config.type == moduleID then
+    bar:GetFrame():SetParent(PossessBarFrame)
+    bar.config.parent = "PossessBarFrame"
+  end
+  self:RefreshBar(bar)
+end
+
+function module:RefreshBar(bar)
+  if bar.config.type == moduleID then
+    if self.buttons[bar] == nil then
+      self.buttons[bar] = { }
+    end
+    local btns = self.buttons[bar]
+    local profile = self.db.profile
+    local barName = bar:GetName()
+    if profile.buttons[barName] == nil then
+      profile.buttons[barName] = {}
+    end
+    local btnCfg = profile.buttons[barName]
+
+    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 ok, b = pcall(self.BtnClass.new, self.BtnClass, bar, i, btnCfg[i])
+        if ok and b then
+          btns[i] = b
+        end
+      else
+        btns[i]:Refresh(bar,i)
+      end
+    end
+    for i = n+1, #btns do
+      if btns[i] then
+        btns[i] = btns[i]:Destroy()
+        if btnCfg[i] then
+          btnCfg[i] = nil
+        end
+      end
+    end
+  end
+end
+
+function module:RemoveFromBar(bar)
+  if self.buttons[bar] then
+    local btns = self.buttons[bar]
+    for _,b in pairs(btns) do
+      if b then
+        b:Destroy()
+      end
+    end
+    self.buttons[bar] = nil
+  end
+end
+
+function module:EraseBarConfig(barName)
+  self.db.profile.buttons[barName] = nil
+end
+
+function module:RenameBarConfig(oldname, newname)
+  local b = self.db.profile.buttons
+  b[newname], b[oldname] = b[oldname], nil
+end
+
+function module:SetHideEmptyButtons(hide)
+  if hide ~= self.db.profile.hideEmptyButtons then
+    for _, bar in pairs(self.buttons) do
+      for _, b in pairs(bar) do
+        if hide then
+          ActionButton_HideGrid(b.frame)
+        else
+          ActionButton_ShowGrid(b.frame)
+        end
+      end
+    end
+    self.db.profile.hideEmptyButtons = hide
+  end
+end
+
+function module:ApplyConfigMode(mode,bars)
+  for _, bar in pairs(bars) do
+    if bar and self.buttons[bar] then
+      for _, b in pairs(self.buttons[bar]) do
+        if b then
+          if mode then
+            ActionButton_ShowGrid(b.frame)
+            self:showActionIDLabel(b)
+          else
+            ActionButton_HideGrid(b.frame)
+            self:hideActionIDLabel(b)
+          end
+        end
+      end
+      local f = bar:GetFrame()
+      if mode then
+        f:SetParent(UIParent)
+        f:Show()
+      else
+        f:SetParent(PossessBarFrame)
+      end
+    end
+  end
+end
+
+function module:showActionIDLabel(button)
+  if not button.actionIDLabel and button:GetActionID() then
+    local label = button:GetFrame():CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
+    label:SetAllPoints()
+    label:SetJustifyH("CENTER")
+    label:SetShadowColor(0,0,0,1)
+    label:SetShadowOffset(2,-2)
+    label:SetText(tostring(button:GetActionID()))
+    button.actionIDLabel = label
+  end
+  button.actionIDLabel:Show()
+end
+
+function module:hideActionIDLabel(button)
+  if button.actionIDLabel then
+    button.actionIDLabel:Hide()
+  end
+end
+
+
+
+-- use-count of action IDs
+local minActionID = 121
+local maxActionID = 132
+local ActionIDList = setmetatable( {}, {
+  __index = function(self, idx)
+    if idx == nil then
+      for i = minActionID, maxActionID do
+        if rawget(self,i) == nil then
+          rawset(self,i,1)
+          return i
+        end
+      end
+      error("ran out of action IDs")
+    else
+      local c = rawget(self,idx) or 0
+      rawset(self,idx,c+1)
+      return idx
+    end
+  end,
+  __newindex = function(self,idx,value)
+    if value == nil then
+      value = rawget(self,idx)
+      if value == 1 then
+        value = nil
+      elseif value then
+        value = value - 1
+      end
+    end
+    rawset(self,idx,value)
+  end
+})
+
+
+
+
+------ Button class ------
+local Button = { }
+
+local function Constructor( self, bar, idx, config )
+  self.bar, self.idx, self.config = bar, idx, config
+
+  local barFrame = bar:GetFrame()
+
+  config.name = config.name or "ReAction_"..bar:GetName().."_Possess_"..idx
+  self.name = config.name
+  config.actionID = ActionIDList[config.actionID] -- gets a free one if none configured
+  
+  local f = CreateFrame("CheckButton", self.name, barFrame, "BonusActionButtonTemplate")
+
+  -- TODO: re-implement ActionButton event handlers that don't do secure stuff
+
+  -- this will probably cause taint, using right now for display/debugging purposes
+  f:SetScript("OnAttributeChanged", ActionButton_UpdateAction)
+  f:SetAttribute("action", config.actionID)
+
+  barFrame:SetAttribute("addchild",f)
+
+  self.frame = f
+  self:Refresh(bar,idx)
+
+  if not module.db.profile.hideEmptyButtons then
+    ActionButton_ShowGrid(self.frame)
+  end
+
+  if ReAction.configMode then
+    ActionButton_ShowGrid(self.frame)
+    module:showActionIDLabel(self)
+  end
+end
+
+function Button:Destroy()
+  local f = self.frame
+  f:UnregisterAllEvents()
+  f:Hide()
+  f:SetParent(UIParent)
+  f:ClearAllPoints()
+  if self.name then
+    _G[self.name] = nil
+  end
+  if self.config.actionID then
+    ActionIDList[self.config.actionID] = nil
+  end
+  self.frame = nil
+  self.config = nil
+  self.bar = nil
+end
+
+function Button:Refresh(bar,idx)
+  bar:PlaceButton(self.frame, idx, 36, 36)
+end
+
+function Button:GetFrame()
+  return self.frame
+end
+
+function Button:GetName()
+  return self.name
+end
+
+function Button:GetActionID()
+  return self.config.actionID
+end
+
+
+-- export as a class-factory to module
+module.BtnClass = {
+  new = function(self, ...)
+    local x = { }
+    for k,v in pairs(Button) do
+      x[k] = v
+    end
+    Constructor(x, ...)
+    return x
+  end
+}