flickerstreak@122: local ReAction = ReAction flickerstreak@122: local L = ReAction.L flickerstreak@122: local _G = _G flickerstreak@122: local CreateFrame = CreateFrame flickerstreak@122: local format = string.format flickerstreak@122: local IsUsableAction = IsUsableAction flickerstreak@122: local IsEquippedAction = IsEquippedAction flickerstreak@122: local IsConsumableAction = IsConsumableAction flickerstreak@122: local IsStackableAction = IsStackableAction flickerstreak@122: local GetActionText = GetActionText flickerstreak@122: local GetCVar = GetCVar flickerstreak@122: local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor flickerstreak@122: local IsCurrentAction = IsCurrentAction flickerstreak@122: local IsAutoRepeatAction = IsAutoRepeatAction flickerstreak@122: local IsUsableAction = IsUsableAction flickerstreak@122: local IsAttackAction = IsAttackAction flickerstreak@122: local CooldownFrame_SetTimer = CooldownFrame_SetTimer flickerstreak@122: local GetActionCooldown = GetActionCooldown flickerstreak@122: local GetActionTexture = GetActionTexture flickerstreak@122: local ATTACK_BUTTON_FLASH_TIME = ATTACK_BUTTON_FLASH_TIME flickerstreak@122: local TOOLTIP_UPDATE_TIME = TOOLTIP_UPDATE_TIME flickerstreak@122: local IsActionInRange = IsActionInRange flickerstreak@122: local InCombatLockdown = InCombatLockdown flickerstreak@122: local HasAction = HasAction flickerstreak@122: flickerstreak@122: ReAction:UpdateRevision("$Revision: 154 $") flickerstreak@122: flickerstreak@122: -- flickerstreak@122: -- Secure snippets flickerstreak@122: -- These are run within the context of the bar's sandbox, as the flickerstreak@122: -- buttons themselves do not have their own sandbox. flickerstreak@122: -- flickerstreak@122: local _onstate_mc = -- function(self, stateid, newstate) flickerstreak@122: [[ flickerstreak@122: local oldMcVehicleState = mcVehicleState flickerstreak@122: mcVehicleState = newstate flickerstreak@122: control:ChildUpdate() flickerstreak@122: if oldMcVehicleState == "vehicle" or mcVehicleState == "vehicle" then flickerstreak@122: control:ChildUpdate("vehicle") flickerstreak@122: end flickerstreak@122: ]] flickerstreak@122: flickerstreak@122: local _childupdate = -- function(self, snippetid, message) flickerstreak@122: [[ flickerstreak@122: local action = nil flickerstreak@122: if (doVehicle and mcVehicleState == "vehicle") or flickerstreak@122: (doMindControl and mcVehicleState == "mc") then flickerstreak@122: local idx = self:GetAttribute("bar-idx") flickerstreak@145: local maxN = (doVehicle and mcVehicleState == "vehicle") and 7 or 12 flickerstreak@145: if idx and idx <= maxN then flickerstreak@122: action = 120 + idx flickerstreak@122: else flickerstreak@122: action = 0 flickerstreak@122: end flickerstreak@122: elseif page and state and page[state] then flickerstreak@138: action = self:GetAttribute("action-"..page[state]) flickerstreak@138: end flickerstreak@138: if action == nil then flickerstreak@122: action = self:GetAttribute("default-action") flickerstreak@122: end flickerstreak@122: flickerstreak@122: self:SetAttribute("action",action) flickerstreak@122: flickerstreak@128: if not self:GetAttribute("showgrid") then flickerstreak@128: local hasaction = (action > 120) or self:GetAttribute("hasaction-"..action) flickerstreak@128: local tempShow = self:GetAttribute("showgrid-temp") flickerstreak@128: local evtShow = self:GetAttribute("showgrid-event") flickerstreak@128: if tempShow then tempShow = (tempShow > 0) end flickerstreak@128: if evtShow then evtShow = (evtShow > 0) end flickerstreak@128: flickerstreak@128: if tempShow or evtShow or hasaction then flickerstreak@128: self:Show() flickerstreak@128: else flickerstreak@128: self:Hide() flickerstreak@128: end flickerstreak@122: end flickerstreak@122: ]] flickerstreak@122: flickerstreak@122: local _childupdate_vehicleExit = -- function(self, snippetid, message) flickerstreak@122: [[ flickerstreak@122: local show = (mcVehicleState == "vehicle") flickerstreak@124: if show and doVehicle then flickerstreak@122: self:SetAttribute("type","macro") flickerstreak@122: self:Show() flickerstreak@122: else flickerstreak@122: self:SetAttribute("type","action") flickerstreak@122: end flickerstreak@122: control:CallMethod("ShowVehicleExit",show) flickerstreak@122: ]] flickerstreak@122: flickerstreak@122: local _childupdate_showgrid = -- function(self, snippetid, message) flickerstreak@122: [[ flickerstreak@128: self:SetAttribute("showgrid-event",message) flickerstreak@128: if not self:GetAttribute("showgrid") then flickerstreak@128: local count = message + (self:GetAttribute("showgrid-temp") or 0) flickerstreak@128: if count <= 0 then flickerstreak@128: local action = self:GetAttribute("action") flickerstreak@128: local hasaction = (action > 120) or self:GetAttribute("hasaction-"..action) flickerstreak@128: if hasaction then flickerstreak@128: self:Show() flickerstreak@128: else flickerstreak@128: self:Hide() flickerstreak@128: end flickerstreak@128: else flickerstreak@122: self:Show() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: ]] flickerstreak@122: flickerstreak@122: local _onDragStart = -- function(self, button, kind, value, ...) flickerstreak@122: [[ flickerstreak@122: if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then flickerstreak@122: return kind, value, ... flickerstreak@122: else flickerstreak@122: -- don't make any assumptions about hiding on grid show here, as we don't know if the flickerstreak@122: -- drag gets cancelled later. flickerstreak@122: return "action", self:GetAttribute("action") flickerstreak@122: end flickerstreak@122: ]] flickerstreak@122: flickerstreak@122: local _onReceiveDrag = -- function(self, button, kind, value, ...) flickerstreak@122: [[ flickerstreak@129: if kind ~= "spell" and kind ~= "item" and kind ~= "macro" then flickerstreak@129: return kind, value, ... flickerstreak@122: end flickerstreak@129: self:SetAttribute("hasaction-"..self:GetAttribute("action"),true) flickerstreak@128: return "action", self:GetAttribute("action") flickerstreak@122: ]] flickerstreak@122: flickerstreak@122: -- flickerstreak@122: -- private flickerstreak@122: -- flickerstreak@122: local eventList = { flickerstreak@122: "PLAYER_REGEN_ENABLED", flickerstreak@122: "PLAYER_ENTERING_WORLD", flickerstreak@122: "ACTIONBAR_PAGE_CHANGED", flickerstreak@122: "ACTIONBAR_SLOT_CHANGED", flickerstreak@122: "UPDATE_BINDINGS", flickerstreak@122: "ACTIONBAR_UPDATE_STATE", flickerstreak@122: "ACTIONBAR_UPDATE_USABLE", flickerstreak@122: "ACTIONBAR_UPDATE_COOLDOWN", flickerstreak@122: "UPDATE_INVENTORY_ALERTS", flickerstreak@122: "PLAYER_TARGET_CHANGED", flickerstreak@122: "TRADE_SKILL_SHOW", flickerstreak@122: "TRADE_SKILL_CLOSE", flickerstreak@122: "PLAYER_ENTER_COMBAT", flickerstreak@122: "PLAYER_LEAVE_COMBAT", flickerstreak@122: "START_AUTOREPEAT_SPELL", flickerstreak@122: "STOP_AUTOREPEAT_SPELL", flickerstreak@122: "UNIT_ENTERED_VEHICLE", flickerstreak@122: "UNIT_EXITED_VEHICLE", flickerstreak@122: "COMPANION_UPDATE", flickerstreak@122: } flickerstreak@122: flickerstreak@122: -- flickerstreak@122: -- Action Button class flickerstreak@122: -- flickerstreak@122: local Super = ReAction.Button flickerstreak@122: local Action = setmetatable( { }, { __index = Super } ) flickerstreak@122: ReAction.Button.Action = Action flickerstreak@122: flickerstreak@128: function Action:New( idx, barConfig, bar, idHint ) flickerstreak@123: local name = format("ReAction_%s_Action_%d",bar:GetName(),idx) flickerstreak@123: flickerstreak@129: self = Super.New(self, name, barConfig.buttons[idx], bar, idx, "SecureActionButtonTemplate, ActionButtonTemplate" ) flickerstreak@129: self.barConfig = barConfig flickerstreak@122: flickerstreak@122: local f = self:GetFrame() flickerstreak@122: local barFrame = bar:GetFrame() flickerstreak@128: local config = self:GetConfig() flickerstreak@122: flickerstreak@122: self.rangeTimer = TOOLTIP_UPDATE_TIME flickerstreak@122: flickerstreak@122: -- set up the base action ID flickerstreak@122: self:SetActionIDPool("action",120) flickerstreak@122: config.actionID = self:AcquireActionID(config.actionID, idHint) flickerstreak@122: self.nPages = 1 flickerstreak@122: flickerstreak@122: -- attribute setup flickerstreak@122: f:SetAttribute("type","action") flickerstreak@122: f:SetAttribute("checkselfcast", true) flickerstreak@122: f:SetAttribute("checkfocuscast", true) flickerstreak@122: f:SetAttribute("action", config.actionID) flickerstreak@122: f:SetAttribute("default-action", config.actionID) flickerstreak@128: f:SetAttribute("bar-idx",idx) flickerstreak@122: f:SetAttribute("showgrid-temp",0) flickerstreak@128: f:SetAttribute("showgrid-event",0) flickerstreak@128: f:SetAttribute("showgrid",not self:GetBarConfig().hideEmpty) flickerstreak@128: flickerstreak@122: -- non secure scripts flickerstreak@122: f:SetScript("OnEvent", function(frame, ...) self:OnEvent(...) end) flickerstreak@122: f:SetScript("OnEnter", function(frame) self:OnEnter() end) flickerstreak@122: f:SetScript("OnLeave", function(frame) self:OnLeave() end) flickerstreak@122: f:SetScript("OnAttributeChanged", function(frame, attr, value) self:OnAttributeChanged(attr, value) end) flickerstreak@122: f:SetScript("PostClick", function(frame, ...) self:PostClick(...) end) flickerstreak@122: f:SetScript("OnUpdate", function(frame, elapsed) self:OnUpdate(elapsed) end) flickerstreak@122: f:SetScript("OnDragStart", function(frame) self:OnDragStart() end) flickerstreak@123: f:SetScript("OnReceiveDrag", function(frame) self:OnReceiveDrag() end) flickerstreak@122: flickerstreak@122: -- event registration flickerstreak@124: f:EnableMouse(true) flickerstreak@122: f:RegisterForDrag("LeftButton", "RightButton") flickerstreak@122: f:RegisterForClicks("AnyUp") flickerstreak@122: for _, evt in pairs(eventList) do flickerstreak@122: f:RegisterEvent(evt) flickerstreak@122: end flickerstreak@122: flickerstreak@138: -- secure handlers flickerstreak@138: f:SetAttribute("_childupdate", _childupdate) flickerstreak@138: f:SetAttribute("_childupdate-showgrid",_childupdate_showgrid) flickerstreak@138: barFrame:WrapScript(f, "OnDragStart", _onDragStart) flickerstreak@138: barFrame:WrapScript(f, "OnReceiveDrag", _onReceiveDrag) flickerstreak@123: flickerstreak@140: -- attach to skinner flickerstreak@140: bar:SkinButton(self) flickerstreak@140: flickerstreak@140: -- initial display flickerstreak@140: if ReAction:GetConfigMode() then flickerstreak@140: self:ShowGridTemp(true) flickerstreak@140: end flickerstreak@140: flickerstreak@140: self:Refresh() flickerstreak@140: flickerstreak@123: return self flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:Destroy() flickerstreak@122: local f = self:GetFrame() flickerstreak@128: local c = self:GetConfig() flickerstreak@122: flickerstreak@132: f:SetAttribute("_childupdate-vehicle",nil) flickerstreak@145: f:SetAttribute("action",c.actionID) -- so that Super.Destroy releases the right one flickerstreak@122: flickerstreak@139: if c.pageactions and #c.pageactions > 1 then flickerstreak@139: for i = 2, #c.pageactions do flickerstreak@132: self:ReleaseActionID(c.pageactions[i]) flickerstreak@122: self:ReleaseActionID(id) flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@128: Super.Destroy(self) flickerstreak@122: end flickerstreak@122: flickerstreak@129: function Action:GetBarConfig() flickerstreak@129: -- this is the per-bar Action module config structure, flickerstreak@129: -- not the config structure of the bar itself flickerstreak@129: return self.barConfig flickerstreak@129: end flickerstreak@129: flickerstreak@122: function Action:Refresh() flickerstreak@129: Super.Refresh(self) flickerstreak@138: self:RefreshHasActionAttributes() flickerstreak@122: self:RefreshPages() flickerstreak@124: self:InstallVehicle() flickerstreak@128: self:ShowGrid(not self:GetBarConfig().hideEmpty) flickerstreak@122: self:UpdateAction() flickerstreak@122: end flickerstreak@122: flickerstreak@124: function Action:InstallVehicle() flickerstreak@145: local f = self:GetFrame() flickerstreak@128: if self.idx == 7 and self:GetBarConfig().vehicle then flickerstreak@124: -- install vehicle-exit button on 7th button (only) flickerstreak@145: f:SetAttribute("_childupdate-vehicle", _childupdate_vehicleExit) flickerstreak@145: f:SetAttribute("macrotext","/run VehicleExit()") flickerstreak@128: self:GetBar():GetFrame().ShowVehicleExit = function(bar,show) flickerstreak@124: self:ShowVehicleExit(show) flickerstreak@124: end flickerstreak@124: else flickerstreak@145: f:SetAttribute("_childupdate-vehicle",nil) flickerstreak@145: f:SetAttribute("macrotext",nil) flickerstreak@128: end flickerstreak@128: end flickerstreak@128: flickerstreak@128: function Action:ShowGrid( show ) flickerstreak@128: if not InCombatLockdown() then flickerstreak@128: self.frame:SetAttribute("showgrid", show) flickerstreak@128: self:UpdateShowGrid() flickerstreak@128: end flickerstreak@128: end flickerstreak@128: flickerstreak@128: function Action:ShowGridTemp( show ) flickerstreak@128: -- This function only modifies the show-grid when out flickerstreak@128: -- of combat, and is ignored by the secure handler. Use flickerstreak@128: -- it for configuration modes. flickerstreak@128: if not InCombatLockdown() then flickerstreak@128: local count = self.showGridTempCount or 0 flickerstreak@128: if show then flickerstreak@128: count = count + 1 flickerstreak@128: else flickerstreak@128: count = count - 1 flickerstreak@128: end flickerstreak@128: if count < 0 then count = 0 end flickerstreak@128: self.showGridTempCount = count flickerstreak@128: self:GetFrame():SetAttribute("showgrid-temp",count) flickerstreak@128: self:UpdateShowGrid() flickerstreak@124: end flickerstreak@124: end flickerstreak@124: flickerstreak@122: function Action:UpdateAll() flickerstreak@122: self:UpdateActionIDLabel(ReAction:GetConfigMode()) flickerstreak@122: self:UpdateHotkey() flickerstreak@122: self:UpdateShowGrid() flickerstreak@122: self:UpdateIcon() flickerstreak@122: self:UpdateBorder() flickerstreak@122: self:UpdateMacroText() flickerstreak@122: self:UpdateCount() flickerstreak@122: self:UpdateTooltip() flickerstreak@122: self:UpdateCheckedState() flickerstreak@122: self:UpdateUsable() flickerstreak@122: self:UpdateCooldown() flickerstreak@122: self:UpdateFlash() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateAction() flickerstreak@122: local action = self:GetActionID() flickerstreak@122: if action ~= self.actionID then flickerstreak@122: self.actionID = action flickerstreak@122: self:UpdateAll() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@128: function Action:RefreshHasActionAttributes() flickerstreak@128: -- check if each action has an action or not, and flag an attribute flickerstreak@128: -- so that the showgrid secure handler can make decisions accordingly flickerstreak@128: local f = self:GetFrame() flickerstreak@128: local attr = "hasaction-"..self.config.actionID flickerstreak@128: local hasAction = HasAction(self.config.actionID) flickerstreak@128: if f:GetAttribute(attr) ~= hasAction then flickerstreak@128: f:SetAttribute(attr,hasAction) -- avoid setting attribute and triggering script handler unnecessarily flickerstreak@128: end flickerstreak@128: if self.config.pageactions then flickerstreak@128: for i = 1, self.nPages do flickerstreak@128: attr = "hasaction-"..self.config.pageactions[i] flickerstreak@128: hasAction = HasAction(self.config.pageactions[i]) flickerstreak@128: if f:GetAttribute(attr) ~= hasAction then flickerstreak@128: f:SetAttribute(attr,hasAction) flickerstreak@128: end flickerstreak@128: end flickerstreak@128: end flickerstreak@128: end flickerstreak@128: flickerstreak@122: function Action:UpdateShowGrid() flickerstreak@122: -- this is a little bit complicated because there's no flickerstreak@128: -- secure access to HasAction. flickerstreak@122: if InCombatLockdown() then flickerstreak@122: self.showgridPending = true -- handle after combat flickerstreak@122: else flickerstreak@122: self.showgridPending = false flickerstreak@128: self:RefreshHasActionAttributes() flickerstreak@128: flickerstreak@122: -- the following is an out-of-combat show/hide to supplement the secure flickerstreak@122: -- handling and clean up after it when it guesses flickerstreak@128: local f = self:GetFrame() flickerstreak@128: local count = (f:GetAttribute("showgrid-event") or 0) + flickerstreak@128: (self.showGridTempCount or 0) + flickerstreak@128: (f:GetAttribute("showgrid") and 1 or 0) flickerstreak@128: flickerstreak@128: if count <= 0 and not HasAction(self.actionID) then flickerstreak@128: if f:IsShown() then flickerstreak@128: f:Hide() flickerstreak@128: end flickerstreak@128: elseif not f:IsShown() then flickerstreak@122: f:Show() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateIcon() flickerstreak@122: local action = self.actionID flickerstreak@122: local texture = GetActionTexture(action) flickerstreak@122: local icon = self.frames.icon flickerstreak@122: local hotkey = self.frames.hotkey flickerstreak@122: local f = self:GetFrame() flickerstreak@145: flickerstreak@145: if self.vehicleExitMode then flickerstreak@145: texture = "Interface\\Vehicles\\UI-Vehicles-Button-Exit-Up" flickerstreak@145: icon:SetTexCoord(0.140625, 0.859375, 0.140625, 0.859375) flickerstreak@145: icon:SetVertexColor(1,0,0) flickerstreak@145: else flickerstreak@145: icon:SetTexCoord(0,1,0,1) flickerstreak@145: end flickerstreak@145: flickerstreak@122: if texture then flickerstreak@122: icon:SetTexture(texture) flickerstreak@122: icon:Show() flickerstreak@122: self.rangeTimer = -1 flickerstreak@122: f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2") flickerstreak@122: else flickerstreak@122: icon:Hide() flickerstreak@122: self.frames.cooldown:Hide() flickerstreak@122: self.rangeTimer = nil flickerstreak@145: if self.vehicleExitMode then flickerstreak@145: f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2") flickerstreak@145: else flickerstreak@145: f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot") flickerstreak@145: end flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateBorder() flickerstreak@122: local action = self.actionID flickerstreak@122: if ReAction:GetKeybindMode() then flickerstreak@122: self:UpdateKeybindModeDisplay(true) flickerstreak@122: elseif IsEquippedAction(action) then flickerstreak@122: self.frames.border:SetVertexColor(0, 1.0, 0, 0.35) flickerstreak@122: self.frames.border:Show() flickerstreak@122: else flickerstreak@122: self.frames.border:Hide() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateMacroText() flickerstreak@122: local action = self.actionID flickerstreak@122: if not IsConsumableAction(action) and not IsStackableAction(action) then flickerstreak@122: self.frames.name:SetText(GetActionText(action)) flickerstreak@122: else flickerstreak@122: self.frames.name:SetText("") flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateCount() flickerstreak@122: local action = self.actionID flickerstreak@122: if IsConsumableAction(action) or IsStackableAction(action) then flickerstreak@122: self.frames.count:SetText(GetActionCount(action)) flickerstreak@122: else flickerstreak@122: self.frames.count:SetText("") flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateTooltip() flickerstreak@122: local f = self:GetFrame() flickerstreak@122: if GameTooltip:GetOwner() == f then flickerstreak@122: self:SetTooltip() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:SetTooltip() flickerstreak@122: local f = self:GetFrame() flickerstreak@122: if GetCVar("UberTooltips") == "1" then flickerstreak@122: GameTooltip_SetDefaultAnchor(GameTooltip, f) flickerstreak@122: else flickerstreak@122: GameTooltip:SetOwner(f) flickerstreak@122: end flickerstreak@122: GameTooltip:SetAction(self.actionID) flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateCheckedState() flickerstreak@122: local action = self.actionID flickerstreak@122: if IsCurrentAction(action) or IsAutoRepeatAction(action) then flickerstreak@122: self:GetFrame():SetChecked(1) flickerstreak@122: else flickerstreak@122: self:GetFrame():SetChecked(0) flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateUsable() flickerstreak@122: local isUsable, notEnoughMana = IsUsableAction(self.actionID) flickerstreak@145: if isUsable or self.vehicleExitMode then flickerstreak@122: self.frames.icon:SetVertexColor(1.0, 1.0, 1.0) flickerstreak@122: self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0) flickerstreak@122: elseif notEnoughMana then flickerstreak@122: self.frames.icon:SetVertexColor(0.5, 0.5, 1.0) flickerstreak@122: self.frames.normalTexture:SetVertexColor(0.5, 0.5, 1.0) flickerstreak@122: else flickerstreak@122: self.frames.icon:SetVertexColor(0.4, 0.4, 0.4) flickerstreak@122: self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0) flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateCooldown() flickerstreak@122: CooldownFrame_SetTimer(self.frames.cooldown, GetActionCooldown(self.actionID)) flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateFlash() flickerstreak@122: local action = self.actionID flickerstreak@122: self:SetFlash( (IsAttackAction(action) and IsCurrentAction(action)) or IsAutoRepeatAction(action) ) flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:SetFlash(flash) flickerstreak@122: if self.flashing ~= flash then flickerstreak@122: self.flashing = flash flickerstreak@122: self.flashtime = 0 flickerstreak@122: if not flash then flickerstreak@122: self.frames.flash:Hide() flickerstreak@122: end flickerstreak@122: self:UpdateCheckedState() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:RunFlash(elapsed) flickerstreak@122: if self.flashing then flickerstreak@122: local flashtime = self.flashtime - elapsed flickerstreak@122: self.flashtime = flashtime flickerstreak@122: if flashtime <= 0 then flickerstreak@122: local overtime = -flashtime flickerstreak@122: if overtime >= ATTACK_BUTTON_FLASH_TIME then flickerstreak@122: overtime = 0 flickerstreak@122: end flickerstreak@122: flashtime = ATTACK_BUTTON_FLASH_TIME - overtime flickerstreak@122: local flash = self.frames.flash flickerstreak@122: if flash:IsShown() then flickerstreak@122: flash:Hide() flickerstreak@122: else flickerstreak@122: flash:Show() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:RunRangeFinder(elapsed) flickerstreak@122: local rangeTimer = self.rangeTimer flickerstreak@122: if rangeTimer then flickerstreak@122: rangeTimer = rangeTimer - elapsed flickerstreak@122: self.rangeTimer = rangeTimer flickerstreak@122: if rangeTimer <= 0 then flickerstreak@145: if self.vehicleExitMode then flickerstreak@145: self.frames.icon:SetVertexColor(1,1,1) flickerstreak@145: elseif IsActionInRange(self.actionID) == 0 then flickerstreak@122: self.frames.icon:SetVertexColor(1.0,0.1,0.1) flickerstreak@122: else flickerstreak@122: self:UpdateUsable() flickerstreak@122: end flickerstreak@123: self.rangeTimer = TOOLTIP_UPDATE_TIME flickerstreak@122: end flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:GetActionID(page) flickerstreak@122: if page == nil then flickerstreak@122: -- get the effective ID flickerstreak@122: return self:GetFrame():GetAttribute("action") flickerstreak@122: else flickerstreak@122: if page == 1 then flickerstreak@122: return self.config.actionID flickerstreak@122: else flickerstreak@122: return self.config.pageactions and self.config.pageactions[page] or self.config.actionID flickerstreak@122: end flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:SetActionID( id, page ) flickerstreak@122: id = tonumber(id) flickerstreak@122: page = tonumber(page) flickerstreak@122: if id == nil or id < 1 or id > 120 then flickerstreak@129: ReAction:UserError(L["Action ID range is 1-120"]) flickerstreak@129: return flickerstreak@122: end flickerstreak@122: if page and page ~= 1 then flickerstreak@122: if not self.config.pageactions then flickerstreak@122: self.config.pageactions = { } flickerstreak@122: end flickerstreak@122: self:ReleaseActionID(self.config.pageactions[page]) flickerstreak@122: self.config.pageactions[page] = id flickerstreak@122: self:AcquireActionID(self.config.pageactions[page]) flickerstreak@122: self.frame:SetAttribute("action-page"..page,id) flickerstreak@122: else flickerstreak@122: self:ReleaseActionID(self.config.actionID) flickerstreak@122: self.config.actionID = id flickerstreak@122: self:AcquireActionID(self.config.actionID) flickerstreak@122: self.frame:SetAttribute("action",id) flickerstreak@122: self.frame:SetAttribute("default-action",id) flickerstreak@122: if self.config.pageactions then flickerstreak@122: self.config.pageactions[1] = id flickerstreak@122: self.frame:SetAttribute("action-page1",id) flickerstreak@122: end flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:RefreshPages( force ) flickerstreak@128: local nPages = self:GetBarConfig().nPages flickerstreak@122: if nPages and (nPages ~= self.nPages or force) then flickerstreak@122: local f = self:GetFrame() flickerstreak@122: local c = self.config.pageactions flickerstreak@122: if nPages > 1 and not c then flickerstreak@122: c = { } flickerstreak@122: self.config.pageactions = c flickerstreak@122: end flickerstreak@122: for i = 1, nPages do flickerstreak@122: if i > 1 then flickerstreak@122: c[i] = self:AcquireActionID(c[i], self.config.actionID + (i-1)*self.bar:GetNumButtons()) flickerstreak@122: else flickerstreak@122: c[i] = self.config.actionID -- page 1 is the same as the base actionID flickerstreak@122: end flickerstreak@129: f:SetAttribute("action-page"..i,c[i]) flickerstreak@122: end flickerstreak@122: for i = nPages+1, #c do flickerstreak@122: self:ReleaseActionID(c[i]) flickerstreak@122: c[i] = nil flickerstreak@129: f:SetAttribute("action-page"..i,nil) flickerstreak@122: end flickerstreak@122: self.nPages = nPages flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@128: function Action.SetupBarHeader( bar, config ) -- call this as a static method flickerstreak@122: local f = bar:GetFrame() flickerstreak@128: f:SetAttribute("mindcontrol",config.mindcontrol) flickerstreak@128: f:SetAttribute("vehicle",config.vehicle) flickerstreak@122: f:Execute( flickerstreak@122: [[ flickerstreak@122: doMindControl = self:GetAttribute("mindcontrol") flickerstreak@122: doVehicle = self:GetAttribute("vehicle") flickerstreak@122: control:ChildUpdate() flickerstreak@122: ]]) flickerstreak@122: flickerstreak@122: f:SetAttribute("_onstate-mc", _onstate_mc) flickerstreak@145: RegisterStateDriver(f, "mc", "[target=vehicle,exists,bonusbar:5] vehicle; [bonusbar:5] mc; none") flickerstreak@122: flickerstreak@128: f:SetAttribute("lockbuttons",config.lockButtons) flickerstreak@128: f:SetAttribute("lockbuttonscombat",config.lockButtonsCombat) flickerstreak@122: f:Execute( flickerstreak@122: [[ flickerstreak@122: lockButtons = self:GetAttribute("lockbuttons") flickerstreak@122: lockButtonsCombat = self:GetAttribute("lockbuttonscombat") flickerstreak@122: ]]) flickerstreak@122: end flickerstreak@122: flickerstreak@122: flickerstreak@123: function Action.SetButtonLock( bar, lock, lockCombat ) -- call this as a static method flickerstreak@123: local f = bar:GetFrame() flickerstreak@123: f:SetAttribute("lockbuttons",lock) flickerstreak@123: f:SetAttribute("lockbuttonscombat",lockCombat) flickerstreak@123: f:Execute( flickerstreak@123: [[ flickerstreak@123: lockButtons = self:GetAttribute("lockbuttons") flickerstreak@123: lockButtonsCombat = self:GetAttribute("lockbuttonscombat") flickerstreak@123: ]]) flickerstreak@123: end flickerstreak@123: flickerstreak@123: flickerstreak@122: function Action:ShowVehicleExit(show) flickerstreak@145: self.vehicleExitMode = show and self:GetBarConfig().vehicle flickerstreak@145: self:UpdateIcon() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:OnEnter( ) flickerstreak@122: self:SetTooltip() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:OnLeave( ) flickerstreak@122: GameTooltip:Hide() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:OnAttributeChanged( attr, value ) flickerstreak@122: self:UpdateAction() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:PostClick( ) flickerstreak@122: self:UpdateCheckedState() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:OnUpdate( elapsed ) flickerstreak@122: self:RunFlash(elapsed) flickerstreak@122: self:RunRangeFinder(elapsed) flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:OnDragStart() flickerstreak@122: self:UpdateCheckedState() flickerstreak@122: self:UpdateFlash() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:OnReceiveDrag() flickerstreak@122: self:UpdateCheckedState() flickerstreak@122: self:UpdateFlash() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:OnEvent(event, ...) flickerstreak@122: if self[event] then flickerstreak@122: self[event](self, event, ...) flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:ACTIONBAR_SLOT_CHANGED(event, action) flickerstreak@122: if action == 0 or action == self.actionID then flickerstreak@128: self:UpdateAll() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:PLAYER_ENTERING_WORLD() flickerstreak@122: self:UpdateAction() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:ACTIONBAR_PAGE_CHANGED() flickerstreak@122: self:UpdateAction() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UPDATE_BONUS_ACTIONBAR() flickerstreak@122: self:UpdateAction() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UPDATE_BINDINGS() flickerstreak@122: self:UpdateHotkey() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:PLAYER_TARGET_CHANGED() flickerstreak@122: self.rangeTimer = -1 flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:ACTIONBAR_UPDATE_STATE() flickerstreak@122: self:UpdateCheckedState() flickerstreak@122: end flickerstreak@124: flickerstreak@124: function Action:TRADE_SKILL_SHOW() flickerstreak@124: self:UpdateCheckedState() flickerstreak@124: end flickerstreak@124: Action.TRADE_SKILL_CLOSE = Action.TRADE_SKILL_CLOSE flickerstreak@122: flickerstreak@122: function Action:UNIT_ENTERED_VEHICLE(event,unit) flickerstreak@122: if unit == "player" then flickerstreak@122: self:UpdateCheckedState() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: Action.UNIT_EXITED_VEHICLE = Action.UNIT_ENTERED_VEHICLE flickerstreak@122: flickerstreak@122: function Action:COMPANION_UPDATE(event,unit) flickerstreak@122: if unit == "mount" then flickerstreak@122: self:UpdateCheckedState() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:ACTIONBAR_UPDATE_USABLE() flickerstreak@122: self:UpdateUsable() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:ACTIONBAR_UPDATE_COOLDOWN() flickerstreak@122: self:UpdateCooldown() flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:PLAYER_ENTER_COMBAT() flickerstreak@122: if IsAttackAction(self.actionID) then flickerstreak@122: self:SetFlash(true) flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:PLAYER_LEAVE_COMBAT() flickerstreak@122: if IsAttackAction(self.actionID) then flickerstreak@122: self:SetFlash(false) flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:START_AUTOREPEAT_SPELL() flickerstreak@122: if IsAutoRepeatAction(self.actionID) then flickerstreak@122: self:SetFlash(true) flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:STOP_AUTOREPEAT_SPELL() flickerstreak@122: if not IsAttackAction(self.actionID) then flickerstreak@122: self:SetFlash(false) flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:PLAYER_REGEN_ENABLED() flickerstreak@122: if self.showgridPending then flickerstreak@122: self:UpdateShowGrid() flickerstreak@122: end flickerstreak@122: end