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