PageRenderTime 115ms CodeModel.GetById 40ms app.highlight 20ms RepoModel.GetById 51ms app.codeStats 0ms

/Tukui/modules/actionbars/Bind.lua

http://github.com/Asphyxia/Tukui
Lua | 300 lines | 266 code | 31 blank | 3 comment | 62 complexity | ad7a2bf4c59302e67440a0f4fee9ce31 MD5 | raw file
  1local T, C, L = unpack(select(2, ...)) -- Import: T - functions, constants, variables; C - config; L - locales
  2-- keybind feature
  3local bind = CreateFrame("Frame", "TukuiHoverBind", UIParent)
  4
  5-- SLASH COMMAND
  6SlashCmdList.MOUSEOVERBIND = function()
  7	if InCombatLockdown() then print(L.bind_combat) return end
  8	if not bind.loaded then
  9		local find = string.find
 10		local _G = getfenv(0)
 11
 12		bind:SetFrameStrata("DIALOG")
 13		bind:EnableMouse(true)
 14		bind:EnableKeyboard(true)
 15		bind:EnableMouseWheel(true)
 16		bind.texture = bind:CreateTexture()
 17		bind.texture:SetAllPoints(bind)
 18		bind.texture:SetTexture(0, 0, 0, .25)
 19		bind:Hide()
 20
 21		local elapsed = 0
 22		GameTooltip:HookScript("OnUpdate", function(self, e)
 23			elapsed = elapsed + e
 24			if elapsed < .2 then return else elapsed = 0 end
 25			if (not self.comparing and IsModifiedClick("COMPAREITEMS")) then
 26				GameTooltip_ShowCompareItem(self)
 27				self.comparing = true
 28			elseif ( self.comparing and not IsModifiedClick("COMPAREITEMS")) then
 29				for _, frame in pairs(self.shoppingTooltips) do
 30					frame:Hide()
 31				end
 32				self.comparing = false
 33			end
 34		end)
 35		hooksecurefunc(GameTooltip, "Hide", function(self) for _, tt in pairs(self.shoppingTooltips) do tt:Hide() end end)
 36
 37		bind:SetScript("OnEvent", function(self) self:Deactivate(false) end)
 38		bind:SetScript("OnLeave", function(self) self:HideFrame() end)
 39		bind:SetScript("OnKeyUp", function(self, key) self:Listener(key) end)
 40		bind:SetScript("OnMouseUp", function(self, key) self:Listener(key) end)
 41		bind:SetScript("OnMouseWheel", function(self, delta) if delta>0 then self:Listener("MOUSEWHEELUP") else self:Listener("MOUSEWHEELDOWN") end end)
 42
 43		function bind:Update(b, spellmacro)
 44			if not self.enabled or InCombatLockdown() then return end
 45			self.button = b
 46			self.spellmacro = spellmacro
 47			
 48			self:ClearAllPoints()
 49			self:SetAllPoints(b)
 50			self:Show()
 51			
 52			ShoppingTooltip1:Hide()
 53			
 54			if spellmacro=="SPELL" then
 55				self.button.id = SpellBook_GetSpellBookSlot(self.button)
 56				self.button.name = GetSpellBookItemName(self.button.id, SpellBookFrame.bookType)
 57				
 58				GameTooltip:AddLine("Trigger")
 59				GameTooltip:Show()
 60				GameTooltip:SetScript("OnHide", function(self)
 61					self:SetOwner(bind, "ANCHOR_NONE")
 62					self:SetPoint("BOTTOM", bind, "TOP", 0, 1)
 63					self:AddLine(bind.button.name, 1, 1, 1)
 64					bind.button.bindings = {GetBindingKey(spellmacro.." "..bind.button.name)}
 65					if #bind.button.bindings == 0 then
 66						self:AddLine("No bindings set.", .6, .6, .6)
 67					else
 68						self:AddDoubleLine("Binding", "Key", .6, .6, .6, .6, .6, .6)
 69						for i = 1, #bind.button.bindings do
 70							self:AddDoubleLine(i, bind.button.bindings[i])
 71						end
 72					end
 73					self:Show()
 74					self:SetScript("OnHide", nil)
 75				end)
 76			elseif spellmacro=="MACRO" then
 77				self.button.id = self.button:GetID()
 78				
 79				if floor(.5+select(2,MacroFrameTab1Text:GetTextColor())*10)/10==.8 then self.button.id = self.button.id + 36 end
 80				
 81				self.button.name = GetMacroInfo(self.button.id)
 82				
 83				GameTooltip:SetOwner(bind, "ANCHOR_NONE")
 84				GameTooltip:SetPoint("BOTTOM", bind, "TOP", 0, 1)
 85				GameTooltip:AddLine(bind.button.name, 1, 1, 1)
 86				
 87				bind.button.bindings = {GetBindingKey(spellmacro.." "..bind.button.name)}
 88					if #bind.button.bindings == 0 then
 89						GameTooltip:AddLine("No bindings set.", .6, .6, .6)
 90					else
 91						GameTooltip:AddDoubleLine("Binding", "Key", .6, .6, .6, .6, .6, .6)
 92						for i = 1, #bind.button.bindings do
 93							GameTooltip:AddDoubleLine("Binding"..i, bind.button.bindings[i], 1, 1, 1)
 94						end
 95					end
 96				GameTooltip:Show()
 97			elseif spellmacro=="STANCE" or spellmacro=="PET" then
 98				self.button.id = tonumber(b:GetID())
 99				self.button.name = b:GetName()
