Mercurial > wow > skeletonkey
comparison SkeletonKey/KeySlot.lua @ 17:500f9b2bd9ac
- for RegisterAction, use a function table instead of that if/then rats nest
- consequently pet bar actions work now
- unlocalize bindings data
- activate keyslot input manually instead of on mouse over
- activate checkbox to keep input mode active
- dynamic buttons update in real time for petaction/talent/profession spells
author | Nenue |
---|---|
date | Sat, 30 Jul 2016 00:08:00 -0400 |
parents | cdd387d39137 |
children | 91398d284a99 |
comparison
equal
deleted
inserted
replaced
16:cdd387d39137 | 17:500f9b2bd9ac |
---|---|
3 -- Created: 7/28/2016 11:26 PM | 3 -- Created: 7/28/2016 11:26 PM |
4 -- %file-revision% | 4 -- %file-revision% |
5 -- Code dealing with the slot button innards; they are invoked by frame script and should only chain to Set/Release | 5 -- Code dealing with the slot button innards; they are invoked by frame script and should only chain to Set/Release |
6 | 6 |
7 local kb, print = LibStub('LibKraken').register(KeyBinder, 'Slot') | 7 local kb, print = LibStub('LibKraken').register(KeyBinder, 'Slot') |
8 local CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_PETACTION | 8 local L = kb.L |
9 local CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_PETACTION, CURSOR_TEXTURE | |
9 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544 | 10 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544 |
10 local BORDER_UNASSIGNED = {0.2,0.2,0.2,1} | 11 local BORDER_UNASSIGNED = {0.2,0.2,0.2,1} |
11 local BORDER_ASSIGNED = {1,1,1,1} | 12 local BORDER_ASSIGNED = {1,1,1,1} |
12 local BORDER_DYNAMIC = {1,1,0,1} | 13 local BORDER_DYNAMIC = {1,1,0,1} |
13 local BORDER_PENDING = {1,0.5,0,1 } | 14 local BORDER_PENDING = {1,0.5,0,1 } |
26 | 27 |
27 } | 28 } |
28 | 29 |
29 -- This is needed to identify a spells that aren't reflected by GetCursorInfo() | 30 -- This is needed to identify a spells that aren't reflected by GetCursorInfo() |
30 hooksecurefunc("PickupSpellBookItem", function(slot, bookType) | 31 hooksecurefunc("PickupSpellBookItem", function(slot, bookType) |
31 print('|cFFFF4400PickupSpellBookItem(..', tostring(slot),', '..tostring(bookType)..')') | 32 print('|cFFFF4400PickupSpellBookItem('.. tostring(slot).. ', '..tostring(bookType)..')') |
32 CURSOR_SPELLSLOT = slot | 33 CURSOR_SPELLSLOT = slot |
33 CURSOR_BOOKTYPE = bookType | 34 CURSOR_BOOKTYPE = bookType |
35 CURSOR_TEXTURE = GetSpellBookItemTexture(slot, bookType) | |
36 print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE) | |
34 end) | 37 end) |
35 | 38 |
36 do | |
37 -- Pet actions | 39 -- Pet actions |
38 local isPickup | 40 hooksecurefunc("PickupPetAction", function(slot, ...) |
39 hooksecurefunc("PickupPetAction", function(slot, ...) | 41 local isPickup = GetCursorInfo() |
40 isPickup = GetCursorInfo() | 42 print(slot, ...) |
41 print(slot, ...) | 43 if kb.PetCache.action[slot] then |
42 | 44 if isPickup then |
43 | 45 local key, _, texture = unpack(kb.PetCache.action[slot]) |
44 if kb.PetCache.action[slot] then | 46 local spellName = _G[key] or key |
45 if isPickup then | 47 if spellName and kb.PetCache.spellslot[spellName] then |
46 local key = kb.PetCache.action[slot][1] | 48 CURSOR_SPELLSLOT = kb.PetCache.spellslot[spellName][1] |
47 local spellName = _G[key] or key | 49 CURSOR_BOOKTYPE = BOOKTYPE_PET |
48 if spellName and kb.PetCache.spellslot[spellName] then | 50 CURSOR_TEXTURE = _G[texture] or texture |
49 print('picked up', spellName, kb.PetCache.spellslot[spellName][1]) | 51 end |
50 CURSOR_SPELLSLOT = kb.PetCache.spellslot[spellName][1] | 52 |
51 CURSOR_BOOKTYPE = BOOKTYPE_PET | 53 else |
52 end | 54 CURSOR_SPELLSLOT = nil |
53 | 55 CURSOR_BOOKTYPE = nil |
54 else | 56 CURSOR_TEXTURE = nil |
55 print('Dropped pet action =', GetPetActionInfo(slot)) | 57 end |
56 end | 58 print('|cFFFF4400PickupPetAction|r', isPickup, CURSOR_PETACTION) |
57 print('|cFFFF4400PickupPetAction|r', isPickup, CURSOR_PETACTION) | 59 end |
58 end | 60 |
59 | 61 local name, subtext, texture, isToken = GetPetActionInfo(slot) |
60 local name, subtext, texture, isToken = GetPetActionInfo(slot) | 62 if name then |
61 if name then | 63 kb.PetCache.action[slot] = {name, subtext, texture, isToken} |
62 kb.PetCache.action[slot] = {name, subtext, texture, isToken} | 64 end |
63 end | 65 |
64 | 66 |
65 end) | 67 print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE) |
66 end | 68 |
69 end) | |
67 | 70 |
68 | 71 |
69 kb.DropToSlot = function(self) | 72 kb.DropToSlot = function(self) |
70 print(self:GetName(),'|cFF0088FFreceived|r') | 73 print(self:GetName(),'|cFF0088FFreceived|r') |
71 local actionType, actionID, subType, subData = GetCursorInfo() | 74 local actionType, actionID, subType, subData = GetCursorInfo() |
92 if CURSOR_SPELLSLOT and CURSOR_BOOKTYPE then | 95 if CURSOR_SPELLSLOT and CURSOR_BOOKTYPE then |
93 | 96 |
94 local spellType, spellID = GetSpellBookItemInfo(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE) | 97 local spellType, spellID = GetSpellBookItemInfo(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE) |
95 local spellName, spellText = GetSpellBookItemName(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE) | 98 local spellName, spellText = GetSpellBookItemName(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE) |
96 if spellType == 'PETACTION' then | 99 if spellType == 'PETACTION' then |
100 name = spellName | |
97 actionID = spellText | 101 actionID = spellText |
102 icon = CURSOR_TEXTURE | |
98 else | 103 else |
99 name, _, icon = GetSpellInfo(spellID) | 104 name, _, icon = GetSpellInfo(spellID) |
100 actionID = spellID | 105 actionID = spellID |
101 end | 106 end |
102 | 107 |
181 kb.UpdateSlot(self) | 186 kb.UpdateSlot(self) |
182 end | 187 end |
183 end | 188 end |
184 end | 189 end |
185 | 190 |
191 kb.UnbindSlot = function(self) | |
192 | |
193 local keys = {GetBindingKey(self.command) } | |
194 --print('detected', #keys, 'bindings') | |
195 for i, key in pairs(keys) do | |
196 --print('clearing', key) | |
197 SetBinding(key, nil) | |
198 SaveBindings(GetCurrentBindingSet()) | |
199 if kb.currentProfile.bindings[key] then | |
200 kb:print(L('BINDING_REMOVED', self.actionName, kb.currentHeader)) | |
201 kb.currentProfile.bindings[key] = nil | |
202 end | |
203 if kb.currentProfile.talents[self.actionName] then | |
204 kb.currentProfile.talents[self.actionName] = nil | |
205 end | |
206 kb.bindings[self.actionType][self.actionID] = nil | |
207 end | |
208 if kb.currentProfile.bound[self.command] then | |
209 kb.currentProfile.bound[self.command] = nil | |
210 --kb:print(BINDING_REMOVED:format(self.actionName, configHeaders[db.bindMode])) | |
211 end | |
212 | |
213 self.active = false | |
214 kb.UpdateSlot(self, true) | |
215 end | |
216 | |
217 --- Updates the current KeyBinding for the button's command | |
218 kb.SaveSlot = function(self, key) | |
219 | |
220 if not self.command then | |
221 return | |
222 end | |
223 print('|cFFFFFF00received|cFFFFFF00', self:GetID(), '|cFF00FFFF', key) | |
224 | |
225 local modifier = '' | |
226 if IsAltKeyDown() then | |
227 modifier = 'ALT-' | |
228 end | |
229 if IsControlKeyDown() then | |
230 modifier = modifier.. 'CTRL-' | |
231 end | |
232 if IsShiftKeyDown() then | |
233 modifier = modifier..'SHIFT-' | |
234 end | |
235 local binding = modifier..key | |
236 | |
237 if key == 'ESCAPE' then | |
238 else | |
239 if kb.SystemBinds[binding] then | |
240 kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', binding, kb.SystemBinds[binding])) | |
241 return | |
242 end | |
243 | |
244 | |
245 if self.command then | |
246 | |
247 local previousKeys | |
248 local previousAction = GetBindingAction(binding) | |
249 local binding1, binding2, new1, new2 | |
250 print(type(previousAction), previousAction) | |
251 if previousAction ~= "" and previousAction ~= self.command then | |
252 if kb.SystemBindings[binding] then | |
253 -- bounce out if trying to use a protected key | |
254 kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', key, GetBindingAction(binding))) | |
255 kb.bindingstext:SetText(nil) | |
256 return | |
257 else | |
258 kb:print('Discarding keybind for', previousAction) | |
259 -- todo: sort out retcon'd talent spells | |
260 end | |
261 end | |
262 | |
263 self.binding = binding | |
264 | |
265 SetBinding(self.binding, self.command) | |
266 SaveBindings(GetCurrentBindingSet()) | |
267 | |
268 local talentInfo | |
269 if self.actionType == 'spell' and kb.TalentCache[self.actionID] then | |
270 print('conditional binding (talent = "'..self.actionName..'")') | |
271 talentInfo = {self.macroName, self.actionName, self.actionType, self.actionID} | |
272 local bindings = {GetBindingKey(self.command) } | |
273 for i, key in ipairs(bindings) do | |
274 tinsert(talentInfo, key) | |
275 end | |
276 end | |
277 | |
278 for level, profile in ipairs(kb.orderedProfiles) do | |
279 if (level == kb.db.bindMode) then | |
280 profile.bound[self.command] = true | |
281 if talentInfo then | |
282 profile.bindings[self.binding] = nil | |
283 else | |
284 profile.bindings[self.binding] = self.command | |
285 end | |
286 profile.talents[self.actionName] = talentInfo | |
287 else | |
288 profile.bindings[self.binding] = nil | |
289 profile.bound[self.command] = nil | |
290 kb.currentProfile.talents[self.actionName] = nil | |
291 end | |
292 if kb.currentProfile.talents[self.actionID] then | |
293 kb.currentProfile.talents[self.actionID] = nil | |
294 end | |
295 end | |
296 | |
297 kb:print(L('BINDING_ASSIGNED', self.binding, self.actionName, kb.currentHeader)) | |
298 end | |
299 end | |
300 kb.UpdateSlot(self, true) | |
301 end | |
186 | 302 |
187 | 303 |
188 --- Updates profile assignment and button contents | 304 --- Updates profile assignment and button contents |
189 kb.UpdateSlot = function(self, force) | 305 kb.UpdateSlot = function(self, force) |
190 local slot = self:GetID() | 306 local slot = self:GetID() |
272 self.icon:SetAlpha(0.5) | 388 self.icon:SetAlpha(0.5) |
273 else | 389 else |
274 self.icon:SetAlpha(1) | 390 self.icon:SetAlpha(1) |
275 end | 391 end |
276 | 392 |
393 | |
277 if self.actionType == 'spell' then | 394 if self.actionType == 'spell' then |
278 self.icon:SetTexture(GetSpellTexture(self.actionID)) | 395 self.icon:SetTexture(GetSpellTexture(self.actionID)) |
279 end | 396 end |
280 end | 397 end |
281 | 398 |
282 if not self.isAvailable then | 399 if not self.isAvailable then |
283 self.bind:SetTextColor(0.7,0.7,0.7,1) | 400 self.bind:SetTextColor(0.7,0.7,0.7,1) |
284 else | 401 else |
285 self.bind:SetTextColor(1,1,1,1) | 402 self.bind:SetTextColor(1,1,1,1) |
286 end | 403 end |
404 | |
405 | |
406 if kb.saveTarget and kb.saveTarget ~= self then | |
407 self:SetAlpha(0.25) | |
408 else | |
409 | |
410 self:SetAlpha(1) | |
411 end | |
412 | |
287 | 413 |
288 self.header:SetText(self.statusText) | 414 self.header:SetText(self.statusText) |
289 self.bind:SetText(self.bindingText) | 415 self.bind:SetText(self.bindingText) |
290 self.details:SetText(self.actionName) | 416 self.details:SetText(self.actionName) |
291 end | 417 end |
346 print('|cFFFFFF00SetSlot|r:', self:GetID()) | 472 print('|cFFFFFF00SetSlot|r:', self:GetID()) |
347 if command then | 473 if command then |
348 | 474 |
349 if actionType == 'spell' then | 475 if actionType == 'spell' then |
350 local professionNum, spellNum = command:match("profession_(%d)_(%d)") | 476 local professionNum, spellNum = command:match("profession_(%d)_(%d)") |
351 | |
352 if (professionNum and spellNum) then | 477 if (professionNum and spellNum) then |
353 isDynamic = 'profession' | 478 isDynamic = 'profession' |
354 local cacheInfo = kb.ProfessionCache[professionNum..'_'..spellNum] | 479 local cacheInfo = kb.ProfessionCache[professionNum..'_'..spellNum] |
355 if cacheInfo then | 480 if cacheInfo then |
356 isAvailable = true | 481 isAvailable = true |
373 | 498 |
374 isAvailable = GetSpellInfo(name) | 499 isAvailable = GetSpellInfo(name) |
375 end | 500 end |
376 elseif actionType == 'petaction' then | 501 elseif actionType == 'petaction' then |
377 isDynamic = 'petaction' | 502 isDynamic = 'petaction' |
378 if kb.PetCache.spellslot and kb.PetCache.spellslot[name] then | 503 isAvailable = (kb.PetCache.spellslot and kb.PetCache.spellslot[name]) |
379 isAvailable = true | |
380 kb.RemoveCacheButton(kb.petFrames, self) | |
381 else | |
382 print('|cFFFF4400OnCacheUpdate, re-do #', slot) | |
383 tinsert(kb.petFrames, self) | |
384 end | |
385 elseif actionType == 'macro' then | 504 elseif actionType == 'macro' then |
386 if not actionID then | 505 if not actionID then |
387 actionID = GetMacroIndexByName(name) | 506 actionID = GetMacroIndexByName(name) |
388 end | 507 end |
389 isAvailable = true | 508 isAvailable = true |
413 end | 532 end |
414 | 533 |
415 | 534 |
416 actionID = actionID or 0 | 535 actionID = actionID or 0 |
417 self:EnableKeyboard(true) | 536 self:EnableKeyboard(true) |
418 print(' |cFF00FF00kb.currentProfile.buttons['..slot..'] |cFF00FFFF=|r |cFF00FFFF"'.. command.. '"|r |cFF00FF00"'.. name.. '"|r |cFFFFFF00icon:'.. icon .. '|r |cFFFF8800"'.. actionType, '"|r |cFFFF0088id:'.. actionID ..'|r |cFF00FF00"'.. macroName .. '"|r') | 537 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') |
419 kb.currentProfile.buttons[slot] = {command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook} | 538 kb.currentProfile.buttons[slot] = {command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook} |
420 | 539 |
421 -- Clean up conflicting entries for loaded button | 540 -- Clean up conflicting entries for loaded button |
422 local previous = kb.currentProfile.commands[command] | 541 local previous = kb.currentProfile.commands[command] |
423 if previous ~= slot and kb.buttons[previous] then | 542 if previous ~= slot and kb.buttons[previous] then |
441 self.profile = kb.db.bindMode | 560 self.profile = kb.db.bindMode |
442 self:RegisterForDrag('LeftButton') | 561 self:RegisterForDrag('LeftButton') |
443 end | 562 end |
444 | 563 |
445 | 564 |
446 --- Updates the current KeyBinding for the button's command | |
447 kb.SaveSlot = function(self, key) | |
448 | |
449 if not self.command then | |
450 return | |
451 end | |
452 | |
453 if key:match('[RL]SHIFT') or key:match('[RL]ALT') or key:match('[RL]CTRL') then | |
454 return | |
455 end | |
456 print('|cFFFFFF00received|cFFFFFF00', self:GetID(), '|cFF00FFFF', key) | |
457 | |
458 local modifier = '' | |
459 if IsAltKeyDown() then | |
460 modifier = 'ALT-' | |
461 end | |
462 if IsControlKeyDown() then | |
463 modifier = modifier.. 'CTRL-' | |
464 end | |
465 if IsShiftKeyDown() then | |
466 modifier = modifier..'SHIFT-' | |
467 end | |
468 local binding = modifier..key | |
469 | |
470 if key == 'ESCAPE' then | |
471 local keys = {GetBindingKey(self.command) } | |
472 --print('detected', #keys, 'bindings') | |
473 for i, key in pairs(keys) do | |
474 --print('clearing', key) | |
475 SetBinding(key, nil) | |
476 SaveBindings(GetCurrentBindingSet()) | |
477 if kb.currentProfile.bindings[key] then | |
478 kb:print(L('BINDING_REMOVED', self.actionName, kb.configHeaders[db.bindMode])) | |
479 kb.currentProfile.bindings[key] = nil | |
480 end | |
481 if kb.currentProfile.talents[self.actionName] then | |
482 kb.currentProfile.talents[self.actionName] = nil | |
483 end | |
484 bindings[self.actionType][self.actionID] = nil | |
485 end | |
486 if kb.currentProfile.bound[self.command] then | |
487 kb.currentProfile.bound[self.command] = nil | |
488 --kb:print(BINDING_REMOVED:format(self.actionName, configHeaders[db.bindMode])) | |
489 end | |
490 | |
491 self.active = false | |
492 else | |
493 if kb.SystemBinds[binding] then | |
494 kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', key, kb.SystemBinds[binding])) | |
495 return | |
496 end | |
497 | |
498 | |
499 if self.command then | |
500 | |
501 local previousKeys | |
502 local previousAction = GetBindingAction(binding) | |
503 local binding1, binding2, new1, new2 | |
504 print(type(previousAction), previousAction) | |
505 if previousAction ~= "" and previousAction ~= self.command then | |
506 if protected[previousAction] then | |
507 -- bounce out if trying to use a protected key | |
508 kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', key, GetBindingAction(binding))) | |
509 kb.bindingstext:SetText(nil) | |
510 return | |
511 else | |
512 kb:print('Discarding keybind for', previousAction) | |
513 -- todo: sort out retcon'd talent spells | |
514 end | |
515 end | |
516 | |
517 self.binding = binding | |
518 | |
519 SetBinding(self.binding, self.command) | |
520 SaveBindings(GetCurrentBindingSet()) | |
521 | |
522 local talentInfo | |
523 if self.actionType == 'spell' and kb.TalentCache[self.actionID] then | |
524 print('conditional binding (talent = "'..self.actionName..'")') | |
525 talentInfo = {self.macroName, self.actionName, self.actionType, self.actionID} | |
526 local bindings = {GetBindingKey(self.command) } | |
527 for i, key in ipairs(bindings) do | |
528 tinsert(talentInfo, key) | |
529 end | |
530 end | |
531 | |
532 for level, profile in ipairs(kb.orderedProfiles) do | |
533 if (level == db.bindMode) then | |
534 profile.bound[self.command] = true | |
535 if talentInfo then | |
536 profile.bindings[self.binding] = nil | |
537 else | |
538 profile.bindings[self.binding] = self.command | |
539 end | |
540 profile.talents[self.actionName] = talentInfo | |
541 else | |
542 profile.bindings[self.binding] = nil | |
543 profile.bound[self.command] = nil | |
544 kb.currentProfile.talents[self.actionName] = nil | |
545 end | |
546 if kb.currentProfile.talents[self.actionID] then | |
547 kb.currentProfile.talents[self.actionID] = nil | |
548 end | |
549 end | |
550 | |
551 kb:print(L('BINDING_ASSIGNED', self.binding, self.actionName, kb.configHeaders[db.bindMode])) | |
552 end | |
553 end | |
554 kb.UpdateSlot(self, true) | |
555 KeyBinderSaveButton:Enable() | |
556 end | |
557 | |
558 | 565 |
559 | 566 |
560 --- Add to blizzard interfaces | 567 --- Add to blizzard interfaces |
561 StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"] = { | 568 StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"] = { |
562 text = "Confirm moving an assigned command.", | 569 text = "Confirm moving an assigned command.", |