--[[------------------------------------------------------------------------- -- OptionsPanel.lua -- -- This file contains the definitions of the main interface options panel. -- Any other options panels are sub-categories of this main panel. -- -- Events registered: -- None -------------------------------------------------------------------------]]-- local addonName, addon = ... local L = addon.L local panel = CreateFrame("Frame") panel.name = L["General Options"] panel.parent = addonName addon.optpanels.GENERAL = panel panel:SetScript("OnShow", function(self) if not panel.initialized then panel:CreateOptions() panel.refresh() 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 (experimental)"]) self.fastooc = make_checkbox("CliqueOptionsFastOoc", self) self.fastooc.text:SetText(L["Disable out of combat clicks when party members enter combat"]) -- Set up multiple talent profiles self.talentProfiles = {} self.specswap = make_checkbox("CliqueOptionsSpecSwap", self) self.specswap.text:SetText(L["Swap profiles based on talent spec"]) self.specswap.EnableDisable = function() local toggleFunc if self.specswap:GetChecked() then toggleFunc = UIDropDownMenu_EnableDropDown else toggleFunc = UIDropDownMenu_DisableDropDown end for i = 1, #panel.talentProfiles do toggleFunc(self.talentProfiles[i]) end end self.specswap:SetScript("PostClick", self.specswap.EnableDisable) if addon.compatRelease then -- Generate the dropdowns for each spec for i = 1, GetNumSpecializations() do local _, specName = GetSpecializationInfo(i) local name = "CliqueOptionsSpec" .. i local label = make_label(name .. "Label", self, "GameFontNormalSmall") label:SetText(L["Talent profile: %s"]:format(specName)) self.talentProfiles[i] = make_dropdown(name, self) self.talentProfiles[i].profileLabel = label UIDropDownMenu_SetWidth(self.talentProfiles[i], 200) BlizzardOptionsPanel_SetupDependentControl(self.specswap, self.talentProfiles[i]) end end for i = 1, 1 do local _, specName = "Default" local name = "CliqueOptionsSpec" .. i local label = make_label(name .. "Label", self, "GameFontNormalSmall") label:SetText(L["Talent profile: %s"]:format("Default")) self.talentProfiles[i] = make_dropdown(name, self) self.talentProfiles[i].profileLabel = label UIDropDownMenu_SetWidth(self.talentProfiles[i], 200) BlizzardOptionsPanel_SetupDependentControl(self.specswap, self.talentProfiles[i]) end self.profilelabel = make_label("CliqueOptionsProfileMgmtLabel", self, "GameFontNormalSmall") self.profilelabel:SetText(L["Profile Management:"]) self.profiledd = make_dropdown("CliqueOptionsProfileMgmt", self) UIDropDownMenu_SetWidth(self.profiledd, 200) self.stopcastingfix = make_checkbox("CliqueOptionsStopCastingFix", self) self.stopcastingfix.text:SetText(L["Attempt to fix the issue introduced in 4.3 with casting on dead targets"]) -- Collect and anchor the bits together table.insert(bits, self.updown) table.insert(bits, self.fastooc) table.insert(bits, self.stopcastingfix) table.insert(bits, self.specswap) for i = 1, #self.talentProfiles do table.insert(bits, self.talentProfiles[i].profileLabel) table.insert(bits, self.talentProfiles[i]) end 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"] = { preferredIndex = STATICPOPUPS_NUMDIALOGS, button1 = "Yes", button2 = "No", hideOnEscape = 1, timeout = 0, whileDead = 1, } StaticPopupDialogs["CLIQUE_NEW_PROFILE"] = { preferredIndex = STATICPOPUPS_NUMDIALOGS, text = "Enter the name of a new profile you'd like to create", button1 = "Okay", button2 = "Cancel", OnAccept = function(self) local base = self:GetName() local editbox = _G[base .. "EditBox"] local profileName = editbox:GetText() addon.db:SetProfile(profileName) end, timeout = 0, whileDead = 1, exclusive = 1, showAlert = 1, hideOnEscape = 1, hasEditBox = 1, maxLetters = 32, OnShow = function(self) _G[self:GetName().."Button1"]:Disable(); _G[self:GetName().."EditBox"]:SetFocus(); end, EditBoxOnEnterPressed = function(self) local button = _G[self:GetParent():GetName().."Button1"] if addon:APIIsTrue(button:IsEnabled()) then local base = self:GetParent():GetName() local editbox = _G[base .. "EditBox"] local profileName = editbox:GetText() addon.db:SetProfile(profileName) end self:GetParent():Hide(); end, EditBoxOnTextChanged = function (self) local editBox = _G[self:GetParent():GetName().."EditBox"]; local txt = editBox:GetText() if #txt > 0 then _G[self:GetParent():GetName().."Button1"]:Enable(); else _G[self:GetParent():GetName().."Button1"]:Disable(); end end, EditBoxOnEscapePressed = function(self) self:GetParent():Hide(); ClearCursor(); end } local function getsorttbl() local profiles = addon.db:GetProfiles() local sort = {} for idx, profileName in ipairs(profiles) do table.insert(sort, profileName) 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 >= 10) local currentProfile = addon.db:GetCurrentProfile() 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 -- Don't disable this, allow the user to make their own mistakes --info.disabled = addon.settings.specswap info.func = function(frame) UIDropDownMenu_SetSelectedValue(dropdown, UIDROPDOWNMENU_MENU_VALUE) UIDropDownMenu_SetText(dropdown, UIDROPDOWNMENU_MENU_VALUE) addon.db:SetProfile(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 == currentProfile 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:DeleteProfile(UIDROPDOWNMENU_MENU_VALUE) 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.db:SetProfile(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 == currentProfile 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:DeleteProfile(UIDROPDOWNMENU_MENU_VALUE) 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() xpcall(function() if not panel.initialized then panel:CreateOptions() end -- Initialize the dropdowns local settings = addon.settings local currentProfile = addon.db:GetCurrentProfile() for i = 1, #panel.talentProfiles do local dbKey = string.format("spec%d_profileKey", i) local dropdown = panel.talentProfiles[i] UIDropDownMenu_Initialize(dropdown, spec_initialize) UIDropDownMenu_SetSelectedValue(dropdown, settings[dbKey] or currentProfile) UIDropDownMenu_SetText(dropdown, settings[dbKey] or currentProfile) end UIDropDownMenu_Initialize(panel.profiledd, mgmt_initialize) UIDropDownMenu_SetSelectedValue(panel.profiledd, currentProfile) UIDropDownMenu_SetText(panel.profiledd, L["Current: "] .. currentProfile) panel.updown:SetChecked(settings.downclick) panel.fastooc:SetChecked(settings.fastooc) panel.stopcastingfix:SetChecked(settings.stopcastingfix) panel.specswap:SetChecked(settings.specswap) panel.specswap.EnableDisable() end, geterrorhandler()) end function panel.okay() xpcall(function () local settings = addon.settings local currentProfile = addon.db:GetCurrentProfile() local changed = (not not panel.stopcastingfix:GetChecked()) ~= settings.stopcastingfix -- Update the saved variables settings.downclick = not not panel.updown:GetChecked() settings.stopcastingfix = not not panel.stopcastingfix:GetChecked() settings.fastooc = not not panel.fastooc:GetChecked() settings.specswap = not not panel.specswap:GetChecked() for i = 1, #panel.talentProfiles do local settingsKey = string.format("spec%d_profileKey", i) local dropdown = panel.talentProfiles[i] settings[settingsKey] = UIDropDownMenu_GetSelectedValue(dropdown) end addon:UpdateCombatWatch() if changed then addon:FireMessage("BINDINGS_CHANGED") end end, geterrorhandler()) end panel.cancel = panel.refresh function addon:UpdateOptionsPanel() if panel:IsVisible() and panel.initialized then panel.refresh() end end InterfaceOptions_AddCategory(panel, addon.optpanels.ABOUT)