flickerstreak@1: -- private constants flickerstreak@2: local namePrefix = "ReActionButton" flickerstreak@1: local _G = getfenv(0) flickerstreak@1: local ACTION_FREE = { } flickerstreak@1: local MAX_ACTIONS = 120 flickerstreak@1: flickerstreak@1: local hotKeyDefaultColor = { r=1.0, g=1.0, b=1.0, a=1.0 } flickerstreak@1: local hotKeyDisabledColor = { r=0.6, g=0.6, b=0.6, a=1.0 } flickerstreak@1: local hotKeyOutOfRangeColor = { r=1.0, g=0.2, b=0.2, a=1.0 } flickerstreak@1: flickerstreak@1: local hotKeyModifierColors = { flickerstreak@1: S = { r=0.6, g=0.6, b=1.0, a=1.0 }, -- shift flickerstreak@1: C = { r=1.0, g=0.82, b=0, a=1.0 }, -- ctrl flickerstreak@1: A = { r=0.1, g=1.0, b=0.1, a=1.0 }, -- alt flickerstreak@1: } flickerstreak@1: flickerstreak@2: -- TODO: localize these key names with GetBindingText(KEY_) flickerstreak@2: local keybindAbbreviations = { flickerstreak@2: ["Mouse Button "] = "M-", flickerstreak@2: ["Spacebar"] = "Sp", flickerstreak@2: ["Num Pad "] = "Num-", flickerstreak@2: ["Page Up"] = "PgUp", flickerstreak@2: ["Page Down"] = "PgDn", flickerstreak@2: [" Arrow"] = "", flickerstreak@2: } flickerstreak@2: flickerstreak@1: local equippedActionBorderColor = { r=0, g=1.0, b=0, a=0.35 } flickerstreak@1: flickerstreak@1: local actionUsableColor = { r=1.0, g=1.0, b=1.0, a=1.0 } flickerstreak@1: local actionNotUsableColor = { r=0.4, g=0.4, b=0.4, a=1.0 } flickerstreak@1: local actionNotEnoughManaColor = { r=0.2, g=0.2, b=0.7, a=1.0 } flickerstreak@1: local actionOutOfRangeColor = { r=1.0, g=0.2, b=0.2, a=1.0 } flickerstreak@1: flickerstreak@1: -- private variables flickerstreak@1: local kbValidate = AceLibrary("AceConsole-2.0").keybindingValidateFunc flickerstreak@1: local actionButtonTbl = { } flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: -- ReActionButton is a class prototype object. flickerstreak@1: ReActionButton = AceLibrary("AceOO-2.0").Class("AceEvent-2.0") flickerstreak@1: flickerstreak@1: ------------------- flickerstreak@1: -- Class methods flickerstreak@1: ------------------- flickerstreak@1: flickerstreak@1: -- In addition to supporting the 'new' creation method (in which case an action ID must be specified directly), flickerstreak@1: -- ReActionButton supports the 'acquire'/'release' creation method, which recycles objects and manages actionID assignment. flickerstreak@1: flickerstreak@1: function ReActionButton:acquire(parent, config, barIdx) flickerstreak@1: local id = nil flickerstreak@1: for i = 1, MAX_ACTIONS do flickerstreak@1: if actionButtonTbl[i] == nil or actionButtonTbl[i].inUse == false then flickerstreak@1: id = i flickerstreak@1: break flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: if id == nil then return nil end -- all buttons and action ids are in use flickerstreak@1: flickerstreak@1: local hint = config.actionIDs[barIdx] flickerstreak@1: if hint and (actionButtonTbl[hint] == nil or actionButtonTbl[hint].inUse == false) then flickerstreak@1: id = hint flickerstreak@1: end flickerstreak@1: flickerstreak@1: if actionButtonTbl[id] == nil then flickerstreak@1: actionButtonTbl[id] = { } flickerstreak@1: end flickerstreak@1: local t = actionButtonTbl[id] flickerstreak@1: flickerstreak@1: t.inUse = true flickerstreak@1: if t.button then flickerstreak@2: t.button:Configure(parent,config,barIdx) flickerstreak@1: else flickerstreak@1: t.button = self:new(parent,config,barIdx,id) flickerstreak@1: end flickerstreak@1: flickerstreak@2: -- fix screwy config with overlapping IDs flickerstreak@2: config.actionIDs[barIdx] = id flickerstreak@1: return t.button flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton:release( b ) flickerstreak@1: if b then flickerstreak@1: actionButtonTbl[b:GetActionID()].inUse = false flickerstreak@1: b:Recycle() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: function ReActionButton:ShowAllActionIDs() flickerstreak@1: for _, b in ipairs(actionButtonTbl) do flickerstreak@1: b:ShowActionID() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton:HideAllActionIDs() flickerstreak@1: for _, b in ipairs(actionButtonTbl) do flickerstreak@1: b:HideActionID() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: ---------------------- flickerstreak@1: -- Instance methods flickerstreak@1: ---------------------- flickerstreak@1: function ReActionButton.prototype:init( parentFrame, config, barIdx, id ) flickerstreak@1: ReActionButton.super.prototype.init(self) flickerstreak@1: flickerstreak@1: -- create the button widget flickerstreak@2: self.name = namePrefix..id flickerstreak@1: self.button = CreateFrame("CheckButton", self.name, parentFrame, "ReActionButtonTemplate") flickerstreak@1: flickerstreak@1: -- store references to the various sub-frames so we don't have to look it up all the time flickerstreak@1: self.frames = { flickerstreak@1: hotkey = _G[self.name.."HotKey"], flickerstreak@1: count = _G[self.name.."Count"], flickerstreak@1: cooldown = _G[self.name.."Cooldown"], flickerstreak@1: -- nCooldown = _G[self.name.."CooldownNumeric"], flickerstreak@1: macro = _G[self.name.."Name"], flickerstreak@1: icon = _G[self.name.."Icon"], flickerstreak@1: border = _G[self.name.."Border"], flickerstreak@1: normalTexture = _G[self.name.."NormalTexture"], flickerstreak@1: flash = _G[self.name.."Flash"], flickerstreak@2: actionID = _G[self.name.."ActionID"], flickerstreak@1: } flickerstreak@1: flickerstreak@1: -- provide a reference back to this object for the frame to use in event handlers flickerstreak@1: self.button.rxnBtn = self flickerstreak@1: flickerstreak@2: -- set the action ID flickerstreak@2: self:SetActionID(id) flickerstreak@2: flickerstreak@2: -- register button with ReBinder for keybinding flickerstreak@2: ReBinder:AddKeybindTarget(self.button) flickerstreak@2: flickerstreak@1: -- initialize flickerstreak@2: self:Configure(parentFrame, config, barIdx) flickerstreak@2: end flickerstreak@2: flickerstreak@2: local function tcopy(t) flickerstreak@2: local r = { } flickerstreak@2: for k, v in pairs(t) do flickerstreak@2: r[k] = (type(v) == "table" and tcopy(v) or v) flickerstreak@2: end flickerstreak@2: return r flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:Recycle() flickerstreak@1: local b = self.button flickerstreak@1: flickerstreak@1: self:SetKeyBinding(nil) flickerstreak@1: self:UpdateDisplay() flickerstreak@1: b:UnregisterAllEvents() flickerstreak@2: b:SetParent(ReActionButtonRecycleFrame) flickerstreak@2: b:ClearAllPoints() flickerstreak@2: b:SetPoint("TOPLEFT",0,0) flickerstreak@1: b:Hide() flickerstreak@2: self.config = tcopy(self.config) -- ew, but necessary flickerstreak@1: end flickerstreak@1: flickerstreak@2: function ReActionButton.prototype:BarUnlocked() flickerstreak@2: self:ShowGridTmp() flickerstreak@2: end flickerstreak@2: flickerstreak@2: function ReActionButton.prototype:BarLocked() flickerstreak@2: self:HideGridTmp() flickerstreak@2: end flickerstreak@1: flickerstreak@1: flickerstreak@1: -- set the button location flickerstreak@1: function ReActionButton.prototype:PlaceButton(point, x, y, sz) flickerstreak@1: local b = self.button flickerstreak@1: local scale = sz / 36 flickerstreak@1: b:ClearAllPoints() flickerstreak@1: b:SetScale( scale ) flickerstreak@1: b:SetPoint(point,x/scale,y/scale) flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ShowActionID() flickerstreak@1: self.frames.actionID:Show() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:HideActionID() flickerstreak@1: self.frames.actionID:Hide() flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: -- configuration and setup flickerstreak@2: function ReActionButton.prototype:Configure( parentFrame, config, barIdx ) flickerstreak@1: self.config = config flickerstreak@1: self.barIdx = barIdx flickerstreak@2: self.showGridTmp_ = 0 flickerstreak@1: flickerstreak@1: self.button:ClearAllPoints() flickerstreak@1: self.button:SetParent(parentFrame) flickerstreak@1: flickerstreak@1: self:SetupAttributes() flickerstreak@1: self:RegisterStaticEvents() flickerstreak@1: flickerstreak@1: self:ApplyLayout() flickerstreak@1: self:ApplyStyle() flickerstreak@1: flickerstreak@1: self:UpdateDisplay() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:SetupAttributes() flickerstreak@1: local b = self.button flickerstreak@1: b:SetAttribute("type", "action") flickerstreak@1: b:SetAttribute("shift-type*", ATTRIBUTE_NOOP) flickerstreak@1: b:SetAttribute("checkselfcast", true) flickerstreak@1: b:SetAttribute("useparent-unit", true) flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:RegisterStaticEvents() flickerstreak@1: self:RegisterEvent("PLAYER_ENTERING_WORLD") flickerstreak@1: self:RegisterEvent("ACTIONBAR_SLOT_CHANGED") flickerstreak@1: self:RegisterEvent("UPDATE_BINDINGS") flickerstreak@1: self:RegisterEvent("ACTIONBAR_SHOWGRID") flickerstreak@1: self:RegisterEvent("ACTIONBAR_HIDEGRID") flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:RegisterActionEvents() flickerstreak@1: self:RegisterEvent("ACTIONBAR_UPDATE_STATE") flickerstreak@1: self:RegisterEvent("ACTIONBAR_UPDATE_USABLE") flickerstreak@1: self:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN", "ACTIONBAR_UPDATE_USABLE") flickerstreak@1: self:RegisterEvent("UPDATE_INVENTORY_ALERTS", "ACTIONBAR_UPDATE_USABLE") flickerstreak@1: self:RegisterEvent("PLAYER_AURAS_CHANGED", "ACTIONBAR_UPDATE_USABLE") flickerstreak@1: self:RegisterEvent("PLAYER_TARGET_CHANGED", "ACTIONBAR_UPDATE_USABLE") flickerstreak@1: self:RegisterEvent("UNIT_INVENTORY_CHANGED") flickerstreak@1: self:RegisterEvent("CRAFT_SHOW") flickerstreak@1: self:RegisterEvent("CRAFT_CLOSE", "CRAFT_SHOW") flickerstreak@1: self:RegisterEvent("TRADE_SKILL_SHOW", "CRAFT_SHOW") flickerstreak@1: self:RegisterEvent("TRADE_SKILL_CLOSE", "CRAFT_SHOW") flickerstreak@1: self:RegisterEvent("PLAYER_ENTER_COMBAT", "CRAFT_SHOW") flickerstreak@1: self:RegisterEvent("PLAYER_LEAVE_COMBAT") flickerstreak@1: self:RegisterEvent("START_AUTOREPEAT_SPELL") flickerstreak@1: self:RegisterEvent("STOP_AUTOREPEAT_SPELL") flickerstreak@1: flickerstreak@1: self.button:SetScript("OnUpdate", function() self:OnUpdate(arg1) end) flickerstreak@1: self.actionEventsRegistered = true flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UnregisterActionEvents() flickerstreak@1: self:UnregisterEvent("ACTIONBAR_UPDATE_STATE") flickerstreak@1: self:UnregisterEvent("ACTIONBAR_UPDATE_USABLE") flickerstreak@1: self:UnregisterEvent("ACTIONBAR_UPDATE_COOLDOWN") flickerstreak@1: self:UnregisterEvent("UPDATE_INVENTORY_ALERTS") flickerstreak@1: self:UnregisterEvent("PLAYER_AURAS_CHANGED") flickerstreak@1: self:UnregisterEvent("PLAYER_TARGET_CHANGED") flickerstreak@1: self:UnregisterEvent("UNIT_INVENTORY_CHANGED") flickerstreak@1: self:UnregisterEvent("CRAFT_SHOW") flickerstreak@1: self:UnregisterEvent("CRAFT_CLOSE") flickerstreak@1: self:UnregisterEvent("TRADE_SKILL_SHOW") flickerstreak@1: self:UnregisterEvent("TRADE_SKILL_CLOSE") flickerstreak@1: self:UnregisterEvent("PLAYER_ENTER_COMBAT") flickerstreak@1: self:UnregisterEvent("PLAYER_LEAVE_COMBAT") flickerstreak@1: self:UnregisterEvent("START_AUTOREPEAT_SPELL") flickerstreak@1: self:UnregisterEvent("STOP_AUTOREPEAT_SPELL") flickerstreak@1: flickerstreak@1: self.button:SetScript("OnUpdate", nil) flickerstreak@1: self.actionEventsRegistered = false flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: -- event handlers flickerstreak@1: function ReActionButton.prototype:ACTIONBAR_SLOT_CHANGED() flickerstreak@1: if arg1 == 0 or arg1 == self:GetActionID() then flickerstreak@1: self:UpdateDisplay() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:PLAYER_ENTERING_WORLD() flickerstreak@1: self:UpdateDisplay() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UPDATE_BINDINGS() flickerstreak@1: self:UpdateDisplay() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ACTIONBAR_SHOWGRID() flickerstreak@1: self:ShowGridTmp() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ACTIONBAR_HIDEGRID() flickerstreak@1: self:HideGridTmp() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ACTIONBAR_UPDATE_STATE() flickerstreak@1: self:UpdateCheckedState() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ACTIONBAR_UPDATE_USABLE() flickerstreak@1: self:UpdateUsable() flickerstreak@1: self:UpdateCooldown() flickerstreak@1: self:ColorHotKey() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UNIT_INVENTORY_CHANGED() flickerstreak@1: if arg1 == "player" then flickerstreak@1: self:UpdateDisplay() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:CRAFT_SHOW() flickerstreak@1: self:UpdateCheckedState() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:PLAYER_ENTER_COMBAT() flickerstreak@1: if IsAttackAction(self:GetActionID()) then flickerstreak@1: self:StartFlash() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:PLAYER_LEAVE_COMBAT() flickerstreak@1: if IsAttackAction(self:GetActionID()) then flickerstreak@1: self:StopFlash() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:START_AUTOREPEAT_SPELL() flickerstreak@1: if IsAutoRepeatAction(self:GetActionID()) then flickerstreak@1: self:StartFlash() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:STOP_AUTOREPEAT_SPELL() flickerstreak@1: if self:IsFlashing() and not IsAttackAction(self:GetActionID()) then flickerstreak@1: self:StopFlash() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: -- OnUpdate handler flickerstreak@1: function ReActionButton.prototype:OnUpdate(elapsed) flickerstreak@1: local action = self:GetActionID() flickerstreak@1: local f = self.frames flickerstreak@1: flickerstreak@1: -- handle flashing flickerstreak@1: if self:IsFlashing() then flickerstreak@1: self.flashtime = self.flashtime - elapsed flickerstreak@1: if self.flashtime <= 0 then flickerstreak@1: local overtime = -self.flashtime flickerstreak@1: if overtime >= ATTACK_BUTTON_FLASH_TIME then flickerstreak@1: overtime = 0 flickerstreak@1: end flickerstreak@1: self.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime flickerstreak@1: flickerstreak@1: if f.flash:IsVisible() then flickerstreak@1: f.flash:Hide() flickerstreak@1: else flickerstreak@1: f.flash:Show() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: -- Handle range indicator flickerstreak@1: if self.rangeTimer then flickerstreak@1: self.rangeTimer = self.rangeTimer - elapsed flickerstreak@1: if self.rangeTimer <= 0 then flickerstreak@1: self:ColorHotKey() flickerstreak@1: self:UpdateUsable() flickerstreak@1: self.rangeTimer = TOOLTIP_UPDATE_TIME flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: -- handle toltip update flickerstreak@1: if self.tooltipTime then flickerstreak@1: self.tooltipTime = self.tooltipTime - elapsed flickerstreak@1: if self.tooltipTime <= 0 then flickerstreak@1: if GameTooltip:IsOwned(self.button) then flickerstreak@1: self:UpdateTooltip() flickerstreak@1: else flickerstreak@1: self.tooltipTime = nil flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: -- keybinding functions flickerstreak@1: function ReActionButton.prototype:SetKeyBinding( k ) flickerstreak@1: if k == nil or kbValidate(k) then flickerstreak@1: local current = self:GetKeyBinding() flickerstreak@1: ClearOverrideBindings(self.button) flickerstreak@1: if current then flickerstreak@1: SetBinding(current,nil) flickerstreak@1: end flickerstreak@1: if k then flickerstreak@1: SetBindingClick(k, self.name, "LeftButton") flickerstreak@1: end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:GetKeyBinding() flickerstreak@1: return GetBindingKey("CLICK "..self.name..":LeftButton") flickerstreak@1: end flickerstreak@1: flickerstreak@1: -- action ID functions flickerstreak@1: function ReActionButton.prototype:SetActionID( id ) flickerstreak@2: self.actionID = tonumber(id) -- force data integrity flickerstreak@1: self:ApplyActionID() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:GetActionID() flickerstreak@2: return self.actionID flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ApplyActionID() flickerstreak@1: local action = tonumber(self:GetActionID()) flickerstreak@2: self.button:SetAttribute("action",action) flickerstreak@1: self.frames.actionID:SetText(action or "") flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ShowActionID() flickerstreak@1: self.frames.actionID:Show() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:HideActionID() flickerstreak@1: self.frames.actionID:Hide() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton:ShowAllActionIDs() -- class-wide function flickerstreak@1: for _, tbl in pairs(actionButtonTbl) do flickerstreak@1: if tbl.button then tbl.button:ShowActionID() end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton:HideAllActionIDs() -- class-wide function flickerstreak@1: for _, tbl in pairs(actionButtonTbl) do flickerstreak@1: if tbl.button then tbl.button:HideActionID() end flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: -- action transfer functions flickerstreak@1: function ReActionButton.prototype:ShouldPickupAction(mouseButton) flickerstreak@1: return IsShiftKeyDown() and not SecureButton_GetModifiedAttribute(self.button, "type", mouseButton) flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ShowGridTmp() flickerstreak@2: self.showGridTmp_ = self.showGridTmp_ + 1 flickerstreak@1: self:UpdateVisibility() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:HideGridTmp() flickerstreak@2: self.showGridTmp_ = self.showGridTmp_ - 1 flickerstreak@1: self:UpdateVisibility() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ShowGrid() flickerstreak@1: self.config.showGrid = true flickerstreak@2: self:UpdateVisibility() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:HideGrid() flickerstreak@1: self.config.showGrid = false flickerstreak@2: self:UpdateVisibility() flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: -- layout & style functions flickerstreak@1: function ReActionButton.prototype:ApplyLayout() flickerstreak@1: local f = self.frames flickerstreak@1: flickerstreak@1: if self.config.keyBindLoc then flickerstreak@1: local h = f.hotkey flickerstreak@1: local loc = self.config.keyBindLoc flickerstreak@2: local top = string.match(loc,"TOP") flickerstreak@2: local bottom = string.match(loc, "BOTTOM") flickerstreak@1: h:ClearAllPoints() flickerstreak@2: h:SetWidth(40) flickerstreak@2: h:SetPoint(top or bottom,0,top and 2 or -2) flickerstreak@1: local j flickerstreak@1: if string.match(loc,"LEFT") then flickerstreak@1: j = "LEFT" flickerstreak@1: elseif string.match(loc,"RIGHT") then flickerstreak@1: j = "RIGHT" flickerstreak@1: else flickerstreak@1: j = "CENTER" flickerstreak@1: end flickerstreak@1: h:SetJustifyH(j) flickerstreak@1: end flickerstreak@1: flickerstreak@1: if self.config.stackCountLoc then flickerstreak@1: local c = f.count flickerstreak@1: local loc = self.config.stackCountLoc flickerstreak@2: local top = string.match(loc,"TOP") flickerstreak@2: local bottom = string.match(loc, "BOTTOM") flickerstreak@1: c:ClearAllPoints() flickerstreak@2: c:SetWidth(40) flickerstreak@2: c:SetPoint(top or bottom,0,top and 2 or -2) flickerstreak@1: local j flickerstreak@1: if string.match(loc,"LEFT") then flickerstreak@1: j = "LEFT" flickerstreak@1: elseif string.match(loc,"RIGHT") then flickerstreak@1: j = "RIGHT" flickerstreak@1: else flickerstreak@1: j = "CENTER" flickerstreak@1: end flickerstreak@1: c:SetJustifyH(j) flickerstreak@1: end flickerstreak@1: flickerstreak@1: if self.config.showKeyBind then flickerstreak@1: f.hotkey:Show() flickerstreak@1: else flickerstreak@1: f.hotkey:Hide() flickerstreak@1: end flickerstreak@1: flickerstreak@1: if self.config.showStackCount then flickerstreak@1: f.count:Show() flickerstreak@1: else flickerstreak@1: f.count:Hide() flickerstreak@1: end flickerstreak@1: flickerstreak@1: --[[ flickerstreak@1: if self.config.showNumericCooldown then flickerstreak@1: f.nCooldown:Show() flickerstreak@1: else flickerstreak@1: f.nCooldown:Hide() flickerstreak@1: end flickerstreak@1: ]] flickerstreak@1: flickerstreak@1: if self.config.showMacroName then flickerstreak@1: f.macro:Show() flickerstreak@1: else flickerstreak@1: f.macro:Hide() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ApplyStyle() flickerstreak@1: local f = self.frames flickerstreak@1: -- for now, just a static style flickerstreak@1: f.hotkey:SetFontObject(NumberFontNormal) flickerstreak@1: f.count:SetFontObject(NumberFontNormalYellow) flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: -- start/stop flashing flickerstreak@1: function ReActionButton.prototype:StartFlash() flickerstreak@1: self.flashing = true flickerstreak@1: self.flashtime = 0 flickerstreak@1: self:UpdateCheckedState() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:StopFlash() flickerstreak@1: self.flashing = false flickerstreak@1: self.frames.flash:Hide() flickerstreak@1: self:UpdateCheckedState() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:IsFlashing() flickerstreak@1: return self.flashing flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: -- set the tooltip flickerstreak@1: function ReActionButton.prototype:SetTooltip() flickerstreak@1: GameTooltip_SetDefaultAnchor(GameTooltip, self.button) flickerstreak@1: self:UpdateTooltip() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ClearTooltip() flickerstreak@1: tooltipTime = nil flickerstreak@1: GameTooltip:Hide() flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: -- colorize the hotkey flickerstreak@1: function ReActionButton.prototype:ColorHotKey() flickerstreak@1: local action = self:GetActionID() flickerstreak@1: local c = hotKeyDefaultColor flickerstreak@1: flickerstreak@1: if action and HasAction(action) then flickerstreak@1: if IsActionInRange(action) == 0 then flickerstreak@1: c = hotKeyOutOfRangeColor flickerstreak@1: elseif self.config.keyBindColorCode then flickerstreak@1: local modKey = string.match( self.frames.hotkey:GetText() or "", "([ACS])%-") flickerstreak@1: c = modKey and hotKeyModifierColors[modKey] or c flickerstreak@1: end flickerstreak@1: else flickerstreak@1: c = hotKeyDisabledColor flickerstreak@1: end flickerstreak@1: flickerstreak@1: self.frames.hotkey:SetTextColor(c.r, c.g, c.b) flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: flickerstreak@1: -- display update functions flickerstreak@1: function ReActionButton.prototype:UpdateDisplay() flickerstreak@1: self:UpdateIcon() flickerstreak@1: self:UpdateHotkey() flickerstreak@1: self:UpdateCount() flickerstreak@1: self:UpdateMacroText() flickerstreak@1: self:UpdateUsable() flickerstreak@1: self:UpdateCooldown() flickerstreak@1: self:UpdateFlash() flickerstreak@1: self:UpdateEvents() flickerstreak@1: self:UpdateVisibility() flickerstreak@1: self:UpdateTooltip() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateIcon() flickerstreak@1: local f = self.frames flickerstreak@1: local b = self.button flickerstreak@1: flickerstreak@1: local action = self:GetActionID() flickerstreak@1: local texture = action and GetActionTexture(action) flickerstreak@1: flickerstreak@1: if action and texture then flickerstreak@1: f.icon:SetTexture(texture) flickerstreak@1: f.icon:Show() flickerstreak@1: self.rangeTimer = -1 flickerstreak@1: b:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2") flickerstreak@1: else flickerstreak@1: f.icon:Hide() flickerstreak@1: f.cooldown:Hide() flickerstreak@1: self.rangeTimer = nil flickerstreak@1: b:SetNormalTexture("Interface\\Buttons\\UI-Quickslot") flickerstreak@1: end flickerstreak@1: flickerstreak@1: self:UpdateCheckedState() flickerstreak@1: flickerstreak@1: -- Add a green border if action is an equipped item flickerstreak@1: if action and IsEquippedAction(action) then flickerstreak@1: local c = equippedActionBorderColor flickerstreak@1: f.border:SetVertexColor(c.r, c.g, c.b, c.a or 1) flickerstreak@1: f.border:Show() flickerstreak@1: else flickerstreak@1: f.border:Hide() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateCheckedState() flickerstreak@1: local action = self:GetActionID() flickerstreak@1: if action and (IsCurrentAction(action) or IsAutoRepeatAction(action)) then flickerstreak@1: self.button:SetChecked(1) flickerstreak@1: else flickerstreak@1: self.button:SetChecked(0) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateHotkey() flickerstreak@1: local action = self:GetActionID() flickerstreak@1: local b = self.button flickerstreak@1: local f = self.frames flickerstreak@1: local key = self:GetKeyBinding() flickerstreak@1: local txt = GetBindingText(key, "KEY_",1) flickerstreak@1: flickerstreak@2: -- abbreviate long key names flickerstreak@2: for pat, rep in pairs(keybindAbbreviations) do flickerstreak@2: txt = string.gsub(txt,pat,rep) flickerstreak@2: end flickerstreak@2: flickerstreak@1: if txt then flickerstreak@1: f.hotkey:SetText(string.upper(txt)) flickerstreak@1: self:ColorHotKey() flickerstreak@1: else flickerstreak@1: f.hotkey:SetText("") flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateCount() flickerstreak@1: local action = self:GetActionID() flickerstreak@1: if action and (IsConsumableAction(action) or IsStackableAction(action)) then flickerstreak@1: self.frames.count:SetText(GetActionCount(action)) flickerstreak@1: else flickerstreak@1: self.frames.count:SetText("") flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateMacroText() flickerstreak@1: local action = self:GetActionID() flickerstreak@1: self.frames.macro:SetText(action and GetActionText(action) or "") flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateUsable() flickerstreak@1: local f = self.frames flickerstreak@1: local action = self:GetActionID() flickerstreak@1: local isUsable, notEnoughMana flickerstreak@1: if action then flickerstreak@1: isUsable, notEnoughMana = IsUsableAction(action) flickerstreak@1: end flickerstreak@1: if isUsable then flickerstreak@1: local c = actionUsableColor flickerstreak@1: if IsActionInRange(action) == 0 then flickerstreak@1: c = actionOutOfRangeColor flickerstreak@1: else flickerstreak@1: f.normalTexture:SetVertexColor(c.r, c.g, c.b, c.a) flickerstreak@1: end flickerstreak@1: f.icon:SetVertexColor(c.r, c.g, c.b, c.a) flickerstreak@1: elseif notEnoughMana then flickerstreak@1: local c = actionNotEnoughManaColor flickerstreak@1: f.icon:SetVertexColor(c.r, c.g, c.b, c.a) flickerstreak@1: f.normalTexture:SetVertexColor(c.r, c.g, c.b, c.a) flickerstreak@1: else flickerstreak@1: local c = actionNotUsableColor flickerstreak@1: f.icon:SetVertexColor(c.r, c.g, c.b, c.a) flickerstreak@1: f.normalTexture:SetVertexColor(1.0, 1.0, 1.0) flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateCooldown() flickerstreak@1: local action = self:GetActionID() flickerstreak@1: if action then flickerstreak@1: local start, duration, enable = GetActionCooldown(self:GetActionID()) flickerstreak@1: CooldownFrame_SetTimer(self.frames.cooldown, start, duration, enable) flickerstreak@1: -- do numeric cooldown stuff here flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateFlash() flickerstreak@1: local b = self.button flickerstreak@1: local action = self:GetActionID() flickerstreak@1: if action and ((IsAttackAction(action) and IsCurrentAction(action)) or IsAutoRepeatAction(action)) then flickerstreak@1: self:StartFlash() flickerstreak@1: else flickerstreak@1: self:StopFlash() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateVisibility() flickerstreak@1: local action = self:GetActionID() flickerstreak@1: local b = self.button flickerstreak@1: flickerstreak@1: if b:GetAttribute("statehidden") then flickerstreak@1: b:Hide() flickerstreak@1: elseif action and HasAction(action) then flickerstreak@1: b:GetNormalTexture():SetAlpha(1.0) flickerstreak@1: b:Show() flickerstreak@2: elseif self.showGridTmp_ > 0 or self.config.showGrid then flickerstreak@1: b:GetNormalTexture():SetAlpha(0.5) flickerstreak@1: self.frames.cooldown:Hide() flickerstreak@1: b:Show() flickerstreak@1: else flickerstreak@1: b:Hide() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateEvents() flickerstreak@1: local action = self:GetActionID() flickerstreak@1: if action and HasAction(action) then flickerstreak@1: self:RegisterActionEvents() flickerstreak@1: elseif self.actionEventsRegistered then flickerstreak@1: self:UnregisterActionEvents() flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:UpdateTooltip() flickerstreak@1: local action = self:GetActionID() flickerstreak@2: if GameTooltip:IsOwned(self.button) and action and GameTooltip:SetAction(action) then flickerstreak@1: self.tooltipTime = TOOLTIP_UPDATE_TIME flickerstreak@1: else flickerstreak@1: self.tooltipTime = nil flickerstreak@1: end flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: