Nenue@70
|
1 -- SkeletonKey
|
Nenue@70
|
2 -- KeyButton.lua
|
Nenue@70
|
3 -- Created: 7/28/2016 11:26 PM
|
Nenue@70
|
4 -- %file-revision%
|
Nenue@70
|
5 -- Deals with display and manipulation of binding slots
|
Nenue@70
|
6
|
Nenue@70
|
7 local _, kb = ...
|
Nenue@70
|
8 local print = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('SkeletonKey', ...) end or function() end
|
Nenue@70
|
9 local cprint = (DEVIAN_PNAME == 'SkeletonKey') and function(...) _G.print('Cfg', ...) end or function() end
|
Nenue@70
|
10 local L = kb.L
|
Nenue@70
|
11 local type, tonumber, tostring, tinsert, tremove, ipairs, pairs = type, tonumber, tostring, tinsert, tremove, ipairs, pairs
|
Nenue@70
|
12 local _G, unpack, select, tostring = _G, unpack, select, tostring
|
Nenue@70
|
13 local GetSpellBookItemName, GetSpellBookItemTexture, GetSpellBookItemInfo, GetPetActionInfo = GetSpellBookItemName, GetSpellBookItemTexture, GetSpellBookItemInfo, GetPetActionInfo
|
Nenue@70
|
14 local GetSpellInfo, GetMacroInfo, GetItemInfo, GetItemIcon = GetSpellInfo, GetMacroInfo, GetItemInfo, GetItemIcon
|
Nenue@70
|
15 local GetCursorInfo, ClearCursor, ResetCursor = GetCursorInfo, ClearCursor, ResetCursor
|
Nenue@70
|
16 local GetSpellTexture, IsTalentSpell, GetMacroIndexByName, IsAltKeyDown, IsControlKeyDown, IsShiftKeyDown = GetSpellTexture, IsTalentSpell, GetMacroIndexByName, IsAltKeyDown, IsControlKeyDown,IsShiftKeyDown
|
Nenue@70
|
17 local GetBindingKey, GetProfessionInfo = GetBindingKey, GetProfessionInfo
|
Nenue@70
|
18 local GetMountInfoByID, GetPetInfoByPetID = C_MountJournal.GetMountInfoByID, C_PetJournal.GetPetInfoByPetID
|
Nenue@70
|
19 local skb = SkeletonKeyButtonMixin
|
Nenue@70
|
20 local CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_PETACTION, CURSOR_TEXTURE
|
Nenue@70
|
21 local SUMMON_RANDOM_FAVORITE_MOUNT_SPELL = 150544
|
Nenue@70
|
22 local BORDER_UNASSIGNED = {0.6,0.6,0.6,1}
|
Nenue@70
|
23 local BORDER_ASSIGNED = {1,1,1,1}
|
Nenue@70
|
24 local BORDER_DYNAMIC = {1,1,0,1}
|
Nenue@70
|
25 local BORDER_PENDING = {1,0.5,0,1 }
|
Nenue@70
|
26 local BUTTON_HEADERS = {
|
Nenue@70
|
27 ['spell'] = SPELLS,
|
Nenue@70
|
28 ['macro'] = MACRO,
|
Nenue@70
|
29 ['petaction'] = PET,
|
Nenue@70
|
30 ['mount'] = MOUNT,
|
Nenue@70
|
31 ['battlepet'] = BATTLEPET,
|
Nenue@70
|
32
|
Nenue@70
|
33
|
Nenue@70
|
34 [5] = PROFESSIONS_FIRST_AID,
|
Nenue@70
|
35 [7] = PROFESSIONS_COOKING,
|
Nenue@70
|
36 [9] = PROFESSIONS_FISHING,
|
Nenue@70
|
37 [10] = PROFESSIONS_ARCHAEOLOGY,
|
Nenue@70
|
38
|
Nenue@70
|
39 }
|
Nenue@70
|
40
|
Nenue@70
|
41 local PROFESSION_HEADERS = {
|
Nenue@70
|
42 [1] = 'Profession 1',
|
Nenue@70
|
43 [2] = 'Profession 2',
|
Nenue@70
|
44 [3] = 10,
|
Nenue@70
|
45 [4] = 7,
|
Nenue@70
|
46 [5] = 9,
|
Nenue@70
|
47 [6] = 5
|
Nenue@70
|
48 }
|
Nenue@70
|
49
|
Nenue@70
|
50
|
Nenue@70
|
51 -- This is needed to identify a spells that aren't reflected by GetCursorInfo()
|
Nenue@70
|
52 kb.OnPickupPetAction = function(slot, ...)
|
Nenue@70
|
53 local isPickup = GetCursorInfo()
|
Nenue@70
|
54 print(slot, ...)
|
Nenue@70
|
55 if kb.PetCache.action[slot] then
|
Nenue@70
|
56 if isPickup then
|
Nenue@70
|
57 local key, _, texture = unpack(kb.PetCache.action[slot])
|
Nenue@70
|
58 local spellName = _G[key] or key
|
Nenue@70
|
59 if spellName and kb.PetCache.spellslot[spellName] then
|
Nenue@70
|
60 CURSOR_SPELLSLOT = kb.PetCache.spellslot[spellName][1]
|
Nenue@70
|
61 CURSOR_BOOKTYPE = BOOKTYPE_PET
|
Nenue@70
|
62 CURSOR_TEXTURE = _G[texture] or texture
|
Nenue@70
|
63 end
|
Nenue@70
|
64 else
|
Nenue@70
|
65 CURSOR_SPELLSLOT = nil
|
Nenue@70
|
66 CURSOR_BOOKTYPE = nil
|
Nenue@70
|
67 CURSOR_TEXTURE = nil
|
Nenue@70
|
68 end
|
Nenue@70
|
69 print('|cFFFF4400PickupPetAction|r', isPickup, CURSOR_PETACTION)
|
Nenue@70
|
70 end
|
Nenue@70
|
71
|
Nenue@70
|
72 local name, subtext, texture, isToken = GetPetActionInfo(slot)
|
Nenue@70
|
73 if name then
|
Nenue@70
|
74 kb.PetCache.action[slot] = {name, subtext, texture, isToken}
|
Nenue@70
|
75 end
|
Nenue@70
|
76
|
Nenue@70
|
77
|
Nenue@70
|
78 print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE)
|
Nenue@70
|
79
|
Nenue@70
|
80 end
|
Nenue@70
|
81
|
Nenue@70
|
82 kb.OnPickupSpellBookItem = function(slot, bookType)
|
Nenue@70
|
83 print('|cFFFF4400PickupSpellBookItem('.. tostring(slot).. ', '..tostring(bookType)..')')
|
Nenue@70
|
84 CURSOR_SPELLSLOT = slot
|
Nenue@70
|
85 CURSOR_BOOKTYPE = bookType
|
Nenue@70
|
86 CURSOR_TEXTURE = GetSpellBookItemTexture(slot, bookType)
|
Nenue@70
|
87 print('current cursor info', CURSOR_SPELLSLOT, CURSOR_BOOKTYPE, CURSOR_TEXTURE)
|
Nenue@70
|
88 end
|
Nenue@70
|
89
|
Nenue@70
|
90 kb.CreateHooks = function()
|
Nenue@70
|
91 hooksecurefunc("PickupSpellBookItem", kb.OnPickupSpellBookItem)
|
Nenue@70
|
92 hooksecurefunc("PickupPetAction", kb.OnPickupPetAction)
|
Nenue@70
|
93 end
|
Nenue@70
|
94
|
Nenue@70
|
95
|
Nenue@70
|
96
|
Nenue@70
|
97 function skb:OnLoad()
|
Nenue@70
|
98 self:EnableKeyboard(false)
|
Nenue@70
|
99 self:EnableMouse(true)
|
Nenue@70
|
100 self:RegisterForDrag('LeftButton')
|
Nenue@70
|
101 self:RegisterForClicks('AnyUp')
|
Nenue@70
|
102 end
|
Nenue@70
|
103
|
Nenue@70
|
104 function skb:OnEnter()
|
Nenue@70
|
105 if not self.command then
|
Nenue@70
|
106 return
|
Nenue@70
|
107 end
|
Nenue@70
|
108 if self.statusText then
|
Nenue@70
|
109 SkeletonKey.statustext:SetText(self.statusText .. ': '..self.actionName)
|
Nenue@70
|
110 SkeletonKey.bindingstext:SetText(self.bindingText)
|
Nenue@70
|
111 end
|
Nenue@70
|
112
|
Nenue@70
|
113
|
Nenue@70
|
114 if kb.db.hoverInput and kb.saveTarget ~= self then
|
Nenue@70
|
115 self:GetParent():ActivateSlot(self)
|
Nenue@70
|
116 SkeletonKey:Update()
|
Nenue@70
|
117 end
|
Nenue@70
|
118 end
|
Nenue@70
|
119
|
Nenue@70
|
120 function skb:OnLeave()
|
Nenue@70
|
121 if kb.db.hoverInput and kb.saveTarget == self then
|
Nenue@70
|
122 self:GetParent():DeactivateSlot(self)
|
Nenue@70
|
123 SkeletonKey:Update()
|
Nenue@70
|
124 end
|
Nenue@70
|
125 end
|
Nenue@70
|
126
|
Nenue@70
|
127 function skb:OnUpdate()
|
Nenue@70
|
128 end
|
Nenue@70
|
129 function skb:OnClick(click)
|
Nenue@70
|
130 print(self:GetName(), 'OnMouseDown', click)
|
Nenue@70
|
131 local cursorType = GetCursorInfo()
|
Nenue@70
|
132 if click == 'LeftButton' then
|
Nenue@70
|
133 if cursorType then
|
Nenue@70
|
134 self:DropToSlot()
|
Nenue@70
|
135 else
|
Nenue@70
|
136 if self.command and self.isAvailable then
|
Nenue@70
|
137 if IsShiftKeyDown() then
|
Nenue@70
|
138 kb.db.stickyMode = true
|
Nenue@70
|
139 KeyBinderStickyMode:SetChecked(true)
|
Nenue@70
|
140 end
|
Nenue@70
|
141 self:GetParent():ActivateSlot(self)
|
Nenue@70
|
142 end
|
Nenue@70
|
143 end
|
Nenue@70
|
144 elseif click == 'RightButton' then
|
Nenue@70
|
145 self:ReleaseSlot()
|
Nenue@70
|
146 else
|
Nenue@70
|
147 kb.ProcessInput(strupper(click))
|
Nenue@70
|
148 end
|
Nenue@70
|
149 SkeletonKey:Update()
|
Nenue@70
|
150 end
|
Nenue@70
|
151
|
Nenue@70
|
152 function skb:OnDragStart()
|
Nenue@70
|
153 self:PickupSlot()
|
Nenue@70
|
154 end
|
Nenue@70
|
155
|
Nenue@70
|
156 function skb:OnReceiveDrag(...)
|
Nenue@70
|
157 self:DropToSlot()
|
Nenue@70
|
158 end
|
Nenue@70
|
159
|
Nenue@70
|
160 function skb:DropToSlot ()
|
Nenue@70
|
161 print(self:GetName(),'|cFF0088FFreceived|r')
|
Nenue@70
|
162 local actionType, actionID, subType, subData = GetCursorInfo()
|
Nenue@70
|
163 print('GetCursorInfo', GetCursorInfo())
|
Nenue@70
|
164 if actionType then
|
Nenue@70
|
165
|
Nenue@70
|
166 if actionType == 'flyout' then
|
Nenue@70
|
167 ClearCursor()
|
Nenue@70
|
168 ResetCursor()
|
Nenue@70
|
169 return
|
Nenue@70
|
170 end
|
Nenue@70
|
171
|
Nenue@70
|
172
|
Nenue@70
|
173 local name, icon, _
|
Nenue@70
|
174 local pickupID, pickupBook
|
Nenue@70
|
175
|
Nenue@70
|
176 if actionType == 'spell' then
|
Nenue@70
|
177 actionID = subData
|
Nenue@70
|
178 name, _, icon = GetSpellInfo(actionID)
|
Nenue@70
|
179
|
Nenue@70
|
180 elseif actionType == 'macro' then
|
Nenue@70
|
181 name, icon = GetMacroInfo(actionID)
|
Nenue@70
|
182 elseif actionType == 'petaction' then
|
Nenue@70
|
183 if CURSOR_SPELLSLOT and CURSOR_BOOKTYPE then
|
Nenue@70
|
184
|
Nenue@70
|
185 local spellType, spellID = GetSpellBookItemInfo(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE)
|
Nenue@70
|
186 local spellName, spellText = GetSpellBookItemName(CURSOR_SPELLSLOT, CURSOR_BOOKTYPE)
|
Nenue@70
|
187 if spellType == 'PETACTION' then
|
Nenue@70
|
188 name = spellName
|
Nenue@70
|
189 actionID = spellText
|
Nenue@70
|
190 icon = CURSOR_TEXTURE
|
Nenue@70
|
191 else
|
Nenue@70
|
192 name, _, icon = GetSpellInfo(spellID)
|
Nenue@70
|
193 actionID = spellID
|
Nenue@70
|
194 end
|
Nenue@70
|
195
|
Nenue@70
|
196 pickupID = CURSOR_SPELLSLOT
|
Nenue@70
|
197 pickupBook = CURSOR_BOOKTYPE
|
Nenue@70
|
198 else
|
Nenue@70
|
199
|
Nenue@70
|
200
|
Nenue@70
|
201 end
|
Nenue@70
|
202
|
Nenue@70
|
203 elseif actionType == 'mount' then
|
Nenue@70
|
204 if subType == 0 then
|
Nenue@70
|
205 name, _, icon = GetSpellInfo(SUMMON_RANDOM_FAVORITE_MOUNT_SPELL)
|
Nenue@70
|
206 actionID = 0
|
Nenue@70
|
207 else
|
Nenue@70
|
208 name, _, icon = GetMountInfoByID(actionID)
|
Nenue@70
|
209 end
|
Nenue@70
|
210 elseif actionType == 'item' then
|
Nenue@70
|
211 name = GetItemInfo(actionID)
|
Nenue@70
|
212 icon = GetItemIcon(actionID)
|
Nenue@70
|
213 elseif actionType == 'battlepet' then
|
Nenue@70
|
214
|
Nenue@70
|
215 local speciesID, customName, level, xp, maxXp, displayID, isFavorite, petName, petIcon, petType, creatureID = GetPetInfoByPetID(actionID)
|
Nenue@70
|
216 name = customName or petName
|
Nenue@70
|
217 icon = petIcon
|
Nenue@70
|
218
|
Nenue@70
|
219 end
|
Nenue@70
|
220 local macroName, macroText, command = kb.RegisterAction(actionType, actionID, name)
|
Nenue@70
|
221 local slotInfo = {
|
Nenue@70
|
222 command = command,
|
Nenue@70
|
223 actionName = name,
|
Nenue@70
|
224 iconPath = icon,
|
Nenue@70
|
225 actionType = actionType,
|
Nenue@70
|
226 actionID = actionID,
|
Nenue@70
|
227 macroName = macroName,
|
Nenue@70
|
228 macroText = macroText,
|
Nenue@70
|
229 spellbookSlot = pickupID,
|
Nenue@70
|
230 spellbookType = pickupBook,
|
Nenue@70
|
231 assignedKeys = {GetBindingKey(command)}
|
Nenue@70
|
232 }
|
Nenue@70
|
233
|
Nenue@70
|
234 local isAssigned, isBound, assignedBy, boundBy = kb.IsCommandBound(self, command)
|
Nenue@70
|
235 if isAssigned then
|
Nenue@70
|
236 local popup = StaticPopupDialogs["SKELETONKEY_CONFIRM_ASSIGN_SLOT"]
|
Nenue@70
|
237 popup.slot = self
|
Nenue@70
|
238 popup.text = "Currently assigned in |cFFFFFF00"..tostring(kb.configHeaders[assignedBy]).."|r. Are you sure?"
|
Nenue@70
|
239 popup.oldProfile = assignedBy
|
Nenue@70
|
240 popup.args = {slotInfo}
|
Nenue@70
|
241 SkeletonKey:SetScript('OnMouseWheel', nil) -- disable scrolling
|
Nenue@70
|
242 StaticPopup_Show('SKELETONKEY_CONFIRM_ASSIGN_SLOT')
|
Nenue@70
|
243 else
|
Nenue@70
|
244 kb.currentProfile.buttons[self:GetID()] = slotInfo
|
Nenue@70
|
245 self:SetSlot(slotInfo)
|
Nenue@70
|
246 self:UpdateSlot()
|
Nenue@70
|
247 self.active = nil
|
Nenue@70
|
248 ClearCursor()
|
Nenue@70
|
249 ResetCursor()
|
Nenue@70
|
250 end
|
Nenue@70
|
251 end
|
Nenue@70
|
252 end
|
Nenue@70
|
253
|
Nenue@70
|
254
|
Nenue@70
|
255 do
|
Nenue@70
|
256 local PickupAction = {
|
Nenue@70
|
257 spell = _G.PickupSpell,
|
Nenue@70
|
258 petaction =
|
Nenue@70
|
259 function(...)
|
Nenue@70
|
260 -- needs to be enclosed to acquire hooksecurefunc effects
|
Nenue@70
|
261 _G.PickupSpellBookItem(...)
|
Nenue@70
|
262 end,
|
Nenue@70
|
263 macro = _G.PickupMacro,
|
Nenue@70
|
264 item = _G.PickupItem,
|
Nenue@70
|
265 mount = _G.C_MountJournal.Pickup
|
Nenue@70
|
266 }
|
Nenue@70
|
267 local GetPickupValue = {
|
Nenue@70
|
268 spell = function(self) return select(7, GetSpellInfo(self.actionID)) end,
|
Nenue@70
|
269 petaction = function(self) return self.pickupSlot, self.pickupBook end,
|
Nenue@70
|
270 }
|
Nenue@70
|
271 function skb:PickupSlot ()
|
Nenue@70
|
272 if not (self.command and self.isAvailable) then
|
Nenue@70
|
273 return
|
Nenue@70
|
274 end
|
Nenue@70
|
275 print(self.actionType)
|
Nenue@70
|
276 if self.actionType == 'spell' then
|
Nenue@70
|
277 -- It can't be picked up if SpellInfo(name) returns void
|
Nenue@70
|
278 local dummy = GetSpellInfo(self.actionName)
|
Nenue@70
|
279 if not dummy then
|
Nenue@70
|
280 return
|
Nenue@70
|
281 end
|
Nenue@70
|
282 end
|
Nenue@70
|
283 if PickupAction[self.actionType] then
|
Nenue@70
|
284 if GetPickupValue[self.actionType] then
|
Nenue@70
|
285 PickupAction[self.actionType](GetPickupValue[self.actionType](self))
|
Nenue@70
|
286 else
|
Nenue@70
|
287 PickupAction[self.actionType](self.actionID)
|
Nenue@70
|
288 end
|
Nenue@70
|
289 self:ReleaseSlot()
|
Nenue@70
|
290 self:UpdateSlot()
|
Nenue@70
|
291 end
|
Nenue@70
|
292 end
|
Nenue@70
|
293 end
|
Nenue@70
|
294
|
Nenue@70
|
295
|
Nenue@70
|
296
|
Nenue@70
|
297
|
Nenue@70
|
298 --- Updates profile assignment and button contents
|
Nenue@70
|
299 function skb:UpdateSlot (force)
|
Nenue@70
|
300 local slot = self:GetID()
|
Nenue@70
|
301
|
Nenue@70
|
302 if force then
|
Nenue@70
|
303 if kb.currentProfile.buttons[slot] then
|
Nenue@70
|
304 print('loading in', slot, kb.db.bindMode)
|
Nenue@70
|
305 self:SetSlot(kb.currentProfile.buttons[slot])
|
Nenue@70
|
306 else
|
Nenue@70
|
307 self:ReleaseSlot()
|
Nenue@70
|
308 end
|
Nenue@70
|
309 end
|
Nenue@70
|
310
|
Nenue@70
|
311 local borderType = BORDER_UNASSIGNED
|
Nenue@70
|
312
|
Nenue@70
|
313 if self.command then
|
Nenue@70
|
314
|
Nenue@70
|
315 if not self.isAvailable then
|
Nenue@70
|
316 borderType = BORDER_DYNAMIC
|
Nenue@70
|
317 self.ignoreTexture:Show()
|
Nenue@70
|
318 else
|
Nenue@70
|
319 self.ignoreTexture:Hide()
|
Nenue@70
|
320
|
Nenue@70
|
321 if self.pending then
|
Nenue@70
|
322 borderType = BORDER_PENDING
|
Nenue@70
|
323 elseif self.dynamicType then
|
Nenue@70
|
324 borderType = BORDER_DYNAMIC
|
Nenue@70
|
325 else
|
Nenue@70
|
326 borderType = BORDER_ASSIGNED
|
Nenue@70
|
327 end
|
Nenue@70
|
328 end
|
Nenue@70
|
329
|
Nenue@70
|
330
|
Nenue@70
|
331 if self.actionType == 'macro' then
|
Nenue@70
|
332 self.macro:Show()
|
Nenue@70
|
333 else
|
Nenue@70
|
334 self.macro:Hide()
|
Nenue@70
|
335 if self.actionType == 'spell' then
|
Nenue@70
|
336 local dummy = GetSpellInfo(self.actionName)
|
Nenue@70
|
337 if not dummy then
|
Nenue@70
|
338 self.icon:SetDesaturated(true)
|
Nenue@70
|
339 else
|
Nenue@70
|
340 self.icon:SetDesaturated(false)
|
Nenue@70
|
341 end
|
Nenue@70
|
342
|
Nenue@70
|
343 end
|
Nenue@70
|
344 end
|
Nenue@70
|
345
|
Nenue@70
|
346
|
Nenue@70
|
347 if self.dynamicType == 'profession' then
|
Nenue@70
|
348 if self.isAvailable then
|
Nenue@70
|
349
|
Nenue@70
|
350 self.statusText = '|cFFFFFF00Profession|r'
|
Nenue@70
|
351 self.bindingText = kb.BindingString(GetBindingKey(self.command))
|
Nenue@70
|
352 else
|
Nenue@70
|
353
|
Nenue@70
|
354 self.statusText = '|cFFFF4400'..PROFESSION_HEADERS[self.dynamicIndex]..'|r'
|
Nenue@70
|
355 self.actionName = '(#'..self.dynamicIndex..')'
|
Nenue@70
|
356 self.bindingText ='?'
|
Nenue@70
|
357 end
|
Nenue@70
|
358 elseif self.dynamicType == 'talent' then
|
Nenue@70
|
359
|
Nenue@70
|
360 self.statusText = '|cFF00FFFF'.. TALENT .. '|r'
|
Nenue@70
|
361 if self.isAvailable then
|
Nenue@70
|
362 self.bindingText = kb.BindingString(GetBindingKey(self.command))
|
Nenue@70
|
363 else
|
Nenue@70
|
364 if kb.TalentBindings[self.actionID] then
|
Nenue@70
|
365 print(self.actionID, #kb.TalentBindings[self.actionID])
|
Nenue@70
|
366 self.bindingText= kb.BindingString(unpack(kb.TalentBindings[self.actionID]))
|
Nenue@70
|
367 end
|
Nenue@70
|
368
|
Nenue@70
|
369 end
|
Nenue@70
|
370 elseif self.dynamicType == 'petaction' then
|
Nenue@70
|
371 self.bindingText = kb.BindingString(GetBindingKey(self.command))
|
Nenue@70
|
372 else
|
Nenue@70
|
373 self.bindingText = kb.BindingString(GetBindingKey(self.command))
|
Nenue@70
|
374 end
|
Nenue@70
|
375
|
Nenue@70
|
376 local locked, layer = kb.IsCommandBound(self)
|
Nenue@70
|
377 if locked then
|
Nenue@70
|
378 self.icon:SetAlpha(0.5)
|
Nenue@70
|
379 else
|
Nenue@70
|
380 self.icon:SetAlpha(1)
|
Nenue@70
|
381 end
|
Nenue@70
|
382
|
Nenue@70
|
383
|
Nenue@70
|
384 if self.actionType == 'spell' then
|
Nenue@70
|
385 self.icon:SetTexture(GetSpellTexture(self.actionID))
|
Nenue@70
|
386 end
|
Nenue@70
|
387 print('|cFF00BBFFUpdateSlot|r:', '['..slot..'] =', self.command, self.bindingText, self.dynamicType, self.isAvailable, self.actionID)
|
Nenue@70
|
388 else
|
Nenue@70
|
389 if kb.saveTarget == self then
|
Nenue@70
|
390 kb.DeactivateSlot(self)
|
Nenue@70
|
391 end
|
Nenue@70
|
392
|
Nenue@70
|
393 end
|
Nenue@70
|
394
|
Nenue@70
|
395 self.ignoreTexture:SetShown(self.command and not self.isAvailable)
|
Nenue@70
|
396
|
Nenue@70
|
397 if not self.isAvailable then
|
Nenue@70
|
398 self.bind:SetTextColor(0.7,0.7,0.7,1)
|
Nenue@70
|
399 else
|
Nenue@70
|
400 self.bind:SetTextColor(1,1,1,1)
|
Nenue@70
|
401 end
|
Nenue@70
|
402
|
Nenue@70
|
403
|
Nenue@70
|
404 if kb.saveTarget and kb.saveTarget ~= self then
|
Nenue@70
|
405 self:SetAlpha(0.25)
|
Nenue@70
|
406 else
|
Nenue@70
|
407
|
Nenue@70
|
408 self:SetAlpha(1)
|
Nenue@70
|
409 end
|
Nenue@70
|
410
|
Nenue@70
|
411 --self.alert:SetShown(self.command and not self.isBound)
|
Nenue@70
|
412
|
Nenue@70
|
413 self.icon:SetTexture(self.iconPath)
|
Nenue@70
|
414
|
Nenue@70
|
415 self.border:SetColorTexture(unpack(borderType))
|
Nenue@70
|
416 self.header:SetText(self.statusText)
|
Nenue@70
|
417 self.bind:SetText(self.bindingText)
|
Nenue@70
|
418 self.details:SetText(self.actionName)
|
Nenue@70
|
419 end
|
Nenue@70
|
420
|
Nenue@70
|
421 --- Resets button command
|
Nenue@70
|
422 function skb:ReleaseSlot ()
|
Nenue@70
|
423 local slot = self:GetID()
|
Nenue@70
|
424
|
Nenue@70
|
425
|
Nenue@70
|
426 if kb.currentProfile.buttons[slot] then
|
Nenue@70
|
427 kb.currentProfile.buttons[slot] = nil
|
Nenue@70
|
428 end
|
Nenue@70
|
429 if self.command then
|
Nenue@70
|
430 kb.currentProfile.commands[self.command] = nil
|
Nenue@70
|
431 end
|
Nenue@70
|
432 local talentName = self.actionName
|
Nenue@70
|
433 if self.actionType == 'macro' then
|
Nenue@70
|
434 talentName = GetMacroSpell(self.actionID)
|
Nenue@70
|
435 end
|
Nenue@70
|
436 -- remove any matching talent data
|
Nenue@70
|
437 if talentName and kb.currentProfile.talents[talentName] then
|
Nenue@70
|
438 kb.currentProfile.talents[talentName] = nil
|
Nenue@70
|
439 end
|
Nenue@70
|
440 local droppedKeys = {}
|
Nenue@70
|
441
|
Nenue@70
|
442 -- doing removal in second loop to avoid possible iterator shenanigans
|
Nenue@70
|
443 for k,v in pairs(kb.currentProfile.bindings) do
|
Nenue@70
|
444 if v == self.command then
|
Nenue@70
|
445 tinsert(droppedKeys, k)
|
Nenue@70
|
446 end
|
Nenue@70
|
447 end
|
Nenue@70
|
448 if #droppedKeys >=1 then
|
Nenue@70
|
449 for i, k in ipairs(droppedKeys) do
|
Nenue@70
|
450 kb.currentProfile.bindings[k] = nil
|
Nenue@70
|
451 end
|
Nenue@70
|
452 end
|
Nenue@70
|
453
|
Nenue@70
|
454 self.isAvailable = nil
|
Nenue@70
|
455 self.dynamicType = nil
|
Nenue@70
|
456 self.bindingText = nil
|
Nenue@70
|
457 self.statusText = nil
|
Nenue@70
|
458 self.command = nil
|
Nenue@70
|
459 self.iconPath = nil
|
Nenue@70
|
460 self.actionType = nil
|
Nenue@70
|
461 self.actionID = nil
|
Nenue@70
|
462 self.actionName = nil
|
Nenue@70
|
463 self.pickupSlot = nil
|
Nenue@70
|
464 self.pickupBook = nil
|
Nenue@70
|
465 self.macroName = nil
|
Nenue@70
|
466 self.profile = nil
|
Nenue@70
|
467 self.border:SetColorTexture(unpack(BORDER_UNASSIGNED))
|
Nenue@70
|
468 self:EnableKeyboard(false)
|
Nenue@70
|
469 self:SetScript('OnKeyDown', nil)
|
Nenue@70
|
470 self.bindingText = nil
|
Nenue@70
|
471 self.icon:SetTexture(nil)
|
Nenue@70
|
472 self.ignoreTexture:Hide()
|
Nenue@70
|
473
|
Nenue@70
|
474 end
|
Nenue@70
|
475
|
Nenue@70
|
476 local spells = {}
|
Nenue@70
|
477 local SkeletonKey_GetGenericSpell = function(spellName, spellID, icon)
|
Nenue@70
|
478 if not spells[spellID] then
|
Nenue@70
|
479 spells[spellID] = {}
|
Nenue@70
|
480 spells[spellID].actionType = 'spell'
|
Nenue@70
|
481 spells[spellID].actionID = spellID
|
Nenue@70
|
482 spells[spellID].actionName = spellName
|
Nenue@70
|
483 spells[spellID].iconPath = icon
|
Nenue@70
|
484 spells[spellID].statusText = '|cFFBBBBBBSpell|r'
|
Nenue@70
|
485 spells[spellID].dynamicType = nil
|
Nenue@70
|
486 end
|
Nenue@70
|
487 return spells[spellID]
|
Nenue@70
|
488 end
|
Nenue@70
|
489
|
Nenue@70
|
490 local tempInfo = {}
|
Nenue@70
|
491 -- tries to resolve spells from talent overrides/profession book/etc
|
Nenue@70
|
492 local dynamicTypes = {['profession'] = 'ProfessionCache', ['talent'] = 'TalentCache', ['petaction'] = 'PetInfoCache'}
|
Nenue@70
|
493 local SkeletonKey_GetSpellDetails = function(self)
|
Nenue@70
|
494
|
Nenue@70
|
495 local spellName, spellID, command, icon = self.actionName, self.actionID, self.command, self.iconPath
|
Nenue@70
|
496
|
Nenue@70
|
497
|
Nenue@70
|
498 cprint(' In:', spellName, spellID, command)
|
Nenue@70
|
499 cprint(GetSpellInfo(spellName or spellID))
|
Nenue@70
|
500 local internalName, _, internalIcon, _, _, _, _ = GetSpellInfo(spellName or spellID)
|
Nenue@70
|
501 local isAvailable = internalName and true
|
Nenue@70
|
502
|
Nenue@70
|
503 if internalName and (internalName ~= spellName) then
|
Nenue@70
|
504 -- it's a binding for the originating spell, leave it as is
|
Nenue@70
|
505 cprint(' |cFFFF4400spell is an override(', internalName, '~=', spellName,') leave the name info alone')
|
Nenue@70
|
506 self.statusText = '|cFFFFFF00Spell|r'
|
Nenue@70
|
507 self.isAvailable = true
|
Nenue@70
|
508 return
|
Nenue@70
|
509 end
|
Nenue@70
|
510
|
Nenue@70
|
511 -- let's us match spells replaced by talents
|
Nenue@70
|
512 local info = kb.DynamicSpells[internalName or spellName]
|
Nenue@70
|
513 if not info then
|
Nenue@70
|
514 local dynamicType, dynamicIndex, dynamicSubIndex = command:match("(%a+)_(%S+)_(%S+)")
|
Nenue@70
|
515 if kb.DynamicSpells[dynamicType] then
|
Nenue@70
|
516 cprint('|cFFFF4400resolving dynamic type index:', internalName, spellName, command)
|
Nenue@70
|
517 dynamicIndex = tonumber(dynamicIndex)
|
Nenue@70
|
518 dynamicSubIndex = tonumber(dynamicSubIndex)
|
Nenue@70
|
519 local cache = kb.DynamicSpells[dynamicType]
|
Nenue@70
|
520 cprint('type:', dynamicType)
|
Nenue@70
|
521 if dynamicIndex and cache[dynamicIndex] then
|
Nenue@70
|
522 info = kb.DynamicSpells[dynamicType][dynamicIndex]
|
Nenue@70
|
523 cprint('index:', dynamicIndex)
|
Nenue@70
|
524 if dynamicSubIndex and info[dynamicSubIndex] then
|
Nenue@70
|
525 info = info[dynamicSubIndex]
|
Nenue@70
|
526 cprint('sub-index:', dynamicSubIndex)
|
Nenue@70
|
527 end
|
Nenue@70
|
528 isAvailable = true
|
Nenue@70
|
529 end
|
Nenue@70
|
530 end
|
Nenue@70
|
531 if not info then
|
Nenue@70
|
532 info = SkeletonKey_GetGenericSpell(spellName, spellID, internalIcon or icon)
|
Nenue@70
|
533 end
|
Nenue@70
|
534 end
|
Nenue@70
|
535 info.isAvailable = isAvailable
|
Nenue@70
|
536
|
Nenue@70
|
537 cprint('|cFF00FF88SpellDetails:|r', info.actionName, info.actionID, info.dynamicType)
|
Nenue@70
|
538 for k,v in pairs(info) do
|
Nenue@70
|
539 cprint(' ',k,v)
|
Nenue@70
|
540 self[k] = v
|
Nenue@70
|
541 end
|
Nenue@70
|
542
|
Nenue@70
|
543 return info
|
Nenue@70
|
544 end
|
Nenue@70
|
545
|
Nenue@70
|
546 --- Assigns the slot via table copy; any manipulations from this point are temporary and
|
Nenue@70
|
547 function skb:SetSlot(slotInfo)
|
Nenue@70
|
548 print('slot info', self:GetID())
|
Nenue@70
|
549
|
Nenue@70
|
550 for k,v in pairs(slotInfo) do
|
Nenue@70
|
551 print(' -', k, v)
|
Nenue@70
|
552 self[k] = v
|
Nenue@70
|
553 end
|
Nenue@70
|
554 self.dynamicType = slotInfo.dynamicType
|
Nenue@70
|
555 local command, name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook
|
Nenue@70
|
556 = self.command, self.actionName, self.iconPath, self.actionType, self.actionID, self.macroName, self.macroText, self.spellbookSlot, self.spellbookType
|
Nenue@70
|
557
|
Nenue@70
|
558
|
Nenue@70
|
559 local slot = self:GetID()
|
Nenue@70
|
560 local isBound = false
|
Nenue@70
|
561 print('|cFFFFFF00SetSlot|r:', self:GetID())
|
Nenue@70
|
562 if self.command then
|
Nenue@70
|
563
|
Nenue@70
|
564 isBound = kb.IsCommandBound(self, self.command)
|
Nenue@70
|
565 if actionType == 'spell' then
|
Nenue@70
|
566 local info = SkeletonKey_GetSpellDetails(self)
|
Nenue@70
|
567 name, icon, actionType, actionID, macroName, macroText, pickupSlot, pickupBook = self.actionName, self.iconPath, self.actionType, self.actionID, self.macroName, self.macroText, self.spellbookSlot, self.spellbookType
|
Nenue@70
|
568
|
Nenue@70
|
569 elseif actionType == 'petaction' then
|
Nenue@70
|
570 self.dynamicType = 'petaction'
|
Nenue@70
|
571 local specialType, specialNum = command:match(actionType..'_([%a%s]+)_(%d)')
|
Nenue@70
|
572
|
Nenue@70
|
573 if kb.PetCache.subtext[specialType] then
|
Nenue@70
|
574
|
Nenue@70
|
575 local info = kb.PetCache.subtext[specialType][tonumber(specialNum)]
|
Nenue@70
|
576 if info then
|
Nenue@70
|
577 print('***dynamic pet skill', specialType, specialNum)
|
Nenue@70
|
578 --[[ i, spellName, subText, spellID, texture, specialNum[subText ]]
|
Nenue@70
|
579
|
Nenue@70
|
580 for k,v in pairs(info) do
|
Nenue@70
|
581 self[k] = v
|
Nenue@70
|
582 end
|
Nenue@70
|
583 end
|
Nenue@70
|
584
|
Nenue@70
|
585 end
|
Nenue@70
|
586 self.statusText = 'Pet Action'
|
Nenue@70
|
587 self.isAvailable = (kb.PetCache.spellslot[name])
|
Nenue@70
|
588 elseif actionType == 'macro' then
|
Nenue@70
|
589 if actionID then
|
Nenue@70
|
590 -- look for corruption
|
Nenue@70
|
591 local nameByID, _, bodyByID = GetMacroInfo(actionID)
|
Nenue@70
|
592 local nameByName, _, bodyByName = GetMacroInfo(name)
|
Nenue@70
|
593 if (nameByID ~= name) or (bodyByID ~= macroText) then
|
Nenue@70
|
594 local prevIndex = actionID
|
Nenue@70
|
595 actionID = GetMacroIndexByName(name)
|
Nenue@70
|
596 local firstName, _, firstBody = GetMacroInfo(actionID)
|
Nenue@70
|
597 if (firstName ~= name) or (firstBody ~= macroText) then
|
Nenue@70
|
598 -- go even deeper
|
Nenue@70
|
599 for i = 1, GetNumMacros() do
|
Nenue@70
|
600 local searchName, _ , searchBody = GetMacroInfo(i)
|
Nenue@70
|
601 if (searchName == name) and (searchBody == macroText) then
|
Nenue@70
|
602 -- complete match
|
Nenue@70
|
603 actionID = i
|
Nenue@70
|
604 break
|
Nenue@70
|
605 elseif (searchName == name) or (searchBody == macroText) then
|
Nenue@70
|
606 -- partial match, continue the search
|
Nenue@70
|
607 actionID = i
|
Nenue@70
|
608 end
|
Nenue@70
|
609 end
|
Nenue@70
|
610 end
|
Nenue@70
|
611 kb:print('Macro index changed: |cFFFFFF00', actionType, '|r', name, '(was '..tostring(prevIndex)..', now '..tostring(actionID)..')')
|
Nenue@70
|
612 end
|
Nenue@70
|
613 else
|
Nenue@70
|
614 actionID = GetMacroIndexByName(name)
|
Nenue@70
|
615 end
|
Nenue@70
|
616 self.statusText = 'Macro'
|
Nenue@70
|
617 self.isAvailable = true
|
Nenue@70
|
618 else
|
Nenue@70
|
619 if not actionID then
|
Nenue@70
|
620 actionID = command:match("^KeyBinderMacro:(.+)")
|
Nenue@70
|
621 end
|
Nenue@70
|
622 self.isAvailable = true
|
Nenue@70
|
623 end
|
Nenue@70
|
624
|
Nenue@70
|
625 if self.isAvailable then
|
Nenue@70
|
626 local oldCommand = command
|
Nenue@70
|
627 command = kb.LoadBinding(self)
|
Nenue@70
|
628 if oldCommand ~= command then
|
Nenue@70
|
629 print('|cFFFF4400fixing command string', actionType, actionID, name)
|
Nenue@70
|
630 kb.currentProfile.bound[oldCommand] = nil
|
Nenue@70
|
631 kb.currentProfile.bound[command] = slot
|
Nenue@70
|
632 for k,v in pairs(kb.currentProfile.bindings) do
|
Nenue@70
|
633 if v == oldCommand then
|
Nenue@70
|
634 kb.currentProfile.bindings[k] = command
|
Nenue@70
|
635 end
|
Nenue@70
|
636 end
|
Nenue@70
|
637 end
|
Nenue@70
|
638 end
|
Nenue@70
|
639
|
Nenue@70
|
640
|
Nenue@70
|
641 actionID = actionID or 0
|
Nenue@70
|
642 self:EnableKeyboard(true)
|
Nenue@70
|
643
|
Nenue@70
|
644 -- this is done to keep legacy key-values from breaking algorithm assumptions
|
Nenue@70
|
645 local slotInfo = {
|
Nenue@70
|
646 command = command,
|
Nenue@70
|
647 actionName = name,
|
Nenue@70
|
648 iconPath = icon,
|
Nenue@70
|
649 actionID = actionID,
|
Nenue@70
|
650 actionType = actionType,
|
Nenue@70
|
651 macroName = macroName,
|
Nenue@70
|
652 macroText = macroText,
|
Nenue@70
|
653 spellbookSlot = pickupSlot,
|
Nenue@70
|
654 spellbookType = pickupBook,
|
Nenue@70
|
655 assignedKeys = {GetBindingKey(command)}
|
Nenue@70
|
656 }
|
Nenue@70
|
657 kb.currentProfile.buttons[slot] = slotInfo
|
Nenue@70
|
658
|
Nenue@70
|
659 -- Clean up conflicting entries for loaded button
|
Nenue@70
|
660 local previous = kb.currentProfile.commands[command]
|
Nenue@70
|
661 if previous ~= slot and kb.buttons[previous] then
|
Nenue@70
|
662 kb.ReleaseSlot(kb.buttons[previous])
|
Nenue@70
|
663 end
|
Nenue@70
|
664
|
Nenue@70
|
665 local binds = {GetBindingKey(command) }
|
Nenue@70
|
666 if self.isAvailable and (#binds >= 1) then
|
Nenue@70
|
667 local found
|
Nenue@70
|
668 for i, key in ipairs(binds) do
|
Nenue@70
|
669 if not tContains(self.assignedKeys, key) then
|
Nenue@70
|
670 tinsert(self.assignedKeys, key)
|
Nenue@70
|
671 kb.currentProfile.bindings[key] = command
|
Nenue@70
|
672 kb.currentProfile.bound[command] = true
|
Nenue@70
|
673 found = true
|
Nenue@70
|
674 end
|
Nenue@70
|
675 end
|
Nenue@70
|
676 if found then
|
Nenue@70
|
677 kb:print('Recovered key binding for', name)
|
Nenue@70
|
678 end
|
Nenue@70
|
679 end
|
Nenue@70
|
680
|
Nenue@70
|
681 kb.currentProfile.commands[command] = slot
|
Nenue@70
|
682 end
|
Nenue@70
|
683
|
Nenue@70
|
684
|
Nenue@70
|
685
|
Nenue@70
|
686 self.isBound = isBound
|
Nenue@70
|
687 self.pickupSlot = pickupSlot
|
Nenue@70
|
688 self.pickupBook = pickupBook
|
Nenue@70
|
689 self.macroText = macroText
|
Nenue@70
|
690 self.macroName = macroName
|
Nenue@70
|
691 self.actionType = actionType
|
Nenue@70
|
692 self.actionID = actionID
|
Nenue@70
|
693 self.actionName = name
|
Nenue@70
|
694 self.command = command
|
Nenue@70
|
695 self.iconPath = icon
|
Nenue@70
|
696 self.profile = kb.db.bindMode
|
Nenue@70
|
697 self:RegisterForDrag('LeftButton')
|
Nenue@70
|
698 end
|
Nenue@70
|
699
|
Nenue@70
|
700 kb.GetCommandAction = function(command)
|
Nenue@70
|
701 for i, data in ipairs(kb.loadedProfiles) do
|
Nenue@70
|
702 if data.commands[command] then
|
Nenue@70
|
703 if data.buttons[data.commands[command]] then
|
Nenue@70
|
704 local _, _, _, actionType, actionID = unpack(data.buttons[data.commands[command]])
|
Nenue@70
|
705 return actionType, actionID
|
Nenue@70
|
706 end
|
Nenue@70
|
707 end
|
Nenue@70
|
708 end
|
Nenue@70
|
709 end
|
Nenue@70
|
710
|