You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
513 lines
14 KiB
513 lines
14 KiB
-- Neuron is a World of Warcraft® user interface addon.
|
|
-- Copyright (c) 2017-2021 Britt W. Yazel
|
|
-- Copyright (c) 2006-2014 Connor H. Chenoweth
|
|
-- This code is licensed under the MIT license (see LICENSE for details)
|
|
|
|
local _, addonTable = ...
|
|
local Neuron = addonTable.Neuron
|
|
|
|
---The functions in this file are part of the ActionButton class.
|
|
---It was just easier to put them all in their own file for organization.
|
|
|
|
local ActionButton = Neuron.ActionButton
|
|
|
|
local macroDrag = {} --this is a table that holds onto the contents of the current macro being dragged
|
|
local macroCache = {} --this will hold onto any previous contents of our button
|
|
|
|
local L = LibStub("AceLocale-3.0"):GetLocale("Neuron")
|
|
|
|
--------------------------------------
|
|
--------------------------------------
|
|
|
|
--this is the function that fires when you begin dragging an item
|
|
function ActionButton:OnDragStart()
|
|
if InCombatLockdown() or not self.bar or self.actionID then
|
|
return
|
|
end
|
|
|
|
local drag
|
|
|
|
if not self.bar:GetBarLock() then
|
|
drag = true
|
|
elseif self.bar:GetBarLock() == "alt" and IsAltKeyDown() then
|
|
drag = true
|
|
elseif self.bar:GetBarLock() == "ctrl" and IsControlKeyDown() then
|
|
drag = true
|
|
elseif self.bar:GetBarLock() == "shift" and IsShiftKeyDown() then
|
|
drag = true
|
|
else
|
|
drag = false
|
|
end
|
|
|
|
if drag and self:GetMacroText() ~= "" then
|
|
Neuron.dragging = true
|
|
|
|
if #macroCache==0 then --don't run if we have a cache, we will call it manually on the OnReceiveDrag on the new button
|
|
self:SetMouseCursor()
|
|
end
|
|
|
|
self:PickUpMacro()
|
|
|
|
self:InitializeButton()
|
|
self:UpdateAll()
|
|
|
|
for _,bar in pairs(Neuron.bars) do
|
|
if bar.class == "ActionBar" then
|
|
bar:ACTIONBAR_SHOWHIDEGRID(true) --show the button grid if we have something picked up (i.e if macroDrag contains something)
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
--This is the function that fires when a button is receiving a dragged item
|
|
function ActionButton:OnReceiveDrag()
|
|
if InCombatLockdown() then --don't allow moving or changing macros while in combat. This will cause taint
|
|
return
|
|
end
|
|
|
|
local cursorType, action1, action2, spellID = GetCursorInfo()
|
|
|
|
if self:HasAction() then --if our button being dropped onto already has content, we need to cache that content
|
|
macroCache[1] = self:GetDragAction()
|
|
macroCache[2] = self:GetMacroText()
|
|
macroCache[3] = self:GetMacroIcon()
|
|
macroCache[4] = self:GetMacroName()
|
|
macroCache[5] = self:GetMacroNote()
|
|
macroCache[6] = self:GetMacroUseNote()
|
|
macroCache[7] = self:GetMacroBlizzMacro()
|
|
macroCache[8] = self:GetMacroEquipmentSet()
|
|
else
|
|
wipe(macroCache)
|
|
end
|
|
|
|
if #macroCache > 0 then --if we have a cache, pickup the current icon before replacing it with the new content
|
|
self:SetMouseCursor()
|
|
end
|
|
|
|
if #macroDrag > 0 then --checks to see if the thing we are placing is a Neuron created macro vs something from the spellbook
|
|
self:PlaceMacro()
|
|
elseif cursorType == "spell" then
|
|
self:PlaceSpell(action1, action2, spellID)
|
|
|
|
elseif cursorType == "item" then
|
|
self:PlaceItem(action1, action2)
|
|
|
|
elseif cursorType == "macro" then
|
|
self:PlaceBlizzMacro(action1)
|
|
|
|
elseif cursorType == "equipmentset" then
|
|
self:PlaceBlizzEquipSet(action1)
|
|
|
|
elseif cursorType == "mount" then
|
|
self:PlaceMount(action1, action2)
|
|
|
|
elseif cursorType == "flyout" then
|
|
self:PlaceFlyout(action1, action2)
|
|
|
|
elseif cursorType == "battlepet" then
|
|
self:PlaceBattlePet(action1, action2)
|
|
elseif cursorType == "companion" then
|
|
self:PlaceCompanion(action1, action2)
|
|
elseif cursorType == "petaction" then
|
|
self:PlacePetAbility(action1, action2)
|
|
end
|
|
|
|
wipe(macroDrag)
|
|
|
|
if #macroCache>0 then
|
|
self:OnDragStart() --If we picked up a new ability after dropping this one we have to manually call OnDragStart
|
|
for _,bar in pairs(Neuron.bars) do
|
|
bar:ACTIONBAR_SHOWHIDEGRID(true) --show the button grid if we have something picked up (i.e if macroDrag contains something)
|
|
end
|
|
else
|
|
SetCursor(nil)
|
|
ClearCursor() --if we did not pick up a new spell, clear the cursor
|
|
Neuron.dragging = false
|
|
for _,bar in pairs(Neuron.bars) do
|
|
bar:ACTIONBAR_SHOWHIDEGRID() --show the button grid if we have something picked up (i.e if macroDrag contains something)
|
|
end
|
|
end
|
|
|
|
self:InitializeButton()
|
|
|
|
self:UpdateAll()
|
|
end
|
|
|
|
|
|
function ActionButton:PostClick() --this is necessary because if you are daisy-chain dragging spells to the bar you wont be able to place the last one due to it not firing an OnReceiveDrag
|
|
if #macroDrag>0 then
|
|
self:OnReceiveDrag()
|
|
end
|
|
self:UpdateStatus()
|
|
end
|
|
|
|
--we need to hook to the WorldFrame OnReceiveDrag and OnMouseDown so that we can "let go" of the spell when we drag it off the bar
|
|
function ActionButton:WorldFrame_OnReceiveDrag()
|
|
--CAREFUL! see brittyazel/Neuron/issues/468
|
|
--only do something if there's currently data in macroDrag. Otherwise it is
|
|
--just for normal Blizzard behavior.
|
|
if #macroDrag > 0 then
|
|
SetCursor(nil)
|
|
ClearCursor()
|
|
Neuron.dragging = false
|
|
|
|
wipe(macroDrag)
|
|
wipe(macroCache)
|
|
end
|
|
|
|
for _,bar in pairs(Neuron.bars) do
|
|
bar:ACTIONBAR_SHOWHIDEGRID()
|
|
end
|
|
end
|
|
|
|
--------------------------------------
|
|
--------------------------------------
|
|
|
|
|
|
function ActionButton:PickUpMacro()
|
|
|
|
if macroCache[1] then --triggers when picking up an existing button with a button in the cursor
|
|
|
|
macroDrag = CopyTable(macroCache)
|
|
wipe(macroCache) --once macroCache is loaded into macroDrag, wipe it
|
|
|
|
elseif self:HasAction() then
|
|
|
|
macroDrag[1] = self:GetDragAction()
|
|
macroDrag[2] = self:GetMacroText()
|
|
macroDrag[3] = self:GetMacroIcon()
|
|
macroDrag[4] = self:GetMacroName()
|
|
macroDrag[5] = self:GetMacroNote()
|
|
macroDrag[6] = self:GetMacroUseNote()
|
|
macroDrag[7] = self:GetMacroBlizzMacro()
|
|
macroDrag[8] = self:GetMacroEquipmentSet()
|
|
|
|
self:SetMacroText()
|
|
self:SetMacroIcon()
|
|
self:SetMacroName()
|
|
self:SetMacroNote()
|
|
self:SetMacroUseNote()
|
|
self:SetMacroBlizzMacro()
|
|
self:SetMacroEquipmentSet()
|
|
|
|
self.spell = nil
|
|
self.spellID = nil
|
|
self.item = nil
|
|
|
|
self:InitializeButton()
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
function ActionButton:PlaceMacro()
|
|
self:SetMacroText(macroDrag[2])
|
|
self:SetMacroIcon(macroDrag[3])
|
|
self:SetMacroName(macroDrag[4])
|
|
self:SetMacroNote(macroDrag[5])
|
|
self:SetMacroUseNote(macroDrag[6])
|
|
self:SetMacroBlizzMacro(macroDrag[7])
|
|
self:SetMacroEquipmentSet(macroDrag[8])
|
|
end
|
|
|
|
function ActionButton:PlaceSpell(action1, action2, spellID)
|
|
local spell
|
|
|
|
if action1 == 0 then
|
|
-- I am unsure under what conditions (if any) we wouldn't have a spell ID
|
|
if not spellID or spellID == 0 then
|
|
return
|
|
else
|
|
spell = GetSpellInfo(spellID)
|
|
end
|
|
else
|
|
spell,_= GetSpellBookItemName(action1, action2):lower()
|
|
_,spellID = GetSpellBookItemInfo(action1, action2)
|
|
end
|
|
|
|
|
|
local spellName , _, icon = GetSpellInfo(spellID)
|
|
|
|
if not spellName then
|
|
if Neuron.spellCache[spell:lower()] then
|
|
spellName = Neuron.spellCache[spell:lower()].spellName
|
|
icon = Neuron.spellCache[spell:lower()].icon
|
|
end
|
|
end
|
|
|
|
|
|
self:SetMacroText(self:AutoWriteMacro(spell))
|
|
self:SetMacroIcon() --will pull icon automatically unless explicitly overridden
|
|
self:SetMacroName(spellName)
|
|
self:SetMacroNote()
|
|
self:SetMacroUseNote()
|
|
self:SetMacroBlizzMacro()
|
|
self:SetMacroEquipmentSet()
|
|
end
|
|
|
|
function ActionButton:PlacePetAbility(action1, action2)
|
|
|
|
local spellID = action1
|
|
local spellIndex = action2
|
|
|
|
if spellIndex then --if the ability doesn't have a spellIndex, i.e (passive, follow, defensive, etc, print a warning)
|
|
local spellInfoName , _, icon = GetSpellInfo(spellID)
|
|
|
|
self:SetMacroText(self:AutoWriteMacro(spellInfoName))
|
|
self:SetMacroIcon() --will pull icon automatically unless explicitly overridden
|
|
self:SetMacroName(spellInfoName)
|
|
self:SetMacroNote()
|
|
self:SetMacroUseNote()
|
|
self:SetMacroBlizzMacro()
|
|
self:SetMacroEquipmentSet()
|
|
|
|
else
|
|
Neuron:Print(L["DragDrop_Error_Message"])
|
|
end
|
|
end
|
|
|
|
|
|
function ActionButton:PlaceItem(action1, action2)
|
|
local item, link = GetItemInfo(action2)
|
|
|
|
if link and not Neuron.itemCache[item:lower()] then --add the item to the itemcache if it isn't otherwise in it
|
|
local _, itemID = link:match("(item:)(%d+)")
|
|
Neuron.itemCache[item:lower()] = itemID
|
|
end
|
|
|
|
if IsEquippableItem(item) then
|
|
self:SetMacroText("/equip "..item.."\n/use "..item)
|
|
else
|
|
self:SetMacroText("/use "..item)
|
|
end
|
|
|
|
self:SetMacroIcon() --will pull icon automatically unless explicitly overridden
|
|
self:SetMacroName(item)
|
|
self:SetMacroNote()
|
|
self:SetMacroUseNote()
|
|
self:SetMacroBlizzMacro()
|
|
self:SetMacroEquipmentSet()
|
|
|
|
end
|
|
|
|
|
|
function ActionButton:PlaceBlizzMacro(action1)
|
|
if action1 == 0 then
|
|
return
|
|
end
|
|
|
|
local name, texture, body = GetMacroInfo(action1)
|
|
|
|
if body then
|
|
self:SetMacroText(body)
|
|
self:SetMacroName(name)
|
|
self:SetMacroIcon(texture)
|
|
self:SetMacroBlizzMacro(name)
|
|
else
|
|
self:SetMacroText()
|
|
self:SetMacroName()
|
|
self:SetMacroIcon()
|
|
self:SetMacroBlizzMacro()
|
|
end
|
|
|
|
self:SetMacroNote()
|
|
self:SetMacroUseNote()
|
|
self:SetMacroEquipmentSet()
|
|
end
|
|
|
|
|
|
function ActionButton:PlaceBlizzEquipSet(equipmentSetName)
|
|
if equipmentSetName == 0 then
|
|
return
|
|
end
|
|
|
|
local equipsetNameIndex --cycle through the equipment sets to find the index of the one with the right name
|
|
|
|
for i = 0,C_EquipmentSet.GetNumEquipmentSets()-1 do
|
|
if equipmentSetName == C_EquipmentSet.GetEquipmentSetInfo(i) then
|
|
equipsetNameIndex = i
|
|
break
|
|
end
|
|
end
|
|
|
|
if not equipsetNameIndex then --bail out of we don't find an equipset index (should never happen but just in case
|
|
return
|
|
end
|
|
|
|
local name, texture = C_EquipmentSet.GetEquipmentSetInfo(equipsetNameIndex)
|
|
|
|
if texture then
|
|
self:SetMacroText("/equipset "..equipmentSetName)
|
|
self:SetMacroName(name)
|
|
self:SetMacroIcon(texture)
|
|
self:SetMacroEquipmentSet(equipmentSetName)
|
|
else
|
|
self:SetMacroText()
|
|
self:SetMacroName()
|
|
self:SetMacroIcon()
|
|
self:SetMacroEquipmentSet()
|
|
end
|
|
|
|
self:SetMacroNote()
|
|
self:SetMacroUseNote()
|
|
self:SetMacroBlizzMacro()
|
|
end
|
|
|
|
|
|
--Hooks mount journal mount buttons on enter to pull spellid from tooltip--
|
|
--Based on discussion thread http://www.wowinterface.com/forums/showthread.php?t=49599&page=2
|
|
--More dynamic than the manual list that was originally implement
|
|
|
|
function ActionButton:PlaceMount(action1, action2)
|
|
local mountName, mountSpellID, mountIcon = C_MountJournal.GetMountInfoByID(action1)
|
|
local mountSpell
|
|
|
|
if action1 == 0 or not mountSpellID or mountSpellID == 0 then
|
|
return
|
|
else
|
|
mountSpell = GetSpellInfo(mountSpellID)
|
|
end
|
|
|
|
--The Summon Random Mount from the Mount Journal
|
|
if action1 == 268435455 then
|
|
self:SetMacroText("#autowrite\n/run C_MountJournal.SummonByID(0);")
|
|
self:SetMacroIcon("Interface\\ICONS\\ACHIEVEMENT_GUILDPERK_MOUNTUP")
|
|
self:SetMacroName("Random Mount")
|
|
else
|
|
self:SetMacroText(self:AutoWriteMacro(mountSpell))
|
|
self:SetMacroIcon() --will pull icon automatically unless explicitly overridden
|
|
self:SetMacroName(mountName)
|
|
end
|
|
self:SetMacroNote()
|
|
self:SetMacroUseNote()
|
|
self:SetMacroBlizzMacro()
|
|
self:SetMacroEquipmentSet()
|
|
end
|
|
|
|
|
|
function ActionButton:PlaceCompanion(action1, action2)
|
|
if action1 == 0 then
|
|
return
|
|
end
|
|
|
|
local _, _, spellID, icon = GetCompanionInfo(action2, action1)
|
|
local name = GetSpellInfo(spellID)
|
|
|
|
if name then
|
|
self:SetMacroName(name)
|
|
self:SetMacroText(self:AutoWriteMacro(name))
|
|
else
|
|
self:SetMacroName()
|
|
self:SetMacroText()
|
|
end
|
|
|
|
self:SetMacroIcon(icon) --need to set icon here, it won't pull it automatically
|
|
self:SetMacroNote()
|
|
self:SetMacroUseNote()
|
|
self:SetMacroBlizzMacro()
|
|
self:SetMacroEquipmentSet()
|
|
end
|
|
|
|
function ActionButton:PlaceBattlePet(action1, action2)
|
|
if action1 == 0 then
|
|
return
|
|
end
|
|
|
|
local _, _, _, _, _, _, _,petName, petIcon= C_PetJournal.GetPetInfoByPetID(action1)
|
|
|
|
self:SetMacroText("#autowrite\n/summonpet "..petName)
|
|
self:SetMacroIcon(petIcon) --need to set icon here, it won't pull it automatically
|
|
self:SetMacroName(petName)
|
|
self:SetMacroNote()
|
|
self:SetMacroUseNote()
|
|
self:SetMacroBlizzMacro()
|
|
self:SetMacroEquipmentSet()
|
|
end
|
|
|
|
|
|
function ActionButton:PlaceFlyout(action1, action2)
|
|
if action1 == 0 then
|
|
return
|
|
end
|
|
|
|
local count = #self.bar.buttons
|
|
local columns = self.bar.data.columns or count
|
|
local rows = count/columns
|
|
|
|
local point = self:GetPosition(UIParent)
|
|
|
|
if columns/rows > 1 then
|
|
|
|
if point:find("BOTTOM") then
|
|
point = "b:t:1"
|
|
elseif point:find("TOP") then
|
|
point = "t:b:1"
|
|
elseif point:find("RIGHT") then
|
|
point = "r:l:12"
|
|
elseif point:find("LEFT") then
|
|
point = "l:r:12"
|
|
else
|
|
point = "r:l:12"
|
|
end
|
|
else
|
|
if point:find("RIGHT") then
|
|
point = "r:l:12"
|
|
elseif point:find("LEFT") then
|
|
point = "l:r:12"
|
|
elseif point:find("BOTTOM") then
|
|
point = "b:t:1"
|
|
elseif point:find("TOP") then
|
|
point = "t:b:1"
|
|
else
|
|
point = "r:l:12"
|
|
end
|
|
end
|
|
|
|
self:SetMacroText("/flyout blizz:"..action1..":l:"..point..":c")
|
|
self:SetMacroIcon()
|
|
self:SetMacroName()
|
|
self:SetMacroNote()
|
|
self:SetMacroUseNote()
|
|
self:SetMacroBlizzMacro()
|
|
self:SetMacroEquipmentSet()
|
|
|
|
self:UpdateFlyout(true)
|
|
end
|
|
|
|
|
|
--This is all just to put an icon on the mouse cursor. Sadly we can't use SetCursor, because once you leave the frame the icon goes away. PickupSpell seems to work, but we need a valid spellID
|
|
--This trick here is that we ignore what is 'actually' and are just using it for the icon and the sound effects
|
|
function ActionButton:SetMouseCursor()
|
|
ClearCursor()
|
|
|
|
if self.spell and self.spellID then
|
|
PickupSpell(self.spellID)
|
|
if GetCursorInfo() then
|
|
return
|
|
end
|
|
end
|
|
|
|
if self.item then
|
|
PickupItem(self.item) --this is to try to catch any stragglers that might not have a spellID on the button. Things like mounts and such. This only works on currently available items
|
|
if GetCursorInfo() then --if this isn't a normal spell (like a flyout) or it is a pet abiity, revert to a question mark symbol
|
|
return
|
|
end
|
|
|
|
PickupItem(GetItemInfoInstant(self.item))
|
|
if GetCursorInfo() then
|
|
return
|
|
end
|
|
|
|
if Neuron.itemCache[self.item:lower()] then --try to pull the spellID from our ItemCache as a last resort
|
|
PickupItem(Neuron.itemCache[self.item:lower()])
|
|
if GetCursorInfo() then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
--failsafe so there is 'something' on the mouse cursor
|
|
PickupItem(1217) --questionmark symbol
|
|
end
|
|
|