annotate SkeletonKey/KeySlot.lua @ 19:67db6b712bf3

- option checkbutton literals are stored by enclosure - detect and save any old keybindings when a slot is assigned (anything that begins with 'CLICK KeyBinder*' is ours) - mouseover mode key input will stay active after leaving a button - button border flashes when a non-modifier key is pressed
author Nenue
date Sat, 30 Jul 2016 19:08:11 -0400
parents 91398d284a99
children 564015ef0317
rev   line source
Nenue@14 1 -- SkeletonKey
Nenue@14 2 -- KeySlot.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@14 30 -- This is needed to identify a spells that aren't reflected by GetCursorInfo()
Nenue@14 31 hooksecurefunc("PickupSpellBookItem", function(slot, bookType)
Nenue@17 32 print('|cFFFF4400PickupSpellBookItem('.. tostring(slot).. ', '..tostring(bookType)..')')
Nenue@14 33 CURSOR_SPELLSLOT = slot
Nenue@14 34 CURSOR_BOOKTYPE = bookType
Nenue@17 35 CURSOR_TEXTURE = GetSpellBookItemTexture(slot, bookType)
Nenue@17 36 print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE)
Nenue@14 37 end)
Nenue@14 38
Nenue@14 39 -- Pet actions
Nenue@17 40 hooksecurefunc("PickupPetAction", 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@14 52
Nenue@17 53 else
Nenue@17 54 CURSOR_SPELLSLOT = nil
Nenue@17 55 CURSOR_BOOKTYPE = nil
Nenue@17 56 CURSOR_TEXTURE = nil
Nenue@17 57 end
Nenue@17 58 print('|cFFFF4400PickupPetAction|r', isPickup, CURSOR_PETACTION)
Nenue@17 59 end
Nenue@15 60
Nenue@17 61 local name, subtext, texture, isToken = GetPetActionInfo(slot)
Nenue@17 62 if name then
Nenue@17 63 kb.PetCache.action[slot] = {name, subtext, texture, isToken}
Nenue@17 64 end
Nenue@15 65
Nenue@15 66
Nenue@17 67 print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE)
Nenue@15 68
Nenue@17 69 end)
Nenue@14 70
Nenue@14 71
Nenue@14 72 kb.DropToSlot = function(self)
Nenue@14 73 print(self:GetName(),'|cFF0088FFreceived|r')
Nenue@14 74 local actionType, actionID, subType, subData = GetCursorInfo()
Nenue@14 75 print('GetCursorInfo', GetCursorInfo())
Nenue@14 76 if actionType then
Nenue@14 77
Nenue@14 78 if actionType == 'flyout' then
Nenue@14 79 ClearCursor()
Nenue@14 80 ResetCursor()
Nenue@14 81 return
Nenue@14 82 end
Nenue@14 83
Nenue@14 84
Nenue@15 85 local name, icon, _
Nenue@14 86 local pickupID, pickupBook
Nenue@14 87
Nenue@14 88 if actionType == 'spell' then
Nenue@14 89 actionID = subData
Nenue@14 90 name, _, icon = GetSpellInfo(actionID)
Nenue@14 91
Nenue@14 92 elseif actionType == 'macro' then
Nenue@14 93 name, icon = GetMacroInfo(actionID)
Nenue@14 94 elseif actionType == 'petaction' then
Nenue@15 95 if CURSOR_SPELLSLOT and CURSOR_BOOKTYPE then
Nenue@14 96
Nenue@15 97 local spellType, spellID = GetSpellBookItemInfo(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE)
Nenue@15 98 local spellName, spellText = GetSpellBookItemName(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE)
Nenue@15 99 if spellType == 'PETACTION' then
Nenue@17 100 name = spellName
Nenue@15 101 actionID = spellText
Nenue@17 102 icon = CURSOR_TEXTURE
Nenue@15 103 else
Nenue@15 104 name, _, icon = GetSpellInfo(spellID)
Nenue@15 105 actionID = spellID
Nenue@15 106 end
Nenue@15 107
Nenue@15 108 pickupID = CURSOR_SPELLSLOT
Nenue@15 109 pickupBook = CURSOR_BOOKTYPE
Nenue@15 110 else
Nenue@15 111
Nenue@14 112 end
Nenue@14 113
Nenue@14 114 elseif actionType == 'mount' then
Nenue@14 115 if subType == 0 then
Nenue@14 116 name, _, icon = GetSpellInfo(SUMMON_RANDOM_FAVORITE_MOUNT_SPELL)
Nenue@14 117 actionID = 0
Nenue@14 118 else
Nenue@14 119 name, _, icon = C_MountJournal.GetMountInfoByID(actionID)
Nenue@14 120 end
Nenue@14 121 elseif actionType == 'item' then
Nenue@14 122 name = GetItemInfo(actionID)
Nenue@14 123 icon = GetItemIcon(actionID)
Nenue@14 124 actionID = name
Nenue@14 125 elseif actionType == 'battlepet' then
Nenue@14 126
Nenue@14 127 local speciesID, customName, level, xp, maxXp, displayID, isFavorite, petName, petIcon, petType, creatureID = C_PetJournal.GetPetInfoByPetID(detail);
Nenue@14 128 name = customName or petName
Nenue@14 129 icon = petIcon
Nenue@14 130
Nenue@14 131 end
Nenue@15 132 local macroName, macroText, command = kb.RegisterAction(actionType, actionID, name)
Nenue@14 133
Nenue@14 134
Nenue@14 135 local isAssigned, isBound, assignedBy, boundBy = kb.IsCommandBound(self, command)
Nenue@14 136 if isAssigned then
Nenue@14 137 local popup = StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"]
Nenue@14 138 popup.slot = self
Nenue@14 139 popup.text = "Currently assigned in |cFFFFFF00"..tostring(kb.configHeaders[assignedBy]).."|r. Are you sure?"
Nenue@14 140 popup.oldProfile = assignedBy
Nenue@14 141 popup.args = {command, name, icon, actionType, actionID, macroName, macroText, pickupID, pickupBook }
Nenue@14 142 kb:SetScript('OnMouseWheel', nil) -- disable scrolling
Nenue@14 143 StaticPopup_Show('SKELETONKEY_CONFIRM_ASSIGN_SLOT')
Nenue@14 144 else
Nenue@14 145 kb.SetSlot(self, command, name, icon, actionType, actionID, macroName, macroText, pickupID, pickupBook)
Nenue@14 146 kb.UpdateSlot(self)
Nenue@14 147 self.active = nil
Nenue@14 148 ClearCursor()
Nenue@14 149 ResetCursor()
Nenue@14 150 end
Nenue@14 151 end
Nenue@14 152 end
Nenue@14 153
Nenue@14 154
Nenue@14 155 do
Nenue@14 156 local PickupAction = {
Nenue@14 157 spell = _G.PickupSpell,
Nenue@14 158 petaction = _G.PickupSpellBookItem,
Nenue@14 159 macro = _G.PickupMacro,
Nenue@14 160 item = _G.PickupItem,
Nenue@14 161 mount = _G.C_MountJournal.Pickup
Nenue@14 162 }
Nenue@14 163 local GetPickupValue = {
Nenue@14 164 spell = function(self) return select(7, GetSpellInfo(self.actionID)) end,
Nenue@14 165 petaction = function(self) return self.pickupSlot, self.pickupBook end,
Nenue@14 166 }
Nenue@14 167 kb.PickupSlot = function(self)
Nenue@15 168 if not (self.command and self.isAvailable) then
Nenue@14 169 return
Nenue@14 170 end
Nenue@14 171 print(self.actionType)
Nenue@14 172 if self.actionType == 'spell' then
Nenue@14 173 -- It can't be picked up if SpellInfo(name) returns void
Nenue@14 174 local dummy = GetSpellInfo(self.actionName)
Nenue@14 175 if not dummy then
Nenue@14 176 return
Nenue@14 177 end
Nenue@14 178 end
Nenue@14 179 if PickupAction[self.actionType] then
Nenue@14 180 if GetPickupValue[self.actionType] then
Nenue@14 181 PickupAction[self.actionType](GetPickupValue[self.actionType](self))
Nenue@14 182 else
Nenue@14 183 PickupAction[self.actionType](self.actionID)
Nenue@14 184 end
Nenue@14 185 kb.ReleaseSlot(self)
Nenue@14 186 kb.UpdateSlot(self)
Nenue@14 187 end
Nenue@14 188 end
Nenue@14 189 end
Nenue@14 190
Nenue@17 191 kb.UnbindSlot = function(self)
Nenue@17 192
Nenue@17 193 local keys = {GetBindingKey(self.command) }
Nenue@17 194 --print('detected', #keys, 'bindings')
Nenue@17 195 for i, key in pairs(keys) do
Nenue@17 196 --print('clearing', key)
Nenue@17 197 SetBinding(key, nil)
Nenue@17 198 SaveBindings(GetCurrentBindingSet())
Nenue@17 199 if kb.currentProfile.bindings[key] then
Nenue@18 200 --kb:print(L('BINDING_REMOVED', self.actionName, kb.currentHeader))
Nenue@17 201 kb.currentProfile.bindings[key] = nil
Nenue@17 202 end
Nenue@17 203 if kb.currentProfile.talents[self.actionName] then
Nenue@17 204 kb.currentProfile.talents[self.actionName] = nil
Nenue@17 205 end
Nenue@17 206 kb.bindings[self.actionType][self.actionID] = nil
Nenue@17 207 end
Nenue@17 208 if kb.currentProfile.bound[self.command] then
Nenue@17 209 kb.currentProfile.bound[self.command] = nil
Nenue@17 210 --kb:print(BINDING_REMOVED:format(self.actionName, configHeaders[db.bindMode]))
Nenue@17 211 end
Nenue@17 212
Nenue@17 213 self.active = false
Nenue@17 214 kb.UpdateSlot(self, true)
Nenue@17 215 end
Nenue@17 216
Nenue@17 217 --- Updates the current KeyBinding for the button's command
Nenue@17 218 kb.SaveSlot = function(self, key)
Nenue@17 219
Nenue@17 220 if not self.command then
Nenue@17 221 return
Nenue@17 222 end
Nenue@17 223 print('|cFFFFFF00received|cFFFFFF00', self:GetID(), '|cFF00FFFF', key)
Nenue@17 224
Nenue@17 225 local modifier = ''
Nenue@17 226 if IsAltKeyDown() then
Nenue@17 227 modifier = 'ALT-'
Nenue@17 228 end
Nenue@17 229 if IsControlKeyDown() then
Nenue@17 230 modifier = modifier.. 'CTRL-'
Nenue@17 231 end
Nenue@17 232 if IsShiftKeyDown() then
Nenue@17 233 modifier = modifier..'SHIFT-'
Nenue@17 234 end
Nenue@17 235 local binding = modifier..key
Nenue@17 236
Nenue@17 237 if key == 'ESCAPE' then
Nenue@17 238 else
Nenue@19 239 if kb.SystemBindings[binding] then
Nenue@19 240 kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', binding, kb.SystemBindings[binding]))
Nenue@17 241 return
Nenue@17 242 end
Nenue@17 243
Nenue@17 244
Nenue@17 245 if self.command then
Nenue@17 246
Nenue@17 247 local previousAction = GetBindingAction(binding)
Nenue@17 248 if previousAction ~= "" and previousAction ~= self.command then
Nenue@17 249 if kb.SystemBindings[binding] then
Nenue@17 250 -- bounce out if trying to use a protected key
Nenue@17 251 kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', key, GetBindingAction(binding)))
Nenue@17 252 kb.bindingstext:SetText(nil)
Nenue@19 253 return false
Nenue@17 254 else
Nenue@17 255 kb:print('Discarding keybind for', previousAction)
Nenue@17 256 -- todo: sort out retcon'd talent spells
Nenue@17 257 end
Nenue@17 258 end
Nenue@17 259
Nenue@17 260 self.binding = binding
Nenue@17 261
Nenue@17 262 SetBinding(self.binding, self.command)
Nenue@17 263 SaveBindings(GetCurrentBindingSet())
Nenue@17 264
Nenue@17 265 local talentInfo
Nenue@17 266 if self.actionType == 'spell' and kb.TalentCache[self.actionID] then
Nenue@17 267 print('conditional binding (talent = "'..self.actionName..'")')
Nenue@17 268 talentInfo = {self.macroName, self.actionName, self.actionType, self.actionID}
Nenue@17 269 local bindings = {GetBindingKey(self.command) }
Nenue@17 270 for i, key in ipairs(bindings) do
Nenue@17 271 tinsert(talentInfo, key)
Nenue@17 272 end
Nenue@17 273 end
Nenue@17 274
Nenue@17 275 for level, profile in ipairs(kb.orderedProfiles) do
Nenue@17 276 if (level == kb.db.bindMode) then
Nenue@17 277 profile.bound[self.command] = true
Nenue@17 278 if talentInfo then
Nenue@17 279 profile.bindings[self.binding] = nil
Nenue@17 280 else
Nenue@17 281 profile.bindings[self.binding] = self.command
Nenue@17 282 end
Nenue@17 283 profile.talents[self.actionName] = talentInfo
Nenue@17 284 else
Nenue@17 285 profile.bindings[self.binding] = nil
Nenue@17 286 profile.bound[self.command] = nil
Nenue@17 287 kb.currentProfile.talents[self.actionName] = nil
Nenue@17 288 end
Nenue@17 289 if kb.currentProfile.talents[self.actionID] then
Nenue@17 290 kb.currentProfile.talents[self.actionID] = nil
Nenue@17 291 end
Nenue@17 292 end
Nenue@17 293
Nenue@17 294 kb:print(L('BINDING_ASSIGNED', self.binding, self.actionName, kb.currentHeader))
Nenue@17 295 end
Nenue@17 296 end
Nenue@17 297 kb.UpdateSlot(self, true)
Nenue@19 298 return true
Nenue@17 299 end
Nenue@14 300
Nenue@14 301
Nenue@14 302 --- Updates profile assignment and button contents
Nenue@14 303 kb.UpdateSlot = function(self, force)
Nenue@14 304 local slot = self:GetID()
Nenue@14 305
Nenue@14 306 if force then
Nenue@14 307 if kb.currentProfile.buttons[slot] then
Nenue@14 308 kb.SetSlot(self, unpack(kb.currentProfile.buttons[slot]))
Nenue@14 309 else
Nenue@14 310 kb.ReleaseSlot(self)
Nenue@14 311 end
Nenue@14 312 end
Nenue@14 313
Nenue@14 314 if self.command then
Nenue@14 315 print('['..slot..'] =', self.command, GetBindingKey(self.command))
Nenue@14 316
Nenue@15 317 if not self.isAvailable then
Nenue@15 318 self.border:SetColorTexture(1,0,0,1)
Nenue@15 319 self.ignoreTexture:Show()
Nenue@14 320 else
Nenue@15 321 self.ignoreTexture:Hide()
Nenue@15 322
Nenue@15 323 if self.pending then
Nenue@15 324 self.border:SetColorTexture(unpack(BORDER_PENDING))
Nenue@15 325 elseif self.isDynamic then
Nenue@15 326 self.border:SetColorTexture(unpack(BORDER_DYNAMIC))
Nenue@15 327 else
Nenue@15 328 self.border:SetColorTexture(unpack(BORDER_ASSIGNED))
Nenue@15 329 end
Nenue@14 330 end
Nenue@14 331
Nenue@15 332
Nenue@14 333 if self.actionType == 'macro' then
Nenue@14 334 self.macro:Show()
Nenue@14 335 else
Nenue@14 336 self.macro:Hide()
Nenue@14 337 if self.actionType == 'spell' then
Nenue@14 338 local dummy = GetSpellInfo(self.actionName)
Nenue@14 339 if not dummy then
Nenue@14 340 self.icon:SetDesaturated(true)
Nenue@14 341 else
Nenue@14 342 self.icon:SetDesaturated(false)
Nenue@14 343 end
Nenue@14 344
Nenue@14 345 end
Nenue@14 346 end
Nenue@14 347
Nenue@14 348 if self.isDynamic then
Nenue@15 349 print('|cFF00BBFFUpdateSlot|r:', self.isDynamic, self.isAvailable, self.actionID)
Nenue@14 350 end
Nenue@14 351
Nenue@14 352 if self.isDynamic == 'profession' then
Nenue@14 353 local profText = (self.spellNum == 1) and TRADE_SKILLS or (BUTTON_HEADERS[self.profIndex] or GetProfessionInfo(self.profIndex))
Nenue@14 354 if self.isAvailable then
Nenue@14 355 print(self.profIndex, 'spnum', type(self.spellNum), (self.spellNum == 1))
Nenue@14 356
Nenue@14 357 self.statusText = '|cFFFFFF00'..profText..'|r'
Nenue@14 358 self.bindingText = kb.BindingString(GetBindingKey(self.command))
Nenue@14 359 else
Nenue@14 360 self.statusText = '|cFFFF4400'..profText..'|r'
Nenue@14 361 self.actionName = '(need to train profession #'..self.profNum..')'
Nenue@14 362 self.bindingText ='?'
Nenue@14 363 end
Nenue@14 364 elseif self.isDynamic == 'talent' then
Nenue@14 365
Nenue@14 366 self.statusText = '|cFF00FFFF'.. TALENT .. '|r'
Nenue@14 367 if self.isAvailable then
Nenue@14 368 self.bindingText = kb.BindingString(GetBindingKey(self.command))
Nenue@14 369 else
Nenue@19 370 if kb.TalentBindings[self.actionID] then
Nenue@19 371 print(self.actionID, #kb.TalentBindings[self.actionID])
Nenue@19 372 self.bindingText= kb.BindingString(unpack(kb.TalentBindings[self.actionID]))
Nenue@14 373 end
Nenue@14 374
Nenue@14 375 end
Nenue@19 376 elseif self.isDynamic == 'petaction' then
Nenue@19 377 local specialNum = self.command:match("special(%d)")
Nenue@19 378 if specialNum then
Nenue@19 379 self.statusText = L('Pet Special %%d'):format(specialNum)
Nenue@19 380 else
Nenue@19 381 self.statusText = L('Pet Action')
Nenue@19 382 end
Nenue@15 383 self.bindingText = kb.BindingString(GetBindingKey(self.command))
Nenue@14 384 else
Nenue@14 385 self.statusText = '|cFF00FF00'.. (BUTTON_HEADERS[self.actionType] and BUTTON_HEADERS[self.actionType] or self.actionType) .. '|r'
Nenue@14 386 self.bindingText = kb.BindingString(GetBindingKey(self.command))
Nenue@14 387 end
Nenue@14 388
Nenue@14 389 local locked, layer = kb.IsCommandBound(self)
Nenue@14 390 if locked then
Nenue@14 391 self.icon:SetAlpha(0.5)
Nenue@14 392 else
Nenue@14 393 self.icon:SetAlpha(1)
Nenue@14 394 end
Nenue@14 395
Nenue@17 396
Nenue@14 397 if self.actionType == 'spell' then
Nenue@14 398 self.icon:SetTexture(GetSpellTexture(self.actionID))
Nenue@14 399 end
Nenue@14 400 end
Nenue@14 401
Nenue@14 402 if not self.isAvailable then
Nenue@14 403 self.bind:SetTextColor(0.7,0.7,0.7,1)
Nenue@14 404 else
Nenue@14 405 self.bind:SetTextColor(1,1,1,1)
Nenue@14 406 end
Nenue@14 407
Nenue@17 408
Nenue@17 409 if kb.saveTarget and kb.saveTarget ~= self then
Nenue@17 410 self:SetAlpha(0.25)
Nenue@17 411 else
Nenue@17 412
Nenue@17 413 self:SetAlpha(1)
Nenue@17 414 end
Nenue@17 415
Nenue@17 416
Nenue@14 417 self.header:SetText(self.statusText)
Nenue@14 418 self.bind:SetText(self.bindingText)
Nenue@14 419 self.details:SetText(self.actionName)
Nenue@14 420 end
Nenue@14 421
Nenue@14 422 --- Resets button command
Nenue@14 423 kb.ReleaseSlot = function(self)
Nenue@14 424 local slot = self:GetID()
Nenue@14 425
Nenue@14 426
Nenue@14 427 if kb.currentProfile.buttons[slot] then
Nenue@14 428 kb.currentProfile.buttons[slot] = nil
Nenue@14 429 end
Nenue@14 430 if self.command then
Nenue@14 431 kb.currentProfile.commands[self.command] = nil
Nenue@14 432 end
Nenue@14 433 if self.actionType == 'spell' and IsTalentSpell(self.actionName) then
Nenue@14 434 if kb.currentProfile.talents[self.actionID] then
Nenue@14 435 kb.currentProfile.talents[self.actionID] = nil
Nenue@14 436 end
Nenue@14 437 end
Nenue@14 438 local droppedKeys = {}
Nenue@14 439
Nenue@14 440 -- doing removal in second loop to avoid possible iterator shenanigans
Nenue@14 441 for k,v in pairs(kb.currentProfile.bindings) do
Nenue@14 442 if v == self.command then
Nenue@14 443 tinsert(droppedKeys, k)
Nenue@14 444 end
Nenue@14 445 end
Nenue@14 446 if #droppedKeys >=1 then
Nenue@14 447 for i, k in ipairs(droppedKeys) do
Nenue@14 448 kb.currentProfile.bindings[k] = nil
Nenue@14 449 end
Nenue@14 450 end
Nenue@14 451
Nenue@14 452 self.isAvailable = nil
Nenue@14 453 self.isDynamic = nil
Nenue@14 454 self.bindingText = nil
Nenue@14 455 self.statusText = nil
Nenue@14 456 self.command = nil
Nenue@14 457 self.actionType = nil
Nenue@14 458 self.actionID = nil
Nenue@14 459 self.actionName = nil
Nenue@14 460 self.pickupSlot = nil
Nenue@14 461 self.pickupBook = nil
Nenue@14 462 self.macroName = nil
Nenue@14 463 self.profile = nil
Nenue@14 464 self.icon:SetTexture(nil)
Nenue@14 465 self.border:SetColorTexture(unpack(BORDER_UNASSIGNED))
Nenue@14 466 self:EnableKeyboard(false)
Nenue@14 467 self:SetScript('OnKeyDown', nil)
Nenue@15 468 self.ignoreTexture:Hide()
Nenue@14 469 end
Nenue@14 470
Nenue@14 471 kb.SetSlot = function(self, command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook)
Nenue@14 472 local slot = self:GetID()
Nenue@14 473 local isDynamic, isAvailable
Nenue@14 474
Nenue@14 475 print('|cFFFFFF00SetSlot|r:', self:GetID())
Nenue@14 476 if command then
Nenue@14 477
Nenue@14 478 if actionType == 'spell' then
Nenue@14 479 local professionNum, spellNum = command:match("profession_(%d)_(%d)")
Nenue@14 480 if (professionNum and spellNum) then
Nenue@14 481 isDynamic = 'profession'
Nenue@14 482 local cacheInfo = kb.ProfessionCache[professionNum..'_'..spellNum]
Nenue@14 483 if cacheInfo then
Nenue@14 484 isAvailable = true
Nenue@14 485 name = cacheInfo.spellName
Nenue@14 486 icon = cacheInfo.icon
Nenue@14 487 actionID = cacheInfo.spellID
Nenue@14 488 self.profIndex = cacheInfo.profIndex
Nenue@14 489 self.spellOffset = cacheInfo.spellOffset
Nenue@14 490 end
Nenue@14 491 print(' Special slot: |cFF00FFFFProfession|r', professionNum, spellNum, isDynamic, isAvailable)
Nenue@14 492
Nenue@14 493 self.professionNum = tonumber(professionNum)
Nenue@14 494 self.spellNum = tonumber(spellNum)
Nenue@14 495
Nenue@14 496 else
Nenue@14 497 if kb.TalentCache[actionID] then
Nenue@14 498 isDynamic = 'talent'
Nenue@14 499 print(' Special slot: |cFFBBFF00talent|r', name, isAvailable)
Nenue@14 500 end
Nenue@14 501
Nenue@14 502 isAvailable = GetSpellInfo(name)
Nenue@14 503 end
Nenue@15 504 elseif actionType == 'petaction' then
Nenue@15 505 isDynamic = 'petaction'
Nenue@17 506 isAvailable = (kb.PetCache.spellslot and kb.PetCache.spellslot[name])
Nenue@14 507 elseif actionType == 'macro' then
Nenue@14 508 if not actionID then
Nenue@14 509 actionID = GetMacroIndexByName(name)
Nenue@14 510 end
Nenue@14 511 isAvailable = true
Nenue@14 512 else
Nenue@14 513 --- Journal selections
Nenue@14 514 -- todo: consider using the deep end of blizzard action bar instead
Nenue@14 515 if not actionID then
Nenue@14 516 actionID = command:match("^KeyBinderMacro:(.+)")
Nenue@14 517 end
Nenue@14 518 isAvailable = true
Nenue@14 519 end
Nenue@14 520
Nenue@14 521 if isAvailable then
Nenue@14 522 local oldCommand = command
Nenue@14 523 macroName, macroText, command = kb.RegisterAction(actionType, actionID, name)
Nenue@14 524 if oldCommand ~= command then
Nenue@14 525 print('|cFFFF4400fixing command string', actionType, actionID, name)
Nenue@14 526 kb.currentProfile.bound[oldCommand] = nil
Nenue@14 527 kb.currentProfile.bound[command] = slot
Nenue@14 528 for k,v in pairs(kb.currentProfile.bindings) do
Nenue@14 529 if v == oldCommand then
Nenue@14 530 kb.currentProfile.bindings[k] = command
Nenue@14 531 end
Nenue@14 532 end
Nenue@14 533 end
Nenue@14 534 kb.LoadBinding(command, name, icon, actionType, actionID, macroName, macroText)
Nenue@14 535 end
Nenue@14 536
Nenue@14 537
Nenue@14 538 actionID = actionID or 0
Nenue@14 539 self:EnableKeyboard(true)
Nenue@17 540 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 541 kb.currentProfile.buttons[slot] = {command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook }
Nenue@19 542
Nenue@14 543
Nenue@14 544 -- Clean up conflicting entries for loaded button
Nenue@14 545 local previous = kb.currentProfile.commands[command]
Nenue@14 546 if previous ~= slot and kb.buttons[previous] then
Nenue@14 547 kb.ReleaseSlot(kb.buttons[previous])
Nenue@14 548 end
Nenue@19 549
Nenue@19 550 if not (kb.IsCommandBound(self, command) or kb.currentProfile.bound[command]) then
Nenue@19 551
Nenue@19 552 local binds = {GetBindingKey(command) }
Nenue@19 553 if #binds >= 1 then
Nenue@19 554 kb:print('Recovered key binding for', name)
Nenue@19 555 for i, key in ipairs(binds) do
Nenue@19 556 kb.currentProfile.bindings[key] = command
Nenue@19 557 kb.currentProfile.bound[command] = true
Nenue@19 558 end
Nenue@19 559 end
Nenue@19 560 end
Nenue@19 561
Nenue@19 562
Nenue@14 563 kb.currentProfile.commands[command] = slot
Nenue@19 564
Nenue@14 565 end
Nenue@14 566
Nenue@14 567 self.isAvailable = isAvailable
Nenue@14 568 self.isDynamic = isDynamic
Nenue@14 569
Nenue@15 570 self.pickupSlot = pickupSlot
Nenue@15 571 self.pickupBook = pickupBook
Nenue@14 572 self.macroText = macroText
Nenue@14 573 self.macroName = macroName
Nenue@14 574 self.actionType = actionType
Nenue@14 575 self.actionID = actionID
Nenue@14 576 self.actionName = name
Nenue@14 577 self.command = command
Nenue@14 578 self.icon:SetTexture(icon)
Nenue@14 579 self.profile = kb.db.bindMode
Nenue@14 580 self:RegisterForDrag('LeftButton')
Nenue@14 581 end
Nenue@14 582
Nenue@14 583
Nenue@16 584
Nenue@14 585
Nenue@14 586 --- Add to blizzard interfaces
Nenue@14 587 StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"] = {
Nenue@14 588 text = "Confirm moving an assigned command.",
Nenue@14 589 button1 = OKAY,
Nenue@14 590 button2 = CANCEL,
Nenue@14 591 timeout = 0,
Nenue@14 592 whileDead = 1,
Nenue@14 593 showAlert = 1,
Nenue@14 594 OnAccept = kb.AcceptAssignment,
Nenue@14 595 OnCancel = function() kb:SetScript('OnMouseWheel', KeyBinder_OnMouseWheel) end
Nenue@14 596 }