annotate SkeletonKey/KeyButton.lua @ 50:1aba8a6fd4a9

- fix kb.bindings content and define a generic function for constructing its keystrings - handle hotkey text for actions placed in multiple slots -- hotkey.actionbar generates a cache table for use during binding changes
author Nenue
date Fri, 19 Aug 2016 01:12:56 -0400
parents 9a9d7f2a7c07
children 81a7c71c4483
rev   line source
Nenue@14 1 -- SkeletonKey
Nenue@27 2 -- KeyButton.lua
Nenue@14 3 -- Created: 7/28/2016 11:26 PM
Nenue@14 4 -- %file-revision%
Nenue@16 5 -- Code dealing with the slot button innards; they are invoked by frame script and should only chain to Set/Release
Nenue@14 6
Nenue@14 7 local kb, print = LibStub('LibKraken').register(KeyBinder, 'Slot')
Nenue@17 8 local L = kb.L
Nenue@17 9 local CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_PETACTION, CURSOR_TEXTURE
Nenue@14 10 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544
Nenue@15 11 local BORDER_UNASSIGNED = {0.2,0.2,0.2,1}
Nenue@15 12 local BORDER_ASSIGNED = {1,1,1,1}
Nenue@14 13 local BORDER_DYNAMIC = {1,1,0,1}
Nenue@14 14 local BORDER_PENDING = {1,0.5,0,1 }
Nenue@14 15 local BUTTON_HEADERS = {
Nenue@14 16 ['spell'] = SPELLS,
Nenue@14 17 ['macro'] = MACRO,
Nenue@14 18 ['petaction'] = PET,
Nenue@14 19 ['mount'] = MOUNT,
Nenue@14 20 ['battlepet'] = BATTLEPET,
Nenue@14 21
Nenue@14 22
Nenue@14 23 [5] = PROFESSIONS_FIRST_AID,
Nenue@14 24 [7] = PROFESSIONS_COOKING,
Nenue@14 25 [9] = PROFESSIONS_FISHING,
Nenue@14 26 [10] = PROFESSIONS_ARCHAEOLOGY,
Nenue@14 27
Nenue@14 28 }
Nenue@14 29
Nenue@30 30 local PROFESSION_HEADERS = {
Nenue@30 31 [1] = 'Profession 1',
Nenue@30 32 [2] = 'Profession 2',
Nenue@30 33 [3] = 10,
Nenue@30 34 [4] = 7,
Nenue@30 35 [5] = 9,
Nenue@30 36 [6] = 5
Nenue@30 37 }
Nenue@30 38
Nenue@14 39 -- This is needed to identify a spells that aren't reflected by GetCursorInfo()
Nenue@27 40 kb.OnPickupPetAction = function(slot, ...)
Nenue@17 41 local isPickup = GetCursorInfo()
Nenue@17 42 print(slot, ...)
Nenue@17 43 if kb.PetCache.action[slot] then
Nenue@17 44 if isPickup then
Nenue@17 45 local key, _, texture = unpack(kb.PetCache.action[slot])
Nenue@17 46 local spellName = _G[key] or key
Nenue@17 47 if spellName and kb.PetCache.spellslot[spellName] then
Nenue@17 48 CURSOR_SPELLSLOT = kb.PetCache.spellslot[spellName][1]
Nenue@17 49 CURSOR_BOOKTYPE = BOOKTYPE_PET
Nenue@17 50 CURSOR_TEXTURE = _G[texture] or texture
Nenue@17 51 end
Nenue@17 52 else
Nenue@17 53 CURSOR_SPELLSLOT = nil
Nenue@17 54 CURSOR_BOOKTYPE = nil
Nenue@17 55 CURSOR_TEXTURE = nil
Nenue@17 56 end
Nenue@27 57 print('|cFFFF4400PickupPetAction|r', isPickup, CURSOR_PETACTION)
Nenue@17 58 end
Nenue@15 59
Nenue@17 60 local name, subtext, texture, isToken = GetPetActionInfo(slot)
Nenue@17 61 if name then
Nenue@27 62 kb.PetCache.action[slot] = {name, subtext, texture, isToken}
Nenue@17 63 end
Nenue@15 64
Nenue@15 65
Nenue@17 66 print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE)
Nenue@15 67
Nenue@27 68 end
Nenue@27 69
Nenue@27 70 kb.OnPickupSpellBookItem = function(slot, bookType)
Nenue@27 71 print('|cFFFF4400PickupSpellBookItem('.. tostring(slot).. ', '..tostring(bookType)..')')
Nenue@27 72 CURSOR_SPELLSLOT = slot
Nenue@27 73 CURSOR_BOOKTYPE = bookType
Nenue@27 74 CURSOR_TEXTURE = GetSpellBookItemTexture(slot, bookType)
Nenue@27 75 print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE)
Nenue@27 76 end
Nenue@27 77
Nenue@27 78 kb.CreateHooks = function()
Nenue@27 79 hooksecurefunc("PickupSpellBookItem", kb.OnPickupSpellBookItem)
Nenue@27 80 hooksecurefunc("PickupPetAction", kb.OnPickupPetAction)
Nenue@27 81 end
Nenue@14 82
Nenue@14 83
Nenue@14 84 kb.DropToSlot = function(self)
Nenue@14 85 print(self:GetName(),'|cFF0088FFreceived|r')
Nenue@14 86 local actionType, actionID, subType, subData = GetCursorInfo()
Nenue@14 87 print('GetCursorInfo', GetCursorInfo())
Nenue@14 88 if actionType then
Nenue@14 89
Nenue@14 90 if actionType == 'flyout' then
Nenue@14 91 ClearCursor()
Nenue@14 92 ResetCursor()
Nenue@14 93 return
Nenue@14 94 end
Nenue@14 95
Nenue@14 96
Nenue@15 97 local name, icon, _
Nenue@14 98 local pickupID, pickupBook
Nenue@14 99
Nenue@14 100 if actionType == 'spell' then
Nenue@14 101 actionID = subData
Nenue@14 102 name, _, icon = GetSpellInfo(actionID)
Nenue@14 103
Nenue@14 104 elseif actionType == 'macro' then
Nenue@14 105 name, icon = GetMacroInfo(actionID)
Nenue@14 106 elseif actionType == 'petaction' then
Nenue@15 107 if CURSOR_SPELLSLOT and CURSOR_BOOKTYPE then
Nenue@14 108
Nenue@15 109 local spellType, spellID = GetSpellBookItemInfo(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE)
Nenue@15 110 local spellName, spellText = GetSpellBookItemName(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE)
Nenue@15 111 if spellType == 'PETACTION' then
Nenue@17 112 name = spellName
Nenue@15 113 actionID = spellText
Nenue@17 114 icon = CURSOR_TEXTURE
Nenue@15 115 else
Nenue@15 116 name, _, icon = GetSpellInfo(spellID)
Nenue@15 117 actionID = spellID
Nenue@15 118 end
Nenue@15 119
Nenue@15 120 pickupID = CURSOR_SPELLSLOT
Nenue@15 121 pickupBook = CURSOR_BOOKTYPE
Nenue@15 122 else
Nenue@15 123
Nenue@14 124 end
Nenue@14 125
Nenue@14 126 elseif actionType == 'mount' then
Nenue@14 127 if subType == 0 then
Nenue@14 128 name, _, icon = GetSpellInfo(SUMMON_RANDOM_FAVORITE_MOUNT_SPELL)
Nenue@14 129 actionID = 0
Nenue@14 130 else
Nenue@14 131 name, _, icon = C_MountJournal.GetMountInfoByID(actionID)
Nenue@14 132 end
Nenue@14 133 elseif actionType == 'item' then
Nenue@14 134 name = GetItemInfo(actionID)
Nenue@14 135 icon = GetItemIcon(actionID)
Nenue@14 136 actionID = name
Nenue@14 137 elseif actionType == 'battlepet' then
Nenue@14 138
Nenue@14 139 local speciesID, customName, level, xp, maxXp, displayID, isFavorite, petName, petIcon, petType, creatureID = C_PetJournal.GetPetInfoByPetID(detail);
Nenue@14 140 name = customName or petName
Nenue@14 141 icon = petIcon
Nenue@14 142
Nenue@14 143 end
Nenue@15 144 local macroName, macroText, command = kb.RegisterAction(actionType, actionID, name)
Nenue@14 145
Nenue@14 146
Nenue@14 147 local isAssigned, isBound, assignedBy, boundBy = kb.IsCommandBound(self, command)
Nenue@14 148 if isAssigned then
Nenue@14 149 local popup = StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"]
Nenue@14 150 popup.slot = self
Nenue@14 151 popup.text = "Currently assigned in |cFFFFFF00"..tostring(kb.configHeaders[assignedBy]).."|r. Are you sure?"
Nenue@14 152 popup.oldProfile = assignedBy
Nenue@14 153 popup.args = {command, name, icon, actionType, actionID, macroName, macroText, pickupID, pickupBook }
Nenue@14 154 kb:SetScript('OnMouseWheel', nil) -- disable scrolling
Nenue@14 155 StaticPopup_Show('SKELETONKEY_CONFIRM_ASSIGN_SLOT')
Nenue@14 156 else
Nenue@14 157 kb.SetSlot(self, command, name, icon, actionType, actionID, macroName, macroText, pickupID, pickupBook)
Nenue@14 158 kb.UpdateSlot(self)
Nenue@14 159 self.active = nil
Nenue@14 160 ClearCursor()
Nenue@14 161 ResetCursor()
Nenue@14 162 end
Nenue@14 163 end
Nenue@14 164 end
Nenue@14 165
Nenue@14 166
Nenue@14 167 do
Nenue@14 168 local PickupAction = {
Nenue@14 169 spell = _G.PickupSpell,
Nenue@14 170 petaction = _G.PickupSpellBookItem,
Nenue@14 171 macro = _G.PickupMacro,
Nenue@14 172 item = _G.PickupItem,
Nenue@14 173 mount = _G.C_MountJournal.Pickup
Nenue@14 174 }
Nenue@14 175 local GetPickupValue = {
Nenue@14 176 spell = function(self) return select(7, GetSpellInfo(self.actionID)) end,
Nenue@14 177 petaction = function(self) return self.pickupSlot, self.pickupBook end,
Nenue@14 178 }
Nenue@14 179 kb.PickupSlot = function(self)
Nenue@15 180 if not (self.command and self.isAvailable) then
Nenue@14 181 return
Nenue@14 182 end
Nenue@14 183 print(self.actionType)
Nenue@14 184 if self.actionType == 'spell' then
Nenue@14 185 -- It can't be picked up if SpellInfo(name) returns void
Nenue@14 186 local dummy = GetSpellInfo(self.actionName)
Nenue@14 187 if not dummy then
Nenue@14 188 return
Nenue@14 189 end
Nenue@14 190 end
Nenue@14 191 if PickupAction[self.actionType] then
Nenue@14 192 if GetPickupValue[self.actionType] then
Nenue@14 193 PickupAction[self.actionType](GetPickupValue[self.actionType](self))
Nenue@14 194 else
Nenue@14 195 PickupAction[self.actionType](self.actionID)
Nenue@14 196 end
Nenue@14 197 kb.ReleaseSlot(self)
Nenue@14 198 kb.UpdateSlot(self)
Nenue@14 199 end
Nenue@14 200 end
Nenue@14 201 end
Nenue@14 202
Nenue@17 203 kb.UnbindSlot = function(self)
Nenue@17 204
Nenue@17 205 local keys = {GetBindingKey(self.command) }
Nenue@27 206 if #keys >= 1 then
Nenue@27 207 kb.UpdateBindingsCache(self.actionType, self.actionID, {})
Nenue@27 208 end
Nenue@27 209
Nenue@27 210
Nenue@17 211 --print('detected', #keys, 'bindings')
Nenue@17 212 for i, key in pairs(keys) do
Nenue@17 213 --print('clearing', key)
Nenue@17 214 SetBinding(key, nil)
Nenue@17 215 SaveBindings(GetCurrentBindingSet())
Nenue@17 216 if kb.currentProfile.bindings[key] then
Nenue@18 217 --kb:print(L('BINDING_REMOVED', self.actionName, kb.currentHeader))
Nenue@17 218 kb.currentProfile.bindings[key] = nil
Nenue@17 219 end
Nenue@17 220 if kb.currentProfile.talents[self.actionName] then
Nenue@17 221 kb.currentProfile.talents[self.actionName] = nil
Nenue@17 222 end
Nenue@50 223
Nenue@50 224 kb.bindings[tostring(self.actionType)..'_'..tostring(self.actionID)] = nil
Nenue@17 225 end
Nenue@17 226 if kb.currentProfile.bound[self.command] then
Nenue@17 227 kb.currentProfile.bound[self.command] = nil
Nenue@17 228 --kb:print(BINDING_REMOVED:format(self.actionName, configHeaders[db.bindMode]))
Nenue@17 229 end
Nenue@17 230
Nenue@27 231
Nenue@17 232 self.active = false
Nenue@17 233 kb.UpdateSlot(self, true)
Nenue@17 234 end
Nenue@17 235
Nenue@17 236 --- Updates the current KeyBinding for the button's command
Nenue@17 237 kb.SaveSlot = function(self, key)
Nenue@17 238
Nenue@17 239 if not self.command then
Nenue@17 240 return
Nenue@17 241 end
Nenue@17 242 print('|cFFFFFF00received|cFFFFFF00', self:GetID(), '|cFF00FFFF', key)
Nenue@17 243
Nenue@17 244 local modifier = ''
Nenue@17 245 if IsAltKeyDown() then
Nenue@17 246 modifier = 'ALT-'
Nenue@17 247 end
Nenue@17 248 if IsControlKeyDown() then
Nenue@17 249 modifier = modifier.. 'CTRL-'
Nenue@17 250 end
Nenue@17 251 if IsShiftKeyDown() then
Nenue@17 252 modifier = modifier..'SHIFT-'
Nenue@17 253 end
Nenue@17 254 local binding = modifier..key
Nenue@17 255
Nenue@17 256 if key == 'ESCAPE' then
Nenue@17 257 else
Nenue@19 258 if kb.SystemBindings[binding] then
Nenue@19 259 kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', binding, kb.SystemBindings[binding]))
Nenue@17 260 return
Nenue@17 261 end
Nenue@17 262
Nenue@17 263
Nenue@17 264 if self.command then
Nenue@17 265
Nenue@27 266 local previousCommand = GetBindingAction(binding)
Nenue@27 267 if previousCommand ~= "" and previousCommand ~= self.command then
Nenue@17 268 if kb.SystemBindings[binding] then
Nenue@17 269 -- bounce out if trying to use a protected key
Nenue@17 270 kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', key, GetBindingAction(binding)))
Nenue@17 271 kb.bindingstext:SetText(nil)
Nenue@19 272 return false
Nenue@17 273 end
Nenue@27 274
Nenue@27 275 local actionType, actionID, name = kb.GetCommandAction(previousCommand)
Nenue@27 276 if actionType then
Nenue@27 277 local keys = {GetBindingKey(previousCommand) }
Nenue@27 278 local i = 1
Nenue@27 279 while keys[i] do
Nenue@27 280 if keys[i] == binding then
Nenue@27 281 table.remove(keys, i)
Nenue@27 282 kb.UpdateBindingsCache(actionType, actionID, keys)
Nenue@27 283 break
Nenue@27 284 end
Nenue@27 285 i = i + 1
Nenue@27 286 end
Nenue@27 287 end
Nenue@27 288 end
Nenue@27 289
Nenue@27 290 local currentHotKeys = {GetBindingKey(self.command)}
Nenue@27 291 local found
Nenue@27 292 for i, key in ipairs(currentHotKeys) do
Nenue@27 293 if key == binding then
Nenue@27 294 found = true
Nenue@27 295 kb:print('hotkey already assigned')
Nenue@27 296 end
Nenue@27 297 end
Nenue@27 298 if not found then
Nenue@27 299 table.insert(currentHotKeys, 1, binding)
Nenue@27 300 kb.UpdateBindingsCache(self.actionType, self.actionID, currentHotKeys)
Nenue@17 301 end
Nenue@17 302
Nenue@17 303 self.binding = binding
Nenue@17 304
Nenue@27 305
Nenue@49 306 print('SetBinding', binding, self.command)
Nenue@49 307 SetBinding(self.binding, self.command)
Nenue@17 308 SaveBindings(GetCurrentBindingSet())
Nenue@17 309
Nenue@27 310
Nenue@27 311
Nenue@17 312 local talentInfo
Nenue@17 313 if self.actionType == 'spell' and kb.TalentCache[self.actionID] then
Nenue@17 314 print('conditional binding (talent = "'..self.actionName..'")')
Nenue@17 315 talentInfo = {self.macroName, self.actionName, self.actionType, self.actionID}
Nenue@17 316 local bindings = {GetBindingKey(self.command) }
Nenue@17 317 for i, key in ipairs(bindings) do
Nenue@17 318 tinsert(talentInfo, key)
Nenue@17 319 end
Nenue@17 320 end
Nenue@17 321
Nenue@17 322 for level, profile in ipairs(kb.orderedProfiles) do
Nenue@17 323 if (level == kb.db.bindMode) then
Nenue@17 324 profile.bound[self.command] = true
Nenue@17 325 if talentInfo then
Nenue@17 326 profile.bindings[self.binding] = nil
Nenue@17 327 else
Nenue@17 328 profile.bindings[self.binding] = self.command
Nenue@17 329 end
Nenue@17 330 profile.talents[self.actionName] = talentInfo
Nenue@17 331 else
Nenue@17 332 profile.bindings[self.binding] = nil
Nenue@17 333 profile.bound[self.command] = nil
Nenue@17 334 kb.currentProfile.talents[self.actionName] = nil
Nenue@17 335 end
Nenue@17 336 if kb.currentProfile.talents[self.actionID] then
Nenue@17 337 kb.currentProfile.talents[self.actionID] = nil
Nenue@17 338 end
Nenue@17 339 end
Nenue@17 340
Nenue@17 341 kb:print(L('BINDING_ASSIGNED', self.binding, self.actionName, kb.currentHeader))
Nenue@17 342 end
Nenue@17 343 end
Nenue@17 344 kb.UpdateSlot(self, true)
Nenue@19 345 return true
Nenue@17 346 end
Nenue@14 347
Nenue@14 348
Nenue@14 349 --- Updates profile assignment and button contents
Nenue@14 350 kb.UpdateSlot = function(self, force)
Nenue@14 351 local slot = self:GetID()
Nenue@14 352
Nenue@14 353 if force then
Nenue@14 354 if kb.currentProfile.buttons[slot] then
Nenue@14 355 kb.SetSlot(self, unpack(kb.currentProfile.buttons[slot]))
Nenue@14 356 else
Nenue@14 357 kb.ReleaseSlot(self)
Nenue@14 358 end
Nenue@14 359 end
Nenue@14 360
Nenue@34 361
Nenue@14 362 if self.command then
Nenue@14 363 print('['..slot..'] =', self.command, GetBindingKey(self.command))
Nenue@14 364
Nenue@15 365 if not self.isAvailable then
Nenue@15 366 self.border:SetColorTexture(1,0,0,1)
Nenue@15 367 self.ignoreTexture:Show()
Nenue@14 368 else
Nenue@15 369 self.ignoreTexture:Hide()
Nenue@15 370
Nenue@15 371 if self.pending then
Nenue@15 372 self.border:SetColorTexture(unpack(BORDER_PENDING))
Nenue@15 373 elseif self.isDynamic then
Nenue@15 374 self.border:SetColorTexture(unpack(BORDER_DYNAMIC))
Nenue@15 375 else
Nenue@15 376 self.border:SetColorTexture(unpack(BORDER_ASSIGNED))
Nenue@15 377 end
Nenue@14 378 end
Nenue@14 379
Nenue@15 380
Nenue@14 381 if self.actionType == 'macro' then
Nenue@14 382 self.macro:Show()
Nenue@14 383 else
Nenue@14 384 self.macro:Hide()
Nenue@14 385 if self.actionType == 'spell' then
Nenue@14 386 local dummy = GetSpellInfo(self.actionName)
Nenue@14 387 if not dummy then
Nenue@14 388 self.icon:SetDesaturated(true)
Nenue@14 389 else
Nenue@14 390 self.icon:SetDesaturated(false)
Nenue@14 391 end
Nenue@14 392
Nenue@14 393 end
Nenue@14 394 end
Nenue@14 395
Nenue@14 396 if self.isDynamic then
Nenue@15 397 print('|cFF00BBFFUpdateSlot|r:', self.isDynamic, self.isAvailable, self.actionID)
Nenue@14 398 end
Nenue@14 399
Nenue@14 400 if self.isDynamic == 'profession' then
Nenue@30 401 if self.profIndex then
Nenue@29 402
Nenue@29 403 local profText = (self.spellNum == 1) and TRADE_SKILLS or (BUTTON_HEADERS[self.profIndex] or GetProfessionInfo(self.profIndex))
Nenue@14 404 print(self.profIndex, 'spnum', type(self.spellNum), (self.spellNum == 1))
Nenue@14 405
Nenue@29 406 self.statusText = '|cFFFFFF00'..tostring(profText)..'|r'
Nenue@14 407 self.bindingText = kb.BindingString(GetBindingKey(self.command))
Nenue@14 408 else
Nenue@29 409
Nenue@30 410 self.statusText = '|cFFFF4400'..PROFESSION_HEADERS[self.professionNum]..'|r'
Nenue@29 411 self.actionName = '(#'..self.professionNum..')'
Nenue@14 412 self.bindingText ='?'
Nenue@14 413 end
Nenue@14 414 elseif self.isDynamic == 'talent' then
Nenue@14 415
Nenue@14 416 self.statusText = '|cFF00FFFF'.. TALENT .. '|r'
Nenue@14 417 if self.isAvailable then
Nenue@14 418 self.bindingText = kb.BindingString(GetBindingKey(self.command))
Nenue@14 419 else
Nenue@19 420 if kb.TalentBindings[self.actionID] then
Nenue@19 421 print(self.actionID, #kb.TalentBindings[self.actionID])
Nenue@19 422 self.bindingText= kb.BindingString(unpack(kb.TalentBindings[self.actionID]))
Nenue@14 423 end
Nenue@14 424
Nenue@14 425 end
Nenue@19 426 elseif self.isDynamic == 'petaction' then
Nenue@21 427 local specialType, specialNum = self.command:match("petaction_([%a%s]+)_(%d)")
Nenue@21 428 if specialType and specialNum then
Nenue@21 429 print('pet skill|cFF00FF00', specialType..'|r', specialNum)
Nenue@21 430 self.statusText = L(specialType..' %%d'):format(specialNum)
Nenue@19 431 else
Nenue@19 432 self.statusText = L('Pet Action')
Nenue@19 433 end
Nenue@15 434 self.bindingText = kb.BindingString(GetBindingKey(self.command))
Nenue@14 435 else
Nenue@14 436 self.statusText = '|cFF00FF00'.. (BUTTON_HEADERS[self.actionType] and BUTTON_HEADERS[self.actionType] or self.actionType) .. '|r'
Nenue@14 437 self.bindingText = kb.BindingString(GetBindingKey(self.command))
Nenue@14 438 end
Nenue@14 439
Nenue@14 440 local locked, layer = kb.IsCommandBound(self)
Nenue@14 441 if locked then
Nenue@14 442 self.icon:SetAlpha(0.5)
Nenue@14 443 else
Nenue@14 444 self.icon:SetAlpha(1)
Nenue@14 445 end
Nenue@14 446
Nenue@17 447
Nenue@14 448 if self.actionType == 'spell' then
Nenue@14 449 self.icon:SetTexture(GetSpellTexture(self.actionID))
Nenue@14 450 end
Nenue@21 451 else
Nenue@34 452 if kb.saveTarget == self then
Nenue@34 453 kb.DeactivateSlot(self)
Nenue@34 454 end
Nenue@34 455
Nenue@21 456 self.ignoreTexture:Hide()
Nenue@14 457 end
Nenue@14 458
Nenue@14 459 if not self.isAvailable then
Nenue@14 460 self.bind:SetTextColor(0.7,0.7,0.7,1)
Nenue@14 461 else
Nenue@14 462 self.bind:SetTextColor(1,1,1,1)
Nenue@14 463 end
Nenue@14 464
Nenue@17 465
Nenue@17 466 if kb.saveTarget and kb.saveTarget ~= self then
Nenue@17 467 self:SetAlpha(0.25)
Nenue@17 468 else
Nenue@17 469
Nenue@17 470 self:SetAlpha(1)
Nenue@17 471 end
Nenue@17 472
Nenue@17 473
Nenue@14 474 self.header:SetText(self.statusText)
Nenue@14 475 self.bind:SetText(self.bindingText)
Nenue@14 476 self.details:SetText(self.actionName)
Nenue@14 477 end
Nenue@14 478
Nenue@14 479 --- Resets button command
Nenue@14 480 kb.ReleaseSlot = function(self)
Nenue@14 481 local slot = self:GetID()
Nenue@14 482
Nenue@14 483
Nenue@14 484 if kb.currentProfile.buttons[slot] then
Nenue@14 485 kb.currentProfile.buttons[slot] = nil
Nenue@14 486 end
Nenue@14 487 if self.command then
Nenue@14 488 kb.currentProfile.commands[self.command] = nil
Nenue@14 489 end
Nenue@14 490 if self.actionType == 'spell' and IsTalentSpell(self.actionName) then
Nenue@14 491 if kb.currentProfile.talents[self.actionID] then
Nenue@14 492 kb.currentProfile.talents[self.actionID] = nil
Nenue@14 493 end
Nenue@14 494 end
Nenue@14 495 local droppedKeys = {}
Nenue@14 496
Nenue@14 497 -- doing removal in second loop to avoid possible iterator shenanigans
Nenue@14 498 for k,v in pairs(kb.currentProfile.bindings) do
Nenue@14 499 if v == self.command then
Nenue@14 500 tinsert(droppedKeys, k)
Nenue@14 501 end
Nenue@14 502 end
Nenue@14 503 if #droppedKeys >=1 then
Nenue@14 504 for i, k in ipairs(droppedKeys) do
Nenue@14 505 kb.currentProfile.bindings[k] = nil
Nenue@14 506 end
Nenue@14 507 end
Nenue@14 508
Nenue@14 509 self.isAvailable = nil
Nenue@14 510 self.isDynamic = nil
Nenue@14 511 self.bindingText = nil
Nenue@14 512 self.statusText = nil
Nenue@14 513 self.command = nil
Nenue@14 514 self.actionType = nil
Nenue@14 515 self.actionID = nil
Nenue@14 516 self.actionName = nil
Nenue@14 517 self.pickupSlot = nil
Nenue@14 518 self.pickupBook = nil
Nenue@14 519 self.macroName = nil
Nenue@14 520 self.profile = nil
Nenue@14 521 self.icon:SetTexture(nil)
Nenue@14 522 self.border:SetColorTexture(unpack(BORDER_UNASSIGNED))
Nenue@14 523 self:EnableKeyboard(false)
Nenue@14 524 self:SetScript('OnKeyDown', nil)
Nenue@15 525 self.ignoreTexture:Hide()
Nenue@14 526 end
Nenue@14 527
Nenue@14 528 kb.SetSlot = function(self, command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook)
Nenue@14 529 local slot = self:GetID()
Nenue@14 530 local isDynamic, isAvailable
Nenue@14 531
Nenue@14 532 print('|cFFFFFF00SetSlot|r:', self:GetID())
Nenue@14 533 if command then
Nenue@14 534
Nenue@14 535 if actionType == 'spell' then
Nenue@14 536 local professionNum, spellNum = command:match("profession_(%d)_(%d)")
Nenue@14 537 if (professionNum and spellNum) then
Nenue@14 538 isDynamic = 'profession'
Nenue@14 539 local cacheInfo = kb.ProfessionCache[professionNum..'_'..spellNum]
Nenue@14 540 if cacheInfo then
Nenue@14 541 isAvailable = true
Nenue@14 542 name = cacheInfo.spellName
Nenue@14 543 icon = cacheInfo.icon
Nenue@14 544 actionID = cacheInfo.spellID
Nenue@14 545 self.profIndex = cacheInfo.profIndex
Nenue@14 546 self.spellOffset = cacheInfo.spellOffset
Nenue@30 547 else
Nenue@30 548 print(professionNum, type(professionNum), PROFESSION_HEADERS[tonumber(professionNum)])
Nenue@30 549 local profID = PROFESSION_HEADERS[tonumber(professionNum)]
Nenue@30 550 if type(profID) == 'number' then
Nenue@30 551 local pname, texture, _, _, numSpells, spellOffset = GetProfessionInfo(profID)
Nenue@30 552 self.profIndex = profID
Nenue@30 553 else
Nenue@30 554 name = profID
Nenue@30 555 end
Nenue@30 556
Nenue@14 557 end
Nenue@14 558 print(' Special slot: |cFF00FFFFProfession|r', professionNum, spellNum, isDynamic, isAvailable)
Nenue@14 559
Nenue@14 560 self.professionNum = tonumber(professionNum)
Nenue@14 561 self.spellNum = tonumber(spellNum)
Nenue@14 562
Nenue@14 563 else
Nenue@14 564 if kb.TalentCache[actionID] then
Nenue@14 565 isDynamic = 'talent'
Nenue@14 566 print(' Special slot: |cFFBBFF00talent|r', name, isAvailable)
Nenue@14 567 end
Nenue@14 568
Nenue@14 569 isAvailable = GetSpellInfo(name)
Nenue@14 570 end
Nenue@15 571 elseif actionType == 'petaction' then
Nenue@15 572 isDynamic = 'petaction'
Nenue@21 573 local specialType, specialNum = command:match(actionType..'_([%a%s]+)_(%d)')
Nenue@21 574
Nenue@21 575 if kb.PetCache.subtext[specialType] and kb.PetCache.subtext[specialType][tonumber(specialNum)] then
Nenue@30 576 print('***dynamic pet skill', specialType, specialNum)
Nenue@21 577 --[[ i, spellName, subText, spellID, texture, specialNum[subText ]]
Nenue@21 578 pickupSlot, name, specialType, actionID, icon, specialNum = unpack(kb.PetCache.subtext[specialType][tonumber(specialNum)])
Nenue@21 579 pickupBook = BOOKTYPE_PET
Nenue@21 580 end
Nenue@21 581
Nenue@22 582 isAvailable = (kb.PetCache.spellslot[name])
Nenue@22 583
Nenue@21 584
Nenue@14 585 elseif actionType == 'macro' then
Nenue@14 586 if not actionID then
Nenue@14 587 actionID = GetMacroIndexByName(name)
Nenue@14 588 end
Nenue@14 589 isAvailable = true
Nenue@14 590 else
Nenue@14 591 --- Journal selections
Nenue@14 592 -- todo: consider using the deep end of blizzard action bar instead
Nenue@14 593 if not actionID then
Nenue@14 594 actionID = command:match("^KeyBinderMacro:(.+)")
Nenue@14 595 end
Nenue@14 596 isAvailable = true
Nenue@14 597 end
Nenue@14 598
Nenue@14 599 if isAvailable then
Nenue@14 600 local oldCommand = command
Nenue@14 601 macroName, macroText, command = kb.RegisterAction(actionType, actionID, name)
Nenue@14 602 if oldCommand ~= command then
Nenue@14 603 print('|cFFFF4400fixing command string', actionType, actionID, name)
Nenue@14 604 kb.currentProfile.bound[oldCommand] = nil
Nenue@14 605 kb.currentProfile.bound[command] = slot
Nenue@14 606 for k,v in pairs(kb.currentProfile.bindings) do
Nenue@14 607 if v == oldCommand then
Nenue@14 608 kb.currentProfile.bindings[k] = command
Nenue@14 609 end
Nenue@14 610 end
Nenue@14 611 end
Nenue@14 612 kb.LoadBinding(command, name, icon, actionType, actionID, macroName, macroText)
Nenue@14 613 end
Nenue@14 614
Nenue@14 615
Nenue@14 616 actionID = actionID or 0
Nenue@14 617 self:EnableKeyboard(true)
Nenue@17 618 print(' |cFF00FF00kb.currentProfile.buttons['..slot..'] |cFF00FFFF=|r |cFF00FFFF"'.. command.. '"|r |cFF00FF00"'.. name.. '"|r |cFFFFFF00icon:'.. tostring(icon) .. '|r |cFFFF8800"'.. actionType, '"|r |cFFFF0088id:'.. actionID ..'|r |cFF00FF00"'.. macroName .. '"|r')
Nenue@19 619 kb.currentProfile.buttons[slot] = {command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook }
Nenue@19 620
Nenue@14 621
Nenue@14 622 -- Clean up conflicting entries for loaded button
Nenue@14 623 local previous = kb.currentProfile.commands[command]
Nenue@14 624 if previous ~= slot and kb.buttons[previous] then
Nenue@14 625 kb.ReleaseSlot(kb.buttons[previous])
Nenue@14 626 end
Nenue@19 627
Nenue@19 628 if not (kb.IsCommandBound(self, command) or kb.currentProfile.bound[command]) then
Nenue@19 629
Nenue@19 630 local binds = {GetBindingKey(command) }
Nenue@19 631 if #binds >= 1 then
Nenue@19 632 kb:print('Recovered key binding for', name)
Nenue@19 633 for i, key in ipairs(binds) do
Nenue@19 634 kb.currentProfile.bindings[key] = command
Nenue@19 635 kb.currentProfile.bound[command] = true
Nenue@19 636 end
Nenue@19 637 end
Nenue@19 638 end
Nenue@19 639
Nenue@19 640
Nenue@14 641 kb.currentProfile.commands[command] = slot
Nenue@19 642
Nenue@14 643 end
Nenue@14 644
Nenue@14 645 self.isAvailable = isAvailable
Nenue@14 646 self.isDynamic = isDynamic
Nenue@14 647
Nenue@15 648 self.pickupSlot = pickupSlot
Nenue@15 649 self.pickupBook = pickupBook
Nenue@14 650 self.macroText = macroText
Nenue@14 651 self.macroName = macroName
Nenue@14 652 self.actionType = actionType
Nenue@14 653 self.actionID = actionID
Nenue@14 654 self.actionName = name
Nenue@14 655 self.command = command
Nenue@14 656 self.icon:SetTexture(icon)
Nenue@14 657 self.profile = kb.db.bindMode
Nenue@14 658 self:RegisterForDrag('LeftButton')
Nenue@14 659 end
Nenue@14 660
Nenue@27 661 kb.GetCommandAction = function(command)
Nenue@27 662 for i, data in ipairs(kb.loadedProfiles) do
Nenue@27 663 if data.commands[command] then
Nenue@27 664 if data.buttons[data.commands[command]] then
Nenue@27 665 local _, _, _, actionType, actionID = unpack(data.buttons[data.commands[command]])
Nenue@27 666 return actionType, actionID
Nenue@27 667 end
Nenue@27 668 end
Nenue@27 669 end
Nenue@27 670 end
Nenue@16 671
Nenue@14 672
Nenue@14 673 --- Add to blizzard interfaces
Nenue@14 674 StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"] = {
Nenue@14 675 text = "Confirm moving an assigned command.",
Nenue@14 676 button1 = OKAY,
Nenue@14 677 button2 = CANCEL,
Nenue@14 678 timeout = 0,
Nenue@14 679 whileDead = 1,
Nenue@14 680 showAlert = 1,
Nenue@14 681 OnAccept = kb.AcceptAssignment,
Nenue@14 682 OnCancel = function() kb:SetScript('OnMouseWheel', KeyBinder_OnMouseWheel) end
Nenue@14 683 }