Mercurial > wow > reaction
diff PetActionButton.lua @ 257:920d17851a93 stable
Merge 1.1 beta 4 to stable
author | Flick |
---|---|
date | Tue, 12 Apr 2011 16:06:31 -0700 |
parents | 65f2805957a0 |
children | c918ff9ac787 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PetActionButton.lua Tue Apr 12 16:06:31 2011 -0700 @@ -0,0 +1,324 @@ +local addonName, addonTable = ... +local ReAction = addonTable.ReAction +local L = ReAction.L +local _G = _G +local CreateFrame = CreateFrame +local format = string.format +local GetCVar = GetCVar +local InCombatLockdown = InCombatLockdown +local GetPetActionInfo = GetPetActionInfo +local GetPetActionSlotUsable = GetPetActionSlotUsable +local GetPetActionCooldown = GetPetActionCooldown +local AutoCastShine_AutoCastStart = AutoCastShine_AutoCastStart +local AutoCastShine_AutoCastStop = AutoCastShine_AutoCastStop +local SetDesaturation = SetDesaturation +local CooldownFrame_SetTimer = CooldownFrame_SetTimer +local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor + +-- +-- Secure snippets +-- These are run within the context of the bar's sandbox, as the +-- buttons themselves do not have their own sandbox. +-- +local _onDragStart = -- function(self, button, kind, value, ...) +[[ + if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then + return kind, value, ... + else + return "petaction", self:GetAttribute("action") + end +]] + +local _onReceiveDrag = -- function(self, button, kind, value, ...) +[[ + if kind then -- pet spells on the cursor return nil from GetCursorInfo(), which is very strange + return kind, value, ... + end + return "petaction", self:GetAttribute("action") +]] + +-- +-- private +-- +local eventList = { +"PLAYER_CONTROL_LOST", +"PLAYER_CONTROL_GAINED", +"PLAYER_FARSIGHT_FOCUS_CHANGED", +"UNIT_PET", +"UNIT_FLAGS", +"UNIT_AURA", +"PET_BAR_UPDATE", +"PET_BAR_UPDATE_COOLDOWN", +"PET_BAR_UPDATE_USABLE", +"UPDATE_BINDINGS", +} + +-- +-- Pet Action Button class +-- +local buttonTypeID = "PetAction" +local Super = ReAction.Button +local Pet = setmetatable( + { + defaultBarConfig = { + type = buttonTypeID, + btnWidth = 30, + btnHeight = 30, + btnRows = 1, + btnColumns = 10, + spacing = 8, + buttons = { } + }, + + barType = L["Pet Action Bar"], + buttonTypeID = buttonTypeID + }, + { __index = Super } ) + +ReAction.Button.PetAction = Pet +ReAction:RegisterBarType(Pet) + +function Pet:New( config, bar, idx, idHint ) + local name = format("ReAction_%s_PetAction_%d",bar:GetName(),idx) + + self = Super.New(self, name, config, bar, idx, "SecureActionButtonTemplate, ActionButtonTemplate" ) + + local f = self:GetFrame() + if not f.autoCastTexture then + -- store autocast stuff with the frame for recycling + local tex = f:CreateTexture(nil,"OVERLAY") + tex:SetTexture([[Interface\Buttons\UI-AutoCastableOverlay]]) + tex:SetHeight(58) + tex:SetWidth(58) + tex:SetPoint("CENTER") + f.autoCastTexture = tex + f.autoCastShine = CreateFrame("Frame",name.."Shine",f,"AutoCastShineTemplate") -- create after autocast texture so it's on top + -- move the cooldown around + local cd = self.frames.cooldown + cd:ClearAllPoints() + cd:SetWidth(33) + cd:SetHeight(33) + cd:SetPoint("CENTER", f, "CENTER", -2, -1) + -- resize to 30x30 + f:SetHeight(30) + f:SetWidth(30) + local nt = _G[name.."NormalTexture"] + nt:SetHeight(54) + nt:SetWidth(54) + end + local barFrame = bar:GetFrame() + + -- set up the base action ID + self:SetActionIDPool("pet",10) + config.actionID = self:AcquireActionID(config.actionID, idHint, true) + + -- attribute setup + -- There's no secure way to do PetAutoCastToggle by actionID, so use + -- a click-through proxy to the Blizzard pet buttons for right-click + -- Note that technically this doesn't do PetStopAttack() when + -- IsPetAttackActive() is true: however that's only true when using + -- Eyes of the Beast and appears not to really do anything (at least + -- I can't find any difference) + f:SetAttribute("type","pet") + f:SetAttribute("type2","click") + f:SetAttribute("clickbutton2",_G["PetActionButton"..config.actionID]) + f:SetAttribute("action",config.actionID) + f:SetAttribute("checkselfcast", true) + f:SetAttribute("checkfocuscast", 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("OnAttributeChanged", function(frame, attr, value) self:OnAttributeChanged(attr, value) end) + f:SetScript("PreClick", function(frame) self:PreClick() end) + f:SetScript("OnDragStart", function(frame) self:OnDragStart() end) + f:SetScript("OnReceiveDrag", function(frame) self:OnReceiveDrag() end) + + -- secure handlers + barFrame:WrapScript(f, "OnDragStart", _onDragStart) + barFrame:WrapScript(f, "OnReceiveDrag", _onReceiveDrag) + + -- event registration + f:EnableMouse(true) + f:RegisterForDrag("LeftButton", "RightButton") + f:RegisterForClicks("AnyUp") + for _, evt in pairs(eventList) do + f:RegisterEvent(evt) + end + + -- attach to skinner + bar:SkinButton(self, + { + AutoCast = f.autoCastShine, + AutoCastable = f.autoCastTexture + }) + + self:Refresh() + f:Show() + + return self +end + +function Pet:SetupBar(bar) + Super.SetupBar(self,bar) + + -- auto show/hide when pet exists + bar:RegisterUnitWatch("pet",true) + + self:UpdateButtonLock(bar) +end + +function Pet:UpdateButtonLock(bar) + local f = bar:GetFrame() + f:SetAttribute("lockbuttons",bar.config.lockButtons) + f:SetAttribute("lockbuttonscombat",bar.config.lockButtonsCombat) + f:Execute( + [[ + lockButtons = self:GetAttribute("lockbuttons") + lockButtonsCombat = self:GetAttribute("lockbuttonscombat") + ]]) +end + +function Pet:Refresh() + Super.Refresh(self) + self:Update() + self:UpdateHotkey() +end + +function Pet:GetActionID() + return self.config.actionID +end + +function Pet:SetActionID(id) + if not InCombatLockdown() then + if id < 0 or id > 10 then + ReAction:UserError(L["Pet action ID range is 1-10"]) + return + end + self.config.actionID = id + f:SetAttribute("clickbutton2",_G["PetActionButton"..id]) + f:SetAttribute("action",id) + self:Update() + self:UpdateHotkey() + end +end + +function Pet:Update() + local action = self.config.actionID + local name, subtext, texture, isToken, isActive, autoCastAllowed, autoCastEnabled = GetPetActionInfo(action) + local f = self:GetFrame() + local icon = self.frames.icon + + if isToken then + icon:SetTexture(_G[texture]) + self.tooltipName = _G[name] + else + icon:SetTexture(texture) + self.tooltipName = name + end + + self.isToken = isToken + self.tooltipSubtext = subtext + f:SetChecked( isActive and 1 or 0 ) + + if autoCastAllowed then + f.autoCastTexture:Show() + else + f.autoCastTexture:Hide() + end + + if autoCastEnabled then + AutoCastShine_AutoCastStart(f.autoCastShine) + else + AutoCastShine_AutoCastStop(f.autoCastShine) + end + + if texture then + if GetPetActionSlotUsable(action) then + SetDesaturation(icon,nil) + else + SetDesaturation(icon,1) + end + icon:Show() + f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2") + else + icon:Hide() + f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot") + end + + self:UpdateCooldown() +end + +function Pet:UpdateCooldown() + CooldownFrame_SetTimer(self.frames.cooldown, GetPetActionCooldown(self.config.actionID)) +end + +function Pet:SetTooltip() + if self.tooltipName then + local f = self:GetFrame() + local uber = GetCVar("UberTooltips") + if self.isToken or (uber == "0") then + if uber == "0" then + GameTooltip:SetOwner(f, "ANCHOR_RIGHT") + else + GameTooltip_SetDefaultAnchor(GameTooltip, f) + end + GameTooltip:SetText(self.tooltipName) + if self.tooltipSubtext then + GameTooltip:AddLine(self.tooltipSubtext, "", 0.5, 0.5, 0.5) + end + GameTooltip:Show() + else + GameTooltip_SetDefaultAnchor(GameTooltip, f) + GameTooltip:SetPetAction(self.config.actionID) + end + else + GameTooltip:Hide() + end +end + +function Pet:OnEvent(event, unit) + if event =="PET_BAR_UPDATE_COOLDOWN" then + self:UpdateCooldown() + elseif event == "UPDATE_BINDINGS" then + self:UpdateHotkey() + elseif event == "UNIT_PET" then + if unit == "player" then + self:Update() + end + elseif event == "UNIT_FLAGS" or event == "UNIT_AURA" then + if unit == "pet" then + self:Update() + end + else + self:Update() + end +end + +function Pet:OnEnter() + self:SetTooltip() +end + +function Pet:OnLeave() + GameTooltip:Hide() +end + +function Pet:OnAttributeChanged(attr,value) + self:Update() +end + +function Pet:PreClick() + self:GetFrame():SetChecked(0) +end + +function Pet:OnDragStart() + self:SetChecked(0) + self:Update() +end + +function Pet:OnReceiveDrag() + self:SetChecked(0) + self:Update() +end +