annotate classes/ActionButton.lua @ 186:77858d975df6

Fix showgrid for action buttons in combat. HasAction() isn't updated prior to ACTIONBAR_HIDEGRID being fired, so capture drags and clicks and assume that HasAction() will report true immediately afterward.
author Flick <flickerstreak@gmail.com>
date Thu, 11 Nov 2010 10:22:36 -0800
parents df68b5a40490
children e63aefb8a555
rev   line source
flickerstreak@175 1 local addonName, addonTable = ...
flickerstreak@175 2 local ReAction = addonTable.ReAction
flickerstreak@122 3 local L = ReAction.L
flickerstreak@122 4 local _G = _G
flickerstreak@122 5 local CreateFrame = CreateFrame
flickerstreak@122 6 local format = string.format
flickerstreak@122 7 local IsUsableAction = IsUsableAction
flickerstreak@122 8 local IsEquippedAction = IsEquippedAction
flickerstreak@122 9 local IsConsumableAction = IsConsumableAction
flickerstreak@122 10 local IsStackableAction = IsStackableAction
flickerstreak@122 11 local GetActionText = GetActionText
flickerstreak@122 12 local GetCVar = GetCVar
flickerstreak@122 13 local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor
flickerstreak@122 14 local IsCurrentAction = IsCurrentAction
flickerstreak@122 15 local IsAutoRepeatAction = IsAutoRepeatAction
flickerstreak@122 16 local IsUsableAction = IsUsableAction
flickerstreak@122 17 local IsAttackAction = IsAttackAction
flickerstreak@122 18 local CooldownFrame_SetTimer = CooldownFrame_SetTimer
flickerstreak@122 19 local GetActionCooldown = GetActionCooldown
flickerstreak@122 20 local GetActionTexture = GetActionTexture
flickerstreak@122 21 local ATTACK_BUTTON_FLASH_TIME = ATTACK_BUTTON_FLASH_TIME
flickerstreak@122 22 local TOOLTIP_UPDATE_TIME = TOOLTIP_UPDATE_TIME
flickerstreak@122 23 local IsActionInRange = IsActionInRange
flickerstreak@122 24 local InCombatLockdown = InCombatLockdown
flickerstreak@122 25 local HasAction = HasAction
flickerstreak@122 26
flickerstreak@122 27 --
flickerstreak@122 28 -- Secure snippets
flickerstreak@122 29 -- These are run within the context of the bar's sandbox, as the
flickerstreak@122 30 -- buttons themselves do not have their own sandbox.
flickerstreak@122 31 --
flickerstreak@122 32 local _onstate_mc = -- function(self, stateid, newstate)
flickerstreak@122 33 [[
flickerstreak@122 34 local oldMcVehicleState = mcVehicleState
flickerstreak@122 35 mcVehicleState = newstate
flickerstreak@122 36 control:ChildUpdate()
flickerstreak@122 37 if oldMcVehicleState == "vehicle" or mcVehicleState == "vehicle" then
flickerstreak@122 38 control:ChildUpdate("vehicle")
flickerstreak@122 39 end
flickerstreak@122 40 ]]
flickerstreak@122 41
flickerstreak@122 42 local _childupdate = -- function(self, snippetid, message)
flickerstreak@122 43 [[
flickerstreak@122 44 local action = nil
flickerstreak@122 45 if (doVehicle and mcVehicleState == "vehicle") or
flickerstreak@122 46 (doMindControl and mcVehicleState == "mc") then
flickerstreak@122 47 local idx = self:GetAttribute("bar-idx")
flickerstreak@145 48 local maxN = (doVehicle and mcVehicleState == "vehicle") and 7 or 12
flickerstreak@145 49 if idx and idx <= maxN then
flickerstreak@122 50 action = 120 + idx
flickerstreak@122 51 else
flickerstreak@122 52 action = 0
flickerstreak@122 53 end
flickerstreak@155 54 elseif state and settings[state] and settings[state].page then
flickerstreak@155 55 action = self:GetAttribute("action-"..settings[state].page)
flickerstreak@138 56 end
flickerstreak@138 57 if action == nil then
flickerstreak@122 58 action = self:GetAttribute("default-action")
flickerstreak@122 59 end
flickerstreak@122 60
flickerstreak@122 61 self:SetAttribute("action",action)
flickerstreak@122 62
flickerstreak@128 63 if not self:GetAttribute("showgrid") then
flickerstreak@128 64 local tempShow = self:GetAttribute("showgrid-temp")
flickerstreak@128 65 local evtShow = self:GetAttribute("showgrid-event")
flickerstreak@128 66 if tempShow then tempShow = (tempShow > 0) end
flickerstreak@128 67 if evtShow then evtShow = (evtShow > 0) end
flickerstreak@128 68
flickerstreak@170 69 if tempShow or evtShow or HasAction(action) then
flickerstreak@128 70 self:Show()
flickerstreak@128 71 else
flickerstreak@128 72 self:Hide()
flickerstreak@128 73 end
flickerstreak@122 74 end
flickerstreak@122 75 ]]
flickerstreak@122 76
flickerstreak@122 77 local _childupdate_vehicleExit = -- function(self, snippetid, message)
flickerstreak@122 78 [[
flickerstreak@122 79 local show = (mcVehicleState == "vehicle")
flickerstreak@124 80 if show and doVehicle then
flickerstreak@122 81 self:SetAttribute("type","macro")
flickerstreak@122 82 self:Show()
flickerstreak@122 83 else
flickerstreak@122 84 self:SetAttribute("type","action")
flickerstreak@122 85 end
flickerstreak@122 86 control:CallMethod("ShowVehicleExit",show)
flickerstreak@122 87 ]]
flickerstreak@122 88
flickerstreak@122 89 local _childupdate_showgrid = -- function(self, snippetid, message)
flickerstreak@122 90 [[
flickerstreak@186 91 showgrid_event = message
flickerstreak@128 92 self:SetAttribute("showgrid-event",message)
flickerstreak@128 93 if not self:GetAttribute("showgrid") then
flickerstreak@128 94 local count = message + (self:GetAttribute("showgrid-temp") or 0)
flickerstreak@128 95 if count <= 0 then
flickerstreak@128 96 local action = self:GetAttribute("action")
flickerstreak@186 97 -- note that HasAction is not updated on the target of a drag until after ACTIONBAR_HIDEGRID
flickerstreak@186 98 -- so, we set a flag for this button in pre-click/receive-drag and check for it here
flickerstreak@186 99 if HasAction(action) or self:GetAttribute("showgrid-clicked") then
flickerstreak@186 100 if not self:IsShown() then
flickerstreak@186 101 self:Show()
flickerstreak@186 102 end
flickerstreak@186 103 self:SetAttribute("showgrid-clicked",false)
flickerstreak@186 104 else
flickerstreak@186 105 if self:IsShown() then
flickerstreak@186 106 self:Hide()
flickerstreak@186 107 end
flickerstreak@128 108 end
flickerstreak@128 109 else
flickerstreak@122 110 self:Show()
flickerstreak@122 111 end
flickerstreak@122 112 end
flickerstreak@122 113 ]]
flickerstreak@122 114
flickerstreak@122 115 local _onDragStart = -- function(self, button, kind, value, ...)
flickerstreak@122 116 [[
flickerstreak@122 117 if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then
flickerstreak@122 118 return kind, value, ...
flickerstreak@122 119 else
flickerstreak@122 120 return "action", self:GetAttribute("action")
flickerstreak@122 121 end
flickerstreak@122 122 ]]
flickerstreak@122 123
flickerstreak@122 124 local _onReceiveDrag = -- function(self, button, kind, value, ...)
flickerstreak@122 125 [[
flickerstreak@129 126 if kind ~= "spell" and kind ~= "item" and kind ~= "macro" then
flickerstreak@129 127 return kind, value, ...
flickerstreak@170 128 else
flickerstreak@186 129 if showgrid_event and showgrid_event > 0 then
flickerstreak@186 130 self:SetAttribute("showgrid-clicked",true)
flickerstreak@186 131 end
flickerstreak@170 132 return "action", self:GetAttribute("action")
flickerstreak@122 133 end
flickerstreak@122 134 ]]
flickerstreak@122 135
flickerstreak@186 136 local _onClick = -- function(self, button, down)
flickerstreak@186 137 [[
flickerstreak@186 138 if showgrid_event and showgrid_event > 0 then
flickerstreak@186 139 self:SetAttribute("showgrid-clicked",true)
flickerstreak@186 140 end
flickerstreak@186 141 return button
flickerstreak@186 142 ]]
flickerstreak@186 143
flickerstreak@122 144 --
flickerstreak@122 145 -- private
flickerstreak@122 146 --
flickerstreak@122 147 local eventList = {
flickerstreak@122 148 "PLAYER_ENTERING_WORLD",
flickerstreak@122 149 "ACTIONBAR_PAGE_CHANGED",
flickerstreak@122 150 "ACTIONBAR_SLOT_CHANGED",
flickerstreak@122 151 "UPDATE_BINDINGS",
flickerstreak@122 152 "ACTIONBAR_UPDATE_STATE",
flickerstreak@122 153 "ACTIONBAR_UPDATE_USABLE",
flickerstreak@122 154 "ACTIONBAR_UPDATE_COOLDOWN",
flickerstreak@165 155 "UNIT_INVENTORY_CHANGED",
flickerstreak@165 156 "LEARNED_SPELL_IN_TAB",
flickerstreak@122 157 "UPDATE_INVENTORY_ALERTS",
flickerstreak@122 158 "PLAYER_TARGET_CHANGED",
flickerstreak@122 159 "TRADE_SKILL_SHOW",
flickerstreak@122 160 "TRADE_SKILL_CLOSE",
flickerstreak@122 161 "PLAYER_ENTER_COMBAT",
flickerstreak@122 162 "PLAYER_LEAVE_COMBAT",
flickerstreak@122 163 "START_AUTOREPEAT_SPELL",
flickerstreak@122 164 "STOP_AUTOREPEAT_SPELL",
flickerstreak@122 165 "UNIT_ENTERED_VEHICLE",
flickerstreak@122 166 "UNIT_EXITED_VEHICLE",
flickerstreak@122 167 "COMPANION_UPDATE",
flickerstreak@122 168 }
flickerstreak@122 169
flickerstreak@122 170 --
flickerstreak@122 171 -- Action Button class
flickerstreak@122 172 --
flickerstreak@122 173 local Super = ReAction.Button
flickerstreak@122 174 local Action = setmetatable( { }, { __index = Super } )
flickerstreak@122 175 ReAction.Button.Action = Action
flickerstreak@122 176
flickerstreak@128 177 function Action:New( idx, barConfig, bar, idHint )
flickerstreak@123 178 local name = format("ReAction_%s_Action_%d",bar:GetName(),idx)
flickerstreak@123 179
flickerstreak@129 180 self = Super.New(self, name, barConfig.buttons[idx], bar, idx, "SecureActionButtonTemplate, ActionButtonTemplate" )
flickerstreak@129 181 self.barConfig = barConfig
flickerstreak@122 182
flickerstreak@122 183 local f = self:GetFrame()
flickerstreak@122 184 local barFrame = bar:GetFrame()
flickerstreak@128 185 local config = self:GetConfig()
flickerstreak@122 186
flickerstreak@122 187 self.rangeTimer = TOOLTIP_UPDATE_TIME
flickerstreak@122 188
flickerstreak@122 189 -- set up the base action ID
flickerstreak@122 190 self:SetActionIDPool("action",120)
flickerstreak@122 191 config.actionID = self:AcquireActionID(config.actionID, idHint)
flickerstreak@122 192 self.nPages = 1
flickerstreak@122 193
flickerstreak@122 194 -- attribute setup
flickerstreak@122 195 f:SetAttribute("type","action")
flickerstreak@122 196 f:SetAttribute("checkselfcast", true)
flickerstreak@122 197 f:SetAttribute("checkfocuscast", true)
flickerstreak@122 198 f:SetAttribute("action", config.actionID)
flickerstreak@122 199 f:SetAttribute("default-action", config.actionID)
flickerstreak@128 200 f:SetAttribute("bar-idx",idx)
flickerstreak@122 201 f:SetAttribute("showgrid-temp",0)
flickerstreak@128 202 f:SetAttribute("showgrid-event",0)
flickerstreak@128 203 f:SetAttribute("showgrid",not self:GetBarConfig().hideEmpty)
flickerstreak@128 204
flickerstreak@122 205 -- non secure scripts
flickerstreak@122 206 f:SetScript("OnEvent", function(frame, ...) self:OnEvent(...) end)
flickerstreak@122 207 f:SetScript("OnEnter", function(frame) self:OnEnter() end)
flickerstreak@122 208 f:SetScript("OnLeave", function(frame) self:OnLeave() end)
flickerstreak@122 209 f:SetScript("OnAttributeChanged", function(frame, attr, value) self:OnAttributeChanged(attr, value) end)
flickerstreak@122 210 f:SetScript("PostClick", function(frame, ...) self:PostClick(...) end)
flickerstreak@122 211 f:SetScript("OnUpdate", function(frame, elapsed) self:OnUpdate(elapsed) end)
flickerstreak@122 212 f:SetScript("OnDragStart", function(frame) self:OnDragStart() end)
flickerstreak@123 213 f:SetScript("OnReceiveDrag", function(frame) self:OnReceiveDrag() end)
flickerstreak@122 214
flickerstreak@122 215 -- event registration
flickerstreak@124 216 f:EnableMouse(true)
flickerstreak@122 217 f:RegisterForDrag("LeftButton", "RightButton")
flickerstreak@122 218 f:RegisterForClicks("AnyUp")
flickerstreak@122 219 for _, evt in pairs(eventList) do
flickerstreak@122 220 f:RegisterEvent(evt)
flickerstreak@122 221 end
flickerstreak@122 222
flickerstreak@138 223 -- secure handlers
flickerstreak@138 224 f:SetAttribute("_childupdate", _childupdate)
flickerstreak@138 225 f:SetAttribute("_childupdate-showgrid",_childupdate_showgrid)
flickerstreak@138 226 barFrame:WrapScript(f, "OnDragStart", _onDragStart)
flickerstreak@138 227 barFrame:WrapScript(f, "OnReceiveDrag", _onReceiveDrag)
flickerstreak@186 228 barFrame:WrapScript(f, "OnClick", _onClick)
flickerstreak@123 229
flickerstreak@140 230 -- attach to skinner
flickerstreak@140 231 bar:SkinButton(self)
flickerstreak@140 232
flickerstreak@140 233 -- initial display
flickerstreak@140 234 if ReAction:GetConfigMode() then
flickerstreak@140 235 self:ShowGridTemp(true)
flickerstreak@140 236 end
flickerstreak@140 237
flickerstreak@140 238 self:Refresh()
flickerstreak@140 239
flickerstreak@123 240 return self
flickerstreak@122 241 end
flickerstreak@122 242
flickerstreak@122 243 function Action:Destroy()
flickerstreak@122 244 local f = self:GetFrame()
flickerstreak@128 245 local c = self:GetConfig()
flickerstreak@122 246
flickerstreak@132 247 f:SetAttribute("_childupdate-vehicle",nil)
flickerstreak@145 248 f:SetAttribute("action",c.actionID) -- so that Super.Destroy releases the right one
flickerstreak@122 249
flickerstreak@139 250 if c.pageactions and #c.pageactions > 1 then
flickerstreak@139 251 for i = 2, #c.pageactions do
flickerstreak@132 252 self:ReleaseActionID(c.pageactions[i])
flickerstreak@122 253 self:ReleaseActionID(id)
flickerstreak@122 254 end
flickerstreak@122 255 end
flickerstreak@122 256
flickerstreak@128 257 Super.Destroy(self)
flickerstreak@122 258 end
flickerstreak@122 259
flickerstreak@129 260 function Action:GetBarConfig()
flickerstreak@129 261 -- this is the per-bar Action module config structure,
flickerstreak@129 262 -- not the config structure of the bar itself
flickerstreak@129 263 return self.barConfig
flickerstreak@129 264 end
flickerstreak@129 265
flickerstreak@122 266 function Action:Refresh()
flickerstreak@129 267 Super.Refresh(self)
flickerstreak@122 268 self:RefreshPages()
flickerstreak@124 269 self:InstallVehicle()
flickerstreak@128 270 self:ShowGrid(not self:GetBarConfig().hideEmpty)
flickerstreak@122 271 self:UpdateAction()
flickerstreak@122 272 end
flickerstreak@122 273
flickerstreak@124 274 function Action:InstallVehicle()
flickerstreak@145 275 local f = self:GetFrame()
flickerstreak@128 276 if self.idx == 7 and self:GetBarConfig().vehicle then
flickerstreak@159 277 if not self.vehicleInstalled then
flickerstreak@159 278 self.vehicleInstalled = true
flickerstreak@159 279 -- install vehicle-exit button on 7th button (only)
flickerstreak@159 280 f:SetAttribute("_childupdate-vehicle", _childupdate_vehicleExit)
flickerstreak@159 281 f:SetAttribute("macrotext","/run VehicleExit()")
flickerstreak@159 282 self:GetBar():GetFrame().ShowVehicleExit = function(bar,show)
flickerstreak@159 283 self:ShowVehicleExit(show)
flickerstreak@159 284 end
flickerstreak@124 285 end
flickerstreak@159 286 -- setscale blows away tex coords
flickerstreak@159 287 self:UpdateIcon()
flickerstreak@159 288 elseif self.vehicleInstalled then
flickerstreak@159 289 self.vehicleInstalled = false
flickerstreak@145 290 f:SetAttribute("_childupdate-vehicle",nil)
flickerstreak@145 291 f:SetAttribute("macrotext",nil)
flickerstreak@128 292 end
flickerstreak@128 293 end
flickerstreak@128 294
flickerstreak@128 295 function Action:ShowGrid( show )
flickerstreak@128 296 if not InCombatLockdown() then
flickerstreak@128 297 self.frame:SetAttribute("showgrid", show)
flickerstreak@128 298 self:UpdateShowGrid()
flickerstreak@128 299 end
flickerstreak@128 300 end
flickerstreak@128 301
flickerstreak@128 302 function Action:ShowGridTemp( show )
flickerstreak@128 303 -- This function only modifies the show-grid when out
flickerstreak@128 304 -- of combat, and is ignored by the secure handler. Use
flickerstreak@128 305 -- it for configuration modes.
flickerstreak@128 306 if not InCombatLockdown() then
flickerstreak@128 307 local count = self.showGridTempCount or 0
flickerstreak@128 308 if show then
flickerstreak@128 309 count = count + 1
flickerstreak@128 310 else
flickerstreak@128 311 count = count - 1
flickerstreak@128 312 end
flickerstreak@128 313 if count < 0 then count = 0 end
flickerstreak@128 314 self.showGridTempCount = count
flickerstreak@128 315 self:GetFrame():SetAttribute("showgrid-temp",count)
flickerstreak@128 316 self:UpdateShowGrid()
flickerstreak@124 317 end
flickerstreak@124 318 end
flickerstreak@124 319
flickerstreak@122 320 function Action:UpdateAll()
flickerstreak@122 321 self:UpdateActionIDLabel(ReAction:GetConfigMode())
flickerstreak@122 322 self:UpdateHotkey()
flickerstreak@122 323 self:UpdateShowGrid()
flickerstreak@122 324 self:UpdateIcon()
flickerstreak@122 325 self:UpdateBorder()
flickerstreak@122 326 self:UpdateMacroText()
flickerstreak@122 327 self:UpdateCount()
flickerstreak@122 328 self:UpdateTooltip()
flickerstreak@122 329 self:UpdateCheckedState()
flickerstreak@122 330 self:UpdateUsable()
flickerstreak@122 331 self:UpdateCooldown()
flickerstreak@122 332 self:UpdateFlash()
flickerstreak@122 333 end
flickerstreak@122 334
flickerstreak@122 335 function Action:UpdateAction()
flickerstreak@122 336 local action = self:GetActionID()
flickerstreak@122 337 if action ~= self.actionID then
flickerstreak@122 338 self.actionID = action
flickerstreak@122 339 self:UpdateAll()
flickerstreak@122 340 end
flickerstreak@122 341 end
flickerstreak@122 342
flickerstreak@122 343 function Action:UpdateShowGrid()
flickerstreak@170 344 if not InCombatLockdown() then
flickerstreak@128 345 local f = self:GetFrame()
flickerstreak@128 346 local count = (f:GetAttribute("showgrid-event") or 0) +
flickerstreak@128 347 (self.showGridTempCount or 0) +
flickerstreak@128 348 (f:GetAttribute("showgrid") and 1 or 0)
flickerstreak@128 349
flickerstreak@128 350 if count <= 0 and not HasAction(self.actionID) then
flickerstreak@128 351 if f:IsShown() then
flickerstreak@128 352 f:Hide()
flickerstreak@128 353 end
flickerstreak@128 354 elseif not f:IsShown() then
flickerstreak@122 355 f:Show()
flickerstreak@122 356 end
flickerstreak@122 357 end
flickerstreak@122 358 end
flickerstreak@122 359
flickerstreak@122 360 function Action:UpdateIcon()
flickerstreak@161 361 local texture, tLeft, tRight, tTop, tBottom = self:GetIconTexture()
flickerstreak@122 362 local icon = self.frames.icon
flickerstreak@122 363 local hotkey = self.frames.hotkey
flickerstreak@122 364 local f = self:GetFrame()
flickerstreak@145 365
flickerstreak@145 366 if self.vehicleExitMode then
flickerstreak@145 367 texture = "Interface\\Vehicles\\UI-Vehicles-Button-Exit-Up"
flickerstreak@145 368 icon:SetTexCoord(0.140625, 0.859375, 0.140625, 0.859375)
flickerstreak@159 369 icon:SetVertexColor(1,1,1)
flickerstreak@145 370 else
flickerstreak@145 371 icon:SetTexCoord(0,1,0,1)
flickerstreak@145 372 end
flickerstreak@145 373
flickerstreak@122 374 if texture then
flickerstreak@122 375 icon:SetTexture(texture)
flickerstreak@161 376 if tLeft then
flickerstreak@161 377 icon:SetTexCoord(tLeft,tRight,tTop,tBottom)
flickerstreak@161 378 end
flickerstreak@122 379 icon:Show()
flickerstreak@122 380 self.rangeTimer = -1
flickerstreak@122 381 f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2")
flickerstreak@122 382 else
flickerstreak@122 383 icon:Hide()
flickerstreak@122 384 self.frames.cooldown:Hide()
flickerstreak@122 385 self.rangeTimer = nil
flickerstreak@159 386 f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot")
flickerstreak@122 387 end
flickerstreak@122 388 end
flickerstreak@122 389
flickerstreak@161 390 function Action:GetIconTexture()
flickerstreak@161 391 return GetActionTexture(self.actionID)
flickerstreak@161 392 end
flickerstreak@161 393
flickerstreak@122 394 function Action:UpdateBorder()
flickerstreak@122 395 local action = self.actionID
flickerstreak@122 396 if ReAction:GetKeybindMode() then
flickerstreak@122 397 self:UpdateKeybindModeDisplay(true)
flickerstreak@122 398 elseif IsEquippedAction(action) then
flickerstreak@122 399 self.frames.border:SetVertexColor(0, 1.0, 0, 0.35)
flickerstreak@122 400 self.frames.border:Show()
flickerstreak@122 401 else
flickerstreak@122 402 self.frames.border:Hide()
flickerstreak@122 403 end
flickerstreak@122 404 end
flickerstreak@122 405
flickerstreak@122 406 function Action:UpdateMacroText()
flickerstreak@122 407 local action = self.actionID
flickerstreak@122 408 if not IsConsumableAction(action) and not IsStackableAction(action) then
flickerstreak@122 409 self.frames.name:SetText(GetActionText(action))
flickerstreak@122 410 else
flickerstreak@122 411 self.frames.name:SetText("")
flickerstreak@122 412 end
flickerstreak@122 413 end
flickerstreak@122 414
flickerstreak@122 415 function Action:UpdateCount()
flickerstreak@122 416 local action = self.actionID
flickerstreak@122 417 if IsConsumableAction(action) or IsStackableAction(action) then
flickerstreak@122 418 self.frames.count:SetText(GetActionCount(action))
flickerstreak@122 419 else
flickerstreak@122 420 self.frames.count:SetText("")
flickerstreak@122 421 end
flickerstreak@122 422 end
flickerstreak@122 423
flickerstreak@122 424 function Action:UpdateTooltip()
flickerstreak@122 425 local f = self:GetFrame()
flickerstreak@122 426 if GameTooltip:GetOwner() == f then
flickerstreak@122 427 self:SetTooltip()
flickerstreak@122 428 end
flickerstreak@122 429 end
flickerstreak@122 430
flickerstreak@122 431 function Action:SetTooltip()
flickerstreak@122 432 local f = self:GetFrame()
flickerstreak@122 433 if GetCVar("UberTooltips") == "1" then
flickerstreak@122 434 GameTooltip_SetDefaultAnchor(GameTooltip, f)
flickerstreak@122 435 else
flickerstreak@165 436 GameTooltip:SetOwner(f,"ANCHOR_RIGHT")
flickerstreak@122 437 end
flickerstreak@122 438 GameTooltip:SetAction(self.actionID)
flickerstreak@122 439 end
flickerstreak@122 440
flickerstreak@122 441 function Action:UpdateCheckedState()
flickerstreak@122 442 local action = self.actionID
flickerstreak@122 443 if IsCurrentAction(action) or IsAutoRepeatAction(action) then
flickerstreak@122 444 self:GetFrame():SetChecked(1)
flickerstreak@122 445 else
flickerstreak@122 446 self:GetFrame():SetChecked(0)
flickerstreak@122 447 end
flickerstreak@122 448 end
flickerstreak@122 449
flickerstreak@122 450 function Action:UpdateUsable()
flickerstreak@161 451 local isUsable, notEnoughMana = self:GetUsable()
flickerstreak@161 452 local noRange = self:GetInRange()
flickerstreak@159 453
flickerstreak@159 454 isUsable = self.vehicleExitMode or (isUsable and not noRange)
flickerstreak@159 455
flickerstreak@159 456 if isUsable then
flickerstreak@159 457 if self.usableStatus ~= "usable" then
flickerstreak@159 458 self.frames.icon:SetVertexColor(1.0, 1.0, 1.0)
flickerstreak@159 459 self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0)
flickerstreak@159 460 self.usableStatus = "usable"
flickerstreak@159 461 end
flickerstreak@159 462 elseif noRange then
flickerstreak@159 463 if self.usableStatus ~= "norange" then
flickerstreak@159 464 self.frames.icon:SetVertexColor(1.0,0.1,0.1)
flickerstreak@159 465 self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0)
flickerstreak@159 466 self.usableStatus = "norange"
flickerstreak@159 467 end
flickerstreak@122 468 elseif notEnoughMana then
flickerstreak@159 469 if self.usableStatus ~= "oom" then
flickerstreak@159 470 self.frames.icon:SetVertexColor(0.5, 0.5, 1.0)
flickerstreak@159 471 self.frames.normalTexture:SetVertexColor(0.5, 0.5, 1.0)
flickerstreak@159 472 self.usableStatus = "oom"
flickerstreak@159 473 end
flickerstreak@122 474 else
flickerstreak@159 475 if self.usableStatus ~= "unusable" then
flickerstreak@159 476 self.frames.icon:SetVertexColor(0.4, 0.4, 0.4)
flickerstreak@159 477 self.frames.normalTexture:SetVertexColor(1.0, 1.0, 1.0)
flickerstreak@159 478 self.usableStatus = "unusable"
flickerstreak@159 479 end
flickerstreak@122 480 end
flickerstreak@122 481 end
flickerstreak@122 482
flickerstreak@161 483 function Action:GetUsable()
flickerstreak@161 484 return IsUsableAction(self.actionID)
flickerstreak@161 485 end
flickerstreak@161 486
flickerstreak@161 487 function Action:GetInRange()
flickerstreak@161 488 return IsActionInRange(self.actionID) == 0
flickerstreak@161 489 end
flickerstreak@161 490
flickerstreak@122 491 function Action:UpdateCooldown()
flickerstreak@161 492 CooldownFrame_SetTimer(self.frames.cooldown, self:GetCooldown())
flickerstreak@161 493 end
flickerstreak@161 494
flickerstreak@161 495 function Action:GetCooldown()
flickerstreak@161 496 return GetActionCooldown(self.actionID)
flickerstreak@122 497 end
flickerstreak@122 498
flickerstreak@122 499 function Action:UpdateFlash()
flickerstreak@122 500 local action = self.actionID
flickerstreak@122 501 self:SetFlash( (IsAttackAction(action) and IsCurrentAction(action)) or IsAutoRepeatAction(action) )
flickerstreak@122 502 end
flickerstreak@122 503
flickerstreak@122 504 function Action:SetFlash(flash)
flickerstreak@122 505 if self.flashing ~= flash then
flickerstreak@122 506 self.flashing = flash
flickerstreak@122 507 self.flashtime = 0
flickerstreak@122 508 if not flash then
flickerstreak@122 509 self.frames.flash:Hide()
flickerstreak@122 510 end
flickerstreak@122 511 self:UpdateCheckedState()
flickerstreak@122 512 end
flickerstreak@122 513 end
flickerstreak@122 514
flickerstreak@122 515 function Action:RunFlash(elapsed)
flickerstreak@122 516 if self.flashing then
flickerstreak@122 517 local flashtime = self.flashtime - elapsed
flickerstreak@122 518 self.flashtime = flashtime
flickerstreak@122 519 if flashtime <= 0 then
flickerstreak@122 520 local overtime = -flashtime
flickerstreak@122 521 if overtime >= ATTACK_BUTTON_FLASH_TIME then
flickerstreak@122 522 overtime = 0
flickerstreak@122 523 end
flickerstreak@122 524 flashtime = ATTACK_BUTTON_FLASH_TIME - overtime
flickerstreak@122 525 local flash = self.frames.flash
flickerstreak@122 526 if flash:IsShown() then
flickerstreak@122 527 flash:Hide()
flickerstreak@122 528 else
flickerstreak@122 529 flash:Show()
flickerstreak@122 530 end
flickerstreak@122 531 end
flickerstreak@122 532 end
flickerstreak@122 533 end
flickerstreak@122 534
flickerstreak@122 535 function Action:RunRangeFinder(elapsed)
flickerstreak@122 536 local rangeTimer = self.rangeTimer
flickerstreak@122 537 if rangeTimer then
flickerstreak@122 538 rangeTimer = rangeTimer - elapsed
flickerstreak@122 539 self.rangeTimer = rangeTimer
flickerstreak@122 540 if rangeTimer <= 0 then
flickerstreak@159 541 self:UpdateUsable()
flickerstreak@123 542 self.rangeTimer = TOOLTIP_UPDATE_TIME
flickerstreak@122 543 end
flickerstreak@122 544 end
flickerstreak@122 545 end
flickerstreak@122 546
flickerstreak@122 547 function Action:GetActionID(page)
flickerstreak@122 548 if page == nil then
flickerstreak@122 549 -- get the effective ID
flickerstreak@122 550 return self:GetFrame():GetAttribute("action")
flickerstreak@122 551 else
flickerstreak@122 552 if page == 1 then
flickerstreak@122 553 return self.config.actionID
flickerstreak@122 554 else
flickerstreak@122 555 return self.config.pageactions and self.config.pageactions[page] or self.config.actionID
flickerstreak@122 556 end
flickerstreak@122 557 end
flickerstreak@122 558 end
flickerstreak@122 559
flickerstreak@122 560 function Action:SetActionID( id, page )
flickerstreak@122 561 id = tonumber(id)
flickerstreak@122 562 page = tonumber(page)
flickerstreak@122 563 if id == nil or id < 1 or id > 120 then
flickerstreak@129 564 ReAction:UserError(L["Action ID range is 1-120"])
flickerstreak@129 565 return
flickerstreak@122 566 end
flickerstreak@122 567 if page and page ~= 1 then
flickerstreak@122 568 if not self.config.pageactions then
flickerstreak@122 569 self.config.pageactions = { }
flickerstreak@122 570 end
flickerstreak@122 571 self:ReleaseActionID(self.config.pageactions[page])
flickerstreak@122 572 self.config.pageactions[page] = id
flickerstreak@122 573 self:AcquireActionID(self.config.pageactions[page])
flickerstreak@122 574 self.frame:SetAttribute("action-page"..page,id)
flickerstreak@122 575 else
flickerstreak@122 576 self:ReleaseActionID(self.config.actionID)
flickerstreak@122 577 self.config.actionID = id
flickerstreak@122 578 self:AcquireActionID(self.config.actionID)
flickerstreak@122 579 self.frame:SetAttribute("action",id)
flickerstreak@122 580 self.frame:SetAttribute("default-action",id)
flickerstreak@122 581 if self.config.pageactions then
flickerstreak@122 582 self.config.pageactions[1] = id
flickerstreak@122 583 self.frame:SetAttribute("action-page1",id)
flickerstreak@122 584 end
flickerstreak@122 585 end
flickerstreak@122 586 end
flickerstreak@122 587
flickerstreak@122 588 function Action:RefreshPages( force )
flickerstreak@128 589 local nPages = self:GetBarConfig().nPages
flickerstreak@122 590 if nPages and (nPages ~= self.nPages or force) then
flickerstreak@122 591 local f = self:GetFrame()
flickerstreak@122 592 local c = self.config.pageactions
flickerstreak@122 593 if nPages > 1 and not c then
flickerstreak@122 594 c = { }
flickerstreak@122 595 self.config.pageactions = c
flickerstreak@122 596 end
flickerstreak@122 597 for i = 1, nPages do
flickerstreak@122 598 if i > 1 then
flickerstreak@122 599 c[i] = self:AcquireActionID(c[i], self.config.actionID + (i-1)*self.bar:GetNumButtons())
flickerstreak@122 600 else
flickerstreak@122 601 c[i] = self.config.actionID -- page 1 is the same as the base actionID
flickerstreak@122 602 end
flickerstreak@129 603 f:SetAttribute("action-page"..i,c[i])
flickerstreak@122 604 end
flickerstreak@122 605 for i = nPages+1, #c do
flickerstreak@122 606 self:ReleaseActionID(c[i])
flickerstreak@122 607 c[i] = nil
flickerstreak@129 608 f:SetAttribute("action-page"..i,nil)
flickerstreak@122 609 end
flickerstreak@122 610 self.nPages = nPages
flickerstreak@122 611 end
flickerstreak@122 612 end
flickerstreak@122 613
flickerstreak@128 614 function Action.SetupBarHeader( bar, config ) -- call this as a static method
flickerstreak@122 615 local f = bar:GetFrame()
flickerstreak@128 616 f:SetAttribute("mindcontrol",config.mindcontrol)
flickerstreak@128 617 f:SetAttribute("vehicle",config.vehicle)
flickerstreak@122 618 f:Execute(
flickerstreak@122 619 [[
flickerstreak@122 620 doMindControl = self:GetAttribute("mindcontrol")
flickerstreak@122 621 doVehicle = self:GetAttribute("vehicle")
flickerstreak@122 622 control:ChildUpdate()
flickerstreak@122 623 ]])
flickerstreak@122 624
flickerstreak@122 625 f:SetAttribute("_onstate-mc", _onstate_mc)
flickerstreak@165 626 RegisterStateDriver(f, "mc", "[vehicleui] vehicle; [bonusbar:5] mc; none")
flickerstreak@122 627
flickerstreak@128 628 f:SetAttribute("lockbuttons",config.lockButtons)
flickerstreak@128 629 f:SetAttribute("lockbuttonscombat",config.lockButtonsCombat)
flickerstreak@122 630 f:Execute(
flickerstreak@122 631 [[
flickerstreak@122 632 lockButtons = self:GetAttribute("lockbuttons")
flickerstreak@122 633 lockButtonsCombat = self:GetAttribute("lockbuttonscombat")
flickerstreak@122 634 ]])
flickerstreak@122 635 end
flickerstreak@122 636
flickerstreak@122 637
flickerstreak@123 638 function Action.SetButtonLock( bar, lock, lockCombat ) -- call this as a static method
flickerstreak@123 639 local f = bar:GetFrame()
flickerstreak@123 640 f:SetAttribute("lockbuttons",lock)
flickerstreak@123 641 f:SetAttribute("lockbuttonscombat",lockCombat)
flickerstreak@123 642 f:Execute(
flickerstreak@123 643 [[
flickerstreak@123 644 lockButtons = self:GetAttribute("lockbuttons")
flickerstreak@123 645 lockButtonsCombat = self:GetAttribute("lockbuttonscombat")
flickerstreak@123 646 ]])
flickerstreak@123 647 end
flickerstreak@123 648
flickerstreak@123 649
flickerstreak@122 650 function Action:ShowVehicleExit(show)
flickerstreak@145 651 self.vehicleExitMode = show and self:GetBarConfig().vehicle
flickerstreak@145 652 self:UpdateIcon()
flickerstreak@122 653 end
flickerstreak@122 654
flickerstreak@122 655 function Action:OnEnter( )
flickerstreak@122 656 self:SetTooltip()
flickerstreak@122 657 end
flickerstreak@122 658
flickerstreak@122 659 function Action:OnLeave( )
flickerstreak@122 660 GameTooltip:Hide()
flickerstreak@122 661 end
flickerstreak@122 662
flickerstreak@122 663 function Action:OnAttributeChanged( attr, value )
flickerstreak@161 664 if attr ~= "statehidden" then
flickerstreak@161 665 self:UpdateAction()
flickerstreak@161 666 end
flickerstreak@122 667 end
flickerstreak@122 668
flickerstreak@122 669 function Action:PostClick( )
flickerstreak@122 670 self:UpdateCheckedState()
flickerstreak@122 671 end
flickerstreak@122 672
flickerstreak@122 673 function Action:OnUpdate( elapsed )
flickerstreak@122 674 self:RunFlash(elapsed)
flickerstreak@122 675 self:RunRangeFinder(elapsed)
flickerstreak@122 676 end
flickerstreak@122 677
flickerstreak@122 678 function Action:OnDragStart()
flickerstreak@122 679 self:UpdateCheckedState()
flickerstreak@122 680 self:UpdateFlash()
flickerstreak@122 681 end
flickerstreak@122 682
flickerstreak@122 683 function Action:OnReceiveDrag()
flickerstreak@122 684 self:UpdateCheckedState()
flickerstreak@122 685 self:UpdateFlash()
flickerstreak@122 686 end
flickerstreak@122 687
flickerstreak@122 688 function Action:OnEvent(event, ...)
flickerstreak@122 689 if self[event] then
flickerstreak@122 690 self[event](self, event, ...)
flickerstreak@122 691 end
flickerstreak@122 692 end
flickerstreak@122 693
flickerstreak@122 694 function Action:ACTIONBAR_SLOT_CHANGED(event, action)
flickerstreak@122 695 if action == 0 or action == self.actionID then
flickerstreak@128 696 self:UpdateAll()
flickerstreak@122 697 end
flickerstreak@122 698 end
flickerstreak@122 699
flickerstreak@122 700 function Action:PLAYER_ENTERING_WORLD()
flickerstreak@122 701 self:UpdateAction()
flickerstreak@122 702 end
flickerstreak@122 703
flickerstreak@122 704 function Action:ACTIONBAR_PAGE_CHANGED()
flickerstreak@122 705 self:UpdateAction()
flickerstreak@122 706 end
flickerstreak@122 707
flickerstreak@122 708 function Action:UPDATE_BONUS_ACTIONBAR()
flickerstreak@122 709 self:UpdateAction()
flickerstreak@122 710 end
flickerstreak@122 711
flickerstreak@122 712 function Action:UPDATE_BINDINGS()
flickerstreak@122 713 self:UpdateHotkey()
flickerstreak@122 714 end
flickerstreak@122 715
flickerstreak@122 716 function Action:PLAYER_TARGET_CHANGED()
flickerstreak@122 717 self.rangeTimer = -1
flickerstreak@122 718 end
flickerstreak@122 719
flickerstreak@122 720 function Action:ACTIONBAR_UPDATE_STATE()
flickerstreak@122 721 self:UpdateCheckedState()
flickerstreak@122 722 end
flickerstreak@124 723
flickerstreak@124 724 function Action:TRADE_SKILL_SHOW()
flickerstreak@124 725 self:UpdateCheckedState()
flickerstreak@124 726 end
flickerstreak@124 727 Action.TRADE_SKILL_CLOSE = Action.TRADE_SKILL_CLOSE
flickerstreak@122 728
flickerstreak@122 729 function Action:UNIT_ENTERED_VEHICLE(event,unit)
flickerstreak@122 730 if unit == "player" then
flickerstreak@122 731 self:UpdateCheckedState()
flickerstreak@122 732 end
flickerstreak@122 733 end
flickerstreak@122 734 Action.UNIT_EXITED_VEHICLE = Action.UNIT_ENTERED_VEHICLE
flickerstreak@122 735
flickerstreak@122 736 function Action:COMPANION_UPDATE(event,unit)
flickerstreak@122 737 if unit == "mount" then
flickerstreak@122 738 self:UpdateCheckedState()
flickerstreak@122 739 end
flickerstreak@122 740 end
flickerstreak@122 741
flickerstreak@122 742 function Action:ACTIONBAR_UPDATE_USABLE()
flickerstreak@122 743 self:UpdateUsable()
flickerstreak@122 744 end
flickerstreak@122 745
flickerstreak@122 746 function Action:ACTIONBAR_UPDATE_COOLDOWN()
flickerstreak@122 747 self:UpdateCooldown()
flickerstreak@122 748 end
flickerstreak@122 749
flickerstreak@122 750 function Action:PLAYER_ENTER_COMBAT()
flickerstreak@122 751 if IsAttackAction(self.actionID) then
flickerstreak@122 752 self:SetFlash(true)
flickerstreak@122 753 end
flickerstreak@122 754 end
flickerstreak@122 755
flickerstreak@122 756 function Action:PLAYER_LEAVE_COMBAT()
flickerstreak@122 757 if IsAttackAction(self.actionID) then
flickerstreak@122 758 self:SetFlash(false)
flickerstreak@122 759 end
flickerstreak@122 760 end
flickerstreak@122 761
flickerstreak@122 762 function Action:START_AUTOREPEAT_SPELL()
flickerstreak@122 763 if IsAutoRepeatAction(self.actionID) then
flickerstreak@122 764 self:SetFlash(true)
flickerstreak@122 765 end
flickerstreak@122 766 end
flickerstreak@122 767
flickerstreak@122 768 function Action:STOP_AUTOREPEAT_SPELL()
flickerstreak@122 769 if not IsAttackAction(self.actionID) then
flickerstreak@122 770 self:SetFlash(false)
flickerstreak@122 771 end
flickerstreak@122 772 end
flickerstreak@122 773
flickerstreak@165 774 function Action:UNIT_INVENTORY_CHANGED(unit)
flickerstreak@165 775 if unit == "player" then
flickerstreak@165 776 self:UpdateTooltip()
flickerstreak@165 777 end
flickerstreak@165 778 end
flickerstreak@165 779
flickerstreak@165 780 function Action:LEARNED_SPELL_IN_TAB()
flickerstreak@165 781 self:UpdateTooltip()
flickerstreak@165 782 end