comparison SkeletonKey/KeyBinds.lua @ 0:69e828f4238a

Initial Commit
author Nenue
date Mon, 20 Jun 2016 06:35:11 -0400
parents
children cd7d06bcd98d
comparison
equal deleted inserted replaced
-1:000000000000 0:69e828f4238a
1 --------------------------------------------
2 -- KrakTool
3 -- Nick
4 -- @project-revision@ @project-hash@
5 -- @file-revision@ @file-hash@
6 -- Created: 6/16/2016 3:47 AM
7 --------------------------------------------
8 -- kb
9 -- .bind(button, key) bind current keystroke to command
10 -- .assign(button, command, name, icon) set button command
11 -- .release(button) clear button command
12 -- .refresh(button) update button contents
13 -- .ui() invoke interface
14 -- .profile(name) set profile character
15 -- .loadbinds(bindings) walk table with SetBinding()
16
17 local kb = KeyBinder
18 local KT = select(2,...)
19 KT.register(KeyBinder)
20 local MIN_BIND_SLOTS = 32
21 local BINDS_PER_ROW = 8
22 local KEY_BUTTON_SIZE = 40
23 local TAB_OFFSET = 12
24 local TAB_HEIGHT = 40
25 local TAB_SPACING = 2
26 local BUTTON_SPACING = 4
27 local BUTTON_PADDING = 12
28 local HEADER_OFFSET
29 local FOOTER_OFFSET
30 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544;
31 local BINDING_TYPE_SPECIALIZATION = 3
32 local BINDING_TYPE_CHARACTER = 2
33 local BINDING_TYPE_GLOBAL = 1
34 local BINDING_ASSIGNED = '|cFF00FF00%s|r assigned to |cFFFFFF00%s|r (%s).'
35 local BINDING_FAILED_PROTECTED = '|cFF00FF00%s|r used by |cFFFFFF00%s|r!'
36 local BINDING_MODE = {
37 [BINDING_TYPE_SPECIALIZATION] = 'Specialization: %s',
38 [BINDING_TYPE_CHARACTER] = 'Character: %s',
39 [BINDING_TYPE_GLOBAL] = 'Global Binds'
40 }
41 local BINDING_SCHEME_COLOR = {
42 [BINDING_TYPE_SPECIALIZATION] = {0,0,0,0.5},
43 [BINDING_TYPE_CHARACTER] = {0,0.25,0,0.5},
44 [BINDING_TYPE_GLOBAL] = {0,.125,.5,.5}
45 }
46 local BINDING_SCHEME_VERTEX = {
47
48 [BINDING_TYPE_SPECIALIZATION] = {1,1,1,1},
49 [BINDING_TYPE_CHARACTER] = {0,1,0,1},
50 [BINDING_TYPE_GLOBAL] = {0,.5,1,1}
51 }
52
53 local BINDING_SCHEME_TEXT = {
54 [BINDING_TYPE_SPECIALIZATION] = {1, 1, 0},
55 [BINDING_TYPE_CHARACTER] = {0, 1, 0},
56 [BINDING_TYPE_GLOBAL] = {0, 1, 1}
57 }
58 local ACTION_SCRIPT = {
59 ['mount'] = "/script C_MountJournal.SummonByID(%d)",
60 ['equipset'] = "/script UseEquipmentSet(%d)",
61 }
62
63 local COMMAND_SPELL = "^SPELL (%S.+)"
64 local COMMAND_MACRO = "^MACRO (%S.+)"
65 local COMMAND_ITEM = "^ITEM (%S.+)"
66 local COMMAND_MOUNT = "^CLICK KeyBinderMacro:mount(%d+)"
67 local COMMAND_EQUIPSET = "^CLICK KeyBinderMacro:equipset(%d+)"
68
69 local PICKUP_TYPES = {
70 [COMMAND_SPELL] = PickupSpell,
71 [COMMAND_MACRO] = PickupMacro,
72 [COMMAND_ITEM] = PickupItem,
73 [COMMAND_MOUNT] = C_MountJournal.Pickup,
74 [COMMAND_EQUIPSET] = PickupEquipmentSet
75 }
76 local PICKUP_VALUES = {
77 [COMMAND_SPELL] = function(name) return select(7, GetSpellInfo(name)) end
78 }
79 local CLASS_ICON_TEXTURE = "Interface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES"
80 local BORDER_UNASSIGNED = {0.2,0.2,0.2,1 }
81 local BORDER_ASSIGNED = {0.5,0.5,0.5,1 }
82 local BORDER_PENDING = {1,0.5,0,1 }
83
84
85
86 local bindMode = 3 -- not to be confused with db.bindMode which is boolean
87 local bindHeader = ''
88 local specHeader, specTexture, characterHeader = 'SPEC_NAME', 'Interface\\ICONS\\INV_Misc_QuestionMark', 'PLAYER_NAME'
89 local bindsCommitted = true
90
91 local profile
92 local character
93 local specialization
94 local global
95 local priority = {}
96 local numButtons = BINDS_PER_ROW * 4
97 local buttons = {}
98 local reverts = {}
99 local KeyButton = {} -- collection of KeyButton template handlers
100 local Action = {} -- collection of special action buttons for special binds
101 local protected = {
102 ['OPENCHATSLASH'] = true,
103 ['OPENCHAT'] = true,
104 }
105 local saveButton, restoreButton, clearButton
106
107 --- Returns a value for use with Texture:SetDesaturated()
108 local CommandIsLocked = function(self)
109 print('command check: 1-'..(bindMode-1))
110 local desaturated, layer = false, 3
111 for i = 1, bindMode-1 do
112 local tier = priority[i]
113 local existing = tier.commands[self.command]
114 print(' ', i, tier.commands[self.command])
115 if existing then
116 if self:GetID() ~= existing then
117 -- sanitize bad data
118 tier.commands[self.command] = nil
119 else
120 layer = i
121 desaturated = true
122 break
123 end
124 end
125 end
126 return desaturated, layer
127 end
128
129 --- Returns a value for use with Texture:SetDesaturated()
130 local BindingIsLocked = function(key)
131 local success = false
132 for i = 1, bindMode-1 do
133 local tier = priority[i]
134 if tier.bindings[key] then
135 success = true
136 break
137 end
138 end
139 return success
140 end
141
142 --- Translates GetBindingKey() results into a printable string.
143 local BindingString = function(...)
144 local stack = {}
145 for i = 1, select('#', ...) do
146 local key = select(i, ...)
147 stack[i] = key:gsub('SHIFT', 's'):gsub('ALT', 'a'):gsub('CTRL', 'c'):gsub('SPACE', 'Sp')
148 end
149
150 if #stack >= 1 then
151 return table.concat(stack, ',')
152 else
153 return nil
154 end
155 end
156
157 --- This keeps our KeyDown handler from getting stuck with game controls
158 KeyButton.OnUpdate = function(self)
159 if not self.command then
160 return
161 end
162
163 if self:IsMouseOver() then
164 if not self.active then
165 -- only set this handler when the button is activated/mouseOver
166 self.active = true
167 self:SetScript('OnKeyDown', kb.bind)
168
169 local bindText = self.command
170 if self.bind:GetText() then
171 bindText = bindText .. ': |cFF00FF00' .. self.bind:GetText()
172 end
173
174 kb.bindlist:SetText(bindText)
175 GameTooltip:SetOwner(self)
176 GameTooltip:SetAnchorType('ANCHOR_BOTTOMRIGHT')
177 GameTooltip:SetText(self.actionName)
178 GameTooltip:Show()
179 end
180 else
181 if self.active then
182 GameTooltip:Hide()
183 self.active = nil
184 self:SetScript('OnKeyDown', nil)
185 end
186 end
187 end
188
189 --- Cursor pickup handler
190 -- Walks through PICKUP_TYPES and runs the function if match(command, key) turns up a result.
191 -- Passes the result through PICKUP_VALUES[pattern]() if defined.
192
193 kb.pickup = function(self)
194 for pattern, pickup in pairs(PICKUP_TYPES) do
195 local value = self.command:match(pattern)
196 if value then
197 if PICKUP_VALUES[pattern] then
198 value = PICKUP_VALUES[pattern](value)
199 end
200
201 pickup(value)
202 kb.release(self)
203 break
204 end
205 end
206 end
207
208 --- Setup an action button base on template info
209 kb.action = function(type, id)
210
211 local macroName = type .. id
212 macroName = macroName:gsub(' ', '')
213
214 local attribute = '*macrotext-'..macroName
215 local value = ACTION_SCRIPT[type]:format(id)
216 local command = 'CLICK KeyBinderMacro:'.. macroName
217 profile.macros[attribute] = {value, command}
218
219 KeyBinderMacro:SetAttribute(attribute, value)
220 return command
221 end
222
223 KeyButton.OnDragStart = function(self)
224 if not self.command then
225 return
226 end
227 kb.pickup(self)
228 end
229
230 KeyButton.OnReceiveDrag = function(self, ...)
231 print(self:GetName(),'|cFF0088FFreceived|r', ...)
232 local type, value, subType, subData = GetCursorInfo()
233 print('GetCursorInfo', type, value, subType, subData)
234 if type then
235 if type == 'spell' then
236 value = subData
237 end
238
239 local command, name, icon, _
240 if type == 'spell' then
241 name, _, icon = GetSpellInfo(value)
242 command = 'SPELL ' .. name
243 name = ''
244 elseif type == 'macro' then
245 name, icon = GetMacroInfo(value)
246 command = 'MACRO ' .. name
247 elseif type == 'mount' then
248 if subType == 0 then
249 name, _, icon = GetSpellInfo(SUMMON_RANDOM_FAVORITE_MOUNT_SPELL)
250 value= 0
251 else
252 name, _, icon = C_MountJournal.GetMountInfoByID(value)
253 end
254 command = kb.action(type, value)
255 elseif type == 'item' then
256 name = GetItemInfo(value)
257 icon = GetItemIcon(value)
258 command = 'ITEM ' .. name
259 end
260 kb.assign(self, command, name, icon)
261 kb.refresh(self)
262 ClearCursor()
263 end
264 end
265
266 KeyButton.OnMouseDown = function(self, click)
267 print(self:GetName(), 'OnMouseDown', click)
268 if click == 'LeftButton' then
269 KeyButton.OnReceiveDrag(self)
270 elseif click == 'RightButton' then
271 kb.release(self)
272 else
273 kb.bind(self)
274 end
275 end
276
277
278 --- Updates the current KeyBinding for the button's command
279 kb.bind = function(self, key)
280
281 print('|cFFFFFF00bind|cFFFFFF00', self:GetID(), '|cFF00FFFF', key)
282 if not self.command then
283 return
284 end
285
286 if key:match('[RL]SHIFT') or key:match('[RL]ALT') or key:match('[RL]CTRL') then
287 return
288 end
289
290 if protected[GetBindingAction(key)] then
291 return
292 kb.bindlist:SetText(BINDING_FAILED_PROTECTED:format(key, GetBindingAction(key)))
293 end
294
295 if key == 'ESCAPE' then
296 local key1, key2 = GetBindingKey(self.command)
297 if key1 then
298 SetBinding(key1, nil)
299 print('Unbound', key1)
300 end
301 if key2 then
302 SetBinding(key2, nil)
303 print('Unbound', key2)
304 end
305 self.active = false
306 return
307 end
308
309 local modifier = ''
310 if IsAltKeyDown() then
311 modifier = 'ALT-'
312 end
313 if IsControlKeyDown() then
314 modifier = modifier.. 'CTRL-'
315 end
316 if IsShiftKeyDown() then
317 modifier = modifier..'SHIFT-'
318 end
319
320 if self.command then
321 self.binding = modifier..key
322 self.pending = true
323 self.border:SetColorTexture(1,.5,0, 1)
324
325 local old = GetBindingAction(self.binding)
326 local binding1, binding2, new1, new2
327 if old and old ~= self.command then
328 print('Discarding keybind for', old)
329 local binding1, binding2 = GetBindingKey(old)
330 -- need to preserve argument order
331 end
332 tinsert(reverts, {old, binding1, binding2, new1, new2})
333
334
335 bindsCommitted = false
336 SetBinding(self.binding, self.command)
337 for level, profile in ipairs(priority) do
338 profile.bindings[self.binding] = (level == bindMode) and self.command or nil
339 end
340 print(BINDING_ASSIGNED:format(self.binding, self.command, BINDING_MODE[bindMode]:format(bindHeader)))
341
342 kb.refresh(self)
343 end
344 end
345
346 --- Resets button command
347 kb.release = function(self)
348 local index = self:GetID()
349 self.command = nil
350 self.actionName = nil
351 self.macro:SetText(nil)
352 self.profile = nil
353 self.bind:SetText(nil)
354 self.icon:SetTexture(nil)
355 self.border:SetColorTexture(unpack(BORDER_UNASSIGNED))
356 self:EnableKeyboard(false)
357 self:SetScript('OnKeyDown', nil)
358
359
360 if profile.buttons[index] then
361 profile.buttons[index] = nil
362 end
363 end
364
365 -- Sets button command
366
367 kb.assign = function(self, command, name, icon)
368 local index = self:GetID()
369 print('|cFF00FFFFassign|cFF0088FF', index, '|cFFFFFF00'.. (command or 'none'), '|cFF00FF00'.. (name or ''), '|cFF00FFFF' .. (icon or ''))
370
371
372 if command then
373 if command:match(COMMAND_SPELL) then
374 name = command:match(COMMAND_SPELL)
375 end
376
377
378 self:EnableKeyboard(true)
379 print('profile.buttons['..index..'] |cFF00FFFF=|r ', command, name, icon)
380 profile.buttons[index] = {command, name, icon}
381
382 --- Clean up any residual buttons
383 local previous = profile.commands[command]
384 if previous ~= index and buttons[previous] then
385 kb.release(buttons[previous])
386 end
387
388 profile.commands[command] = index
389 end
390
391 self.profile = bindMode
392 self.actionName = name
393 self.command = command
394 self.icon:SetTexture(icon)
395 self:RegisterForDrag('LeftButton')
396 end
397
398 --- Retrieves button at index; creates said button and instates any stored parameters
399 kb.keyslot = function(index)
400 if not buttons[index] then
401 local button = CreateFrame('CheckButton', 'KeyBinderSlot'..index, kb, 'KeyButton')
402 button:SetScript('OnMouseDown', KeyButton.OnMouseDown)
403 button:SetScript('OnMouseUp', KeyButton.OnMouseUp)
404 button:SetScript('OnUpdate', KeyButton.OnUpdate)
405 button:SetScript('OnDragStart', KeyButton.OnDragStart)
406 button:SetScript('OnReceiveDrag', KeyButton.OnReceiveDrag)
407 button:SetID(index)
408
409 if profile.buttons[index] and type(profile.buttons[index] ) == 'table' then
410 kb.assign(button, unpack(profile.buttons[index] ))
411 else
412 kb.release(button)
413 end
414
415 local x, y = BUTTON_PADDING, - (BUTTON_PADDING + HEADER_OFFSET)
416 if index ~= 1 then
417 local col = mod(index, BINDS_PER_ROW)
418 if col == 0 then
419 col = BINDS_PER_ROW - 1
420 else
421 col = col - 1
422 end
423 x = col * (KEY_BUTTON_SIZE + BUTTON_SPACING) + BUTTON_PADDING
424 y = (ceil(index/ BINDS_PER_ROW)-1) * - (KEY_BUTTON_SIZE + BUTTON_SPACING) - BUTTON_PADDING - HEADER_OFFSET
425 end
426 button:SetSize(KEY_BUTTON_SIZE, KEY_BUTTON_SIZE)
427 button:SetPoint('TOPLEFT', kb, 'TOPLEFT', x, y)
428 button:Show()
429 buttons[index] = button
430 end
431 return buttons[index]
432 end
433
434 --- Updates profile assignment and button contents
435 kb.refresh = function(self)
436 if self.profile ~= bindMode then
437 if profile.buttons[self:GetID()] then
438 kb.assign(self, unpack(profile.buttons[self:GetID()]))
439 else
440 kb.release(self)
441 end
442 end
443
444 if self.command then
445 if self.pending then
446 self.border:SetColorTexture(unpack(BORDER_PENDING))
447 else
448 self.border:SetColorTexture(unpack(BORDER_ASSIGNED))
449 end
450 --self.macro:SetText(self.actionName)
451 self.bind:SetText(BindingString(GetBindingKey(self.command)))
452 local locked, layer = CommandIsLocked(self)
453 self.icon:SetDesaturated(locked)
454 self.icon:SetVertexColor(unpack(BINDING_SCHEME_VERTEX[layer]))
455 else
456 self.border:SetColorTexture(unpack(BORDER_UNASSIGNED))
457 --self.macro:SetText(nil)
458 self.bind:SetText(nil)
459 end
460 end
461
462 local SetupUI = function()
463
464
465 kb.tabAnchor = {'TOPLEFT', kb, 'TOPRIGHT', 2, -TAB_OFFSET}
466 kb.tabGrowth = {'TOPLEFT', nil,'BOTTOMLEFT', 0, -TAB_SPACING}
467 kb.tabSize = {TAB_HEIGHT, TAB_HEIGHT }
468 kb.UIPanelAnchor = {'TOPLEFT', kb, 'TOPLEFT', BUTTON_PADDING + 12, -BUTTON_PADDING}
469 kb.UIPanelGrowth = {'TOPLEFT', nil, 'TOPRIGHT', 14, 0 }
470 kb.controlsAnchor = {'BOTTOMLEFT', kb, BUTTON_PADDING, BUTTON_PADDING }
471 kb.controlsGrowth = {'BOTTOMLEFT', nil, 'BOTTOMRIGHT', BUTTON_SPACING, 0}
472
473 --tab() frame, name, tooltip, texture, coords
474 kb:tab('KeyBinderGlobalTab', BINDING_MODE[1], "Interface\\ICONS\\item_azereansphere", {0.15,.85,.15,.85})
475 kb:tab('KeyBinderCharacterTab', characterHeader, nil)
476 kb:tab('KeyBinderSpecTab', specHeader, specTexture)
477 SetPortraitTexture(KeyBinderCharacterTab.icon, 'player')
478 KeyBinderCharacterTab.icon:SetTexCoord(0.15,.85,.15,.85)
479
480 saveButton = kb:button('KeyBinderSaveButton', 'Save', 'Commit all changes.', nil, kb.save)
481 restoreButton = kb:button('KeyBinderRestoreButton', 'Discard', 'Revert all changes.', nil, kb.restore)
482 clearButton = kb:button('KeyBinderClearButton', 'Clear Page', 'Release all buttons.', nil, kb.ResetProfile)
483
484 kb:uibutton(
485 'KeyBinderSpellBookButton', 'SpellBook', nil,
486 function() ToggleSpellBook(BOOKTYPE_SPELL) end,
487 "Interface\\Spellbook\\Spellbook-Icon")
488 kb:uibutton(
489 'KeyBinderTalentFrameButton', 'Talents', nil,
490 function() ToggleTalentFrame() end,
491 "Interface\\TargetingFrame\\UI-Classes-Circles",
492 CLASS_ICON_TCOORDS[strupper(select(2,UnitClass("player")))])
493
494 kb:uibutton(
495 'KeyBinderMacroFrameButton', 'Macros', nil,
496 function() if MacroFrame then HideUIPanel(MacroFrame) else ShowMacroFrame() end end,
497 "Interface\\MacroFrame\\MacroFrame-Icon")
498
499 kb:uibutton(
500 'KeyBinderInventoryButton', 'Bags', nil,
501 function() OpenAllBags() end,
502 "Interface\\BUTTONS\\Button-Backpack-Up")
503
504 kb.info:SetPoint('TOPLEFT', kb.UIPanels[1], 'BOTTOMLEFT', 0, -BUTTON_SPACING)
505 HEADER_OFFSET = kb.UIPanels[1]:GetHeight() + BUTTON_PADDING
506 FOOTER_OFFSET = saveButton:GetHeight() + BUTTON_PADDING
507 end
508
509 --- Invokes the KeyBinder frame (from the /kb function or some other source)
510 kb.ui = function()
511 if not KT.db.bindMode then
512 return
513 end
514
515 if not kb:IsVisible() then
516 kb:Show()
517 KT.db.bindMode = true
518 end
519
520 if not kb.loaded then
521 SetupUI()
522 kb.loaded = true
523 end
524
525 for i = 1, numButtons do
526 kb.refresh(kb.keyslot(i))
527 end
528
529 if bindMode == BINDING_TYPE_SPECIALIZATION then
530 bindHeader = select(2,GetSpecializationInfo(GetSpecialization()))
531 elseif bindMode == BINDING_TYPE_CHARACTER then
532 bindHeader = UnitName('player')
533 else
534 bindHeader = ''
535 end
536
537 if bindsCommitted then
538 KeyBinderSaveButton:Disable()
539 KeyBinderRestoreButton:Disable()
540 else
541 KeyBinderSaveButton:Enable()
542 KeyBinderRestoreButton:Enable()
543 end
544
545 --- panel attributes
546 local numRows = numButtons/BINDS_PER_ROW
547 kb:SetHeight( numRows * (KEY_BUTTON_SIZE) + (numRows - 1) * BUTTON_SPACING + HEADER_OFFSET + FOOTER_OFFSET + BUTTON_PADDING * 2)
548 kb:SetWidth((BINDS_PER_ROW - 1) * BUTTON_SPACING + BINDS_PER_ROW * KEY_BUTTON_SIZE + BUTTON_PADDING * 2)
549 kb.bg:SetColorTexture(unpack(BINDING_SCHEME_COLOR[bindMode]))
550
551
552 for i, tab in ipairs(kb.tabButtons) do
553
554 local n = tab:GetNormalTexture()
555 local tabTexture = "Interface\\Buttons\\UI-Quickslot2"
556 local left, top, right, bottom = -12, 12, 13, -13
557 if i == bindMode then
558 tabTexture = "Interface\\Buttons\\CheckButtonGlow"
559 left, top, right, bottom = -14, 14, 15, -15
560 end
561 n:SetTexture(tabTexture)
562 n:SetPoint('TOPLEFT', tab, 'TOPLEFT', left, top)
563 n:SetPoint('BOTTOMRIGHT', tab, 'BOTTOMRIGHT', right, bottom)
564 end
565 end
566
567 kb.loadbinds = function (bindings)
568 for key, command in pairs(bindings) do
569 -- store for reversion
570 local oldAction = GetBindingAction(key)
571 if oldAction ~= command then
572 local bind1, bind2 = GetBindingKey(oldAction)
573 if bind1 and not reverts[bind1] then
574 reverts[bind1] = oldAction
575 end
576 if bind2 and not reverts[bind2] then
577 reverts[bind2] = oldAction
578 end
579 end
580 SetBindings(key, command)
581 end
582 SaveBindings()
583 end
584
585 local ACTION_BARS = {
586 'MultiBarBottomLeftButton',
587 'MultiBarBottomRighttButton',
588 'MultiBarLeftButton',
589 'MultiBarRightButton',
590 'ActionButton'
591 }
592 kb.HotKeyText = function ()
593 for _, prefix in ipairs(ACTION_BARS) do
594 for i = 1,12 do
595 local button = _G[prefix .. i]
596 if button and button.action then
597 local type, id, subType, subID = GetActionInfo(button.action)
598 if type == 'spell' then
599 local name = GetSpellInfo(id)
600 local bind, bind2 = GetBindingKey('SPELL '..name)
601 if bind or bind2 then
602 --print('SPELL '..name, GetBindingKey('SPELL '..name))
603 button.HotKey:SetText(BindingString(bind))
604 button.HotKey:Show()
605 end
606 end
607 end
608 end
609 end
610 end
611
612 kb.InitProfile = function(profile)
613 profile.buttons = profile.buttons or {}
614 profile.commands = profile.commands or {}
615 profile.bindings = profile.bindings or {}
616 profile.macros = profile.macros or {}
617 return profile
618 end
619 kb.ResetProfile = function()
620
621 for i, button in pairs(buttons) do
622 kb.release(button)
623 end
624
625 profile.commands = {}
626 profile.bindings = {}
627 profile.macros = {}
628 end
629
630 --- Gives us the profile structure to work with while instating data
631 kb.profile = function(name)
632 KT.db = KT.db or {}
633 global = kb.InitProfile(KT.db)
634 profile = global
635 local subtitle
636 if name then
637 KT.db[name] = KT.db[name] or {}
638 KT.db[name] = kb.InitProfile(KT.db[name])
639 character = KT.db[name]
640 local spec = GetSpecialization()
641 if spec then
642 KT.db[name][spec] = KT.db[name][spec] or {}
643 profile = kb.InitProfile(KT.db[name][spec])
644 bindMode = BINDING_TYPE_SPECIALIZATION
645 subtitle = select(2,GetSpecializationInfo(spec))
646 specialization = KT.db[name][spec]
647 else
648 profile = kb.InitProfile(KT.db[name])
649 bindMode = BINDING_TYPE_CHARACTER
650 subtitle = name
651 specialization = character
652 end
653 end
654 priority = {global, character, specialization }
655
656
657
658 if not KT.db.bindsPage then
659 KT.db.bindsPage = bindMode
660 end
661 bindMode = KT.db.bindsPage
662
663
664 if not BINDING_MODE[bindMode] then
665 bindMode = 3
666 KT.db.bindsPage = 3
667 print('overriding', bindMode)
668 end
669
670 profile = priority[bindMode]
671
672
673 local _
674 _, specHeader, _, specTexture = GetSpecializationInfo(GetSpecialization())
675 print(GetSpecializationInfo(GetSpecialization()))
676 specHeader = BINDING_MODE[2]:format(specHeader)
677 characterHeader = BINDING_MODE[2]:format(UnitName('player'))
678
679 print('Using binding profile |cFF00FF88'..BINDING_MODE[bindMode]:format(subtitle)..'|r')
680 end
681
682 kb.SelectTab = function(self)
683 bindMode = self:GetID()
684 profile = priority[self:GetID()]
685 KT.db.bindsPage = self:GetID()
686 kb.ui()
687 end
688 kb.save = function()
689 SaveBindings(GetCurrentBindingSet())
690 bindsCommitted = true
691 for i, button in ipairs(buttons) do
692 button.pending = false
693 end
694
695 kb.ui()
696 print('Bindings saved.')
697 end
698 kb.restore = function()
699 for i, button in pairs(buttons) do
700 button.pending = false
701 end
702 bindsCommitted = true
703 LoadBindings(GetCurrentBindingSet())
704 print('All changes discarded.')
705 end
706
707 --- Tells all the hud buttons what to do
708 kb.init = function()
709 KeyBinderMacro:SetAttribute('*type*', 'macro')
710 end
711
712 --- Get started
713 kb.variables = function()
714 kb.profile(GetUnitName('player', true))
715 for i = 1, 3 do
716 for attribute, data in pairs(priority[i].macros) do
717 KeyBinderMacro:SetAttribute(attribute, data[1])
718 end
719 end
720
721 kb.UPDATE_BINDINGS()
722 kb:RegisterEvent('UPDATE_BINDINGS')
723 kb:RegisterEvent('UPDATE_MACROS')
724 kb:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED')
725 kb:RegisterEvent('PLAYER_EQUIPMENT_CHANGED')
726 kb:RegisterEvent('PLAYER_REGEN_DISABLED')
727 kb:RegisterEvent('PLAYER_REGEN_ENABLED')
728 kb:RegisterEvent('ACTIONBAR_SLOT_CHANGED')
729 end
730
731 kb.close = function()
732 KT.db.bindMode = false
733 kb:Hide()
734 end
735
736 kb.PLAYER_REGEN_DISABLED = function()
737 if KT.db.bindMode then
738
739 kb:Hide()
740 end
741 end
742
743 kb.PLAYER_REGEN_ENABLED = function()
744 if KT.db.bindMode then
745 kb.ui()
746 end
747 end
748 --- Refresh buttons if macros are updated
749 kb.UPDATE_BINDINGS = function()
750 if KT.db.bindMode then
751 kb.ui()
752 end
753 kb.HotKeyText()
754 end
755
756 kb.ACTIONBAR_SLOT_CHANGED = function()
757 kb.HotKeyText()
758 end
759
760
761
762 kb.UPDATE_MACROS = kb.UPDATE_BINDINGS
763
764
765 SLASH_KB1 = "/kb"
766 SlashCmdList.KB = function()
767 if KT.db.bindMode then
768 KT.db.bindMode = false
769 print('|cFFFFFF00KeyBinds|r trace, |cFFFF0000OFF|r.')
770 kb:Hide()
771 else
772 KT.db.bindMode = true
773 print('|cFFFFFF00KeyBinds|r trace, |cFF00FF00ON|r.')
774 kb.ui()
775 end
776 end