diff --git a/Clique.lua b/Clique.lua index 1b79704..8727545 100755 --- a/Clique.lua +++ b/Clique.lua @@ -107,12 +107,15 @@ function addon:Initialize() end self:EnableBlizzardFrames() - -- Update GLOBAL attributes - self:UpdateGlobalAttributes() + -- Trigger a profile change, updating all attributes + self:ChangeProfile() -- Register for combat events to ensure we can swap between the two states self:RegisterEvent("PLAYER_REGEN_DISABLED", "UpdateAttributes") self:RegisterEvent("PLAYER_REGEN_ENABLED", "UpdateAttributes") + self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED", function() + self:ChangeProfile() + end) end function addon:RegisterFrame(button) @@ -167,7 +170,9 @@ function addon:InitializeDatabase() local db = CliqueDB2 local realmKey = GetRealmName() local charKey = UnitName("player") .. " - " .. realmKey + addon.staticProfileKey = charKey + addon.db = db if not db.settings[charKey] then db.settings[charKey] = { profileKey = charKey, @@ -437,6 +442,38 @@ function addon:UpdateGlobalAttributes() globutton:Execute(globutton.setbinds) end +function addon:ChangeProfile(profileName) + -- Clear the current profile + addon:ClearAttributes() + addon:ClearGlobalAttributes() + + -- Check to see if this is a force-create of a new profile + if type(profileName) == "string" and #profileName > 0 then + -- Do nothing + else + -- Determine which profile to set, based on talent group + self.talentGroup = GetActiveTalentGroup() + if self.talentGroup == 1 and self.settings.pri_profileKey then + profileName = self.settings.pri_profileKey + elseif self.talentGroup == 2 and self.settings.sec_profileKey then + profileName = self.settings.sec_profileKey + end + + if type(profileName) == "string" and addon.db.bindings[profileName] then + -- Do nothing + else + profileName = addon.staticProfileKey + end + end + + -- We've been given a profile name, so just change to it + addon.settings.profileKey = profileName + addon:InitializeBindingProfile() + addon:UpdateAttributes() + addon:UpdateGlobalAttributes() + addon:UpdateOptionsPanel() +end + SLASH_CLIQUE1 = "/clique" SlashCmdList["CLIQUE"] = function(msg, editbox) ShowUIPanel(CliqueConfig) diff --git a/Clique.toc b/Clique.toc index e2905e5..42ffad7 100755 --- a/Clique.toc +++ b/Clique.toc @@ -14,8 +14,11 @@ Clique.xml Clique.lua Utils.lua + BindConfig.lua + OptionsPanel.lua +FrameOptionsPanel.lua HeaderTest.xml HeaderTest.lua diff --git a/FrameOptionsPanel.lua b/FrameOptionsPanel.lua new file mode 100644 index 0000000..678ee5d --- /dev/null +++ b/FrameOptionsPanel.lua @@ -0,0 +1,17 @@ +local addonName, addon = ... + +local panel = CreateFrame("Frame") +panel.name = "Frame Editor" +panel.parent = addonName + +panel:SetScript("OnShow", function(self) + if not panel.initialized then + panel:CreateOptions() + end +end) + +function panel:CreateOptions() +end + +InterfaceOptions_AddCategory(panel) + diff --git a/OptionsPanel.lua b/OptionsPanel.lua index 27f067b..f596a6a 100644 --- a/OptionsPanel.lua +++ b/OptionsPanel.lua @@ -1,7 +1,8 @@ local addonName, addon = ... +local L = addon.L local panel = CreateFrame("Frame") -panel.name = "Clique" +panel.name = addonName panel:SetScript("OnShow", function(self) if not panel.initialized then @@ -9,7 +10,367 @@ panel:SetScript("OnShow", function(self) end end) +local function make_checkbox(name, parent) + local frame = CreateFrame("CheckButton", name, parent, "UICheckButtonTemplate") + frame.text = _G[frame:GetName() .. "Text"] + frame.type = "checkbox" + return frame +end + +local function make_dropdown(name, parent) + local frame = CreateFrame("Frame", name, parent, "UIDropDownMenuTemplate") + frame:SetClampedToScreen(true) + frame.type = "dropdown" + return frame +end + +local function make_label(name, parent, template) + local label = parent:CreateFontString("OVERLAY", name, template) + label:SetWidth(parent:GetWidth()) + label:SetJustifyH("LEFT") + label.type = "label" + return label +end + function panel:CreateOptions() + -- Ensure the panel isn't created twice (thanks haste) + panel.initialized = true + + -- Create the general options panel here: + local bits = {} + + self.updown = make_checkbox("CliqueOptionsUpDownClick", self) + self.updown.text:SetText(L["Trigger bindings on the 'down' portion of the click (requires reload)"]) + + self.specswap = make_checkbox("CliqueOptionsSpecSwap", self) + self.specswap.text:SetText(L["Swap profiles based on talent spec"]) + self.specswap.EnableDisable = function() + if self.specswap:GetChecked() then + UIDropDownMenu_EnableDropDown(panel.prispec) + UIDropDownMenu_EnableDropDown(panel.secspec) + else + UIDropDownMenu_DisableDropDown(panel.prispec) + UIDropDownMenu_DisableDropDown(panel.secspec) + end + end + self.specswap:SetScript("PostClick", self.specswap.EnableDisable) + + self.prispeclabel = make_label("CliqueOptionsPriSpecLabel", self, "GameFontNormalSmall") + self.prispeclabel:SetText(L["Primary talent spec profile:"]) + self.prispec = make_dropdown("CliqueOptionsPriSpec", self) + UIDropDownMenu_SetWidth(self.prispec, 150) + BlizzardOptionsPanel_SetupDependentControl(self.specswap, self.prispec) + + self.secspeclabel = make_label("CliqueOptionsSecSpecLabel", self, "GameFontNormalSmall") + self.secspeclabel:SetText(L["Secondary talent spec profile:"]) + self.secspec = make_dropdown("CliqueOptionsSecSpec", self) + UIDropDownMenu_SetWidth(self.secspec, 150) + BlizzardOptionsPanel_SetupDependentControl(self.specswap, self.secspec) + + self.profilelabel = make_label("CliqueOptionsProfileMgmtLabel", self, "GameFontNormalSmall") + self.profilelabel:SetText(L["Profile Management:"]) + self.profiledd = make_dropdown("CliqueOptionsProfileMgmt", self) + UIDropDownMenu_SetWidth(self.profiledd, 150) + + -- Collect and anchor the bits together + table.insert(bits, self.intro) + table.insert(bits, self.updown) + table.insert(bits, self.specswap) + table.insert(bits, self.prispeclabel) + table.insert(bits, self.prispec) + table.insert(bits, self.secspeclabel) + table.insert(bits, self.secspec) + table.insert(bits, self.profilelabel) + table.insert(bits, self.profiledd) + + bits[1]:SetPoint("TOPLEFT", 5, -5) + + for i = 2, #bits, 1 do + if bits[i].type == "label" then + bits[i]:SetPoint("TOPLEFT", bits[i-1], "BOTTOMLEFT", 5, -5) + elseif bits[i].type == "dropdown" then + bits[i]:SetPoint("TOPLEFT", bits[i-1], "BOTTOMLEFT", -5, -5) + else + bits[i]:SetPoint("TOPLEFT", bits[i-1], "BOTTOMLEFT", 0, -5) + end + end + + -- Trigger bindings on 'down' clicks instead of 'up' clicks + -- Automatically switch profile based on spec + -- Dropdown to select primary profile + -- Dropdown to select secondary profile + -- Profile managerment + -- * set profile + -- * delete profile + -- * add profile +end + +StaticPopupDialogs["CLIQUE_CONFIRM_PROFILE_DELETE"] = { + button1 = YES, + button2 = NO, + hideOnEscape = 1, + timeout = 0, + whileDead = 1, +} + +StaticPopupDialogs["CLIQUE_NEW_PROFILE"] = { + text = TEXT("Enter the name of a new profile you'd like to create"), + button1 = TEXT(OKAY), + button2 = TEXT(CANCEL), + OnAccept = function(self) + local base = self:GetName() + local editbox = getglobal(base .. "EditBox") + local profileName = editbox:GetText() + addon:ChangeProfile(profileName) + end, + timeout = 0, + whileDead = 1, + exclusive = 1, + showAlert = 1, + hideOnEscape = 1, + hasEditBox = 1, + maxLetters = 32, + OnShow = function(self) + getglobal(self:GetName().."Button1"):Disable(); + getglobal(self:GetName().."EditBox"):SetFocus(); + end, + EditBoxOnEnterPressed = function(self) + if ( getglobal(self:GetParent():GetName().."Button1"):IsEnabled() == 1 ) then + local base = self:GetParent():GetName() + local editbox = _G[base .. "EditBox"] + local profileName = editbox:GetText() + addon:ChangeProfile(profileName) + end + self:GetParent():Hide(); + end, + EditBoxOnTextChanged = function (self) + local editBox = getglobal(self:GetParent():GetName().."EditBox"); + local txt = editBox:GetText() + if #txt > 0 then + getglobal(self:GetParent():GetName().."Button1"):Enable(); + else + getglobal(self:GetParent():GetName().."Button1"):Disable(); + end + end, + EditBoxOnEscapePressed = function(self) + self:GetParent():Hide(); + ClearCursor(); + end +} + +local function getsorttbl() + local sort = {} + for k, v in pairs(addon.db.bindings) do + table.insert(sort, k) + end + table.sort(sort) + return sort +end + +local function spec_initialize(dropdown, level) + local sort = getsorttbl() + local paged = (#sort >= 15) + + if not level or level == 1 then + if not paged then + -- Display the profiles un-paged + for idx, entry in ipairs(sort) do + local info = UIDropDownMenu_CreateInfo() + info.text = entry + info.value = entry + info.func = function(frame, ...) + UIDropDownMenu_SetSelectedValue(dropdown, entry) + end + UIDropDownMenu_AddButton(info, level) + end + else + -- Page the results into sub-menus + for idx = 1, #sort, 10 do + -- Make the submenus for each group + local lastidx = (idx + 9 > #sort) and #sort or (idx + 9) + local info = UIDropDownMenu_CreateInfo() + local first = sort[idx] + local last = sort[lastidx] + info.text = first:sub(1, 5):trim() .. ".." .. last:sub(1, 5):trim() + info.value = idx + info.hasArrow = true + info.notCheckable = true + UIDropDownMenu_AddButton(info, level) + end + end + elseif level == 2 then + -- Generate the appropriate submenus depending on need + if paged then + -- Generate the frame submenu + local startIdx = UIDROPDOWNMENU_MENU_VALUE + local lastIdx = (startIdx + 9 > #sort) and #sort or (startIdx + 9) + for idx = startIdx, lastIdx do + local info = UIDropDownMenu_CreateInfo() + info.text = sort[idx] + info.value = sort[idx] + info.func = function(frame, ...) + UIDropDownMenu_SetSelectedValue(dropdown, sort[idx]) + end + UIDropDownMenu_AddButton(info, level) + end + end + end +end + +local function mgmt_initialize(dropdown, level) + local sort = getsorttbl() + local paged = (#sort >= 15) + + if not level or level == 1 then + if not paged then + -- Display the profiles un-paged + for idx, entry in ipairs(sort) do + local info = UIDropDownMenu_CreateInfo() + info.text = entry + info.value = entry + info.notCheckable = true + info.hasArrow = true + UIDropDownMenu_AddButton(info, level) + end + else + -- Page the results into sub-menus + for idx = 1, #sort, 10 do + -- Make the submenus for each group + local lastidx = (idx + 9 > #sort) and #sort or (idx + 9) + local info = UIDropDownMenu_CreateInfo() + local first = sort[idx] + local last = sort[lastidx] + info.text = first:sub(1, 5):trim() .. ".." .. last:sub(1, 5):trim() + info.value = idx + info.notCheckable = true + info.hasArrow = true + UIDropDownMenu_AddButton(info, level) + end + end + + -- Create the 'Add profile' option regardless + local info = UIDropDownMenu_CreateInfo() + info.text = L["Add new profile"] + info.value = "add" + info.notCheckable = true + info.func = function() + HideDropDownMenu(1) + StaticPopup_Show("CLIQUE_NEW_PROFILE") + end + UIDropDownMenu_AddButton(info, level) + elseif level == 2 then + -- Generate the appropriate submenus depending on need + if paged then + -- Generate the frame submenu + local startIdx = UIDROPDOWNMENU_MENU_VALUE + local lastIdx = (startIdx + 9 > #sort) and #sort or (startIdx + 9) + for idx = startIdx, lastIdx do + local info = UIDropDownMenu_CreateInfo() + info.text = sort[idx] + info.value = sort[idx] + info.hasArrow = true + info.notCheckable = true + UIDropDownMenu_AddButton(info, level) + end + else + local info = UIDropDownMenu_CreateInfo() + info.text = L["Select profile: %s"]:format(UIDROPDOWNMENU_MENU_VALUE) + info.value = sort[UIDROPDOWNMENU_MENU_VALUE] + info.notCheckable = true + info.disabled = addon.settings.specswap + info.func = function(frame) + UIDropDownMenu_SetSelectedValue(dropdown, UIDROPDOWNMENU_MENU_VALUE) + UIDropDownMenu_SetText(dropdown, UIDROPDOWNMENU_MENU_VALUE) + addon:ChangeProfile(UIDROPDOWNMENU_MENU_VALUE) + end + UIDropDownMenu_AddButton(info, level) + + info = UIDropDownMenu_CreateInfo() + info.text = L["Delete profile: %s"]:format(UIDROPDOWNMENU_MENU_VALUE) + info.disabled = UIDROPDOWNMENU_MENU_VALUE == addon.settings.profileKey + info.value = sort[UIDROPDOWNMENU_MENU_VALUE] + info.notCheckable = true + info.func = function(frame) + local dialog = StaticPopupDialogs["CLIQUE_CONFIRM_PROFILE_DELETE"] + dialog.text = L["Delete profile '%s'"]:format(UIDROPDOWNMENU_MENU_VALUE) + dialog.OnAccept = function(self) + addon.db.bindings[UIDROPDOWNMENU_MENU_VALUE] = nil + end + HideDropDownMenu(1) + StaticPopup_Show("CLIQUE_CONFIRM_PROFILE_DELETE") + end + UIDropDownMenu_AddButton(info, level) + end + elseif level == 3 then + local info = UIDropDownMenu_CreateInfo() + info.text = L["Select profile: %s"]:format(UIDROPDOWNMENU_MENU_VALUE) + info.value = sort[UIDROPDOWNMENU_MENU_VALUE] + info.disabled = addon.settings.specswap + info.func = function(frame) + UIDropDownMenu_SetSelectedValue(dropdown, UIDROPDOWNMENU_MENU_VALUE) + UIDropDownMenu_SetText(dropdown, UIDROPDOWNMENU_MENU_VALUE) + addon:ChangeProfile(UIDROPDOWNMENU_MENU_VALUE) + end + UIDropDownMenu_AddButton(info, level) + + info = UIDropDownMenu_CreateInfo() + info.text = L["Delete profile: %s"]:format(UIDROPDOWNMENU_MENU_VALUE) + info.disabled = UIDROPDOWNMENU_MENU_VALUE == addon.settings.profileKey + info.value = sort[UIDROPDOWNMENU_MENU_VALUE] + info.func = function(frame) + local dialog = StaticPopupDialogs["CLIQUE_CONFIRM_PROFILE_DELETE"] + dialog.text = L["Delete profile '%s'"]:format(UIDROPDOWNMENU_MENU_VALUE) + dialog.OnAccept = function(self) + addon.db.bindings[UIDROPDOWNMENU_MENU_VALUE] = nil + end + HideDropDownMenu(1) + StaticPopup_Show("CLIQUE_CONFIRM_PROFILE_DELETE") + end + UIDropDownMenu_AddButton(info, level) + end +end + +-- Update the elements on the panel to the current state +function panel.refresh() + -- Initialize the dropdowns + local settings = addon.settings + + UIDropDownMenu_Initialize(panel.prispec, spec_initialize) + UIDropDownMenu_SetSelectedValue(panel.prispec, settings.pri_profileKey or settings.profileKey) + UIDropDownMenu_SetText(panel.prispec, settings.pri_profileKey or settings.profileKey) + + UIDropDownMenu_Initialize(panel.secspec, spec_initialize) + UIDropDownMenu_SetSelectedValue(panel.secspec, settings.sec_profileKey or settings.profileKey) + UIDropDownMenu_SetText(panel.secspec, settings.sec_profileKey or settings.profileKey) + + UIDropDownMenu_Initialize(panel.profiledd, mgmt_initialize) + UIDropDownMenu_SetSelectedValue(panel.profiledd, settings.profileKey) + UIDropDownMenu_SetText(panel.profiledd, settings.profileKey) + + panel.updown:SetChecked(settings.downclick) + panel.specswap:SetChecked(settings.specswap) + panel.specswap.EnableDisable() +end + +function panel.okay() + local settings = addon.settings + + -- Update the saved variables + settings.downclick = not not panel.updown:GetChecked() + settings.specswap = not not panel.specswap:GetChecked() + settings.pri_profileKey = UIDropDownMenu_GetSelectedValue(panel.prispec) + settings.sec_profileKey = UIDropDownMenu_GetSelectedValue(panel.secspec) + settings.profileKey = UIDropDownMenu_GetSelectedValue(panel.profiledd) + + addon:ChangeProfile() +end + +panel.cancel = panel.refresh + +function addon:UpdateOptionsPanel() + if panel:IsVisible() and panel.initialized then + panel.refresh() + end end InterfaceOptions_AddCategory(panel)