100				
101				if not self.button.name then return end
102				
103				if not self.button.id or self.button.id < 1 or self.button.id > (spellmacro=="STANCE" and 10 or 12) then
104					self.button.bindstring = "CLICK "..self.button.name..":LeftButton"
105				else
106					self.button.bindstring = (spellmacro=="STANCE" and "SHAPESHIFTBUTTON" or "BONUSACTIONBUTTON")..self.button.id
107				end
108				
109				GameTooltip:AddLine("Trigger")
110				GameTooltip:Show()
111				GameTooltip:SetScript("OnHide", function(self)
112					self:SetOwner(bind, "ANCHOR_NONE")
113					self:SetPoint("BOTTOM", bind, "TOP", 0, 1)
114					self:AddLine(bind.button.name, 1, 1, 1)
115					bind.button.bindings = {GetBindingKey(bind.button.bindstring)}
116					if #bind.button.bindings == 0 then
117						self:AddLine("No bindings set.", .6, .6, .6)
118					else
119						self:AddDoubleLine("Binding", "Key", .6, .6, .6, .6, .6, .6)
120						for i = 1, #bind.button.bindings do
121							self:AddDoubleLine(i, bind.button.bindings[i])
122						end
123					end
124					self:Show()
125					self:SetScript("OnHide", nil)
126				end)
127			else
128				self.button.action = tonumber(b.action)
129				self.button.name = b:GetName()
130				
131				if not self.button.name then return end
132				
133				if not self.button.action or self.button.action < 1 or self.button.action > 132 then
134					self.button.bindstring = "CLICK "..self.button.name..":LeftButton"
135				else
136					local modact = 1+(self.button.action-1)%12
137					if self.button.action < 25 or self.button.action > 72 then
138						self.button.bindstring = "ACTIONBUTTON"..modact
139					elseif self.button.action < 73 and self.button.action > 60 then
140						self.button.bindstring = "MULTIACTIONBAR1BUTTON"..modact
141					elseif self.button.action < 61 and self.button.action > 48 then
142						self.button.bindstring = "MULTIACTIONBAR2BUTTON"..modact
143					elseif self.button.action < 49 and self.button.action > 36 then
144						self.button.bindstring = "MULTIACTIONBAR4BUTTON"..modact
145					elseif self.button.action < 37 and self.button.action > 24 then
146						self.button.bindstring = "MULTIACTIONBAR3BUTTON"..modact
147					end
148				end
149				
150				GameTooltip:AddLine("Trigger")
151				GameTooltip:Show()
152				GameTooltip:SetScript("OnHide", function(self)
153					self:SetOwner(bind, "ANCHOR_NONE")
154					self:SetPoint("BOTTOM", bind, "TOP", 0, 1)
155					self:AddLine(bind.button.name, 1, 1, 1)
156					bind.button.bindings = {GetBindingKey(bind.button.bindstring)}
157					if #bind.button.bindings == 0 then
158						self:AddLine("No bindings set.", .6, .6, .6)
159					else
160						self:AddDoubleLine("Binding", "Key", .6, .6, .6, .6, .6, .6)
161						for i = 1, #bind.button.bindings do
162							self:AddDoubleLine(i, bind.button.bindings[i])
163						end
164					end
165					self:Show()
166					self:SetScript("OnHide", nil)
167				end)
168			end
169		end
170
171		function bind:Listener(key)
172			if key == "ESCAPE" or key == "RightButton" then
173				for i = 1, #self.button.bindings do
174					SetBinding(self.button.bindings[i])
175				end
176				print("All keybindings cleared for |cff00ff00"..self.button.name.."|r.")
177				self:Update(self.button, self.spellmacro)
178				if self.spellmacro~="MACRO" then GameTooltip:Hide() end
179				return
180			end
181			
182			if key == "LSHIFT"
183			or key == "RSHIFT"
184			or key == "LCTRL"
185			or key == "RCTRL"
186			or key == "LALT"
187			or key == "RALT"
188			or key == "UNKNOWN"
189			or key == "LeftButton"
190			then return end
191			
192			if key == "MiddleButton" then key = "BUTTON3" end
193			if key == "Button4" then key = "BUTTON4" end
194			if key == "Button5" then key = "BUTTON5" end
195			
196			local alt = IsAltKeyDown() and "ALT-" or ""
197			local ctrl = IsControlKeyDown() and "CTRL-" or ""
198			local shift = IsShiftKeyDown() and "SHIFT-" or ""
199			
200			if not self.spellmacro or self.spellmacro=="PET" or self.spellmacro=="STANCE" then
201				SetBinding(alt..ctrl..shift..key, self.button.bindstring)
202			else
203				SetBinding(alt..ctrl..shift..key, self.spellmacro.." "..self.button.name)
204			end
205			print(alt..ctrl..shift..key.." |cff00ff00bound to |r"..self.button.name..".")
206			self:Update(self.button, self.spellmacro)
207			if self.spellmacro~="MACRO" then GameTooltip:Hide() end
208		end
209		function bind:HideFrame()
210			self:ClearAllPoints()
211			self:Hide()
212			GameTooltip:Hide()
213		end
214		function bind:Activate()
215			self.enabled = true
216			self:RegisterEvent("PLAYER_REGEN_DISABLED")
217		end
218		function bind:Deactivate(save)
219			if save then
220				SaveBindings(2)
221				print(L.bind_saved)
222			else
223				LoadBindings(2)
224				print(L.bind_discard)
225			end
226			self.enabled = false
227			self:HideFrame()
228			self:UnregisterEvent("PLAYER_REGEN_DISABLED")
229			StaticPopup_Hide("KEYBIND_MODE")
230		end
231
232		StaticPopupDialogs["KEYBIND_MODE"] = {
233			text = L.bind_instruct,
234			button1 = L.bind_save,
235			button2 = L.bind_discardbind,
236			OnAccept = function() bind:Deactivate(true) end,
237			OnCancel = function() bind:Deactivate(false) end,
238			timeout = 0,
239			whileDead = 1,
240			hideOnEscape = false,
241			preferredIndex = 3,
242		}
243
244		-- REGISTERING
245		local stance = ShapeshiftButton1:GetScript("OnClick")
246		local pet = PetActionButton1:GetScript("OnClick")
247		local button = SecureActionButton_OnClick
248
249		local function register(val)
250			if val.IsProtected and val.GetObjectType and val.GetScript and val:GetObjectType()=="CheckButton" and val:IsProtected() then
251				local script = val:GetScript("OnClick")
252				if script==button then
253					val:HookScript("OnEnter", function(self) bind:Update(self) end)
254				elseif script==stance then
255					val:HookScript("OnEnter", function(self) bind:Update(self, "STANCE") end)
256				elseif script==pet then
257					val:HookScript("OnEnter", function(self) bind:Update(self, "PET") end)
258				end
259			end
260		end
261
262		local val = EnumerateFrames()
263		while val do
264			register(val)
265			val = EnumerateFrames(val)
266		end
267
268		for i=1,12 do
269			local b = _G["SpellButton"..i]
270			b:HookScript("OnEnter", function(self) bind:Update(self, "SPELL") end)
271		end
272		
273		local function registermacro()
274			for i=1,36 do
275				local b = _G["MacroButton"..i]
276				b:HookScript("OnEnter", function(self) bind:Update(self, "MACRO") end)
277			end
278		end
279		
280		if not IsAddOnLoaded("Blizzard_MacroUI") then
281			hooksecurefunc("LoadAddOn", function(addon)
282				if addon=="Blizzard_MacroUI" then
283					registermacro()
284				end
285			end)
286		else
287			registermacro()
288		end
289		bind.loaded = 1
290	end
291	if not bind.enabled then
292		bind:Activate()
293		StaticPopup_Show("KEYBIND_MODE")
294	end
295end
296SLASH_MOUSEOVERBIND1 = "/bindkey"
297SLASH_MOUSEOVERBIND2 = "/hoverbind"
298if not IsAddOnLoaded("HealBot") then
299	SLASH_MOUSEOVERBIND3 = "/hb"
300end