Quantcast WoWInterface - View Single Post - dynamic key bindings with SecureHandlers
View Single Post
10-20-19, 03:15 AM   #5
illej
A Murloc Raider
Join Date: Oct 2019
Posts: 4
Originally Posted by kurapica.igas View Post
It seems like a feature in my IGAS_UI/ActionBar, you can find an example at the end of the page. Well, maybe not, you require two level key binding.

Back to the question, I have an example for you

Lua Code:
  1. -- The button configs
  2. local Config = {
  3.     {
  4.         {
  5.             type = "macro",
  6.             macrotext = "/run print('1-1')"
  7.         },
  8.         {
  9.             type = "macro",
  10.             macrotext = "/run print('1-2')"
  11.         },
  12.     },
  13.     {
  14.         {
  15.             type = "macro",
  16.             macrotext = "/run print('2-1')"
  17.         },
  18.     },
  19.     {
  20.         {
  21.             type = "macro",
  22.             macrotext = "/run print('3-1')"
  23.         },
  24.     },
  25. }
  26.  
  27. -- A mananger frame to control all secure behaviors
  28. local _ManagerFrame = CreateFrame("Frame", "TwoLevelKeyManager", UIParent, "SecureHandlerStateTemplate")
  29.  
  30. _ManagerFrame.Execute = SecureHandlerExecute
  31. _ManagerFrame.WrapScript = function(self, frame, script, preBody, postBody) return SecureHandlerWrapScript(frame, script, self, preBody, postBody) end
  32. _ManagerFrame.SetFrameRef = SecureHandlerSetFrameRef
  33.  
  34. _ManagerFrame:Execute[[
  35.     Manager = self
  36.  
  37.     ToggleButtons = newtable()
  38.     ToggleState = newtable()
  39.  
  40.     -- secure code snippets to be run by manager
  41.     CloseFinalLevel = [==[
  42.         local index = ...
  43.         print("CloseFinalLevel", index)
  44.         if ToggleState[index] then
  45.             ToggleState[index] = false
  46.  
  47.             for i, btn in ipairs(ToggleButtons[index]) do
  48.                 print("Clear Bind", btn:GetName())
  49.                 btn:ClearBinding("" .. i)
  50.             end
  51.         end
  52.         print("Clear Bind", ToggleButtons[index][0]:GetName())
  53.         ToggleButtons[index][0]:ClearBinding("" .. index)
  54.     ]==]
  55.  
  56.     OpenFinalLevel = [==[
  57.         local index = ...
  58.         print("OpenFinalLevel", index)
  59.         if not ToggleState[index] then
  60.             ToggleState[index] = true
  61.  
  62.             for i, btn in ipairs(ToggleButtons[index]) do
  63.                 print("Bind", btn:GetName())
  64.                 btn:SetBindingClick(true, "" .. i, btn:GetName(), "LeftButton")
  65.             end
  66.         end
  67.     ]==]
  68.  
  69.     ToggleRoot = [==[
  70.         print("ToggleRoot", not ToggleState[0])
  71.         if ToggleState[0] then
  72.             -- Clear binding for all
  73.             ToggleState[0] = false
  74.  
  75.             for i, buttons in ipairs(ToggleButtons) do
  76.                 Manager:Run(CloseFinalLevel, i)
  77.             end
  78.         else
  79.             -- Bind key to first level
  80.             ToggleState[0] = true
  81.  
  82.             for i, buttons in ipairs(ToggleButtons) do
  83.                 print("Bind", buttons[0]:GetName())
  84.                 buttons[0]:SetBindingClick(true, "" .. i, buttons[0]:GetName(), "LeftButton")
  85.             end
  86.         end
  87.     ]==]
  88. ]]
  89.  
  90. -- Create buttons
  91. local rootbtn = CreateFrame("CheckButton", "RootToggle", UIParent, "SecureActionButtonTemplate")
  92.  
  93. -- Bind the root key
  94. SetOverrideBindingClick(rootbtn, true, "F", "RootToggle", "LeftButton")
  95.  
  96. -- Toggle the first level button's key binding
  97. _ManagerFrame:WrapScript(rootbtn, "OnClick", [[Manager:Run(ToggleRoot)]])
  98.  
  99. -- Generate the first and second level buttons and register them to the mananger
  100. for i, firstlvl in ipairs(Config) do
  101.     local btn = CreateFrame("CheckButton", "FirstLvlToggle" .. i, UIParent, "SecureActionButtonTemplate")
  102.     _ManagerFrame:SetFrameRef("FirstLvlToggle", btn)
  103.  
  104.     for j, nxtlvl in ipairs(firstlvl) do
  105.         local fbtn = CreateFrame("CheckButton", "NxtLvlToggle" .. i .. "_" .. j, UIParent, "SecureActionButtonTemplate")
  106.         _ManagerFrame:SetFrameRef("NxtLvlToggle" .. j, fbtn)
  107.  
  108.         for k, v in pairs(nxtlvl) do
  109.             fbtn:SetAttribute(k, v) -- Bind marco
  110.         end
  111.  
  112.         -- Clear all key bindings after click the second level button
  113.         _ManagerFrame:WrapScript(fbtn, "OnClick", [[return button, true]], [[Manager:Run(ToggleRoot)]])
  114.     end
  115.  
  116.     _ManagerFrame:Execute(string.format([[
  117.         local index, count = %d, %d
  118.         local buttons = newtable()
  119.         buttons[0] = Manager:GetFrameRef("FirstLvlToggle")
  120.         print("Register", index, buttons[0]:GetName())
  121.         for i = 1, count do
  122.             buttons[i] = Manager:GetFrameRef("NxtLvlToggle" .. i)
  123.             print("Register", buttons[i]:GetName())
  124.         end
  125.  
  126.         ToggleButtons[index] = buttons
  127.     ]], i, #firstlvl))
  128.  
  129.     -- Bind the key to the second level
  130.     _ManagerFrame:WrapScript(btn, "OnClick", string.format([[Manager:Run(OpenFinalLevel, %d)]], i))
  131. end

Run it with WowLua or my Cube or whatever in the game, then press F-1-1, F-1-2, F-2-1 to see the result, the log should show how the code works.

I have no high level shaman, so I use other macro for examples.
Oh wow that is exactly what I was looking for! Thank you so much! There is no way I would have figured that out myself! How did you learn about this stuff? Any particular resources? Or did you just work through the Blizz UI source?
  Reply With Quote