Update to 1.6 version (#6)

* Merge from origin https://gitlab.com/Tsoukie/clique-3.3.5

* Linting

* Ascension Modifications
Fixes Spec swap and adds the 12 slots
Fixes ascension compact raid frame support
Fixes ascension spell panel integration

* Add profile dropdown to binding window

* Fix menu buttons showing as invisible

* cleanup xml button definitions

* enable or disable Bind Spell button when spellbook is visible

* give the labels a bit more spacing for default UI
This commit is contained in:
Anthony Narkevicius
2025-11-09 09:40:17 -08:00
committed by GitHub
parent c2bb10665d
commit 9c36ee6e47
43 changed files with 4191 additions and 5221 deletions
+775
View File
@@ -0,0 +1,775 @@
--[[-------------------------------------------------------------------------
-- BindConfig.lua
--
-- This file contains the definitions of the binding configuration panel.
--
-- Events registered:
-- None
-------------------------------------------------------------------------]] --
local addonName, addon = ...
local L = addon.L
local MAX_ROWS = 12
function CliqueConfig:ShowWithSpellBook()
self:ClearAllPoints()
self:SetParent(AscensionSpellbookFrame)
self:SetPoint("LEFT", AscensionSpellbookFrame, "RIGHT", 55, 0)
self:Show()
end
function CliqueConfig:OnShow()
if not self.initialized then
self:SetupGUI()
self:HijackSpellbook()
self.initialized = true
end
-- Hide the alertTab if the spellbook isn't shown
if AscensionSpellbookFrameContentSpellsSpellButton1:IsVisible() then
self.bindAlert:Show()
else
self.bindAlert:Hide()
end
CliqueSpellTab:SetChecked(true)
self:UpdateList()
self:UpdateProfileDisplay()
UIDropDownMenu_Refresh(self.page1.profileDropdown)
self:EnableSpellbookButtons()
self:UpdateBindSpellButtonState()
self:UpdateAlert()
end
function CliqueConfig:OnHide()
self:ClearAllPoints()
self:SetParent(UIParent)
HideUIPanel(self)
CliqueSpellTab:SetChecked(false)
self:UpdateAlert()
end
function CliqueConfig:SetupGUI()
self.rows = {}
for i = 1, MAX_ROWS do self.rows[i] = CreateFrame("Button", "CliqueRow" .. i, self.page1, "CliqueRowTemplate") end
self.rows[1]:ClearAllPoints()
self.rows[1]:SetPoint("TOPLEFT", "CliqueConfigPage1Column1", "BOTTOMLEFT", 0, -3)
self.rows[1]:SetPoint("RIGHT", CliqueConfigPage1Column2, "RIGHT", 0, 0)
for i = 2, MAX_ROWS do
self.rows[i]:ClearAllPoints()
self.rows[i]:SetPoint("TOPLEFT", self.rows[i - 1], "BOTTOMLEFT")
self.rows[i]:SetPoint("RIGHT", CliqueConfigPage1Column2, "RIGHT", 0, 0)
end
_G[self:GetName() .. "TitleText"]:SetText(L["Clique Binding Configuration"])
self.dialog = _G["CliqueDialog"]
self.dialog.title = _G["CliqueDialogTitleText"]
self.dialog:SetUserPlaced(false)
self.dialog:ClearAllPoints()
self.dialog:SetPoint("CENTER", self, "CENTER", 30, 0)
self.dialog.title:SetText(L["Set binding"])
self.dialog.button_accept:SetText(L["Accept"])
self.dialog.button_binding:SetText(L["Set binding"])
local desc =
L["In order to specify a binding, move your mouse over the button labelled 'Set binding' and either click with your mouse or press a key on your keyboard. You can modify the binding by holding down a combination of the alt, control and shift keys on your keyboard."]
self.dialog.desc:SetText(desc)
self.alert = _G["CliqueTabAlert"]
self.bindAlert.text:SetText(L["You are in Clique binding mode"])
self.close = _G[self:GetName() .. "CloseButton"]
self.close:SetScript("OnClick", function() HideUIPanel(CliqueConfig) end)
self.page1.column1:SetText(L["Action"])
self.page1.column2:SetText(L["Binding"])
-- Set columns up to handle sorting
self.page1.column1.sortType = "name"
self.page1.column2.sortType = "key"
self.page1.sortType = self.page1.column2.sortType
self.page2.button_binding:SetText(L["Set binding"])
local desc =
L["You can use this page to create a custom macro to be run when activating a binding on a unit. When creating this macro you should keep in mind that you will need to specify the target of any actions in the macro by using the 'mouseover' unit, which is the unit you are clicking on. For example, you can do any of the following:\n\n/cast [target=mouseover] Regrowth\n/cast [@mouseover] Regrowth\n/cast [@mouseovertarget] Taunt\n\nHover over the 'Set binding' button below and either click or press a key with any modifiers you would like included. Then edit the box below to contain the macro you would like to have run when this binding is activated."]
self.page2.desc:SetText(desc)
self.page2.editbox = CliqueScrollFrameEditBox
-- Create profile UI elements programmatically
self:CreateProfileUI()
-- Create page 2 buttons programmatically
self:CreatePage2Buttons()
self.page1:Show()
end
function CliqueConfig:CreateProfileUI()
-- Create profile label with support for long names and multiple lines
self.page1.profileLabel = self.page1:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
self.page1.profileLabel:SetJustifyH("LEFT")
self.page1.profileLabel:SetJustifyV("TOP")
self.page1.profileLabel:SetSize(265, 24) -- Increased height for two lines
self.page1.profileLabel:SetPoint("TOPLEFT", self, "TOPLEFT", 60, -30)
self.page1.profileLabel:SetWordWrap(true) -- Enable word wrapping
self.page1.profileLabel:SetText(L["Current Profile: "])
-- Create profile dropdown in bottom left corner
self.page1.profileDropdown = CreateFrame("Frame", "CliqueConfigProfileDropdown", self.page1, "UIDropDownMenuTemplate")
self.page1.profileDropdown:SetPoint("BOTTOMLEFT", self, "BOTTOMLEFT", -15, -2)
self.page1.profileDropdown:SetFrameLevel(self.page1:GetFrameLevel() + 10) -- Ensure dropdown is on top
UIDropDownMenu_SetWidth(self.page1.profileDropdown, 100)
UIDropDownMenu_Initialize(self.page1.profileDropdown, function(dropdown, level) self:ProfileDropdown_Initialize(dropdown, level) end)
-- Create buttons programmatically since XML-defined ones weren't showing
-- Bind spell button
self.page1.button_spell = CreateFrame("Button", nil, self.page1, "UIPanelButtonTemplate")
self.page1.button_spell:SetSize(70, 22)
self.page1.button_spell:SetPoint("TOPLEFT", self.page1.profileDropdown, "TOPRIGHT", -15, -2)
self.page1.button_spell:SetText(L["Bind spell"])
self.page1.button_spell:SetScript("OnClick", function(button) self:Button_OnClick(button) end)
self.page1.button_spell:Show()
-- Bind other button
self.page1.button_other = CreateFrame("Button", nil, self.page1, "UIPanelButtonTemplate")
self.page1.button_other:SetSize(70, 22)
self.page1.button_other:SetPoint("LEFT", self.page1.button_spell, "RIGHT", 0, 0)
self.page1.button_other:SetText(L["Bind other"])
self.page1.button_other:SetScript("OnClick", function(button) self:Button_OnClick(button) end)
self.page1.button_other:Show()
-- Options button
self.page1.button_options = CreateFrame("Button", nil, self.page1, "UIPanelButtonTemplate")
self.page1.button_options:SetSize(70, 22)
self.page1.button_options:SetPoint("LEFT", self.page1.button_other, "RIGHT", 0, 0)
self.page1.button_options:SetText(L["Options"])
self.page1.button_options:SetScript("OnClick", function(button) self:Button_OnClick(button) end)
self.page1.button_options:Show()
end
function CliqueConfig:CreatePage2Buttons()
-- Set binding button is working fine from XML, only create Save and Cancel buttons
-- Create Save button in bottom left corner
self.page2.button_save = CreateFrame("Button", nil, self.page2, "UIPanelButtonTemplate")
self.page2.button_save:SetSize(90, 22)
self.page2.button_save:SetPoint("BOTTOMLEFT", self.page2, "BOTTOMLEFT", 0, -22)
self.page2.button_save:SetText(L["Save"])
self.page2.button_save:SetScript("OnClick", function(button) self:Button_OnClick(button) end)
self.page2.button_save:SetFrameLevel(self.page2:GetFrameLevel() + 10)
self.page2.button_save:Disable() -- Start disabled
self.page2.button_save:Show()
-- Create Cancel button in bottom right corner
self.page2.button_cancel = CreateFrame("Button", nil, self.page2, "UIPanelButtonTemplate")
self.page2.button_cancel:SetSize(90, 22)
self.page2.button_cancel:SetPoint("BOTTOMRIGHT", self.page2, "BOTTOMRIGHT", 0, -22)
self.page2.button_cancel:SetText(L["Cancel"])
self.page2.button_cancel:SetScript("OnClick", function(button) self:Button_OnClick(button) end)
self.page2.button_cancel:SetFrameLevel(self.page2:GetFrameLevel() + 10)
self.page2.button_cancel:Show()
end
function CliqueConfig:UpdateBindSpellButtonState()
if not self.page1 or not self.page1.button_spell then
return -- Button doesn't exist yet
end
if AscensionSpellbookFrame:IsVisible() then
self.page1.button_spell:Disable()
else
self.page1.button_spell:Enable()
end
end
function CliqueConfig:Column_OnClick(frame, button)
self.page1.sortType = frame.sortType
self:UpdateList()
end
function CliqueConfig:HijackSpellbook()
self.spellbookButtons = {}
for idx = 1, 12 do
local parent = _G["AscensionSpellbookFrameContentSpellsSpellButton" .. idx]
local button = CreateFrame("Button", "CliqueSpellbookButton" .. idx, parent, "CliqueSpellbookButtonTemplate")
button.spellbutton = parent
button:EnableKeyboard(false)
button:EnableMouseWheel(true)
button:RegisterForClicks("AnyDown")
button:SetID(parent:GetID())
self.spellbookButtons[idx] = button
end
AscensionSpellbookFrame:HookScript("OnShow", function(frame)
self:EnableSpellbookButtons()
self:UpdateBindSpellButtonState()
end)
AscensionSpellbookFrame:HookScript("OnHide", function(frame)
self:EnableSpellbookButtons()
self:UpdateBindSpellButtonState()
end)
self:EnableSpellbookButtons()
end
function CliqueConfig:EnableSpellbookButtons()
local enabled;
if self.page1:IsVisible() and AscensionSpellbookFrame:IsVisible() then enabled = true end
if self.spellbookButtons then
for idx, button in ipairs(self.spellbookButtons) do
if enabled and button.spellbutton:IsEnabled() == 1 then
button:Show()
else
button:Hide()
end
end
end
end
-- Spellbook button functions
function CliqueConfig:Spellbook_EnableKeyboard(button, motion) button:EnableKeyboard(true) end
function CliqueConfig:Spellbook_DisableKeyboard(button, motion) button:EnableKeyboard(false) end
function CliqueConfig:Spellbook_OnBinding(button, key)
if key == "ESCAPE" then
HideUIPanel(CliqueConfig)
return
end
local name = getglobal(button.spellbutton:GetName() .. "SpellName"):GetText()
local spellSubName = getglobal(button.spellbutton:GetName() .. "SubSpellName"):GetText()
local texture = getglobal(button.spellbutton:GetName() .. "IconTexture"):GetTexture()
-- Only enable spellSubName if ShowAllSpellRanks is checked
if not AscensionSpellbookFrameContentSpellsShowAllSpellRanks:GetChecked() then
spellSubName = nil
elseif spellSubName == "" then
spellSubName = nil
end
local key = addon:GetCapturedKey(key)
if not key then return end
local succ, err = addon:AddBinding{
key = key,
type = "spell",
spell = name,
spellSubName = spellSubName,
icon = texture
}
CliqueConfig:UpdateList()
end
function CliqueConfig:UpdateProfileDisplay()
local currentProfile = addon.db:GetCurrentProfile()
local displayText = L["Current Profile: "] .. currentProfile
-- Check if spec swap is enabled
if addon.settings.specswap then
local currentSpec = addon.talentGroup or 1
displayText = displayText .. " " .. L["(Spec "] .. currentSpec .. ")"
else
displayText = displayText .. " " .. L["(All specs)"]
end
self.page1.profileLabel:SetText(displayText)
-- Update dropdown text
UIDropDownMenu_SetText(self.page1.profileDropdown, currentProfile)
end
function CliqueConfig:ProfileDropdown_Initialize(dropdown, level)
local profiles = addon.db:GetProfiles()
local currentProfile = addon.db:GetCurrentProfile()
-- Create sorted list of profiles
local sortedProfiles = {}
for idx, profileName in ipairs(profiles) do table.insert(sortedProfiles, profileName) end
table.sort(sortedProfiles)
-- Add each profile as a menu item
for _, profileName in ipairs(sortedProfiles) do
local info = UIDropDownMenu_CreateInfo()
info.text = profileName
info.value = profileName
info.func = function() self:ProfileDropdown_OnClick(profileName) end
info.checked = (profileName == currentProfile)
UIDropDownMenu_AddButton(info, level)
end
end
function CliqueConfig:ProfileDropdown_OnClick(profileName)
if addon.settings.specswap then
-- When spec swap is enabled, change the profile for the current specialization
local currentSpec = addon.talentGroup or 1
addon.settings["specswap" .. currentSpec] = profileName
-- Also switch to that profile immediately
addon.db:SetProfile(profileName)
else
-- When spec swap is disabled, just change the current profile
addon.db:SetProfile(profileName)
end
self:UpdateProfileDisplay()
self:UpdateList()
CloseDropDownMenus()
end
function CliqueConfig:Button_OnClick(button)
-- Click handler for "Bind spell" button
if button == self.page1.button_spell then
ShowUIPanel(AscensionSpellbookFrame)
CliqueConfig:ShowWithSpellBook()
-- Click handler for "Bind other" button
elseif button == self.page1.button_other then
local config = CliqueConfig
local menu = {{
text = L["Select a binding type"],
isTitle = true,
notCheckable = true
}, {
text = L["Target clicked unit"],
func = function() self:SetupCaptureDialog("target") end,
notCheckable = true
}, {
text = L["Open unit menu"],
func = function() self:SetupCaptureDialog("menu") end,
notCheckable = true
}, {
text = L["Run custom macro"],
func = function()
config.page1:Hide()
config.page2.bindType = "macro"
-- Clear out the entries
config.page2.bindText:SetText(L["No binding set"])
config.page2.editbox:SetText("")
config.page2.button_save:Disable()
config.page2:Show()
end,
notCheckable = true
}}
UIDropDownMenu_SetAnchor(self.dropdown, 0, 0, "BOTTOMLEFT", self.page1.button_other, "TOP")
EasyMenu(menu, self.dropdown, nil, 0, 0, "MENU", nil)
-- Click handler for "Options" button
elseif button == self.page1.button_options then
local menu = {{
text = L["Select an options category"],
isTitle = true,
notCheckable = true
}, {
text = L["Clique general options"],
func = function()
HideUIPanel(AscensionSpellbookFrame)
HideUIPanel(CliqueConfig)
InterfaceOptionsFrame_OpenToCategory(addon.optpanels["GENERAL"])
end,
notCheckable = true
}, {
text = L["Frame blacklist"],
func = function()
HideUIPanel(AscensionSpellbookFrame)
HideUIPanel(CliqueConfig)
InterfaceOptionsFrame_OpenToCategory(addon.optpanels["BLACKLIST"])
end,
notCheckable = true
}, {
text = L["Blizzard frame integration options"],
func = function()
HideUIPanel(AscensionSpellbookFrame)
HideUIPanel(CliqueConfig)
InterfaceOptionsFrame_OpenToCategory(addon.optpanels["BLIZZFRAMES"])
end,
notCheckable = true
}}
UIDropDownMenu_SetAnchor(self.dropdown, 0, 0, "BOTTOMLEFT", self.page1.button_options, "TOP")
EasyMenu(menu, self.dropdown, nil, 0, 0, "MENU", nil)
elseif button == self.page2.button_save then
-- Check the input
local key = self.page2.key
local macrotext = self.page2.editbox:GetText()
if self.page2.binding then
self.page2.binding.key = key
self.page2.binding.macrotext = macrotext
self.page2.binding = nil
addon:FireMessage("BINDINGS_CHANGED")
else
local succ, err = addon:AddBinding{
key = key,
type = "macro",
macrotext = macrotext
}
end
self:UpdateList()
self.page2:Hide()
self.page1:Show()
elseif button == self.page2.button_cancel then
self.page2.binding = nil
self.page2:Hide()
self.page1:Show()
end
end
local memoizeBindings = setmetatable({}, {
__index = function(t, k, v)
local binbits = addon:GetBinaryBindingKey(k)
rawset(t, k, binbits)
return binbits
end
})
local compareFunctions;
compareFunctions = {
name = function(a, b)
local texta = addon:GetBindingActionText(a.type, a)
local textb = addon:GetBindingActionText(b.type, b)
if texta == textb then return compareFunctions.key(a, b) end
return texta < textb
end,
key = function(a, b)
local keya = addon:GetBindingKey(a)
local keyb = addon:GetBindingKey(b)
if keya == keyb then
return memoizeBindings[a] < memoizeBindings[b]
elseif not keya or not keyb then
return false
else
return keya < keyb
end
end,
binding = function(a, b)
local mem = memoizeBindings
if mem[a] == mem[b] then
return compareFunctions.name(a, b)
else
return mem[a] < mem[b]
end
end
}
-- Mapping between binding entry and index in profile
function CliqueConfig:UpdateList()
local page = self.page1
local binds = addon.bindings
-- GUI not created yet
if not self.initialized then
return
elseif not self:IsVisible() then
return
end
-- Sort the bindings
local sort = {}
for idx, entry in pairs(binds) do sort[#sort + 1] = entry end
if page.sortType then
table.sort(sort, compareFunctions[page.sortType])
else
table.sort(sort, compareFunctions.key)
end
-- Enable or disable the scroll bar
if #sort > MAX_ROWS - 1 then
-- Set up the scrollbar for the item list
page.slider:SetMinMaxValues(0, #sort - MAX_ROWS)
-- Adjust and show
if not page.slider:IsShown() then
-- Adjust column positions
for idx, row in ipairs(self.rows) do row.bind:SetWidth(90) end
page.slider:SetValue(0)
page.slider:Show()
end
elseif page.slider:IsShown() then
-- Move column positions back and hide the slider
for idx, row in ipairs(self.rows) do row.bind:SetWidth(105) end
page.slider:Hide()
end
-- Update the rows in the list
local offset = page.slider:GetValue() or 0
for idx, row in ipairs(self.rows) do
local offsetIndex = offset + idx
if sort[offsetIndex] then
local bind = sort[offsetIndex]
row.icon:SetTexture(addon:GetBindingIcon(bind))
row.name:SetText(addon:GetBindingActionText(bind.type, bind))
row.info:SetText(addon:GetBindingInfoText(bind))
row.bind:SetText(addon:GetBindingKeyComboText(bind))
row.binding = bind
row:Show()
else
row:Hide()
end
end
end
function CliqueConfig:ClearEditPage() end
function CliqueConfig:ShowEditPage()
self:ClearEditPage()
self.page1:Hide()
self.page3:Show()
end
function CliqueConfig:Save_OnClick(button, down) end
function CliqueConfig:Cancel_OnClick(button, down)
self:ClearEditPage()
self.page3:Hide()
self.page1:Show()
end
function CliqueConfig:SetupCaptureDialog(type, binding)
self.dialog.bindType = type
self.dialog.binding = binding
if not binding then
local actionText = addon:GetBindingActionText(type, binding)
self.dialog.title:SetText(L["Set binding: %s"]:format(actionText))
else
-- This is a change to an existing binding
local actionText = addon:GetBindingActionText(type, binding)
self.dialog.title:SetText(L["Change binding: %s"]:format(actionText))
end
self.dialog.bindText:SetText("")
self.dialog:Show()
end
function CliqueConfig:BindingButton_OnClick(button, key)
local dialog = CliqueDialog
dialog.key = addon:GetCapturedKey(key)
if dialog.key then CliqueDialog.bindText:SetText(addon:GetBindingKeyComboText(dialog.key)) end
end
function CliqueConfig:MacroBindingButton_OnClick(button, key)
local key = addon:GetCapturedKey(key)
if key then
self.page2.key = key
self.page2.bindText:SetText(addon:GetBindingKeyComboText(key))
self.page2.button_save:Enable()
else
self.page2.bindText:SetText(L["No binding set"])
self.page2.button_save:Disable()
end
end
function CliqueConfig:AcceptSetBinding()
local dialog = CliqueDialog
local key = dialog.key
if dialog.binding then
-- This was a CHANGE binding instead of a SET binding
dialog.binding.key = key
dialog.binding = nil
-- Do not forget to update the attributes as well
self:UpdateList()
addon:FireMessage("BINDINGS_CHANGED")
else
local succ, err = addon:AddBinding{
key = key,
type = dialog.bindType
}
if succ then self:UpdateList() end
end
dialog:Hide()
end
local function toggleSet(binding, set, ...)
local exclude = {}
for i = 1, select("#", ...) do
local item = select(i, ...)
table.insert(exclude, item)
end
return function()
if not binding.sets then binding.sets = {} end
if binding.sets[set] then
binding.sets[set] = nil
else
binding.sets[set] = true
end
for idx, exclset in ipairs(exclude) do binding.sets[exclset] = nil end
UIDropDownMenu_Refresh(UIDROPDOWNMENU_OPEN_MENU, nil, UIDROPDOWNMENU_MENU_LEVEL)
CliqueConfig:UpdateList()
addon:FireMessage("BINDINGS_CHANGED")
end
end
function CliqueConfig:Row_OnClick(frame, button)
local binding = frame.binding
local actionText = addon:GetBindingActionText(binding.type, binding)
local menu = {{
text = L["Configure binding: '%s'"]:format(actionText:sub(1, 15)),
notCheckable = true,
isTitle = true
}, {
text = L["Change binding"],
func = function()
local binding = frame.binding
self:SetupCaptureDialog(binding.type, binding)
end,
notCheckable = true
}, {
text = L["Delete binding"],
func = function()
addon:DeleteBinding(frame.binding)
self:UpdateList()
end,
notCheckable = true
}}
if binding.type == "spell" and binding.spellSubName then
-- Enable a 'Remove Rank' option
menu[#menu + 1] = {
text = L["Remove spell rank"],
func = function()
local binding = frame.binding
binding.spellSubName = nil
self:UpdateList()
addon:FireMessage("BINDINGS_CHANGED")
end,
notCheckable = true
}
end
if binding.type == "macro" then
-- Replace 'Change Binding' with 'Edit macro'
menu[2] = {
text = L["Edit macro"],
func = function()
self.page2.bindType = "macro"
local bindText = addon:GetBindingKeyComboText(binding)
self.page2.bindText:SetText(bindText)
self.page2.binding = binding
self.page2.key = binding.key
self.page2.editbox:SetText(binding.macrotext)
self.page2.button_save:Enable()
self.page1:Hide()
self.page2:Show()
end,
notCheckable = true
}
end
local submenu = {
text = L["Enable/Disable binding-sets"],
hasArrow = true,
notCheckable = true,
menuList = {}
}
table.insert(menu, submenu)
table.insert(submenu.menuList, {
text = L["Default"],
checked = function() return binding.sets["default"] end,
func = toggleSet(binding, "default"),
tooltipTitle = L["Clique: 'default' binding-set"],
tooltipText = L["A binding that belongs to the 'default' binding-set will always be active on your unit frames, unless you override it with another binding."]
-- keepShownOnClick = true,
})
table.insert(submenu.menuList, {
text = L["Friend"],
checked = function() return binding.sets["friend"] end,
func = toggleSet(binding, "friend"),
tooltipTitle = L["Clique: 'friend' binding-set"],
tooltipText = L["A binding that belongs to the 'frield' binding-set will only be active when clicking on unit frames that display friendly units, i.e. those you can heal and assist. If you click on a unit that you cannot heal or assist, nothing will happen."]
-- keepShownOnClick = true,
})
table.insert(submenu.menuList, {
text = L["Enemy"],
checked = function() return binding.sets["enemy"] end,
func = toggleSet(binding, "enemy"),
tooltipTitle = L["Clique: 'enemy' binding-set"],
tooltipText = L["A binding that belongs to the 'enemy' binding-set will always be active when clicking on unit frames that display enemy units, i.e. those you can attack. If you click on a unit that you cannot attack, nothing will happen."]
-- keepShownOnClick = true,
})
table.insert(submenu.menuList, {
text = L["Out-of-combat (ONLY)"],
checked = function() return binding.sets["ooc"] end,
func = toggleSet(binding, "ooc"),
tooltipTitle = L["Clique: 'ooc' binding-set"],
tooltipText = L["A binding that belongs to the 'ooc' binding-set will only be active when the player is out-of-combat, regardless of the other binding-sets this binding belongs to. As soon as the player enters combat, these bindings will no longer be active, so be careful when choosing this binding-set for any spells you use frequently."]
-- keepShownOnClick = true,
})
table.insert(submenu.menuList, {
text = L["Primary talent spec (ONLY)"],
checked = function() return binding.sets["pritalent"] end,
func = toggleSet(binding, "pritalent"),
tooltipTitle = L["Clique: 'pritalent' binding-set"],
tooltipText = L["A binding that belongs to the 'pritalent' binding-set is only active when the player is currently using their primary talent spec, regardless of the other binding-sets that this binding belongs to."]
-- keepShownOnClick = true,
})
table.insert(submenu.menuList, {
text = L["Secondary talent spec (ONLY)"],
checked = function() return binding.sets["sectalent"] end,
func = toggleSet(binding, "sectalent"),
tooltipTitle = L["Clique: 'sectalent' binding-set"],
tooltipText = L["A binding that belongs to the 'sectalent' binding-set is only active when the player is currently using their secondary talent spec, regardless of the other binding-sets that this binding belongs to."]
-- keepShownOnClick = true,
})
table.insert(submenu.menuList, {
text = L["Hovercast bindings (target required)"],
checked = function() return binding.sets["hovercast"] end,
func = toggleSet(binding, "hovercast", "global"),
tooltipTitle = L["Clique: 'hovercast' binding-set"],
tooltipText = L["A binding that belongs to the 'hovercast' binding-set is active whenever the mouse is over a unit frame, or a character in the 3D world. This allows you to use 'hovercasting', where you hover over a unit in the world and press a key to cast a spell on them. THese bindings are also active over unit frames."]
-- keepShownOnClick = true,
})
table.insert(submenu.menuList, {
text = L["Global bindings (no target)"],
checked = function() return binding.sets["global"] end,
func = toggleSet(binding, "global", "hovercast"),
tooltipTitle = L["Clique: 'global' binding-set"],
tooltipText = L["A binding that belongs to the 'global' binding-set is always active. If the spell requires a target, you will be given the 'casting hand', otherwise the spell will be cast. If the spell is an AOE spell, then you will be given the ground targeting circle."]
-- keepShownOnClick = true,
})
EasyMenu(menu, self.dropdown, "cursor", 0, 0, "MENU", nil)
end
function CliqueConfig:SpellTab_OnClick(frame)
if self:IsVisible() then
HideUIPanel(CliqueConfig)
elseif AscensionSpellbookFrame:IsVisible() then
self:ShowWithSpellBook()
else
ShowUIPanel(CliqueConfig)
end
end
function CliqueConfig:UpdateAlert(type)
local alert = CliqueTabAlert
if not addon.settings.alerthidden and AscensionSpellbookFrame:IsVisible() and CliqueConfig:IsVisible() then
alert.type = type
alert.text:SetText(
L["When both the Clique binding configuration window and the spellbook are open, you can set new bindings simply by performing them on the spell icon in your spellbook. Simply move your mouse over a spell and then click or press a key on your keyboard along with any combination of the alt, control, and shift keys. The new binding will be added to your binding configuration."])
alert:Show()
else
alert:Hide()
end
end
+125
View File
@@ -0,0 +1,125 @@
--[[-------------------------------------------------------------------------
-- BlizzardFrames.lua
--
-- This file contains the definitions of the blizzard frame integration
-- options. These settings will not apply until the user interface is
-- reloaded.
--
-- Events registered:
-- * ADDON_LOADED - To watch for loading of the ArenaUI
-------------------------------------------------------------------------]] --
local addonName, addon = ...
local L = addon.L
--[[---------------------------------------------------------------------------
-- Options panel definition
---------------------------------------------------------------------------]] --
local panel = CreateFrame("Frame")
panel.name = "Blizzard Frame Options"
panel.parent = addonName
addon.optpanels["BLIZZFRAMES"] = panel
panel:SetScript("OnShow", function(self)
if not panel.initialized then
panel:CreateOptions()
panel.refresh()
end
end)
local function make_checkbox(name, label)
local frame = CreateFrame("CheckButton", "CliqueOptionsBlizzFrame" .. name, panel, "UICheckButtonTemplate")
frame.text = _G[frame:GetName() .. "Text"]
frame.type = "checkbox"
frame.text:SetText(label)
return frame
end
local function make_label(name, template)
local label = panel:CreateFontString("OVERLAY", "CliqueOptionsBlizzFrame" .. name, template)
label:SetWidth(panel:GetWidth())
label:SetJustifyH("LEFT")
label.type = "label"
return label
end
function panel:CreateOptions()
panel.initialized = true
local bits = {}
self.intro = make_label("Intro", "GameFontHighlightSmall")
self.intro:SetText(
L["These options control whether or not Clique automatically 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:SetJustifyV("TOP")
self.intro:SetHeight(40)
self.PlayerFrame = make_checkbox("PlayerFrame", L["Player frame"])
self.PetFrame = make_checkbox("PetFrame", L["Player's pet frame"])
self.TargetFrame = make_checkbox("TargetFrame", L["Player's target frame"])
self.TargetFrameToT = make_checkbox("TargetFrameToT", L["Target of target frame"])
self.FocusFrame = make_checkbox("FocusFrame", L["Player's focus frame"])
self.FocusFrameToT = make_checkbox("FocusFrameToT", L["Target of focus frame"])
self.arena = make_checkbox("ArenaEnemy", L["Arena enemy frames"])
self.party = make_checkbox("Party", L["Party member frames"])
self.compactraid = make_checkbox("CompactRaid", L["Compact raid frames"])
-- self.compactparty = make_checkbox("CompactParty", L["Compact party frames"])
self.boss = make_checkbox("BossTarget", L["Boss target frames"])
table.insert(bits, self.intro)
table.insert(bits, self.PlayerFrame)
table.insert(bits, self.PetFrame)
table.insert(bits, self.TargetFrame)
table.insert(bits, self.FocusFrame)
table.insert(bits, self.FocusFrameToT)
-- Group these together
bits[1]:SetPoint("TOPLEFT", 5, -5)
for i = 2, #bits, 1 do bits[i]:SetPoint("TOPLEFT", bits[i - 1], "BOTTOMLEFT", 0, 0) end
local last = bits[#bits]
table.wipe(bits)
table.insert(bits, self.arena)
table.insert(bits, self.party)
table.insert(bits, self.compactraid)
-- table.insert(bits, self.compactparty)
table.insert(bits, self.boss)
bits[1]:SetPoint("TOPLEFT", last, "BOTTOMLEFT", 0, -15)
for i = 2, #bits, 1 do bits[i]:SetPoint("TOPLEFT", bits[i - 1], "BOTTOMLEFT", 0, 0) end
end
function panel.refresh()
local opt = addon.settings.blizzframes
panel.PlayerFrame:SetChecked(opt.PlayerFrame)
panel.PetFrame:SetChecked(opt.PetFrame)
panel.TargetFrame:SetChecked(opt.TargetFrame)
panel.FocusFrame:SetChecked(opt.FocusFrame)
panel.FocusFrameToT:SetChecked(opt.FocusFrameToT)
panel.arena:SetChecked(opt.arena)
panel.party:SetChecked(opt.party)
panel.compactraid:SetChecked(opt.compactraid)
-- panel.compactparty:SetChecked(opt.compactparty)
panel.boss:SetChecked(opt.boss)
end
function panel.okay()
local opt = addon.settings.blizzframes
opt.PlayerFrame = not not panel.PlayerFrame:GetChecked()
opt.PetFrame = not not panel.PetFrame:GetChecked()
opt.TargetFrame = not not panel.TargetFrame:GetChecked()
opt.FocusFrame = not not panel.FocusFrame:GetChecked()
opt.FocusFrameToT = not not panel.FocusFrameToT:GetChecked()
opt.arena = not not panel.arena:GetChecked()
opt.party = not not panel.party:GetChecked()
opt.compactraid = not not panel.compactraid:GetChecked()
-- opt.compactparty = not not panel.compactparty:GetChecked()
opt.boss = not not panel.boss:GetChecked()
end
InterfaceOptions_AddCategory(panel, addon.optpanels.ABOUT)
+169
View File
@@ -0,0 +1,169 @@
--[[-------------------------------------------------------------------------
-- FrameOptionsPanel.lua
--
-- This file contains the definitions of the frame blacklist options panel.
--
-- Events registered:
-- None
-------------------------------------------------------------------------]] --
local addonName, addon = ...
local L = addon.L
local panel = CreateFrame("Frame")
panel.name = "Frame Blacklist"
panel.parent = addonName
addon.optpanels["BLACKLIST"] = panel
panel:SetScript("OnShow", function(self)
if not panel.initialized then
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 name, frame in pairs(addon.hccframes) do state[name] = true 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)
for frame in pairs(addon.ccframes) do
local name = frame:GetName()
if name then state[name] = false end
end
for name, frame in pairs(addon.hccframes) do state[name] = false end
self:UpdateScrollFrame()
end)
end
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 name, frame in pairs(addon.hccframes) do table.insert(sort, name) 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:FireMessage("BLACKLIST_CHANGED")
end
function panel.refresh()
for frame in pairs(addon.ccframes) do
local name = frame:GetName()
if name then state[name] = false end
end
for name, frame in pairs(addon.hccframes) do state[name] = false end
for frame, value in pairs(addon.settings.blacklist) do state[frame] = value end
panel:UpdateScrollFrame()
end
InterfaceOptions_AddCategory(panel, addon.optpanels.ABOUT)
+554
View File
@@ -0,0 +1,554 @@
--[[-------------------------------------------------------------------------
-- 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
--[[-------------------------------------------------------------------------
-- Addon 'About' Dialog for Interface Options
--
-- Some of this code was taken from/inspired by tekKonfigAboutPanel
--- and it's been moved from AddonCore due to taint issues.
-------------------------------------------------------------------------]] --
local about = CreateFrame("Frame", addonName .. "AboutPanel", InterfaceOptionsFramePanelContainer)
about.name = addonName
about:Hide()
function about.OnShow(frame)
local fields = {"Version", "Author", "Backported"}
local notes = GetAddOnMetadata(addonName, "Notes")
local title = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
title:SetPoint("TOPLEFT", 16, -16)
title:SetText(addonName)
local subtitle = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
subtitle:SetHeight(32)
subtitle:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8)
subtitle:SetPoint("RIGHT", about, -32, 0)
subtitle:SetNonSpaceWrap(true)
subtitle:SetJustifyH("LEFT")
subtitle:SetJustifyV("TOP")
subtitle:SetText(notes)
local anchor
for _, field in pairs(fields) do
local val
if (field == "Backported") then
val = "Tsoukie (Based on v3.4.14)"
else
val = GetAddOnMetadata(addonName, field)
end
if val then
local title = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
title:SetWidth(75)
if not anchor then
title:SetPoint("TOPLEFT", subtitle, "BOTTOMLEFT", -2, -8)
else
title:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, -6)
end
title:SetJustifyH("RIGHT")
title:SetText(field)
local detail = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
detail:SetPoint("LEFT", title, "RIGHT", 4, 0)
detail:SetPoint("RIGHT", -16, 0)
detail:SetJustifyH("LEFT")
detail:SetText(val)
anchor = title
end
end
-- Clear the OnShow so it only happens once
frame:SetScript("OnShow", nil)
end
addon.optpanels = addon.optpanels or {}
addon.optpanels.ABOUT = about
about:SetScript("OnShow", about.OnShow)
InterfaceOptions_AddCategory(addon.optpanels.ABOUT)
--[[-------------------------------------------------------------------------
-- End Dialog
-------------------------------------------------------------------------]] --
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(120)
label:SetJustifyH("LEFT")
label.type = "label"
return label
end
local function make_editbox_with_button(editName, buttonName, parent)
local editbox = CreateFrame("EditBox", editName, parent)
editbox:SetHeight(32)
editbox:SetWidth(200)
editbox:SetAutoFocus(false)
editbox:SetFontObject('GameFontHighlightSmall')
editbox.type = "editbox"
local left = editbox:CreateTexture(nil, "BACKGROUND")
left:SetWidth(8)
left:SetHeight(20)
left:SetPoint("LEFT", -5, 0)
left:SetTexture("Interface\\Common\\Common-Input-Border")
left:SetTexCoord(0, 0.0625, 0, 0.625)
local right = editbox:CreateTexture(nil, "BACKGROUND")
right:SetWidth(8)
right:SetHeight(20)
right:SetPoint("RIGHT", 0, 0)
right:SetTexture("Interface\\Common\\Common-Input-Border")
right:SetTexCoord(0.9375, 1, 0, 0.625)
local center = editbox:CreateTexture(nil, "BACKGROUND")
center:SetHeight(20)
center:SetPoint("RIGHT", right, "LEFT", 0, 0)
center:SetPoint("LEFT", left, "RIGHT", 0, 0)
center:SetTexture("Interface\\Common\\Common-Input-Border")
center:SetTexCoord(0.0625, 0.9375, 0, 0.625)
editbox:SetScript("OnEscapePressed", editbox.ClearFocus)
editbox:SetScript("OnEnterPressed", editbox.ClearFocus)
editbox:SetScript("OnEditFocusGained", function() editbox:HighlightText(0, MAX_HIGHLIGHT_LEN) end)
local button = CreateFrame("Button", buttonName, editbox, "UIPanelButtonTemplate2")
button:Show()
button:SetHeight(22)
button:SetWidth(75)
button:SetPoint("LEFT", editbox, "RIGHT", 0, 0)
return editbox, button
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"])
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
for i = 1, 12 do UIDropDownMenu_EnableDropDown(panel["specswap" .. i]) end
else
for i = 1, 12 do UIDropDownMenu_DisableDropDown(panel["specswap" .. i]) end
end
end
self.specswap:SetScript("PostClick", self.specswap.EnableDisable)
for i = 1, 12 do
self["specswap" .. i .. "label"] = make_label("CliqueOptionsSpecSwap" .. i .. "Label", self, "GameFontNormalSmall")
self["specswap" .. i .. "label"]:SetText(L["Specialization Slot "] .. i .. L[":"])
self["specswap" .. i] = make_dropdown("CliqueOptionsSpecSwap" .. i, self)
UIDropDownMenu_SetWidth(self["specswap" .. i], 200)
BlizzardOptionsPanel_SetupDependentControl(self.specswap, self["specswap" .. 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"])
self.exportbindingslabel = make_label("CliqueOptionsExportBindingsLabel", self, "GameFontNormalSmall")
self.exportbindingslabel:SetText(L["Export bindings:"])
self.exportbindingseditbox, self.exportbindingsbutton = make_editbox_with_button("CliqueOptionsExportBindingsEditbox", "CliqueOptionsExportBindingsEditboxButton", self)
self.exportbindingsbutton:SetText(L["Generate"])
self.exportbindingsbutton:SetScript("OnClick", function(self, button)
local payload = addon:GetExportString()
local editbox = self:GetParent()
editbox:SetText(payload)
editbox:SetFocus()
editbox:HighlightText(0, MAX_HIGHLIGHT_LEN)
end)
self.importbindingslabel = make_label("CliqueOptionsImportBindingsLabel", self, "GameFontNormalSmall")
self.importbindingslabel:SetText(L["Import bindings:"])
local importEditbox, importButton = make_editbox_with_button("CliqueOptionsImportBindingsEditbox", "CliqueOptionsImportBindingsEditboxButton", self)
self.importbindingseditbox, self.importbindingsbutton = importEditbox, importButton
self.importbindingseditbox:SetScript("OnTextChanged", function(self, userInput)
importButton.validated = false
importButton:SetText(L["Validate"])
end)
self.importbindingsbutton.validated = false
self.importbindingsbutton:SetText(L["Validate"])
self.importbindingsbutton:SetScript("OnClick", function(self, button)
if self.validated then
if not InCombatLockdown() then addon:ImportBindings(self.bindingData) end
self:SetText(L["Success!"])
importEditbox:SetText("")
else
local editbox = self:GetParent()
local payload = editbox:GetText()
local bindingData = addon:DecodeExportString(payload)
if bindingData then
self:SetText(L["Import"])
self.validated = true
self.bindingData = bindingData
else
self:SetText(L["Invalid"])
self.validated = false
end
end
end)
-- 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)
table.insert(bits, self.profilelabel)
table.insert(bits, self.profiledd)
table.insert(bits, self.exportbindingslabel)
table.insert(bits, self.exportbindingseditbox)
table.insert(bits, self.importbindingslabel)
table.insert(bits, self.importbindingseditbox)
for i = 1, 12 do
table.insert(bits, self["specswap" .. i .. "label"])
table.insert(bits, self["specswap" .. i])
end
bits[1]:SetPoint("TOPLEFT", 5, -5)
local bump = 1
for i = 2, #bits, 1 do
if bits[i].type == "label" then
bits[i]:SetPoint("TOPLEFT", bits[i - bump], "BOTTOMLEFT", 0, -15)
if bump == 1 then bump = 2 end
elseif bits[i].type == "dropdown" then
bits[i]:SetPoint("LEFT", bits[i - 1], "RIGHT", 5, -5)
elseif bits[i].type == "editbox" then
bits[i]:SetPoint("LEFT", bits[i - 1], "RIGHT", 5, 0)
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 = _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)
if (_G[self:GetParent():GetName() .. "Button1"]:IsEnabled() == 1) 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 >= 15)
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.disabled = UIDROPDOWNMENU_MENU_VALUE == currentProfile
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()
-- Initialize the dropdowns
local settings = addon.settings
local currentProfile = addon.db:GetCurrentProfile()
UIDropDownMenu_Initialize(panel.profiledd, mgmt_initialize)
UIDropDownMenu_SetSelectedValue(panel.profiledd, currentProfile)
UIDropDownMenu_SetText(panel.profiledd, L["Current: "] .. currentProfile)
for i = 1, 12 do
UIDropDownMenu_Initialize(panel["specswap" .. i], spec_initialize)
UIDropDownMenu_SetSelectedValue(panel["specswap" .. i], settings["specswap" .. i] or currentProfile)
UIDropDownMenu_SetText(panel["specswap" .. i], settings["specswap" .. i] or currentProfile)
end
panel.updown:SetChecked(settings.downclick)
panel.fastooc:SetChecked(settings.fastooc)
panel.stopcastingfix:SetChecked(settings.stopcastingfix)
panel.specswap:SetChecked(settings.specswap)
panel.specswap.EnableDisable()
end
function panel.okay()
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, 12 do settings["specswap" .. i] = UIDropDownMenu_GetSelectedValue(panel["specswap" .. i]) end
if newProfile ~= currentProfile then addon.db:SetProfile(newProfile) end
addon:UpdateCombatWatch()
if changed then addon:FireMessage("BINDINGS_CHANGED") end
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)