Quantcast

Working group header registration and attribute generation system

James Whitehead II [09-27-10 - 12:19]
Working group header registration and attribute generation system
Filename
Clique.lua
CliqueTest.lua
CliqueTest.xml
diff --git a/Clique.lua b/Clique.lua
index a5c2220..b876f4a 100755
--- a/Clique.lua
+++ b/Clique.lua
@@ -17,45 +17,65 @@ local addonName, addon = ...
 local L = addon.L

 function addon:Initialize()
+    self:InitializeDatabase()
+
     -- Compatability with old Clique 1.x registrations
-    if not ClickCastFrames then
-        ClickCastFrames = {}
-    else
-        local oldClickCastFrames = ClickCastFrames
-        ClickCastFrames = setmetatable({}, {__newindex = function(t, k, v)
-            if v == nil then
-                self:UnregisterFrame(k)
-            else
-                self:RegisterFrame(k, v)
-            end
-        end})
-
-        -- Iterate over the frames that were set before we arrived
+    local oldClickCastFrames = ClickCastFrames
+
+    ClickCastFrames = setmetatable({}, {__newindex = function(t, k, v)
+        if v == nil then
+            self:UnregisterFrame(k)
+        else
+            self:RegisterFrame(k, v)
+        end
+    end})
+
+    -- Iterate over the frames that were set before we arrived
+    if oldClickCastFrames then
         for frame, options in pairs(oldClickCastFrames) do
             self:RegisterFrame(frame, options)
         end
     end

     -- Registration for group headers (in-combat safe)
-    addon.header = CreateFrame("Frame", addonName .. "HeaderFrame", UIParent, "SecureHandlerBaseTemplate")
+    self.header = CreateFrame("Frame", addonName .. "HeaderFrame", UIParent, "SecureHandlerBaseTemplate")
     ClickCastHeader = addon.header

