Mercurial > wow > skeletonkey
comparison SkeletonKey/SkeletonKey.lua @ 14:82170735e67c
- move co-routine handler to general lib
- slightly better handling of pet actions
| author | Nenue |
|---|---|
| date | Thu, 28 Jul 2016 23:58:53 -0400 |
| parents | SkeletonKey/KeyBinds.lua@eeec4a600064 |
| children | 32d64e42ec9b |
comparison
equal
deleted
inserted
replaced
| 13:eeec4a600064 | 14:82170735e67c |
|---|---|
| 1 -------------------------------------------- | |
| 2 -- SkeletonKey | |
| 3 -- Krakyn-Mal'Ganis | |
| 4 -- @project-revision@ @project-hash@ | |
| 5 -- @file-revision@ @file-hash@ | |
| 6 -- Created: 6/16/2016 3:47 AM | |
| 7 -------------------------------------------- | |
| 8 -- kb | |
| 9 -- .StoreBinding(button, key) bind current keystroke to command | |
| 10 -- .GetSlot(index) return display slot | |
| 11 -- .SetSlot(button, command, name, icon) assign display slot | |
| 12 -- .ReleaseSlot(button) clear button command | |
| 13 -- .UpdateSlot(button) update button contents | |
| 14 -- .SelectProfile(name) set profile character | |
| 15 -- .ApplyBindings(bindings) walk table with SetBinding() | |
| 16 | |
| 17 local _ | |
| 18 local kb, print = LibStub("LibKraken").register(KeyBinder) | |
| 19 local cprint = DEVIAN_WORKSPACE and function(...) _G.print('Cfg', ...) end or function() end | |
| 20 kb.L = setmetatable({}, { | |
| 21 __call = function(t, k, ...) return format(t[k] or '', ...) end | |
| 22 }) | |
| 23 local L = kb.L | |
| 24 | |
| 25 --- Caps Lock literals | |
| 26 local CLICK_KEYBINDER_MACRO = "CLICK KeyBinderMacro:" | |
| 27 local CLICK_KEYBINDER_KEY = "CLICK KeyBinderKey:" | |
| 28 local CLASS_ICON_TEXTURE = "Interface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES" | |
| 29 local FOOTER_OFFSET | |
| 30 local HEADER_OFFSET | |
| 31 L.BINDING_ASSIGNED = '|cFF00FF00%s|r assigned to |cFFFFFF00%s|r (%s).' | |
| 32 L.BINDING_REMOVED = '|cFFFFFF00%s|r (|cFF00FFFF%s|r) unbound.' | |
| 33 L.BINDING_FAILED_PROTECTED = '|cFFFF4400Unable to use |r|cFF00FF00%s|r|cFFFF4400 (currently |cFFFFFF00%s|r|cFFFF4400)|r' | |
| 34 | |
| 35 | |
| 36 local BINDING_TYPE_SPECIALIZATION = 3 | |
| 37 local BINDING_TYPE_CHARACTER = 2 | |
| 38 local BINDING_TYPE_GLOBAL = 1 | |
| 39 | |
| 40 | |
| 41 --- Caps Lock derivatives | |
| 42 local ACTION_SCRIPT = { | |
| 43 ['mount'] = "/script C_MountJournal.SummonByID(%d)", | |
| 44 ['macro'] = "%s", | |
| 45 ['equipset'] = "/script UseEquipmentSet(%d)", | |
| 46 ['spell'] = "/cast %s", | |
| 47 ['petaction'] = "/cast %s", | |
| 48 ['battlepet'] = SLASH_SUMMON_BATTLE_PET1 .. " %s", | |
| 49 ['item'] = "/use %s" | |
| 50 } | |
| 51 | |
| 52 local professionMappings = { | |
| 53 [5] = 3, | |
| 54 [7] = 4, | |
| 55 [9] = 5, | |
| 56 [10] = 6 | |
| 57 } | |
| 58 kb.configTitle = { | |
| 59 [BINDING_TYPE_GLOBAL] = 'Global Binds', | |
| 60 [BINDING_TYPE_CHARACTER] = 'Character: %s', | |
| 61 [BINDING_TYPE_SPECIALIZATION] = 'Specialization: %s' | |
| 62 } | |
| 63 kb.configDescription = { | |
| 64 [BINDING_TYPE_GLOBAL] = 'The bindings are applied globally.', | |
| 65 [BINDING_TYPE_CHARACTER] = 'Applied when you log onto this character.', | |
| 66 [BINDING_TYPE_SPECIALIZATION] = 'Applied when you log onto this character and are that specialization.', | |
| 67 } | |
| 68 | |
| 69 | |
| 70 | |
| 71 kb.inactiveTalentBindings = {} | |
| 72 kb.configHeaders = {} | |
| 73 kb.loadedProfiles = {} | |
| 74 kb.orderedProfiles = {} | |
| 75 kb.buttons = {} | |
| 76 kb.macros = {} | |
| 77 | |
| 78 -- these are sent to plugin | |
| 79 | |
| 80 local bindings = {} | |
| 81 local macros = {} | |
| 82 local talentBindings = {} | |
| 83 | |
| 84 local protected = { | |
| 85 ['OPENCHATSLASH'] = true, | |
| 86 ['OPENCHAT'] = true, | |
| 87 } | |
| 88 | |
| 89 | |
| 90 local db | |
| 91 local bindHeader, currentHeader = '', '' | |
| 92 local specID, specGlobalID, specName, specDesc, specTexture, characterHeader = 0, 0, 'SPEC_NAME', 'SPEC_DESCRIPTION', 'Interface\\ICONS\\INV_Misc_QuestionMark', 'PLAYER_NAME' | |
| 93 local classHeader, className, classID = '', '', 0 | |
| 94 local bindsCommitted = true | |
| 95 local forceButtonUpdate = false | |
| 96 | |
| 97 --- Control handles | |
| 98 local saveButton, restoreButton, clearButton | |
| 99 | |
| 100 --- Returns conflicting assignment and binding profiles for use in displaying confirmations | |
| 101 kb.IsCommandBound = function(self, command) | |
| 102 local isAssigned, assignedBy = false, db.bindMode | |
| 103 local isBound, boundBy = false, db.bindMode | |
| 104 | |
| 105 | |
| 106 command = command or self.command | |
| 107 for i = 1, #kb.orderedProfiles do | |
| 108 local tier = kb.orderedProfiles[i] | |
| 109 if i ~= db.bindMode then | |
| 110 | |
| 111 if tier.commands[command] then | |
| 112 isAssigned = true | |
| 113 assignedBy = i | |
| 114 end | |
| 115 if tier.bound[command] then | |
| 116 isBound = true | |
| 117 boundBy = i | |
| 118 end | |
| 119 | |
| 120 | |
| 121 --print(' *', configHeaders[i], tier.commands[command], tier.bound[command]) | |
| 122 | |
| 123 if isAssigned and isBound then | |
| 124 break | |
| 125 end | |
| 126 end | |
| 127 | |
| 128 end | |
| 129 | |
| 130 print('|cFFFFFF00IsCommandBound:|r', command:gsub(CLICK_KEYBINDER_MACRO, ''),'|r [profile:', db.bindMode .. ']', isAssigned, isBound, assignedBy, boundBy) | |
| 131 return isAssigned, isBound, assignedBy, boundBy | |
| 132 end | |
| 133 | |
| 134 local talentSpellHardCodes = { | |
| 135 [109248] = 'Binding Shot', | |
| 136 } | |
| 137 | |
| 138 --- Returns a value for use with Texture:SetDesaturated() | |
| 139 kb.BindingIsLocked = function(key) | |
| 140 local success = false | |
| 141 for i = 1, db.bindMode-1 do | |
| 142 local tier = kb.orderedProfiles[i] | |
| 143 if tier.bindings[key] then | |
| 144 success = true | |
| 145 break | |
| 146 end | |
| 147 end | |
| 148 return success | |
| 149 end | |
| 150 | |
| 151 --- Translates GetBindingKey() results into a printable string. | |
| 152 kb.BindingString = function(...) | |
| 153 local stack = {} | |
| 154 for i = 1, select('#', ...) do | |
| 155 local key = select(i, ...) | |
| 156 stack[i] = key:gsub('SHIFT', 's'):gsub('ALT', 'a'):gsub('CTRL', 'c'):gsub('SPACE', 'Sp'):gsub('BUTTON', 'M '):gsub('NUMPAD', '# ') | |
| 157 end | |
| 158 | |
| 159 if #stack >= 1 then | |
| 160 return table.concat(stack, ',') | |
| 161 else | |
| 162 return nil | |
| 163 end | |
| 164 end | |
| 165 | |
| 166 | |
| 167 --- Resolve the appropriate command and macroText for the given action parameters | |
| 168 kb.RegisterAction = function(type, id, name) | |
| 169 local macroText, macroName, command = '', '', '' | |
| 170 | |
| 171 if type == 'spell' then | |
| 172 if kb.ProfessionCache[id] then | |
| 173 command = CLICK_KEYBINDER_KEY .. "profession_".. kb.ProfessionCache[id].profOffset .. '_' .. kb.ProfessionCache[id].spellNum | |
| 174 else | |
| 175 command = CLICK_KEYBINDER_KEY ..name | |
| 176 end | |
| 177 else | |
| 178 macroName = type .. ' ' .. name | |
| 179 macroText = ACTION_SCRIPT[type]:format(name) | |
| 180 local baseName, iterative = macroName, 1 | |
| 181 while (macros[macroName] and macros[macroName][1] ~= macroText) do | |
| 182 print(' * cannot use|cFF00FF00', macroName, '|r"'.. (macros[macroName][1] or '') .. '"') | |
| 183 macroName = baseName .. '_' .. iterative | |
| 184 iterative = iterative + 1 | |
| 185 end | |
| 186 if macroName ~= baseName then | |
| 187 print(' * Creating|cFF00FF00', macroName) | |
| 188 else | |
| 189 print(' * Re-using|cFF00FF00', macroName) | |
| 190 end | |
| 191 command = 'CLICK KeyBinderMacro:'.. macroName | |
| 192 macros[macroName] = {macroText, command } | |
| 193 end | |
| 194 | |
| 195 print('RegisterAction', type, id, '->', command , macroText) | |
| 196 return macroName, macroText, command | |
| 197 end | |
| 198 | |
| 199 --- Updates the current KeyBinding for the button's command | |
| 200 kb.StoreBinding = function(self, key) | |
| 201 | |
| 202 if not self.command then | |
| 203 return | |
| 204 end | |
| 205 | |
| 206 if key:match('[RL]SHIFT') or key:match('[RL]ALT') or key:match('[RL]CTRL') then | |
| 207 return | |
| 208 end | |
| 209 print('|cFFFFFF00received|cFFFFFF00', self:GetID(), '|cFF00FFFF', key) | |
| 210 | |
| 211 if key == 'ESCAPE' then | |
| 212 local keys = {GetBindingKey(self.command) } | |
| 213 --print('detected', #keys, 'bindings') | |
| 214 for i, key in pairs(keys) do | |
| 215 --print('clearing', key) | |
| 216 SetBinding(key, nil) | |
| 217 SaveBindings(GetCurrentBindingSet()) | |
| 218 if kb.currentProfile.bindings[key] then | |
| 219 kb:print(L('BINDING_REMOVED', self.actionName, kb.configHeaders[db.bindMode])) | |
| 220 kb.currentProfile.bindings[key] = nil | |
| 221 end | |
| 222 if kb.currentProfile.talents[self.actionName] then | |
| 223 kb.currentProfile.talents[self.actionName] = nil | |
| 224 end | |
| 225 bindings[self.actionType][self.actionID] = nil | |
| 226 end | |
| 227 if kb.currentProfile.bound[self.command] then | |
| 228 kb.currentProfile.bound[self.command] = nil | |
| 229 --kb:print(BINDING_REMOVED:format(self.actionName, configHeaders[db.bindMode])) | |
| 230 end | |
| 231 | |
| 232 bindsCommitted = false | |
| 233 self.active = false | |
| 234 else | |
| 235 | |
| 236 local modifier = '' | |
| 237 if IsAltKeyDown() then | |
| 238 modifier = 'ALT-' | |
| 239 end | |
| 240 if IsControlKeyDown() then | |
| 241 modifier = modifier.. 'CTRL-' | |
| 242 end | |
| 243 if IsShiftKeyDown() then | |
| 244 modifier = modifier..'SHIFT-' | |
| 245 end | |
| 246 | |
| 247 | |
| 248 if self.command then | |
| 249 self.binding = modifier..key | |
| 250 | |
| 251 local previousKeys | |
| 252 local previousAction = GetBindingAction(self.binding) | |
| 253 local binding1, binding2, new1, new2 | |
| 254 print(type(previousAction), previousAction) | |
| 255 if previousAction ~= "" and previousAction ~= self.command then | |
| 256 if protected[previousAction] then | |
| 257 -- bounce out if trying to use a protected key | |
| 258 kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', key, GetBindingAction(previousAction))) | |
| 259 kb.bindingstext:SetText(nil) | |
| 260 return | |
| 261 else | |
| 262 kb:print('Discarding keybind for', previousAction) | |
| 263 -- todo: sort out retcon'd talent spells | |
| 264 end | |
| 265 end | |
| 266 | |
| 267 self.pending = true | |
| 268 | |
| 269 bindsCommitted = false | |
| 270 SetBinding(self.binding, self.command) | |
| 271 SaveBindings(GetCurrentBindingSet()) | |
| 272 | |
| 273 local talentInfo | |
| 274 if self.actionType == 'spell' and kb.TalentCache[self.actionID] then | |
| 275 print('conditional binding (talent = "'..self.actionName..'")') | |
| 276 talentInfo = {self.macroName, self.actionName, self.actionType, self.actionID} | |
| 277 local bindings = {GetBindingKey(self.command) } | |
| 278 for i, key in ipairs(bindings) do | |
| 279 tinsert(talentInfo, key) | |
| 280 end | |
| 281 end | |
| 282 | |
| 283 for level, profile in ipairs(kb.orderedProfiles) do | |
| 284 if (level == db.bindMode) then | |
| 285 profile.bound[self.command] = true | |
| 286 if talentInfo then | |
| 287 profile.bindings[self.binding] = nil | |
| 288 else | |
| 289 profile.bindings[self.binding] = self.command | |
| 290 end | |
| 291 profile.talents[self.actionName] = talentInfo | |
| 292 else | |
| 293 profile.bindings[self.binding] = nil | |
| 294 profile.bound[self.command] = nil | |
| 295 kb.currentProfile.talents[self.actionName] = nil | |
| 296 end | |
| 297 if kb.currentProfile.talents[self.actionID] then | |
| 298 kb.currentProfile.talents[self.actionID] = nil | |
| 299 end | |
| 300 end | |
| 301 | |
| 302 kb:print(L('BINDING_ASSIGNED', self.binding, self.actionName, kb.configHeaders[db.bindMode])) | |
| 303 end | |
| 304 end | |
| 305 kb.UpdateSlot(self, true) | |
| 306 KeyBinderSaveButton:Enable() | |
| 307 end | |
| 308 | |
| 309 | |
| 310 kb.inactiveTalentBindings = {} | |
| 311 kb.ApplyTalentBinding = function(talentInfo, cache) | |
| 312 for i = 5, #talentInfo do | |
| 313 local command = CLICK_KEYBINDER_KEY.. talentInfo[2] | |
| 314 SetBinding(talentInfo[i], command) | |
| 315 cprint(' **', talentInfo[i], '->', command) | |
| 316 tinsert(cache, talentInfo[i]) | |
| 317 end | |
| 318 end | |
| 319 kb.CacheTalentBinding = function(talentInfo, cache) | |
| 320 | |
| 321 local spellID = talentInfo[4] | |
| 322 kb.inactiveTalentBindings[spellID] = kb.inactiveTalentBindings[spellID] or {} | |
| 323 kb.inactiveTalentBindings[spellID] = {select(5,unpack(talentInfo)) } | |
| 324 --cprint(spellID, unpack(kb.inactiveTalentBindings[spellID])) | |
| 325 end | |
| 326 | |
| 327 kb.LoadBinding = function(command, name, icon, actionType, actionID, macroName, macroText ) | |
| 328 | |
| 329 if actionType == 'spell' then | |
| 330 KeyBinderKey:SetAttribute("*type-"..name, actionType) | |
| 331 KeyBinderKey:SetAttribute("*"..actionType.."-"..name, name) | |
| 332 | |
| 333 elseif actionType == 'item' then | |
| 334 KeyBinderKey:SetAttribute("*type-"..name, actionType) | |
| 335 KeyBinderKey:SetAttribute("*"..actionType.."-"..name, name) | |
| 336 elseif actionType == 'macro' then | |
| 337 KeyBinderMacro:SetAttribute("*macro-"..macroName, actionID) | |
| 338 else | |
| 339 KeyBinderMacro:SetAttribute("*macrotext-"..macroName, macroText) | |
| 340 end | |
| 341 | |
| 342 cprint('Loading binding', actionType, actionID) | |
| 343 bindings[actionType] = bindings[actionType] or {} | |
| 344 bindings[actionType][actionID] = bindings[actionType][actionID] or {} | |
| 345 bindings[command] = bindings[actionType][actionID] | |
| 346 return bindings[actionType], actionID | |
| 347 end | |
| 348 | |
| 349 kb.ApplyBindings = function (profile) | |
| 350 cprint('binding profile', profile) | |
| 351 for slot, data in pairs(profile.buttons) do | |
| 352 kb.LoadBinding(unpack(data)) | |
| 353 end | |
| 354 | |
| 355 for key, command in pairs(profile.bindings) do | |
| 356 | |
| 357 cprint(' *', key, '->', command) | |
| 358 | |
| 359 --_G.print('HotKey','loading', key, command) | |
| 360 SetBinding(key, command) | |
| 361 if bindings[command] and not tContains(bindings[command], key) then | |
| 362 tinsert(bindings[command], key) | |
| 363 end | |
| 364 end | |
| 365 | |
| 366 for spellName, talentInfo in pairs(profile.talents) do | |
| 367 local dummy = GetSpellInfo(spellName) | |
| 368 local func = kb.CacheTalentBinding | |
| 369 local dest = kb.inactiveTalentBindings | |
| 370 if dummy then | |
| 371 cprint('|cFFBBFF00Active:|r', dummy) | |
| 372 local macroName, spellName, actionType, actionID = unpack(talentInfo) | |
| 373 bindings[actionType] = bindings[actionType] or {} | |
| 374 bindings[actionType][actionID] = {} | |
| 375 func = kb.ApplyTalentBinding | |
| 376 dest = bindings[actionType][actionID] | |
| 377 else | |
| 378 | |
| 379 cprint('|cFFFF4400Inactive:|r', talentInfo[2]) | |
| 380 end | |
| 381 func(talentInfo, dest) | |
| 382 end | |
| 383 | |
| 384 SaveBindings(GetCurrentBindingSet()) | |
| 385 end | |
| 386 | |
| 387 kb.ApplyAllBindings =function () | |
| 388 table.wipe(kb.inactiveTalentBindings) | |
| 389 | |
| 390 -- reflect action key settings | |
| 391 if GetCVarBool("ActionButtonUseKeyDown") then | |
| 392 KeyBinderMacro:RegisterForClicks("AnyDown") | |
| 393 KeyBinderKey:RegisterForClicks("AnyDown") | |
| 394 else | |
| 395 KeyBinderMacro:RegisterForClicks("AnyUp") | |
| 396 KeyBinderKey:RegisterForClicks("AnyUp") | |
| 397 end | |
| 398 | |
| 399 for i, profile in ipairs(kb.orderedProfiles) do | |
| 400 kb.ApplyBindings(profile) | |
| 401 end | |
| 402 -- do this after to ensure that profession binds are properly overridden | |
| 403 kb.UpdateProfessionInfo() | |
| 404 | |
| 405 | |
| 406 end | |
| 407 | |
| 408 kb.Command = function(args, editor) | |
| 409 if args:match("import") then | |
| 410 kb.ImportCommmit(args) | |
| 411 return | |
| 412 elseif args:match("scan") then | |
| 413 kb.ImportScan(args) | |
| 414 kb.ui() | |
| 415 return | |
| 416 elseif args:match("load") then | |
| 417 kb:ApplyAllBindings() | |
| 418 return | |
| 419 end | |
| 420 | |
| 421 if db.showUI then | |
| 422 db.showUI = false | |
| 423 kb:print('|cFFFFFF00KeyBinds|r trace, |cFFFF0000OFF|r.') | |
| 424 kb:Hide() | |
| 425 else | |
| 426 db.showUI = true | |
| 427 kb:print('|cFFFFFF00KeyBinds|r trace, |cFF00FF00ON|r.') | |
| 428 end | |
| 429 kb.ui(true) | |
| 430 end | |
| 431 | |
| 432 kb.InitProfile = function(profile, prototype) | |
| 433 if not profile then | |
| 434 profile = {} | |
| 435 end | |
| 436 if prototype then | |
| 437 print('appplying prototype', prototype) | |
| 438 for k,v in pairs(prototype) do | |
| 439 if not profile[k] then | |
| 440 profile[k] = v | |
| 441 end | |
| 442 end | |
| 443 end | |
| 444 | |
| 445 profile.bound = profile.bound or {} | |
| 446 profile.buttons = profile.buttons or {} | |
| 447 profile.commands = profile.commands or {} | |
| 448 profile.bindings = profile.bindings or {} | |
| 449 profile.macros = profile.macros or {} | |
| 450 profile.talents = profile.talents or {} | |
| 451 return profile | |
| 452 end | |
| 453 | |
| 454 kb.ResetProfile = function(profile, prototype) | |
| 455 if profile == kb.currentProfile then | |
| 456 for i, button in pairs(buttons) do | |
| 457 kb.ReleaseSlot(button) | |
| 458 end | |
| 459 end | |
| 460 table.wipe(profile) | |
| 461 kb.InitProfile(profile, prototype) | |
| 462 end | |
| 463 | |
| 464 | |
| 465 | |
| 466 --- Handles constructing spec profiles as they are selected | |
| 467 | |
| 468 | |
| 469 --- Obtains profile data or creates the necessary tables | |
| 470 kb.SelectProfileSet = function(name) | |
| 471 | |
| 472 local defaultMode | |
| 473 --- General info | |
| 474 classHeader, className, classID = UnitClass('player') | |
| 475 print('|cFF00FF00profile:|r', name) | |
| 476 print('|cFF00FF00class:|r', UnitClass('player')) | |
| 477 | |
| 478 --- Global | |
| 479 defaultMode = BINDING_TYPE_GLOBAL | |
| 480 kb.InitProfile(db) | |
| 481 kb.loadedProfiles[BINDING_TYPE_GLOBAL] = db | |
| 482 | |
| 483 --- Character | |
| 484 if name then | |
| 485 db[name] = kb.InitProfile(db[name], | |
| 486 {classHeader = classHeader, className = className, classID = classID}) | |
| 487 kb.loadedProfiles[BINDING_TYPE_CHARACTER] = db[name] | |
| 488 defaultMode = BINDING_TYPE_CHARACTER | |
| 489 end | |
| 490 | |
| 491 --- Mutable skills data | |
| 492 kb.UpdateSpecInfo() | |
| 493 kb.UpdateTalentInfo() | |
| 494 | |
| 495 kb.orderedProfiles = {kb.loadedProfiles[BINDING_TYPE_GLOBAL], kb.loadedProfiles[BINDING_TYPE_CHARACTER], kb.loadedProfiles[BINDING_TYPE_SPECIALIZATION]} | |
| 496 if db.bindMode and (not kb.configTitle[db.bindMode]) then | |
| 497 print('fixing bad bindMode value, was', db.bindMode) | |
| 498 db.bindMode = defaultMode | |
| 499 end | |
| 500 | |
| 501 | |
| 502 print(BINDING_TYPE_GLOBAL) | |
| 503 kb.configHeaders[BINDING_TYPE_GLOBAL] = kb.configTitle[BINDING_TYPE_GLOBAL] | |
| 504 kb.configHeaders[BINDING_TYPE_CHARACTER] = kb.configTitle[BINDING_TYPE_CHARACTER]:format(UnitName('player', true)) | |
| 505 kb.configHeaders[BINDING_TYPE_SPECIALIZATION] = kb.configTitle[BINDING_TYPE_SPECIALIZATION]:format(kb.specInfo.name) | |
| 506 | |
| 507 | |
| 508 setmetatable(kb.loadedProfiles[BINDING_TYPE_GLOBAL], {__tostring =function() return kb.configHeaders[BINDING_TYPE_GLOBAL] end}) | |
| 509 setmetatable(kb.loadedProfiles[BINDING_TYPE_CHARACTER], {__tostring =function() return kb.configHeaders[BINDING_TYPE_CHARACTER] end}) | |
| 510 setmetatable(kb.loadedProfiles[BINDING_TYPE_SPECIALIZATION], {__tostring =function() return kb.configHeaders[BINDING_TYPE_SPECIALIZATION] end}) | |
| 511 | |
| 512 print('|cFF00FF00bindMode:|r', db.bindMode) | |
| 513 kb.currentProfile = kb.loadedProfiles[db.bindMode] | |
| 514 end | |
| 515 | |
| 516 local scrollCache = {} | |
| 517 kb.SelectTab = function(self) | |
| 518 scrollCache[db.bindMode] = kb.scrollOffset | |
| 519 db.bindMode = self:GetID() | |
| 520 kb.currentProfile = kb.loadedProfiles[self:GetID()] | |
| 521 kb.scrollOffset = scrollCache[db.bindMode] or 0 | |
| 522 kb.ui(true) | |
| 523 end | |
| 524 | |
| 525 kb.RevertBindings = function() | |
| 526 -- todo: reversion code | |
| 527 end | |
| 528 | |
| 529 kb.ConfirmBindings = function() | |
| 530 SaveBindings(GetCurrentBindingSet()) | |
| 531 bindsCommitted = true | |
| 532 for i, button in ipairs(buttons) do | |
| 533 button.pending = false | |
| 534 end | |
| 535 kb.ApplyAllBindings() | |
| 536 | |
| 537 kb.ui() | |
| 538 kb:print('Keybinds saved.') | |
| 539 end | |
| 540 | |
| 541 | |
| 542 | |
| 543 | |
| 544 --- post ADDON_LOADED | |
| 545 kb.variables = function() | |
| 546 SkeletonKeyDB = SkeletonKeyDB or {spec = {}} | |
| 547 kb.db = SkeletonKeyDB | |
| 548 kb.playerName = UnitName('player') | |
| 549 kb.playerRealm = SelectedRealmName() | |
| 550 kb.profileName = kb.playerRealm .. '_' .. kb.playerName | |
| 551 db = kb.db | |
| 552 | |
| 553 kb.SelectProfileSet(kb.profileName) | |
| 554 -- todo: redo import checking | |
| 555 | |
| 556 | |
| 557 | |
| 558 kb.ApplyAllBindings() | |
| 559 | |
| 560 kb.ui(true) | |
| 561 end | |
| 562 | |
| 563 | |
| 564 kb.wrap = function(module) | |
| 565 kb.modules = kb.modules or {} | |
| 566 tinsert(kb.modules, module) | |
| 567 end | |
| 568 | |
| 569 -- Volatiles Access | |
| 570 kb.GetBindings = function() return bindings end | |
| 571 kb.GetButtons = function() return buttons end | |
| 572 kb.GetCharacterProfile = function () return kb.loadedProfiles[BINDING_TYPE_CHARACTER] end | |
| 573 kb.GetGlobalProfile = function () return kb.loadedProfiles[BINDING_TYPE_GLOBAL] end | |
| 574 kb.GetLooseTalents = function() return talentBindings end | |
| 575 kb.GetReverts = function() return reverts end | |
| 576 kb.GetSpecProfile = function () return kb.loadedProfiles[BINDING_TYPE_SPECIALIZATION] end | |
| 577 | |
| 578 | |
| 579 SLASH_SKB1 = "/skb" | |
| 580 SLASH_SKB2 = "/skeletonkey" | |
| 581 SlashCmdList.SKB = kb.Command |
