/Tukui/modules/actionbars/Bind.lua

http://github.com/Asphyxia/Tukui · Lua · 300 lines · 266 code · 31 blank · 3 comment · 108 complexity · ad7a2bf4c59302e67440a0f4fee9ce31 MD5 · raw file

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