diff --git a/BlizzardFrames.lua b/BlizzardFrames.lua index 42b165a..2fbefa3 100644 --- a/BlizzardFrames.lua +++ b/BlizzardFrames.lua @@ -39,7 +39,8 @@ function panel:CreateOptions() self.intro = make_label("Intro", "GameFontHighlightSmall") self.intro:SetText(L["These options control whether or not Clique auotmatically registers certain Blizzard-created frames for binding. Changes made to these settings will not take effect until the user interface is reloaded."]) self.intro:SetPoint("RIGHT") - self.intro:SetHeight(45) + self.intro:SetJustifyV("TOP") + self.intro:SetHeight(40) self.PlayerFrame = make_checkbox("PlayerFrame", L["Player frame"]) self.PetFrame = make_checkbox("PetFrame", L["Player's pet frame"]) diff --git a/Clique.lua b/Clique.lua index c5380a8..a5ddfc9 100755 --- a/Clique.lua +++ b/Clique.lua @@ -42,6 +42,7 @@ local L = addon.L function addon:Initialize() self:InitializeDatabase() self.ccframes = {} + self.hccframes = {} -- Registration for group headers (in-combat safe) self.header = CreateFrame("Frame", addonName .. "HeaderFrame", UIParent, "SecureHandlerBaseTemplate") @@ -57,6 +58,12 @@ function addon:Initialize() ccframes = table.new() ]]) + -- Create a table within the addon header to store the frame bakcklist + self.header:Execute([[ + blacklist = table.new() + ]]) + self:UpdateBlacklist() + -- OnEnter bootstrap script for group-header frames self.header:SetAttribute("clickcast_onenter", [===[ local header = self:GetParent():GetFrameRef("clickcast_header") @@ -80,6 +87,12 @@ function addon:Initialize() self:RunFor(button, self:GetAttribute("setup_clicks")) ]===]):format(self.attr_setup_clicks)) + self.header:SetScript("OnAttributeChanged", function(frame, name, value) + if name == "clickcast_button" and type(value) ~= nil then + self.hccframes[value] = true + end + end) + local set, clr = self:GetBindingAttributes() self.header:SetAttribute("setup_onenter", set) self.header:SetAttribute("setup_onleave", clr) @@ -151,7 +164,7 @@ end -- forward from this point. The database consists of two sections: -- * settings - used to handle the basic options Clique uses -- * profiles - used for the binding configuration profiles, possibly shared -local current_db_version = 5 +local current_db_version = 6 function addon:InitializeDatabase() local realmKey = GetRealmName() local charKey = UnitName("player") .. " - " .. realmKey @@ -160,7 +173,15 @@ function addon:InitializeDatabase() local reset = false if not CliqueDB2 then reset = true - elseif type(CliqueDB2) == "table" and CliqueDB2.dbversion ~= current_db_version then + elseif CliqueDB2.dbversion == 5 then + if not CliqueDB2.settings or CliqueDB2.settings[charKey] then + reset = true + else + -- Upgrade to add the blacklist table to settings + CliqueDB2.settings[charKey].blacklist = {} + end + CliqueDB2.dbversion = current_db_version + elseif CliqueDB2.dbversion ~= current_db_version then reset = true end @@ -178,6 +199,7 @@ function addon:InitializeDatabase() if not db.settings[charKey] then db.settings[charKey] = { profileKey = charKey, + blacklist = {}, blizzframes = { PlayerFrame = true, PetFrame = true, @@ -190,7 +212,7 @@ function addon:InitializeDatabase() compactraid = true, compactparty = true, boss = true, - } + }, } end @@ -260,6 +282,15 @@ function addon:GetClickAttributes(global) "local button = setupbutton or self", } + -- Global attributes are never blacklisted + if not global then + bits[#bits + 1] = "local name = button:GetName()" + bits[#bits + 1] = "if blacklist[name] then return end" + + rembits[#rembits + 1] = "local name = button:GetName()" + rembits[#rembits + 1] = "if blacklist[name] then return end" + end + table.sort(self.bindings, ApplicationOrder) for idx, entry in ipairs(self.bindings) do @@ -312,8 +343,23 @@ local B_CLR = [[self:ClearBinding("%s");]] -- script and the second being a "clear keybindings" script. function addon:GetBindingAttributes(global) - local set = {} - local clr = {} + local set = { + } + local clr = { + } + + if not global then + set = { + "local button = self", + "local name = button:GetName()", + "if blacklist[name] then return end", + } + clr = { + "local button = self", + "local name = button:GetName()", + "if blacklist[name] then return end", + } + end for idx, entry in ipairs(self.bindings) do if self:ShouldSetBinding(entry, global) then @@ -515,6 +561,20 @@ function addon:UpdateCombatWatch() end end +function addon:UpdateBlacklist() + local bits = { + "blacklist = table.wipe(blacklist)", + } + + for frame, value in pairs(self.settings.blacklist) do + if not not value then + bits[#bits + 1] = string.format("blacklist[%q] = true", frame) + end + end + + addon.header:Execute(table.concat(bits, ";\n")) +end + function addon:EnteringCombat() addon:UpdateAttributes() addon:UpdateGlobalAttributes() diff --git a/FrameOptionsPanel.lua b/FrameOptionsPanel.lua index ad60d8b..8db4f05 100644 --- a/FrameOptionsPanel.lua +++ b/FrameOptionsPanel.lua @@ -2,7 +2,7 @@ local addonName, addon = ... local L = addon.L local panel = CreateFrame("Frame") -panel.name = "Frame Editor" +panel.name = "Frame Blacklist" panel.parent = addonName panel:SetScript("OnShow", function(self) @@ -10,11 +10,176 @@ panel:SetScript("OnShow", function(self) panel:CreateOptions() panel.refresh() end + panel.refresh() end) +local function make_label(name, template) + local label = panel:CreateFontString("OVERLAY", "CliqueOptionsBlacklist" .. name, template) + label:SetWidth(panel:GetWidth()) + label:SetJustifyH("LEFT") + label:SetJustifyV("TOP") + label.type = "label" + return label +end + +local function make_checkbox(name, parent, label) + local frame = CreateFrame("CheckButton", "CliqueOptionsBlacklist" .. name, parent, "UICheckButtonTemplate") + frame.text = _G[frame:GetName() .. "Text"] + frame.type = "checkbox" + frame.text:SetText(label) + return frame +end + + +local state = {} + function panel:CreateOptions() panel.initialized = true + + self.intro = make_label("Intro", "GameFontHighlightSmall") + self.intro:SetPoint("TOPLEFT", panel, 5, -5) + self.intro:SetPoint("RIGHT", panel, -5, 0) + self.intro:SetHeight(45) + self.intro:SetText(L["This panel allows you to blacklist certain frames from being included for Clique bindings. Any frames that are selected in this list will not be registered, although you may have to reload your user interface to have them return to their original bindings."]) + + self.scrollframe = CreateFrame("ScrollFrame", "CliqueOptionsBlacklistScrollFrame", self, "FauxScrollFrameTemplate") + self.scrollframe:SetPoint("TOPLEFT", self.intro, "BOTTOMLEFT", 0, -5) + self.scrollframe:SetPoint("RIGHT", self, "RIGHT", -30, 0) + self.scrollframe:SetHeight(320) + self.scrollframe:Show() + + + local function row_onclick(row) + state[row.frameName] = not not row:GetChecked() + end + + self.rows = {} + + -- Create and anchor some items + for idx = 1, 10 do + self.rows[idx] = make_checkbox("Item" .. idx, self.scrollframe, L["Frame name"]) + self.rows[idx]:SetScript("OnClick", row_onclick) + + if idx == 1 then + self.rows[idx]:SetPoint("TOPLEFT", self.scrollframe, "TOPLEFT", 0, 0) + else + self.rows[idx]:SetPoint("TOPLEFT", self.rows[idx-1], "BOTTOMLEFT", 0, 0) + end + end + + self.rowheight = self.rows[1]:GetHeight() + + -- Number of items? + local function update() + self:UpdateScrollFrame() + end + + self.scrollframe:SetScript("OnVerticalScroll", function(frame, offset) + FauxScrollFrame_OnVerticalScroll(frame, offset, self.rowheight, update) + end) + + self.selectall = CreateFrame("Button", "CliqueOptionsBlacklistSelectAll", self, "UIPanelButtonTemplate2") + self.selectall:SetText(L["Select All"]) + self.selectall:SetPoint("BOTTOMLEFT", 10, 10) + self.selectall:SetWidth(100) + self.selectall:SetScript("OnClick", function(button) + for frame in pairs(addon.ccframes) do + local name = frame:GetName() + if name then + state[name] = true + end + end + + for frame in pairs(addon.hccframes) do + local name = frame:GetName() + if name then + state[name] = true + end + end + + self:UpdateScrollFrame() + end) + + self.selectnone = CreateFrame("Button", "CliqueOptionsBlacklistSelectNone", self, "UIPanelButtonTemplate2") + self.selectnone:SetText(L["Select None"]) + self.selectnone:SetPoint("BOTTOMLEFT", self.selectall, "BOTTOMRIGHT", 5, 0) + self.selectnone:SetWidth(100) + self.selectnone:SetScript("OnClick", function(button) + state = {} + self:UpdateScrollFrame() + end) end -InterfaceOptions_AddCategory(panel) +function panel:UpdateScrollFrame() + local sort = {} + for frame in pairs(addon.ccframes) do + local name = frame:GetName() + if name then + table.insert(sort, name) + end + end + + for frame in pairs(addon.hccframes) do + local name = frame:GetName() + if name then + table.insert(sort, name) + end + end + + table.sort(sort) + + local offset = FauxScrollFrame_GetOffset(self.scrollframe) + FauxScrollFrame_Update(self.scrollframe, #sort, 10, self.rowheight) + for i=1, 10 do + local idx = offset + i + local row = self.rows[i] + if idx <= #sort then + row.frameName = sort[idx] + row.text:SetText(sort[idx]) + row:SetChecked(state[sort[idx]]) + row:Show() + else + row:Hide() + end + end +end + +function panel.okay() + -- Clear the existing blacklist + for frame, value in pairs(state) do + if not not value then + addon.settings.blacklist[frame] = true + else + addon.settings.blacklist[frame] = nil + end + end + + addon:ClearAttributes() + addon:UpdateBlacklist() + addon:UpdateAttributes() +end + +function panel.refresh() + for frame in pairs(addon.ccframes) do + local name = frame:GetName() + if name then + state[name] = false + end + end + + for frame in pairs(addon.hccframes) do + local name = frame:GetName() + if name then + state[name] = false + end + end + + for frame, value in pairs(addon.settings.blacklist) do + state[frame] = value + end + + panel:UpdateScrollFrame() +end + +InterfaceOptions_AddCategory(panel)