-    addon.header:SetAttribute("clickcast_onenter", [===[
+    -- OnEnter bootstrap script for group-header frames
+    self.header:SetAttribute("clickcast_onenter", [===[
         local header = self:GetParent():GetFrameRef("clickcast_header")
-        header:RunAttribute("setup_onenter", self:GetName())
+        header:RunFor(self, header:GetAttribute("setup_onenter"))
     ]===])

-    addon.header:SetAttribute("clickcast_onleave", [===[
+    -- OnLeave bootstrap script for group-header frames
+    self.header:SetAttribute("clickcast_onleave", [===[
         local header = self:GetParent():GetFrameRef("clickcast_header")
-        header:RunAttribute("setup_onleave", self:GetName())
+        header:RunFor(self, header:GetAttribute("setup_onleave"))
     ]===])

-    addon.header:SetAttribute("clickcast_register", [===[
+    self.header:SetAttribute("setup_clicks", self:GetClickAttribute())
+    self.header:SetAttribute("clickcast_register", ([===[
         local button = self:GetAttribute("clickcast_button")
-        print("Registering ", button, " for clickcasting")
         button:SetAttribute("clickcast_onenter", self:GetAttribute("clickcast_onenter"))
         button:SetAttribute("clickcast_onleave", self:GetAttribute("clickcast_onleave"))
-    ]===])
+        self:RunFor(button, self:GetAttribute("setup_clicks"))
+    ]===]):format(self.attr_setup_clicks))
+
+    local set, clr = self:GetBindingAttributes()
+    self.header:SetAttribute("setup_onenter", set)
+    self.header:SetAttribute("setup_onleave", clr)
+end
+
+function addon:RegisterFrame(button)
+    button:RegisterForClicks("AnyDown")
+
+    -- Wrap the OnEnter/OnLeave scripts in order to handle keybindings
+    addon.header:WrapScript(button, "OnEnter", addon.header:GetAttribute("setup_onenter"))
+    addon.header:WrapScript(button, "OnLeave", addon.header:GetAttribute("setup_onleave"))
+
+    -- Set the attributes on the frame
+    -- TODO: Fix this as it is broken
+    self.header:RunFor(button, self.header:GetAttribute("setup_clicks"))
 end

 function addon:Enable()
@@ -66,18 +86,86 @@ function addon:Enable()
         pushable = 1,
         whileDead = 1,
     }
-
-    self:InitializeDatabase()
 end

 function addon:InitializeDatabase()
-    -- Force a clean database everytime
+    -- TODO: This is all testing boilerplate, try to fix it up
     self.profile = {
         binds = {
+            [1] = {key = "BUTTON1", type = "target", unit = "mouseover"},
+            [2] = {key = "BUTTON2", type = "menu"},
+            [3] = {key = "F", type = "spell", spell = "Lifebloom"},
+            [4] = {key = "SHIFT-F", type = "spell", spell = "Regrowth"},
+            [5] = {key = "CTRL-BUTTON1", type = "spell", spell = "Rejuvenation"},
+            [6] = {key = "SHIFT-BUTTON1", type = "spell", spell = "Regrowth"},
         },
     }
 end

+function ATTR(prefix, attr, suffix, value)
+    local fmt = [[self:SetAttribute("%s%s%s%s%s", "%s")]]
+    return fmt:format(prefix, #prefix > 0 and "-" or "", attr, tonumber(suffix) and "" or "-", suffix, value)
+end
+
+-- This function will create an attribute that when run for a given frame
+-- will set the correct set of SAB attributes.
+function addon:GetClickAttribute()
+    local bits = {}
+
+    for idx, entry in ipairs(self.profile.binds) do
+        local prefix, suffix = entry.key:match("^(.-)([^%-]+)$")
+        if prefix:sub(-1, -1) == "-" then
+            prefix = prefix:sub(1, -2)
+        end
+
+        prefix = prefix:lower()
+
+        local button = suffix:match("^BUTTON(%d+)$")
+        if button then
+            suffix = button
+        else
+            suffix = "cliquebutton" .. idx
+            prefix = ""
+        end
+
+        -- Build any needed SetAttribute() calls
+        if entry.type == "target" or entry.type == "menu" then
+            bits[#bits + 1] = ATTR(prefix, "type", suffix, entry.type)
+        elseif entry.type == "spell" then
+            bits[#bits + 1] = ATTR(prefix, "type", suffix, entry.type)
+            bits[#bits + 1] = ATTR(prefix, "spell", suffix, entry.spell)
+        elseif entry.type == "macro" then
+            bits[#bits + 1] = ATTR(prefix, "type", suffix, entry.type)
+            bits[#bits + 1] = ATTR(prefix, "macrotext", suffix, entry.macrotext)
+        else
+            error(string.format("Invalid action type: '%s'", entry.type))
+        end
+    end
+
+    return table.concat(bits, "\n")
+end
+
+local B_SET = [[self:SetBindingClick(true, "%s", self, "%s");]]
+local B_CLR = [[self:ClearBinding("%s");]]
+
+-- This function will create two attributes, the first being a "setup keybindings"
+-- script and the second being a "clear keybindings" script.
+
+function addon:GetBindingAttributes()
+    local set = {}
+    local clr = {}
+
+    for idx, entry in ipairs(self.profile.binds) do
+        if not entry.key:match("BUTTON%d+$") then
+            -- This is a key binding, so we need a binding for it
+            set[#set + 1] = B_SET:format(entry.key, "cliquebutton" .. idx)
+            clr[#clr + 1] = B_CLR:format(entry.key)
+        end
+    end
+
+    return table.concat(set, "\n"), table.concat(clr, "\n")
+end
+
 -- This function adds a binding to the player's current profile. The
 -- following options can be included in the click-cast entry:
 --
diff --git a/CliqueTest.lua b/CliqueTest.lua
index 9a466c5..74d286a 100644
--- a/CliqueTest.lua
+++ b/CliqueTest.lua
@@ -38,10 +38,10 @@ function addon:RunTest()
     -- Set up the group header to display a solo/party/raid frame
     groupheader:SetAttribute("initialConfigFunction", [==[
         self:SetAttribute("shift-type1", "spell")
-        self:SetAttribute("shift-spell1", "Flash Heal")
+        self:SetAttribute("shift-spell1", "Regrowth")

         self:SetAttribute("type-cliquebutton1", "spell")
-        self:SetAttribute("spell-cliquebutton1", "Flash Heal")
+        self:SetAttribute("spell-cliquebutton1", "Lifebloom")

         -- Register this frame with the global click-cast header
         local header = self:GetParent():GetFrameRef("clickcast_header")
@@ -49,15 +49,6 @@ function addon:RunTest()
         header:RunAttribute("clickcast_register")
     ]==])

-    addon.header:SetAttribute("setup_onenter", [[
-        local buttonName = ...
-        self:ClearBinding("F")
-        self:SetBindingClick(true, "F", buttonName, "cliquebutton1")
-    ]])
-    addon.header:SetAttribute("setup_onleave", [[
-        self:ClearBinding("F")
-    ]])
-
     groupheader:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
     groupheader:Show()
 end
diff --git a/CliqueTest.xml b/CliqueTest.xml
index dd4887b..615f47e 100644
--- a/CliqueTest.xml
+++ b/CliqueTest.xml
@@ -44,6 +44,9 @@
           <OnShow>
               CliqueTest_Unit_OnShow(self)
           </OnShow>
+          <PostClick>
+              print("post-click:", self, button)
+          </PostClick>
       </Scripts>
       <HighlightTexture file="Interface\Buttons\ButtonHilight-Square" alphaMode="ADD"/>
   </Button>