flickerstreak@1: -- private constants flickerstreak@1: 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@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@1: t.button:Configure(parent,config,barIdx,id) flickerstreak@1: else flickerstreak@1: t.button = self:new(parent,config,barIdx,id) flickerstreak@1: end flickerstreak@1: flickerstreak@1: if actionButtonTbl[t.button:GetActionID()].inUse ~= true then flickerstreak@1: end flickerstreak@1: 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@1: self.name = namePrefix.."_"..id flickerstreak@1: self.button = CreateFrame("CheckButton", self.name, parentFrame, "ReActionButtonTemplate") flickerstreak@1: flickerstreak@1: -- create the actionID label on the control widget flickerstreak@1: local actionIDLabel = self.button:CreateFontString(nil,"ARTWORK", "NumberFontNormalSmall") flickerstreak@1: actionIDLabel:SetPoint("BOTTOMLEFT",0,0) flickerstreak@1: actionIDLabel:Hide() 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@1: actionID = actionIDLabel 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@1: -- initialize flickerstreak@1: self:Configure(parentFrame, config, barIdx, id) flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:Recycle() flickerstreak@1: local b = self.button flickerstreak@1: local action = self:GetActionID() flickerstreak@1: flickerstreak@1: self.config.actionIDs[self.barIdx] = nil flickerstreak@1: flickerstreak@1: self:SetKeyBinding(nil) flickerstreak@1: self:UpdateDisplay() flickerstreak@1: b:UnregisterAllEvents() flickerstreak@1: b:Hide() flickerstreak@1: b:ClearAllPoints() flickerstreak@1: b:SetParent(ReActionButtonRecycleFrame) flickerstreak@1: end flickerstreak@1: 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@1: function ReActionButton.prototype:Configure( parentFrame, config, barIdx, id ) flickerstreak@1: self.config = config flickerstreak@1: self.barIdx = barIdx flickerstreak@1: self.showGrid = config.showGrid and 1 or 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: if id then flickerstreak@1: -- set action ID flickerstreak@1: self:SetActionID(id) flickerstreak@1: else flickerstreak@1: self:ApplyActionID() flickerstreak@1: end 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("alt-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: function ReActionButton.prototype:ShowAssignKeybinding() flickerstreak@1: local f = ReActionKeybindFrame flickerstreak@1: f:ClearAllPoints() flickerstreak@1: f:SetPoint("BOTTOM", self.button, "TOP", 0, 10) flickerstreak@1: ReActionKeybindFrameButton.keybindTarget = self flickerstreak@1: local k = self:GetKeyBinding() flickerstreak@1: if k then flickerstreak@1: local txt = GetBindingText(k, "KEY_") flickerstreak@1: ReActionKeybindFrameButton:SetText(txt or "") flickerstreak@1: end flickerstreak@1: f:Show() flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: local mouseButtonConvert = { flickerstreak@1: LeftButton = "BUTTON1", flickerstreak@1: RightButton = "BUTTON2", flickerstreak@1: MiddleButton = "BUTTON3", flickerstreak@1: Button4 = "BUTTON4", flickerstreak@1: Button5 = "BUTTON5" flickerstreak@1: } flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:HandleKeybindAssign(button, key, mouseButton) flickerstreak@1: mouseButton = mouseButton and mouseButtonConvert[mouseButton] flickerstreak@1: if mouseButton ~= "BUTTON1" and mouseButton ~= "BUTTON2" then flickerstreak@1: key = key or mouseButton flickerstreak@1: if key == nil or key == "UNKNOWN" or key == "SHIFT" or key == "CTRL" or key == "ALT" then flickerstreak@1: return flickerstreak@1: end flickerstreak@1: if key == "ESCAPE" then flickerstreak@1: ReActionKeybindFrame:Hide() flickerstreak@1: return flickerstreak@1: end flickerstreak@1: if IsShiftKeyDown() then flickerstreak@1: key = "SHIFT-"..key flickerstreak@1: end flickerstreak@1: if IsControlKeyDown() then flickerstreak@1: key = "CTRL-"..key flickerstreak@1: end flickerstreak@1: if IsAltKeyDown() then flickerstreak@1: keyPressed = "ALT-"..key flickerstreak@1: end flickerstreak@1: local oldAction = GetBindingAction(key) flickerstreak@1: local oldKey = self:GetKeyBinding() flickerstreak@1: if oldAction then flickerstreak@1: -- can't pop a modal dialog box, will need to think something up flickerstreak@1: end flickerstreak@1: if oldKey == key then flickerstreak@1: SetBinding(key,nil) flickerstreak@1: key = nil flickerstreak@1: end flickerstreak@1: self:SetKeyBinding(key) flickerstreak@1: button:SetText(key and GetBindingText(key, "KEY_") or "") flickerstreak@1: self:UpdateDisplay() flickerstreak@1: SaveBindings(2) -- 2 = character specific bindings... hmm... flickerstreak@1: end flickerstreak@1: button.selected = false flickerstreak@1: this:SetButtonState("NORMAL") flickerstreak@1: end flickerstreak@1: flickerstreak@1: flickerstreak@1: -- action ID functions flickerstreak@1: function ReActionButton.prototype:SetActionID( id ) flickerstreak@1: self.config.actionIDs[self.barIdx] = tonumber(id) -- force data integrity flickerstreak@1: self:ApplyActionID() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:GetActionID() flickerstreak@1: return self.config.actionIDs[self.barIdx] flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ApplyActionID() flickerstreak@1: local action = tonumber(self:GetActionID()) flickerstreak@1: self.button:SetAttribute("action",action or nil) 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@1: self.showGrid = self.showGrid + 1 flickerstreak@1: self:UpdateVisibility() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:HideGridTmp() flickerstreak@1: self.showGrid = self.showGrid - 1 flickerstreak@1: self:UpdateVisibility() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:ShowGrid() flickerstreak@1: self.config.showGrid = true flickerstreak@1: self:ShowGridTmp() flickerstreak@1: end flickerstreak@1: flickerstreak@1: function ReActionButton.prototype:HideGrid() flickerstreak@1: self.config.showGrid = false flickerstreak@1: self:HideGridTmp() 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@1: h:ClearAllPoints() flickerstreak@1: h:SetPoint(loc,0,0) 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@1: c:ClearAllPoints() flickerstreak@1: c:SetPoint(loc,0,0) 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@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@1: elseif self.showGrid > 0 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@1: if 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: