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