Nenue@14: -- SkeletonKey Nenue@27: -- KeyButton.lua Nenue@14: -- Created: 7/28/2016 11:26 PM Nenue@14: -- %file-revision% Nenue@16: -- Code dealing with the slot button innards; they are invoked by frame script and should only chain to Set/Release Nenue@14: Nenue@14: local kb, print = LibStub('LibKraken').register(KeyBinder, 'Slot') Nenue@17: local L = kb.L Nenue@17: local CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_PETACTION, CURSOR_TEXTURE Nenue@14: local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544 Nenue@15: local BORDER_UNASSIGNED = {0.2,0.2,0.2,1} Nenue@15: local BORDER_ASSIGNED = {1,1,1,1} Nenue@14: local BORDER_DYNAMIC = {1,1,0,1} Nenue@14: local BORDER_PENDING = {1,0.5,0,1 } Nenue@14: local BUTTON_HEADERS = { Nenue@14: ['spell'] = SPELLS, Nenue@14: ['macro'] = MACRO, Nenue@14: ['petaction'] = PET, Nenue@14: ['mount'] = MOUNT, Nenue@14: ['battlepet'] = BATTLEPET, Nenue@14: Nenue@14: Nenue@14: [5] = PROFESSIONS_FIRST_AID, Nenue@14: [7] = PROFESSIONS_COOKING, Nenue@14: [9] = PROFESSIONS_FISHING, Nenue@14: [10] = PROFESSIONS_ARCHAEOLOGY, Nenue@14: Nenue@14: } Nenue@14: Nenue@30: local PROFESSION_HEADERS = { Nenue@30: [1] = 'Profession 1', Nenue@30: [2] = 'Profession 2', Nenue@30: [3] = 10, Nenue@30: [4] = 7, Nenue@30: [5] = 9, Nenue@30: [6] = 5 Nenue@30: } Nenue@30: Nenue@14: -- This is needed to identify a spells that aren't reflected by GetCursorInfo() Nenue@27: kb.OnPickupPetAction = function(slot, ...) Nenue@17: local isPickup = GetCursorInfo() Nenue@17: print(slot, ...) Nenue@17: if kb.PetCache.action[slot] then Nenue@17: if isPickup then Nenue@17: local key, _, texture = unpack(kb.PetCache.action[slot]) Nenue@17: local spellName = _G[key] or key Nenue@17: if spellName and kb.PetCache.spellslot[spellName] then Nenue@17: CURSOR_SPELLSLOT = kb.PetCache.spellslot[spellName][1] Nenue@17: CURSOR_BOOKTYPE = BOOKTYPE_PET Nenue@17: CURSOR_TEXTURE = _G[texture] or texture Nenue@17: end Nenue@17: else Nenue@17: CURSOR_SPELLSLOT = nil Nenue@17: CURSOR_BOOKTYPE = nil Nenue@17: CURSOR_TEXTURE = nil Nenue@17: end Nenue@27: print('|cFFFF4400PickupPetAction|r', isPickup, CURSOR_PETACTION) Nenue@17: end Nenue@15: Nenue@17: local name, subtext, texture, isToken = GetPetActionInfo(slot) Nenue@17: if name then Nenue@27: kb.PetCache.action[slot] = {name, subtext, texture, isToken} Nenue@17: end Nenue@15: Nenue@15: Nenue@17: print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE) Nenue@15: Nenue@27: end Nenue@27: Nenue@27: kb.OnPickupSpellBookItem = function(slot, bookType) Nenue@27: print('|cFFFF4400PickupSpellBookItem('.. tostring(slot).. ', '..tostring(bookType)..')') Nenue@27: CURSOR_SPELLSLOT = slot Nenue@27: CURSOR_BOOKTYPE = bookType Nenue@27: CURSOR_TEXTURE = GetSpellBookItemTexture(slot, bookType) Nenue@27: print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE) Nenue@27: end Nenue@27: Nenue@27: kb.CreateHooks = function() Nenue@27: hooksecurefunc("PickupSpellBookItem", kb.OnPickupSpellBookItem) Nenue@27: hooksecurefunc("PickupPetAction", kb.OnPickupPetAction) Nenue@27: end Nenue@14: Nenue@14: Nenue@14: kb.DropToSlot = function(self) Nenue@14: print(self:GetName(),'|cFF0088FFreceived|r') Nenue@14: local actionType, actionID, subType, subData = GetCursorInfo() Nenue@14: print('GetCursorInfo', GetCursorInfo()) Nenue@14: if actionType then Nenue@14: Nenue@14: if actionType == 'flyout' then Nenue@14: ClearCursor() Nenue@14: ResetCursor() Nenue@14: return Nenue@14: end Nenue@14: Nenue@14: Nenue@15: local name, icon, _ Nenue@14: local pickupID, pickupBook Nenue@14: Nenue@14: if actionType == 'spell' then Nenue@14: actionID = subData Nenue@14: name, _, icon = GetSpellInfo(actionID) Nenue@14: Nenue@14: elseif actionType == 'macro' then Nenue@14: name, icon = GetMacroInfo(actionID) Nenue@14: elseif actionType == 'petaction' then Nenue@15: if CURSOR_SPELLSLOT and CURSOR_BOOKTYPE then Nenue@14: Nenue@15: local spellType, spellID = GetSpellBookItemInfo(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE) Nenue@15: local spellName, spellText = GetSpellBookItemName(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE) Nenue@15: if spellType == 'PETACTION' then Nenue@17: name = spellName Nenue@15: actionID = spellText Nenue@17: icon = CURSOR_TEXTURE Nenue@15: else Nenue@15: name, _, icon = GetSpellInfo(spellID) Nenue@15: actionID = spellID Nenue@15: end Nenue@15: Nenue@15: pickupID = CURSOR_SPELLSLOT Nenue@15: pickupBook = CURSOR_BOOKTYPE Nenue@15: else Nenue@15: Nenue@14: end Nenue@14: Nenue@14: elseif actionType == 'mount' then Nenue@14: if subType == 0 then Nenue@14: name, _, icon = GetSpellInfo(SUMMON_RANDOM_FAVORITE_MOUNT_SPELL) Nenue@14: actionID = 0 Nenue@14: else Nenue@14: name, _, icon = C_MountJournal.GetMountInfoByID(actionID) Nenue@14: end Nenue@14: elseif actionType == 'item' then Nenue@14: name = GetItemInfo(actionID) Nenue@14: icon = GetItemIcon(actionID) Nenue@14: actionID = name Nenue@14: elseif actionType == 'battlepet' then Nenue@14: Nenue@14: local speciesID, customName, level, xp, maxXp, displayID, isFavorite, petName, petIcon, petType, creatureID = C_PetJournal.GetPetInfoByPetID(detail); Nenue@14: name = customName or petName Nenue@14: icon = petIcon Nenue@14: Nenue@14: end Nenue@15: local macroName, macroText, command = kb.RegisterAction(actionType, actionID, name) Nenue@14: Nenue@14: Nenue@14: local isAssigned, isBound, assignedBy, boundBy = kb.IsCommandBound(self, command) Nenue@14: if isAssigned then Nenue@14: local popup = StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"] Nenue@14: popup.slot = self Nenue@14: popup.text = "Currently assigned in |cFFFFFF00"..tostring(kb.configHeaders[assignedBy]).."|r. Are you sure?" Nenue@14: popup.oldProfile = assignedBy Nenue@14: popup.args = {command, name, icon, actionType, actionID, macroName, macroText, pickupID, pickupBook } Nenue@14: kb:SetScript('OnMouseWheel', nil) -- disable scrolling Nenue@14: StaticPopup_Show('SKELETONKEY_CONFIRM_ASSIGN_SLOT') Nenue@14: else Nenue@14: kb.SetSlot(self, command, name, icon, actionType, actionID, macroName, macroText, pickupID, pickupBook) Nenue@14: kb.UpdateSlot(self) Nenue@14: self.active = nil Nenue@14: ClearCursor() Nenue@14: ResetCursor() Nenue@14: end Nenue@14: end Nenue@14: end Nenue@14: Nenue@14: Nenue@14: do Nenue@14: local PickupAction = { Nenue@14: spell = _G.PickupSpell, Nenue@14: petaction = _G.PickupSpellBookItem, Nenue@14: macro = _G.PickupMacro, Nenue@14: item = _G.PickupItem, Nenue@14: mount = _G.C_MountJournal.Pickup Nenue@14: } Nenue@14: local GetPickupValue = { Nenue@14: spell = function(self) return select(7, GetSpellInfo(self.actionID)) end, Nenue@14: petaction = function(self) return self.pickupSlot, self.pickupBook end, Nenue@14: } Nenue@14: kb.PickupSlot = function(self) Nenue@15: if not (self.command and self.isAvailable) then Nenue@14: return Nenue@14: end Nenue@14: print(self.actionType) Nenue@14: if self.actionType == 'spell' then Nenue@14: -- It can't be picked up if SpellInfo(name) returns void Nenue@14: local dummy = GetSpellInfo(self.actionName) Nenue@14: if not dummy then Nenue@14: return Nenue@14: end Nenue@14: end Nenue@14: if PickupAction[self.actionType] then Nenue@14: if GetPickupValue[self.actionType] then Nenue@14: PickupAction[self.actionType](GetPickupValue[self.actionType](self)) Nenue@14: else Nenue@14: PickupAction[self.actionType](self.actionID) Nenue@14: end Nenue@14: kb.ReleaseSlot(self) Nenue@14: kb.UpdateSlot(self) Nenue@14: end Nenue@14: end Nenue@14: end Nenue@14: Nenue@17: kb.UnbindSlot = function(self) Nenue@17: Nenue@17: local keys = {GetBindingKey(self.command) } Nenue@27: if #keys >= 1 then Nenue@27: kb.UpdateBindingsCache(self.actionType, self.actionID, {}) Nenue@27: end Nenue@27: Nenue@27: Nenue@17: --print('detected', #keys, 'bindings') Nenue@17: for i, key in pairs(keys) do Nenue@17: --print('clearing', key) Nenue@17: SetBinding(key, nil) Nenue@17: SaveBindings(GetCurrentBindingSet()) Nenue@17: if kb.currentProfile.bindings[key] then Nenue@18: --kb:print(L('BINDING_REMOVED', self.actionName, kb.currentHeader)) Nenue@17: kb.currentProfile.bindings[key] = nil Nenue@17: end Nenue@17: if kb.currentProfile.talents[self.actionName] then Nenue@17: kb.currentProfile.talents[self.actionName] = nil Nenue@17: end Nenue@17: kb.bindings[self.actionType][self.actionID] = nil Nenue@17: end Nenue@17: if kb.currentProfile.bound[self.command] then Nenue@17: kb.currentProfile.bound[self.command] = nil Nenue@17: --kb:print(BINDING_REMOVED:format(self.actionName, configHeaders[db.bindMode])) Nenue@17: end Nenue@17: Nenue@27: Nenue@17: self.active = false Nenue@17: kb.UpdateSlot(self, true) Nenue@17: end Nenue@17: Nenue@17: --- Updates the current KeyBinding for the button's command Nenue@17: kb.SaveSlot = function(self, key) Nenue@17: Nenue@17: if not self.command then Nenue@17: return Nenue@17: end Nenue@17: print('|cFFFFFF00received|cFFFFFF00', self:GetID(), '|cFF00FFFF', key) Nenue@17: Nenue@17: local modifier = '' Nenue@17: if IsAltKeyDown() then Nenue@17: modifier = 'ALT-' Nenue@17: end Nenue@17: if IsControlKeyDown() then Nenue@17: modifier = modifier.. 'CTRL-' Nenue@17: end Nenue@17: if IsShiftKeyDown() then Nenue@17: modifier = modifier..'SHIFT-' Nenue@17: end Nenue@17: local binding = modifier..key Nenue@17: Nenue@17: if key == 'ESCAPE' then Nenue@17: else Nenue@19: if kb.SystemBindings[binding] then Nenue@19: kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', binding, kb.SystemBindings[binding])) Nenue@17: return Nenue@17: end Nenue@17: Nenue@17: Nenue@17: if self.command then Nenue@17: Nenue@27: local previousCommand = GetBindingAction(binding) Nenue@27: if previousCommand ~= "" and previousCommand ~= self.command then Nenue@17: if kb.SystemBindings[binding] then Nenue@17: -- bounce out if trying to use a protected key Nenue@17: kb.statustext:SetText(L('BINDING_FAILED_PROTECTED', key, GetBindingAction(binding))) Nenue@17: kb.bindingstext:SetText(nil) Nenue@19: return false Nenue@17: end Nenue@27: Nenue@27: local actionType, actionID, name = kb.GetCommandAction(previousCommand) Nenue@27: if actionType then Nenue@27: local keys = {GetBindingKey(previousCommand) } Nenue@27: local i = 1 Nenue@27: while keys[i] do Nenue@27: if keys[i] == binding then Nenue@27: table.remove(keys, i) Nenue@27: kb.UpdateBindingsCache(actionType, actionID, keys) Nenue@27: break Nenue@27: end Nenue@27: i = i + 1 Nenue@27: end Nenue@27: end Nenue@27: end Nenue@27: Nenue@27: local currentHotKeys = {GetBindingKey(self.command)} Nenue@27: local found Nenue@27: for i, key in ipairs(currentHotKeys) do Nenue@27: if key == binding then Nenue@27: found = true Nenue@27: kb:print('hotkey already assigned') Nenue@27: end Nenue@27: end Nenue@27: if not found then Nenue@27: table.insert(currentHotKeys, 1, binding) Nenue@27: kb.UpdateBindingsCache(self.actionType, self.actionID, currentHotKeys) Nenue@17: end Nenue@17: Nenue@17: self.binding = binding Nenue@17: Nenue@27: Nenue@27: Nenue@27: SetBinding(binding, self.command) Nenue@17: SaveBindings(GetCurrentBindingSet()) Nenue@17: Nenue@27: Nenue@27: Nenue@17: local talentInfo Nenue@17: if self.actionType == 'spell' and kb.TalentCache[self.actionID] then Nenue@17: print('conditional binding (talent = "'..self.actionName..'")') Nenue@17: talentInfo = {self.macroName, self.actionName, self.actionType, self.actionID} Nenue@17: local bindings = {GetBindingKey(self.command) } Nenue@17: for i, key in ipairs(bindings) do Nenue@17: tinsert(talentInfo, key) Nenue@17: end Nenue@17: end Nenue@17: Nenue@17: for level, profile in ipairs(kb.orderedProfiles) do Nenue@17: if (level == kb.db.bindMode) then Nenue@17: profile.bound[self.command] = true Nenue@17: if talentInfo then Nenue@17: profile.bindings[self.binding] = nil Nenue@17: else Nenue@17: profile.bindings[self.binding] = self.command Nenue@17: end Nenue@17: profile.talents[self.actionName] = talentInfo Nenue@17: else Nenue@17: profile.bindings[self.binding] = nil Nenue@17: profile.bound[self.command] = nil Nenue@17: kb.currentProfile.talents[self.actionName] = nil Nenue@17: end Nenue@17: if kb.currentProfile.talents[self.actionID] then Nenue@17: kb.currentProfile.talents[self.actionID] = nil Nenue@17: end Nenue@17: end Nenue@17: Nenue@17: kb:print(L('BINDING_ASSIGNED', self.binding, self.actionName, kb.currentHeader)) Nenue@17: end Nenue@17: end Nenue@17: kb.UpdateSlot(self, true) Nenue@19: return true Nenue@17: end Nenue@14: Nenue@14: Nenue@14: --- Updates profile assignment and button contents Nenue@14: kb.UpdateSlot = function(self, force) Nenue@14: local slot = self:GetID() Nenue@14: Nenue@14: if force then Nenue@14: if kb.currentProfile.buttons[slot] then Nenue@14: kb.SetSlot(self, unpack(kb.currentProfile.buttons[slot])) Nenue@14: else Nenue@14: kb.ReleaseSlot(self) Nenue@14: end Nenue@14: end Nenue@14: Nenue@14: if self.command then Nenue@14: print('['..slot..'] =', self.command, GetBindingKey(self.command)) Nenue@14: Nenue@15: if not self.isAvailable then Nenue@15: self.border:SetColorTexture(1,0,0,1) Nenue@15: self.ignoreTexture:Show() Nenue@14: else Nenue@15: self.ignoreTexture:Hide() Nenue@15: Nenue@15: if self.pending then Nenue@15: self.border:SetColorTexture(unpack(BORDER_PENDING)) Nenue@15: elseif self.isDynamic then Nenue@15: self.border:SetColorTexture(unpack(BORDER_DYNAMIC)) Nenue@15: else Nenue@15: self.border:SetColorTexture(unpack(BORDER_ASSIGNED)) Nenue@15: end Nenue@14: end Nenue@14: Nenue@15: Nenue@14: if self.actionType == 'macro' then Nenue@14: self.macro:Show() Nenue@14: else Nenue@14: self.macro:Hide() Nenue@14: if self.actionType == 'spell' then Nenue@14: local dummy = GetSpellInfo(self.actionName) Nenue@14: if not dummy then Nenue@14: self.icon:SetDesaturated(true) Nenue@14: else Nenue@14: self.icon:SetDesaturated(false) Nenue@14: end Nenue@14: Nenue@14: end Nenue@14: end Nenue@14: Nenue@14: if self.isDynamic then Nenue@15: print('|cFF00BBFFUpdateSlot|r:', self.isDynamic, self.isAvailable, self.actionID) Nenue@14: end Nenue@14: Nenue@14: if self.isDynamic == 'profession' then Nenue@30: if self.profIndex then Nenue@29: Nenue@29: local profText = (self.spellNum == 1) and TRADE_SKILLS or (BUTTON_HEADERS[self.profIndex] or GetProfessionInfo(self.profIndex)) Nenue@14: print(self.profIndex, 'spnum', type(self.spellNum), (self.spellNum == 1)) Nenue@14: Nenue@29: self.statusText = '|cFFFFFF00'..tostring(profText)..'|r' Nenue@14: self.bindingText = kb.BindingString(GetBindingKey(self.command)) Nenue@14: else Nenue@29: Nenue@30: self.statusText = '|cFFFF4400'..PROFESSION_HEADERS[self.professionNum]..'|r' Nenue@29: self.actionName = '(#'..self.professionNum..')' Nenue@14: self.bindingText ='?' Nenue@14: end Nenue@14: elseif self.isDynamic == 'talent' then Nenue@14: Nenue@14: self.statusText = '|cFF00FFFF'.. TALENT .. '|r' Nenue@14: if self.isAvailable then Nenue@14: self.bindingText = kb.BindingString(GetBindingKey(self.command)) Nenue@14: else Nenue@19: if kb.TalentBindings[self.actionID] then Nenue@19: print(self.actionID, #kb.TalentBindings[self.actionID]) Nenue@19: self.bindingText= kb.BindingString(unpack(kb.TalentBindings[self.actionID])) Nenue@14: end Nenue@14: Nenue@14: end Nenue@19: elseif self.isDynamic == 'petaction' then Nenue@21: local specialType, specialNum = self.command:match("petaction_([%a%s]+)_(%d)") Nenue@21: if specialType and specialNum then Nenue@21: print('pet skill|cFF00FF00', specialType..'|r', specialNum) Nenue@21: self.statusText = L(specialType..' %%d'):format(specialNum) Nenue@19: else Nenue@19: self.statusText = L('Pet Action') Nenue@19: end Nenue@15: self.bindingText = kb.BindingString(GetBindingKey(self.command)) Nenue@14: else Nenue@14: self.statusText = '|cFF00FF00'.. (BUTTON_HEADERS[self.actionType] and BUTTON_HEADERS[self.actionType] or self.actionType) .. '|r' Nenue@14: self.bindingText = kb.BindingString(GetBindingKey(self.command)) Nenue@14: end Nenue@14: Nenue@14: local locked, layer = kb.IsCommandBound(self) Nenue@14: if locked then Nenue@14: self.icon:SetAlpha(0.5) Nenue@14: else Nenue@14: self.icon:SetAlpha(1) Nenue@14: end Nenue@14: Nenue@17: Nenue@14: if self.actionType == 'spell' then Nenue@14: self.icon:SetTexture(GetSpellTexture(self.actionID)) Nenue@14: end Nenue@21: else Nenue@21: self.ignoreTexture:Hide() Nenue@14: end Nenue@14: Nenue@14: if not self.isAvailable then Nenue@14: self.bind:SetTextColor(0.7,0.7,0.7,1) Nenue@14: else Nenue@14: self.bind:SetTextColor(1,1,1,1) Nenue@14: end Nenue@14: Nenue@17: Nenue@17: if kb.saveTarget and kb.saveTarget ~= self then Nenue@17: self:SetAlpha(0.25) Nenue@17: else Nenue@17: Nenue@17: self:SetAlpha(1) Nenue@17: end Nenue@17: Nenue@17: Nenue@14: self.header:SetText(self.statusText) Nenue@14: self.bind:SetText(self.bindingText) Nenue@14: self.details:SetText(self.actionName) Nenue@14: end Nenue@14: Nenue@14: --- Resets button command Nenue@14: kb.ReleaseSlot = function(self) Nenue@14: local slot = self:GetID() Nenue@14: Nenue@14: Nenue@14: if kb.currentProfile.buttons[slot] then Nenue@14: kb.currentProfile.buttons[slot] = nil Nenue@14: end Nenue@14: if self.command then Nenue@14: kb.currentProfile.commands[self.command] = nil Nenue@14: end Nenue@14: if self.actionType == 'spell' and IsTalentSpell(self.actionName) then Nenue@14: if kb.currentProfile.talents[self.actionID] then Nenue@14: kb.currentProfile.talents[self.actionID] = nil Nenue@14: end Nenue@14: end Nenue@14: local droppedKeys = {} Nenue@14: Nenue@14: -- doing removal in second loop to avoid possible iterator shenanigans Nenue@14: for k,v in pairs(kb.currentProfile.bindings) do Nenue@14: if v == self.command then Nenue@14: tinsert(droppedKeys, k) Nenue@14: end Nenue@14: end Nenue@14: if #droppedKeys >=1 then Nenue@14: for i, k in ipairs(droppedKeys) do Nenue@14: kb.currentProfile.bindings[k] = nil Nenue@14: end Nenue@14: end Nenue@14: Nenue@14: self.isAvailable = nil Nenue@14: self.isDynamic = nil Nenue@14: self.bindingText = nil Nenue@14: self.statusText = nil Nenue@14: self.command = nil Nenue@14: self.actionType = nil Nenue@14: self.actionID = nil Nenue@14: self.actionName = nil Nenue@14: self.pickupSlot = nil Nenue@14: self.pickupBook = nil Nenue@14: self.macroName = nil Nenue@14: self.profile = nil Nenue@14: self.icon:SetTexture(nil) Nenue@14: self.border:SetColorTexture(unpack(BORDER_UNASSIGNED)) Nenue@14: self:EnableKeyboard(false) Nenue@14: self:SetScript('OnKeyDown', nil) Nenue@15: self.ignoreTexture:Hide() Nenue@14: end Nenue@14: Nenue@14: kb.SetSlot = function(self, command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook) Nenue@14: local slot = self:GetID() Nenue@14: local isDynamic, isAvailable Nenue@14: Nenue@14: print('|cFFFFFF00SetSlot|r:', self:GetID()) Nenue@14: if command then Nenue@14: Nenue@14: if actionType == 'spell' then Nenue@14: local professionNum, spellNum = command:match("profession_(%d)_(%d)") Nenue@14: if (professionNum and spellNum) then Nenue@14: isDynamic = 'profession' Nenue@14: local cacheInfo = kb.ProfessionCache[professionNum..'_'..spellNum] Nenue@14: if cacheInfo then Nenue@14: isAvailable = true Nenue@14: name = cacheInfo.spellName Nenue@14: icon = cacheInfo.icon Nenue@14: actionID = cacheInfo.spellID Nenue@14: self.profIndex = cacheInfo.profIndex Nenue@14: self.spellOffset = cacheInfo.spellOffset Nenue@30: else Nenue@30: print(professionNum, type(professionNum), PROFESSION_HEADERS[tonumber(professionNum)]) Nenue@30: local profID = PROFESSION_HEADERS[tonumber(professionNum)] Nenue@30: if type(profID) == 'number' then Nenue@30: local pname, texture, _, _, numSpells, spellOffset = GetProfessionInfo(profID) Nenue@30: self.profIndex = profID Nenue@30: else Nenue@30: name = profID Nenue@30: end Nenue@30: Nenue@14: end Nenue@14: print(' Special slot: |cFF00FFFFProfession|r', professionNum, spellNum, isDynamic, isAvailable) Nenue@14: Nenue@14: self.professionNum = tonumber(professionNum) Nenue@14: self.spellNum = tonumber(spellNum) Nenue@14: Nenue@14: else Nenue@14: if kb.TalentCache[actionID] then Nenue@14: isDynamic = 'talent' Nenue@14: print(' Special slot: |cFFBBFF00talent|r', name, isAvailable) Nenue@14: end Nenue@14: Nenue@14: isAvailable = GetSpellInfo(name) Nenue@14: end Nenue@15: elseif actionType == 'petaction' then Nenue@15: isDynamic = 'petaction' Nenue@21: local specialType, specialNum = command:match(actionType..'_([%a%s]+)_(%d)') Nenue@21: Nenue@21: if kb.PetCache.subtext[specialType] and kb.PetCache.subtext[specialType][tonumber(specialNum)] then Nenue@30: print('***dynamic pet skill', specialType, specialNum) Nenue@21: --[[ i, spellName, subText, spellID, texture, specialNum[subText ]] Nenue@21: pickupSlot, name, specialType, actionID, icon, specialNum = unpack(kb.PetCache.subtext[specialType][tonumber(specialNum)]) Nenue@21: pickupBook = BOOKTYPE_PET Nenue@21: end Nenue@21: Nenue@22: isAvailable = (kb.PetCache.spellslot[name]) Nenue@22: Nenue@21: Nenue@14: elseif actionType == 'macro' then Nenue@14: if not actionID then Nenue@14: actionID = GetMacroIndexByName(name) Nenue@14: end Nenue@14: isAvailable = true Nenue@14: else Nenue@14: --- Journal selections Nenue@14: -- todo: consider using the deep end of blizzard action bar instead Nenue@14: if not actionID then Nenue@14: actionID = command:match("^KeyBinderMacro:(.+)") Nenue@14: end Nenue@14: isAvailable = true Nenue@14: end Nenue@14: Nenue@14: if isAvailable then Nenue@14: local oldCommand = command Nenue@14: macroName, macroText, command = kb.RegisterAction(actionType, actionID, name) Nenue@14: if oldCommand ~= command then Nenue@14: print('|cFFFF4400fixing command string', actionType, actionID, name) Nenue@14: kb.currentProfile.bound[oldCommand] = nil Nenue@14: kb.currentProfile.bound[command] = slot Nenue@14: for k,v in pairs(kb.currentProfile.bindings) do Nenue@14: if v == oldCommand then Nenue@14: kb.currentProfile.bindings[k] = command Nenue@14: end Nenue@14: end Nenue@14: end Nenue@14: kb.LoadBinding(command, name, icon, actionType, actionID, macroName, macroText) Nenue@14: end Nenue@14: Nenue@14: Nenue@14: actionID = actionID or 0 Nenue@14: self:EnableKeyboard(true) Nenue@17: 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: kb.currentProfile.buttons[slot] = {command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook } Nenue@19: Nenue@14: Nenue@14: -- Clean up conflicting entries for loaded button Nenue@14: local previous = kb.currentProfile.commands[command] Nenue@14: if previous ~= slot and kb.buttons[previous] then Nenue@14: kb.ReleaseSlot(kb.buttons[previous]) Nenue@14: end Nenue@19: Nenue@19: if not (kb.IsCommandBound(self, command) or kb.currentProfile.bound[command]) then Nenue@19: Nenue@19: local binds = {GetBindingKey(command) } Nenue@19: if #binds >= 1 then Nenue@19: kb:print('Recovered key binding for', name) Nenue@19: for i, key in ipairs(binds) do Nenue@19: kb.currentProfile.bindings[key] = command Nenue@19: kb.currentProfile.bound[command] = true Nenue@19: end Nenue@19: end Nenue@19: end Nenue@19: Nenue@19: Nenue@14: kb.currentProfile.commands[command] = slot Nenue@19: Nenue@14: end Nenue@14: Nenue@14: self.isAvailable = isAvailable Nenue@14: self.isDynamic = isDynamic Nenue@14: Nenue@15: self.pickupSlot = pickupSlot Nenue@15: self.pickupBook = pickupBook Nenue@14: self.macroText = macroText Nenue@14: self.macroName = macroName Nenue@14: self.actionType = actionType Nenue@14: self.actionID = actionID Nenue@14: self.actionName = name Nenue@14: self.command = command Nenue@14: self.icon:SetTexture(icon) Nenue@14: self.profile = kb.db.bindMode Nenue@14: self:RegisterForDrag('LeftButton') Nenue@14: end Nenue@14: Nenue@27: kb.GetCommandAction = function(command) Nenue@27: for i, data in ipairs(kb.loadedProfiles) do Nenue@27: if data.commands[command] then Nenue@27: if data.buttons[data.commands[command]] then Nenue@27: local _, _, _, actionType, actionID = unpack(data.buttons[data.commands[command]]) Nenue@27: return actionType, actionID Nenue@27: end Nenue@27: end Nenue@27: end Nenue@27: end Nenue@16: Nenue@14: Nenue@14: --- Add to blizzard interfaces Nenue@14: StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"] = { Nenue@14: text = "Confirm moving an assigned command.", Nenue@14: button1 = OKAY, Nenue@14: button2 = CANCEL, Nenue@14: timeout = 0, Nenue@14: whileDead = 1, Nenue@14: showAlert = 1, Nenue@14: OnAccept = kb.AcceptAssignment, Nenue@14: OnCancel = function() kb:SetScript('OnMouseWheel', KeyBinder_OnMouseWheel) end Nenue@14: }