Flick@276: local _, ns = ... Flick@276: local ReAction = ns.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 Flick@292: -- local CooldownFrame_SetTimer = CooldownFrame_SetTimer -- don't stash this API, look it up every time to support some mods that hook it, e.g. Cooldowns 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: -- 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 Flick@295: local pageIndex = (doVehicle and mcVehicleState == "vehicle") and 12 or 14 flickerstreak@145: if idx and idx <= maxN then Flick@295: action = 12*(pageIndex-1) + idx flickerstreak@122: else flickerstreak@122: action = 0 flickerstreak@122: end flickerstreak@155: elseif state and settings[state] and settings[state].page then flickerstreak@155: action = self:GetAttribute("action-"..settings[state].page) 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 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@170: if tempShow or evtShow or HasAction(action) 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@186: showgrid_event = message 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@186: -- note that HasAction is not updated on the target of a drag until after ACTIONBAR_HIDEGRID flickerstreak@186: -- so, we set a flag for this button in pre-click/receive-drag and check for it here flickerstreak@186: if HasAction(action) or self:GetAttribute("showgrid-clicked") then flickerstreak@186: if not self:IsShown() then flickerstreak@186: self:Show() flickerstreak@186: end flickerstreak@186: self:SetAttribute("showgrid-clicked",false) flickerstreak@186: else flickerstreak@186: if self:IsShown() then flickerstreak@186: self:Hide() flickerstreak@186: end 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: return "action", self:GetAttribute("action") flickerstreak@122: end flickerstreak@122: ]] flickerstreak@122: flickerstreak@122: local _onReceiveDrag = -- function(self, button, kind, value, ...) flickerstreak@122: [[ Flick@265: if kind ~= "spell" and kind ~= "item" and kind ~= "macro" and kind ~= "flyout" and kind ~= "equipmentset" and kind ~= "companion" then flickerstreak@129: return kind, value, ... flickerstreak@170: else flickerstreak@186: if showgrid_event and showgrid_event > 0 then flickerstreak@186: self:SetAttribute("showgrid-clicked",true) flickerstreak@186: end flickerstreak@170: return "action", self:GetAttribute("action") flickerstreak@122: end flickerstreak@122: ]] flickerstreak@122: flickerstreak@186: local _onClick = -- function(self, button, down) flickerstreak@186: [[ flickerstreak@186: if showgrid_event and showgrid_event > 0 then flickerstreak@186: self:SetAttribute("showgrid-clicked",true) flickerstreak@186: end flickerstreak@186: return button flickerstreak@186: ]] flickerstreak@186: flickerstreak@122: -- flickerstreak@122: -- private flickerstreak@122: -- flickerstreak@122: local eventList = { flickerstreak@122: "PLAYER_ENTERING_WORLD", flickerstreak@122: "ACTIONBAR_SLOT_CHANGED", flickerstreak@122: "UPDATE_BINDINGS", flickerstreak@122: "ACTIONBAR_UPDATE_USABLE", flickerstreak@165: "UNIT_INVENTORY_CHANGED", flickerstreak@165: "LEARNED_SPELL_IN_TAB", flickerstreak@122: "UPDATE_INVENTORY_ALERTS", flickerstreak@122: "PLAYER_TARGET_CHANGED", flickerstreak@122: "TRADE_SKILL_SHOW", flickerstreak@122: "TRADE_SKILL_CLOSE", Flick@266: "ARCHAEOLOGY_CLOSED", 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", Flick@297: "UPDATE_SHAPESHIFT_FORM", Flick@297: "SPELL_UPDATE_CHARGES", Flick@297: "UPDATE_SUMMONPETS_ACTION", flickerstreak@122: } flickerstreak@122: flickerstreak@122: -- flickerstreak@122: -- Action Button class flickerstreak@122: -- flickerstreak@218: local buttonTypeID = "Action" flickerstreak@122: local Super = ReAction.Button flickerstreak@218: local Action = setmetatable( flickerstreak@218: { flickerstreak@218: defaultBarConfig = { flickerstreak@218: type = buttonTypeID, flickerstreak@218: btnWidth = 36, flickerstreak@218: btnHeight = 36, flickerstreak@218: btnRows = 1, flickerstreak@218: btnColumns = 12, flickerstreak@220: spacing = 3, flickerstreak@220: buttons = { }, flickerstreak@218: }, flickerstreak@218: Flick@231: barType = L["Action Bar"], Flick@299: buttonTypeID = buttonTypeID, Flick@299: eventList = eventList flickerstreak@218: }, flickerstreak@218: { __index = Super } ) flickerstreak@223: flickerstreak@122: ReAction.Button.Action = Action flickerstreak@223: ReAction:RegisterBarType(Action, true) flickerstreak@122: Flick@234: function Action:New( config, bar, idx, idHint ) Flick@277: self = Super.New(self, config, bar, idx, "SecureActionButtonTemplate, ActionButtonTemplate" ) Flick@234: self.barConfig = bar:GetConfig() flickerstreak@122: flickerstreak@122: local f = self:GetFrame() flickerstreak@122: local barFrame = bar:GetFrame() 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@122: f:RegisterForDrag("LeftButton", "RightButton") flickerstreak@122: for _, evt in pairs(eventList) do flickerstreak@122: f:RegisterEvent(evt) flickerstreak@122: end flickerstreak@122: Flick@238: f.action = config.actionID -- need this to support silly ActionButton_UpdateFlyout. Should not taint anything anymore. Flick@238: 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@186: barFrame:WrapScript(f, "OnClick", _onClick) 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@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@159: if not self.vehicleInstalled then flickerstreak@159: self.vehicleInstalled = true flickerstreak@159: -- install vehicle-exit button on 7th button (only) flickerstreak@159: f:SetAttribute("_childupdate-vehicle", _childupdate_vehicleExit) flickerstreak@159: f:SetAttribute("macrotext","/run VehicleExit()") flickerstreak@159: self:GetBar():GetFrame().ShowVehicleExit = function(bar,show) flickerstreak@159: self:ShowVehicleExit(show) flickerstreak@159: end flickerstreak@124: end flickerstreak@159: -- setscale blows away tex coords flickerstreak@159: self:UpdateIcon() flickerstreak@159: elseif self.vehicleInstalled then flickerstreak@159: self.vehicleInstalled = false 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: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 Flick@297: Flick@297: -- update checked state and cooldown in C-code Flick@297: local f = self:GetFrame() Flick@297: SetActionUIButton(f, action, f.cooldown) Flick@297: flickerstreak@122: self:UpdateAll() flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@122: function Action:UpdateShowGrid() flickerstreak@170: if not InCombatLockdown() then 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@161: local texture, tLeft, tRight, tTop, tBottom = self:GetIconTexture() 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@159: icon:SetVertexColor(1,1,1) 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@161: if tLeft then flickerstreak@161: icon:SetTexCoord(tLeft,tRight,tTop,tBottom) flickerstreak@161: end flickerstreak@122: icon:Show() flickerstreak@122: self.rangeTimer = -1 flickerstreak@122: else flickerstreak@122: icon:Hide() flickerstreak@122: self.frames.cooldown:Hide() flickerstreak@122: self.rangeTimer = nil flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@161: function Action:GetIconTexture() flickerstreak@161: return GetActionTexture(self.actionID) flickerstreak@161: end flickerstreak@161: 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 Flick@297: if not IsConsumableAction(action) and Flick@297: not IsStackableAction(action) and Flick@297: (IsItemAction(action) or GetActionCount(action) == 0) 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 Flick@297: local count = GetActionCount(action) or 0 Flick@297: if IsConsumableAction(action) or IsStackableAction(action) or (not IsItemAction(action) and count > 0) then Flick@297: if count > 9999 then Flick@297: self.frames.count:SetText("*") Flick@297: else Flick@297: self.frames.count:SetText(count) Flick@297: end flickerstreak@122: else Flick@297: local charges, maxCharges, chargeStart, chargeDuration = GetActionCharges(action) Flick@297: charges = tonumber(charges) or 0 Flick@297: maxCharges = tonumber(maxCharges) or 0 Flick@297: if maxCharges > 1 then Flick@297: self.frames.count:SetText(charges) Flick@297: else Flick@297: self.frames.count:SetText("") Flick@297: end 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@165: GameTooltip:SetOwner(f,"ANCHOR_RIGHT") 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@161: local isUsable, notEnoughMana = self:GetUsable() flickerstreak@161: local noRange = self:GetInRange() flickerstreak@159: flickerstreak@159: isUsable = self.vehicleExitMode or (isUsable and not noRange) flickerstreak@159: flickerstreak@159: if isUsable then flickerstreak@159: if self.usableStatus ~= "usable" then flickerstreak@159: self.frames.icon:SetVertexColor(1.0, 1.0, 1.0) flickerstreak@159: self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0) flickerstreak@159: self.usableStatus = "usable" flickerstreak@159: end flickerstreak@159: elseif noRange then flickerstreak@159: if self.usableStatus ~= "norange" then flickerstreak@159: self.frames.icon:SetVertexColor(1.0,0.1,0.1) flickerstreak@159: self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0) flickerstreak@159: self.usableStatus = "norange" flickerstreak@159: end flickerstreak@122: elseif notEnoughMana then flickerstreak@159: if self.usableStatus ~= "oom" then flickerstreak@159: self.frames.icon:SetVertexColor(0.5, 0.5, 1.0) flickerstreak@159: self.frames.normalTexture:SetVertexColor(0.5, 0.5, 1.0) flickerstreak@159: self.usableStatus = "oom" flickerstreak@159: end flickerstreak@122: else flickerstreak@159: if self.usableStatus ~= "unusable" then flickerstreak@159: self.frames.icon:SetVertexColor(0.4, 0.4, 0.4) flickerstreak@159: self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0) flickerstreak@159: self.usableStatus = "unusable" flickerstreak@159: end flickerstreak@122: end flickerstreak@122: end flickerstreak@122: flickerstreak@161: function Action:GetUsable() flickerstreak@161: return IsUsableAction(self.actionID) flickerstreak@161: end flickerstreak@161: flickerstreak@161: function Action:GetInRange() flickerstreak@161: return IsActionInRange(self.actionID) == 0 flickerstreak@161: end flickerstreak@161: flickerstreak@161: function Action:GetCooldown() flickerstreak@161: return 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@159: self:UpdateUsable() 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: Flick@234: function Action:SetupBar( bar ) Flick@234: Super.SetupBar(self,bar) Flick@234: flickerstreak@122: local f = bar:GetFrame() Flick@234: local config = bar:GetConfig() 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) Flick@295: RegisterStateDriver(f, "mc", "[vehicleui] vehicle; [overridebar] 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: Flick@237: function Action:SetButtonLock( bar, lock, lockCombat ) 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@161: if attr ~= "statehidden" then flickerstreak@161: self:UpdateAction() flickerstreak@161: end Flick@238: local f = self:GetFrame() Flick@238: f.action = f:GetAttribute("action") -- support ActionButton_UpdateFlyout 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: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@124: function Action:TRADE_SKILL_SHOW() flickerstreak@124: self:UpdateCheckedState() flickerstreak@124: end Flick@266: Action.TRADE_SKILL_CLOSE = Action.TRADE_SKILL_SHOW Flick@266: Action.ARCHAEOLOGY_CLOSED = Action.TRADE_SKILL_SHOW 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: Flick@297: function Action:SPELL_UPDATE_CHARGES() Flick@297: self:UpdateCount() 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: Flick@297: function Action:UPDATE_SHAPESHIFT_FORM() Flick@297: self:UpdateIcon() Flick@297: end Flick@297: flickerstreak@165: function Action:UNIT_INVENTORY_CHANGED(unit) flickerstreak@165: if unit == "player" then flickerstreak@165: self:UpdateTooltip() flickerstreak@165: end flickerstreak@165: end flickerstreak@165: flickerstreak@165: function Action:LEARNED_SPELL_IN_TAB() flickerstreak@165: self:UpdateTooltip() flickerstreak@165: end Flick@297: Flick@297: function Action:UPDATE_SUMMONPETS_ACTION() Flick@297: self:UpdateIcon() Flick@297: end