Mercurial > wow > reaction
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 +