diff classes/ReAction_ActionType.lua @ 7:f920db5fc6b1

version 0.3
author Flick <flickerstreak@gmail.com>
date Tue, 20 Mar 2007 21:25:29 +0000
parents
children c05fd3e18b4f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/classes/ReAction_ActionType.lua	Tue Mar 20 21:25:29 2007 +0000
@@ -0,0 +1,361 @@
+-- The ReAction.ActionType mixin defines 'regular' action button functionality 
+-- and is an implementation of the ReAction.IActionType interface.
+--
+-- The Mixin assumes that it is being mixed in with a ReAction-derived class
+-- which implements the ReAction.IDisplay and ReAction.ActionType.IDisplay interfaces.
+--
+-- This mixin using the following configuration properties:
+--
+-- self.config = {
+--   selfcast = nil / "alt" / "ctrl" / "shift" / "auto" / "none". nil (default) = use Interface Options menu setting.
+-- }
+--
+
+local AceOO = AceLibrary("AceOO-2.0")
+
+ReAction.ActionType = AceOO.Mixin {
+  -- ReAction.IActionType interface
+  "SetID",
+  "GetID",
+  "SetupAction",
+  "UpdateAction",
+  "PickupAction",
+  "PlaceAction",
+  "IsActionEmpty",
+  "UpdateTooltip",
+
+  -- event handlers
+  "ACTIONBAR_SLOT_CHANGED",
+  "PLAYER_ENTERING_WORLD",
+  "ACTIONBAR_SHOWGRID",
+  "ACTIONBAR_HIDEGRID",
+  "ACTIONBAR_UPDATE_STATE",
+  "ACTIONBAR_UPDATE_USABLE",
+  "UNIT_INVENTORY_CHANGED",
+  "CRAFT_SHOW",
+  "PLAYER_ENTER_COMBAT",
+  "PLAYER_LEAVE_COMBAT",
+  "START_AUTOREPEAT_SPELL",
+  "STOP_AUTOREPEAT_SPELL",
+  "OnAttributeChanged",
+  
+  -- internal functions
+  "UpdateSelfcast",
+  "UpdateIcon",
+  "UpdateInUse",
+  "UpdateCount",
+  "UpdateMacroText",
+  "UpdateUsable",
+  "UpdateCooldown",
+  "UpdateActionEvents",
+}
+
+local RAAT = ReAction.ActionType
+
+
+-- Required display elements
+RAAT.IDisplay = AceOO.Interface {
+  DisplayUsable      = "function", -- DisplayUsable(bool, notEnoughMana, outOfRange), change display to indicate action usable/unusable
+  DisplayEquipped    = "function", -- DisplayEquipped(bool)
+  DisplayAutoRepeat  = "function", -- DisplayAutoRepeat(bool)
+  DisplayInUse       = "function", -- DisplayInUse(bool)
+  DisplayIcon        = "function", -- DisplayIcon(texture), nil means empty slot
+  DisplayName        = "function", -- DisplayName(text), macro names
+  DisplayCount       = "function", -- DisplayCount(number), stack count
+  DisplayCooldown    = "function", -- DisplayCooldown(start,duration,enable)
+}
+
+
+---------------------------------------
+-- ReAction.IActionType interface implementation
+---------------------------------------
+function RAAT:SetID( id, page )
+  local f = self:GetActionFrame()
+  id = tonumber(id) -- force data integrity
+  page = tonumber(page)
+  local button = page and ("-page"..page) or "*"
+  if id then
+    f:SetAttribute("*action"..button, id)
+    if page and page > 1 and self.config.selfcast == "right-click" then
+      -- disable right-click auto-cast
+      self.config.selfcast = nil
+    end
+  elseif page then
+    f:SetAttribute("*action"..button, ATTRIBUTE_NOOP)
+  end
+  self:UpdateSelfcast()
+end
+
+function RAAT:GetID(page)
+  local f = self:GetActionFrame()
+  page = tonumber(page)
+  local button = page and ("page"..page) or SecureStateChild_GetEffectiveButton(f)
+  return SecureButton_GetModifiedAttribute(f, "action", button)
+end
+
+function RAAT:SetupAction()
+  local f = self:GetActionFrame()
+	f:SetAttribute("useparent*", true)
+  f:SetAttribute("type", "action")
+
+  self:RegisterEvent("PLAYER_ENTERING_WORLD")
+	self:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
+  self:RegisterEvent("ACTIONBAR_SHOWGRID")
+  self:RegisterEvent("ACTIONBAR_HIDEGRID")
+
+  self:UpdateSelfcast()
+
+  f:SetScript("OnAttributeChanged",  function(frame,name,value) self:OnAttributeChanged(name,value) end)
+end
+
+function RAAT:UpdateAction()
+  self:UpdateIcon()
+  self:UpdateCount()
+  self:UpdateMacroText()
+  self:UpdateUsable()
+  self:UpdateCooldown()
+  self:UpdateActionEvents()
+end
+
+function RAAT:PickupAction()
+  PickupAction(self:GetID())
+  self:UpdateAction()
+end
+
+function RAAT:PlaceAction()
+  if not InCombatLockdown() then
+    -- PlaceAction() is protected. However the user can still drop a new action
+    -- onto a button while in combat by dragging then clicking, because
+    -- UseAction() appears to swap the cursor action for the current action if
+    -- an action is on the cursor.
+    PlaceAction(self:GetID())
+  end
+  self:UpdateActionEvents()
+  self:UpdateIcon()
+end
+
+function RAAT:IsActionEmpty()
+  local slot = self:GetID()
+  return not(slot and HasAction(slot))
+end
+
+function RAAT:UpdateTooltip()
+  local action = self:GetID()
+	if action and GameTooltip:IsOwned(self:GetActionFrame()) then
+    GameTooltip:SetAction(action)
+  end
+end
+
+
+
+
+
+
+
+-----------------------------
+-- Event Handling
+-----------------------------
+function RAAT:ACTIONBAR_SLOT_CHANGED(slot)
+  if slot == 0 or slot == self:GetID() then
+    self:UpdateAction()
+  end
+end
+
+function RAAT:PLAYER_ENTERING_WORLD()
+  self:UpdateAction()
+end
+
+function RAAT:ACTIONBAR_SHOWGRID()
+  self:TempShow(true)
+end
+
+function RAAT:ACTIONBAR_HIDEGRID()
+  self:TempShow(false)
+end
+
+function RAAT:ACTIONBAR_UPDATE_STATE()
+  self:UpdateInUse()
+end
+
+function RAAT:ACTIONBAR_UPDATE_USABLE()
+  self:UpdateUsable()
+  self:UpdateCooldown()
+end
+
+function RAAT:UNIT_INVENTORY_CHANGED(unit)
+  if unit == "player" then
+    self:UpdateIcon()
+    self:UpdateCount()
+  end
+end
+
+function RAAT:CRAFT_SHOW()
+  self:UpdateInUse()
+end
+
+function RAAT:PLAYER_ENTER_COMBAT()
+  if IsAttackAction(self:GetID()) then
+    self:DisplayAutoRepeat(true)
+    self:UpdateInUse()
+  end
+end
+
+function RAAT:PLAYER_LEAVE_COMBAT()
+  if IsAttackAction(self:GetID()) then
+    self:DisplayAutoRepeat(false)
+    self:UpdateInUse()
+  end
+end
+
+function RAAT:START_AUTOREPEAT_SPELL()
+  if IsAutoRepeatAction(self:GetID()) then
+    self:DisplayAutoRepeat(true)
+  end
+end
+
+function RAAT:STOP_AUTOREPEAT_SPELL()
+  if not IsAttackAction(self:GetID()) then
+    self:DisplayAutoRepeat(false)
+    self:UpdateInUse()
+  end
+end
+
+function RAAT:OnAttributeChanged(name, value)
+  if self.config then
+    self:UpdateAction()
+    self:UpdateDisplay()
+  end
+end
+
+
+
+
+---------------------------------
+-- Internal methods
+---------------------------------
+function RAAT:UpdateSelfcast()
+  if not InCombatLockdown() then
+    local c = self.config and self.config.selfcast
+    local f = self:GetActionFrame()
+
+    f:SetAttribute("alt-unit*",nil)
+    f:SetAttribute("ctrl-unit*",nil)
+    f:SetAttribute("shift-unit*",nil)
+    f:SetAttribute("*unit2",nil)
+    if c == nil then
+      f:SetAttribute("unit",nil)
+      f:SetAttribute("checkselfcast", true)
+    else
+      f:SetAttribute("checkselfcast",ATTRIBUTE_NOOP)
+      f:SetAttribute("unit","none") -- "none" gives you the glowing cast hand if no target selected, or casts on target if target selected
+      if c == "none" then
+        -- nothing to do
+      elseif c == "alt" or c == "ctrl" or c == "shift" then
+        f:SetAttribute(c.."-unit*","player")
+      elseif c == "right-click" then
+        if f:GetAttribute("*action-page2") then
+          -- right-click modifier not supported with multipage
+          self.config.selfcast = nil
+          f:SetAttribute("unit",nil)
+          f:SetAttribute("checkselfcast",true)
+        else
+          f:SetAttribute("*unit2","player")
+        end
+      end
+    end
+  end
+end
+
+function RAAT:UpdateIcon()
+  local action = self:GetID()
+  local texture = action and GetActionTexture(action)
+
+  self:DisplayIcon(action and texture)
+  self:DisplayEquipped(action and IsEquippedAction(action))
+  self:UpdateInUse()
+  self:UpdateUsable()
+  self:UpdateCooldown()
+end
+
+function RAAT:UpdateInUse()
+  local action = self:GetID()
+	if action and (IsCurrentAction(action) or IsAutoRepeatAction(action)) then
+		self:DisplayInUse(true)
+	else
+    self:DisplayInUse(false)
+	end
+end
+
+function RAAT:UpdateCount()
+  local action = self:GetID()
+  if action and (IsConsumableAction(action) or IsStackableAction(action)) then
+    self:DisplayCount(GetActionCount(action)) -- will display a 0 if none remaining
+  else
+    self:DisplayCount(nil) -- will display nothing
+  end
+end
+
+function RAAT:UpdateMacroText()
+  local action = self:GetID()
+  self:DisplayName(action and GetActionText(action))
+end
+
+function RAAT:UpdateUsable()
+  local action = self:GetID()
+  if action and HasAction(action) then
+    local isUsable, notEnoughMana = IsUsableAction(action)
+    local outOfRange = IsActionInRange(action) == 0
+    self:DisplayUsable(isUsable and not outOfRange, notEnoughMana, outOfRange)
+  else
+    self:DisplayUsable(false, false, false)
+  end
+end
+
+function RAAT:UpdateCooldown()
+  local action = self:GetID()
+  if action then
+    self:DisplayCooldown(GetActionCooldown(action))
+  end
+end
+
+function RAAT:UpdateActionEvents()
+  local action = self:GetID()
+	if action and HasAction(action) then
+    if not self.actionEventsRegistered then
+      self:RegisterEvent("ACTIONBAR_UPDATE_STATE")
+      self:RegisterEvent("ACTIONBAR_UPDATE_USABLE")
+      self:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN", "ACTIONBAR_UPDATE_USABLE")
+      self:RegisterEvent("UPDATE_INVENTORY_ALERTS", "ACTIONBAR_UPDATE_USABLE")
+      self:RegisterEvent("PLAYER_AURAS_CHANGED", "ACTIONBAR_UPDATE_USABLE")
+      self:RegisterEvent("PLAYER_TARGET_CHANGED", "ACTIONBAR_UPDATE_USABLE")
+      self:RegisterEvent("UNIT_INVENTORY_CHANGED")
+      self:RegisterEvent("CRAFT_SHOW")
+      self:RegisterEvent("CRAFT_CLOSE", "CRAFT_SHOW")
+      self:RegisterEvent("TRADE_SKILL_SHOW", "CRAFT_SHOW")
+      self:RegisterEvent("TRADE_SKILL_CLOSE", "CRAFT_SHOW")
+      self:RegisterEvent("PLAYER_ENTER_COMBAT")
+      self:RegisterEvent("PLAYER_LEAVE_COMBAT")
+      self:RegisterEvent("START_AUTOREPEAT_SPELL")
+      self:RegisterEvent("STOP_AUTOREPEAT_SPELL")
+      self.actionEventsRegistered = true
+    end
+  elseif self.actionEventsRegistered then
+    self:UnregisterEvent("ACTIONBAR_UPDATE_STATE")
+    self:UnregisterEvent("ACTIONBAR_UPDATE_USABLE")
+    self:UnregisterEvent("ACTIONBAR_UPDATE_COOLDOWN")
+    self:UnregisterEvent("UPDATE_INVENTORY_ALERTS")
+    self:UnregisterEvent("PLAYER_AURAS_CHANGED")
+    self:UnregisterEvent("PLAYER_TARGET_CHANGED")
+    self:UnregisterEvent("UNIT_INVENTORY_CHANGED")
+    self:UnregisterEvent("CRAFT_SHOW")
+    self:UnregisterEvent("CRAFT_CLOSE")
+    self:UnregisterEvent("TRADE_SKILL_SHOW")
+    self:UnregisterEvent("TRADE_SKILL_CLOSE")
+    self:UnregisterEvent("PLAYER_ENTER_COMBAT")
+    self:UnregisterEvent("PLAYER_LEAVE_COMBAT")
+    self:UnregisterEvent("START_AUTOREPEAT_SPELL")
+    self:UnregisterEvent("STOP_AUTOREPEAT_SPELL")
+    self.actionEventsRegistered = false
+	end
+end
+