fix(libs): restore ElvUI-namespaced Ace3 stack clobbered by sweep
The coa-ace3 sweep (commits 0c130e0..5ea6e44, before coa-elvui was added to
EXCLUDED_FORKS in coa-ace3 tools/sweep.py) overwrote ElvUI's customized,
-ElvUI-namespaced Ace3 libs with plain canonical ones. ElvUI registers libs
as AceLocale-3.0-ElvUI and the AceConfig-3.0-ElvUI family (plus -ElvUI
widgets that don't exist in canonical), so the clobber left them
unregistered: ElvUI failed to init (16 locale 'L' errors) and /ec would not
open. Restores ElvUI/Libraries/Ace3/AceLocale-3.0 and the
ElvUI_OptionsUI/Libraries/Ace3 stack to their pre-sweep state (5021fd1).
coa-elvui is now in EXCLUDED_FORKS, so this won't be re-clobbered.
This commit is contained in:
+303
-277
@@ -5,9 +5,9 @@
|
||||
|
||||
local LibStub = LibStub
|
||||
local gui = LibStub("AceGUI-3.0")
|
||||
local reg = LibStub("AceConfigRegistry-3.0")
|
||||
local reg = LibStub("AceConfigRegistry-3.0-ElvUI")
|
||||
|
||||
local MAJOR, MINOR = "AceConfigDialog-3.0", 92
|
||||
local MAJOR, MINOR = "AceConfigDialog-3.0-ElvUI", 79
|
||||
local AceConfigDialog, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
|
||||
|
||||
if not AceConfigDialog then return end
|
||||
@@ -15,20 +15,25 @@ if not AceConfigDialog then return end
|
||||
AceConfigDialog.OpenFrames = AceConfigDialog.OpenFrames or {}
|
||||
AceConfigDialog.Status = AceConfigDialog.Status or {}
|
||||
AceConfigDialog.frame = AceConfigDialog.frame or CreateFrame("Frame")
|
||||
AceConfigDialog.tooltip = AceConfigDialog.tooltip or CreateFrame("GameTooltip", "AceConfigDialogTooltip", UIParent, "GameTooltipTemplate")
|
||||
|
||||
AceConfigDialog.frame.apps = AceConfigDialog.frame.apps or {}
|
||||
AceConfigDialog.frame.closing = AceConfigDialog.frame.closing or {}
|
||||
AceConfigDialog.frame.closeAllOverride = AceConfigDialog.frame.closeAllOverride or {}
|
||||
|
||||
-- Lua APIs
|
||||
local tinsert, tsort, tremove, wipe = table.insert, table.sort, table.remove, table.wipe
|
||||
local tconcat, tinsert, tsort, tremove = table.concat, table.insert, table.sort, table.remove
|
||||
local strmatch, format = string.match, string.format
|
||||
local error = error
|
||||
local pairs, next, select, type, unpack, ipairs = pairs, next, select, type, unpack, ipairs
|
||||
local tostring, tonumber = tostring, tonumber
|
||||
local assert, loadstring, error = assert, loadstring, error
|
||||
local pairs, next, select, type, unpack, wipe, ipairs = pairs, next, select, type, unpack, wipe, ipairs
|
||||
local rawset, tostring, tonumber = rawset, tostring, tonumber
|
||||
local math_min, math_max, math_floor = math.min, math.max, math.floor
|
||||
|
||||
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
|
||||
-- List them here for Mikk's FindGlobals script
|
||||
-- GLOBALS: NORMAL_FONT_COLOR, GameTooltip, StaticPopupDialogs, ACCEPT, CANCEL, StaticPopup_Show
|
||||
-- GLOBALS: PlaySound, GameFontHighlight, GameFontHighlightSmall, GameFontHighlightLarge
|
||||
-- GLOBALS: CloseSpecialWindows, InterfaceOptions_AddCategory, geterrorhandler
|
||||
|
||||
local emptyTbl = {}
|
||||
|
||||
--[[
|
||||
@@ -40,10 +45,39 @@ local function errorhandler(err)
|
||||
return geterrorhandler()(err)
|
||||
end
|
||||
|
||||
local function CreateDispatcher(argCount)
|
||||
local code = [[
|
||||
local xpcall, eh = ...
|
||||
local method, ARGS
|
||||
local function call() return method(ARGS) end
|
||||
|
||||
local function dispatch(func, ...)
|
||||
method = func
|
||||
if not method then return end
|
||||
ARGS = ...
|
||||
return xpcall(call, eh)
|
||||
end
|
||||
|
||||
return dispatch
|
||||
]]
|
||||
|
||||
local ARGS = {}
|
||||
for i = 1, argCount do ARGS[i] = "arg"..i end
|
||||
code = code:gsub("ARGS", tconcat(ARGS, ", "))
|
||||
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
|
||||
end
|
||||
|
||||
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
|
||||
local dispatcher = CreateDispatcher(argCount)
|
||||
rawset(self, argCount, dispatcher)
|
||||
return dispatcher
|
||||
end})
|
||||
Dispatchers[0] = function(func)
|
||||
return xpcall(func, errorhandler)
|
||||
end
|
||||
|
||||
local function safecall(func, ...)
|
||||
if func then
|
||||
return xpcall(func, errorhandler, ...)
|
||||
end
|
||||
return Dispatchers[select("#", ...)](func, ...)
|
||||
end
|
||||
|
||||
local width_multiplier = 170
|
||||
@@ -147,7 +181,6 @@ local stringIsLiteral = {
|
||||
width = true,
|
||||
image = true,
|
||||
fontSize = true,
|
||||
tooltipHyperlink = true
|
||||
}
|
||||
|
||||
--Is Never a function or method
|
||||
@@ -189,8 +222,9 @@ local function GetOptionsMemberValue(membername, option, options, path, appName,
|
||||
--We have a function to call
|
||||
local info = new()
|
||||
--traverse the options table, picking up the handler and filling the info with the path
|
||||
local handler
|
||||
local group = options
|
||||
local handler = group.handler
|
||||
handler = group.handler or handler
|
||||
|
||||
for i = 1, #path do
|
||||
group = GetSubOption(group, path[i])
|
||||
@@ -208,21 +242,21 @@ local function GetOptionsMemberValue(membername, option, options, path, appName,
|
||||
info.uiType = "dialog"
|
||||
info.uiName = MAJOR
|
||||
|
||||
local a, b, c ,d
|
||||
local a, b, c, d, e, f, g, h -- ElvUI adds e,f,g,h for default color
|
||||
--using 4 returns for the get of a color type, increase if a type needs more
|
||||
if type(member) == "function" then
|
||||
--Call the function
|
||||
a,b,c,d = member(info, ...)
|
||||
a,b,c,d,e,f,g,h = member(info, ...)
|
||||
else
|
||||
--Call the method
|
||||
if handler and handler[member] then
|
||||
a,b,c,d = handler[member](handler, info, ...)
|
||||
a,b,c,d,e,f,g,h = handler[member](handler, info, ...)
|
||||
else
|
||||
error(format("Method %s doesn't exist in handler for type %s", member, membername))
|
||||
end
|
||||
end
|
||||
del(info)
|
||||
return a,b,c,d
|
||||
return a,b,c,d,e,f,g,h
|
||||
else
|
||||
--The value isnt a function to call, return it
|
||||
return member
|
||||
@@ -499,163 +533,137 @@ local function OptionOnMouseOver(widget, event)
|
||||
local options = user.options
|
||||
local path = user.path
|
||||
local appName = user.appName
|
||||
local tooltip = AceConfigDialog.tooltip
|
||||
|
||||
tooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT")
|
||||
|
||||
local tooltipHyperlink = GetOptionsMemberValue("tooltipHyperlink", opt, options, path, appName)
|
||||
if tooltipHyperlink then
|
||||
tooltip:SetHyperlink(tooltipHyperlink)
|
||||
tooltip:Show()
|
||||
return
|
||||
end
|
||||
-- modified by ElvUI
|
||||
if opt.descStyle and opt.descStyle ~= "tooltip" then return end
|
||||
|
||||
local name = GetOptionsMemberValue("name", opt, options, path, appName)
|
||||
local desc = GetOptionsMemberValue("desc", opt, options, path, appName)
|
||||
local usage = GetOptionsMemberValue("usage", opt, options, path, appName)
|
||||
local descStyle = opt.descStyle
|
||||
|
||||
if descStyle and descStyle ~= "tooltip" then return end
|
||||
local descText = type(desc) == "string"
|
||||
local usageText = type(usage) == "string"
|
||||
local userText = opt.type == "multiselect"
|
||||
local softText = opt.softMin or opt.softMax
|
||||
local bigText = opt.bigStep
|
||||
local Min, Max, Step
|
||||
|
||||
tooltip:SetText(name, 1, .82, 0, 1, true)
|
||||
|
||||
if opt.type == "multiselect" then
|
||||
tooltip:AddLine(user.text, 0.5, 0.5, 0.8, true)
|
||||
if softText then
|
||||
Min = (opt.min and "|cFFCCCCCCMin:|r "..(opt.isPercent and (opt.min*100).."%" or opt.min)) or ""
|
||||
Max = (opt.max and "|cFFCCCCCCMax:|r "..(opt.isPercent and (opt.max*100).."%" or opt.max)) or ""
|
||||
softText = Min ~= "" or Max ~= ""
|
||||
end
|
||||
if type(desc) == "string" then
|
||||
tooltip:AddLine(desc, 1, 1, 1, true)
|
||||
end
|
||||
if type(usage) == "string" then
|
||||
tooltip:AddLine(usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
|
||||
if bigText then
|
||||
local dec = opt.step and format("%f", opt.step):gsub('%.?0-$','')
|
||||
local num = dec and tonumber(dec)
|
||||
Step = (num and num > 0 and "|cFFCCCCCCStep:|r "..dec) or ""
|
||||
bigText = Step ~= ""
|
||||
end
|
||||
|
||||
tooltip:Show()
|
||||
if descText or usageText or userText or softText or bigText then
|
||||
GameTooltip:SetOwner(widget.frame, "ANCHOR_TOPRIGHT")
|
||||
GameTooltip:SetText(name, 1, .82, 0, true)
|
||||
|
||||
if userText then
|
||||
GameTooltip:AddLine(user.text, 0.5, 0.5, 0.8, true)
|
||||
end
|
||||
if descText then
|
||||
GameTooltip:AddLine(desc, 1, 1, 1, true)
|
||||
end
|
||||
if usageText then
|
||||
GameTooltip:AddLine("Usage: "..usage, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
|
||||
end
|
||||
if bigText or softText then
|
||||
GameTooltip:AddLine(" ")
|
||||
end
|
||||
if bigText then
|
||||
GameTooltip:AddLine(Step, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
|
||||
end
|
||||
if softText then
|
||||
GameTooltip:AddDoubleLine(Min, Max)
|
||||
end
|
||||
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local function OptionOnMouseLeave(widget, event)
|
||||
AceConfigDialog.tooltip:Hide()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
local function GetFuncName(option)
|
||||
if option.type == "execute" then
|
||||
local type = option.type
|
||||
if type == "execute" then
|
||||
return "func"
|
||||
else
|
||||
return "set"
|
||||
end
|
||||
end
|
||||
do
|
||||
local InCombatLockdown = InCombatLockdown
|
||||
local frame = AceConfigDialog.popup
|
||||
if not frame or oldminor < 81 then
|
||||
frame = CreateFrame("Frame", nil, UIParent)
|
||||
AceConfigDialog.popup = frame
|
||||
frame:Hide()
|
||||
frame:SetPoint("CENTER", UIParent, "CENTER")
|
||||
frame:SetSize(320, 72)
|
||||
frame:EnableMouse(true) -- Do not allow click-through on the frame
|
||||
frame:SetFrameStrata("TOOLTIP")
|
||||
frame:SetFrameLevel(100) -- Lots of room to draw under it
|
||||
frame:SetScript("OnKeyDown", function(self, key)
|
||||
if key == "ESCAPE" then
|
||||
if not InCombatLockdown() then
|
||||
self:SetPropagateKeyboardInput(false)
|
||||
end
|
||||
if self.cancel:IsShown() then
|
||||
self.cancel:Click()
|
||||
else -- Showing a validation error
|
||||
self:Hide()
|
||||
end
|
||||
elseif not InCombatLockdown() then
|
||||
self:SetPropagateKeyboardInput(true)
|
||||
end
|
||||
end)
|
||||
|
||||
local border = CreateFrame("Frame", nil, frame, "DialogBorderOpaqueTemplate")
|
||||
border:SetAllPoints(frame)
|
||||
frame:SetFixedFrameStrata(true)
|
||||
frame:SetFixedFrameLevel(true)
|
||||
|
||||
local text = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
|
||||
text:SetSize(290, 0)
|
||||
text:SetPoint("TOP", 0, -16)
|
||||
frame.text = text
|
||||
|
||||
local function newButton(newText)
|
||||
local button = CreateFrame("Button", nil, frame)
|
||||
button:SetSize(128, 21)
|
||||
button:SetNormalFontObject(GameFontNormal)
|
||||
button:SetHighlightFontObject(GameFontHighlight)
|
||||
button:SetNormalTexture("Interface\\Buttons\\UI-DialogBox-Button-Up")
|
||||
button:GetNormalTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
|
||||
button:SetPushedTexture("Interface\\Buttons\\UI-DialogBox-Button-Down")
|
||||
button:GetPushedTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
|
||||
button:SetHighlightTexture("Interface\\Buttons\\UI-DialogBox-Button-Highlight")
|
||||
button:GetHighlightTexture():SetTexCoord(0.0, 1.0, 0.0, 0.71875)
|
||||
button:SetText(newText)
|
||||
return button
|
||||
end
|
||||
|
||||
local accept = newButton(ACCEPT)
|
||||
accept:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -6, 16)
|
||||
frame.accept = accept
|
||||
|
||||
local cancel = newButton(CANCEL)
|
||||
cancel:SetPoint("LEFT", accept, "RIGHT", 13, 0)
|
||||
frame.cancel = cancel
|
||||
end
|
||||
end
|
||||
local function confirmPopup(appName, rootframe, basepath, info, message, func, ...)
|
||||
local frame = AceConfigDialog.popup
|
||||
frame:Show()
|
||||
frame.text:SetText(message)
|
||||
-- From StaticPopup.lua
|
||||
-- local height = 32 + text:GetHeight() + 2;
|
||||
-- height = height + 6 + accept:GetHeight()
|
||||
-- We add 32 + 2 + 6 + 21 (button height) == 61
|
||||
local height = 61 + frame.text:GetHeight()
|
||||
frame:SetHeight(height)
|
||||
|
||||
frame.accept:ClearAllPoints()
|
||||
frame.accept:SetPoint("BOTTOMRIGHT", frame, "BOTTOM", -6, 16)
|
||||
frame.cancel:Show()
|
||||
|
||||
local t = {...}
|
||||
local tCount = select("#", ...)
|
||||
frame.accept:SetScript("OnClick", function(self)
|
||||
safecall(func, unpack(t, 1, tCount)) -- Manually set count as unpack() stops on nil (bug with #table)
|
||||
if not StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] then
|
||||
StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"] = {}
|
||||
end
|
||||
local t = StaticPopupDialogs["ACECONFIGDIALOG30_CONFIRM_DIALOG"]
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
t.text = message
|
||||
t.button1 = ACCEPT
|
||||
t.button2 = CANCEL
|
||||
t.preferredIndex = STATICPOPUP_NUMDIALOGS
|
||||
local dialog, oldstrata
|
||||
t.OnAccept = function()
|
||||
safecall(func, unpack(t))
|
||||
if dialog and oldstrata then
|
||||
dialog:SetFrameStrata(oldstrata)
|
||||
end
|
||||
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
|
||||
frame:Hide()
|
||||
self:SetScript("OnClick", nil)
|
||||
frame.cancel:SetScript("OnClick", nil)
|
||||
del(info)
|
||||
end)
|
||||
frame.cancel:SetScript("OnClick", function(self)
|
||||
end
|
||||
t.OnCancel = function()
|
||||
if dialog and oldstrata then
|
||||
dialog:SetFrameStrata(oldstrata)
|
||||
end
|
||||
AceConfigDialog:Open(appName, rootframe, unpack(basepath or emptyTbl))
|
||||
frame:Hide()
|
||||
self:SetScript("OnClick", nil)
|
||||
frame.accept:SetScript("OnClick", nil)
|
||||
del(info)
|
||||
end)
|
||||
end
|
||||
for i = 1, select("#", ...) do
|
||||
t[i] = select(i, ...) or false
|
||||
end
|
||||
t.timeout = 0
|
||||
t.whileDead = 1
|
||||
t.hideOnEscape = 1
|
||||
|
||||
dialog = StaticPopup_Show("ACECONFIGDIALOG30_CONFIRM_DIALOG")
|
||||
if dialog then
|
||||
oldstrata = dialog:GetFrameStrata()
|
||||
dialog:SetFrameStrata("TOOLTIP")
|
||||
end
|
||||
end
|
||||
|
||||
local function validationErrorPopup(message)
|
||||
local frame = AceConfigDialog.popup
|
||||
frame:Show()
|
||||
frame.text:SetText(message)
|
||||
-- From StaticPopup.lua
|
||||
-- local height = 32 + text:GetHeight() + 2;
|
||||
-- height = height + 6 + accept:GetHeight()
|
||||
-- We add 32 + 2 + 6 + 21 (button height) == 61
|
||||
local height = 61 + frame.text:GetHeight()
|
||||
frame:SetHeight(height)
|
||||
if not StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] then
|
||||
StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] = {}
|
||||
end
|
||||
local t = StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"]
|
||||
t.text = message
|
||||
t.button1 = OKAY
|
||||
t.preferredIndex = STATICPOPUP_NUMDIALOGS
|
||||
local dialog, oldstrata
|
||||
t.OnAccept = function()
|
||||
if dialog and oldstrata then
|
||||
dialog:SetFrameStrata(oldstrata)
|
||||
end
|
||||
end
|
||||
t.timeout = 0
|
||||
t.whileDead = 1
|
||||
t.hideOnEscape = 1
|
||||
|
||||
frame.accept:ClearAllPoints()
|
||||
frame.accept:SetPoint("BOTTOM", frame, "BOTTOM", 0, 16)
|
||||
frame.cancel:Hide()
|
||||
|
||||
frame.accept:SetScript("OnClick", function()
|
||||
frame:Hide()
|
||||
end)
|
||||
dialog = StaticPopup_Show("ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG")
|
||||
if dialog then
|
||||
oldstrata = dialog:GetFrameStrata()
|
||||
dialog:SetFrameStrata("TOOLTIP")
|
||||
end
|
||||
end
|
||||
|
||||
local function ActivateControl(widget, event, ...)
|
||||
@@ -678,7 +686,7 @@ local function ActivateControl(widget, event, ...)
|
||||
if group[funcname] ~= nil then
|
||||
func = group[funcname]
|
||||
end
|
||||
handler = group.handler
|
||||
handler = group.handler or handler
|
||||
confirm = group.confirm
|
||||
validate = group.validate
|
||||
for i = 1, #path do
|
||||
@@ -742,6 +750,7 @@ local function ActivateControl(widget, event, ...)
|
||||
end
|
||||
end
|
||||
|
||||
local rootframe = user.rootframe
|
||||
if not validated or type(validated) == "string" then
|
||||
if not validated then
|
||||
if usage then
|
||||
@@ -756,12 +765,12 @@ local function ActivateControl(widget, event, ...)
|
||||
end
|
||||
|
||||
-- show validate message
|
||||
if user.rootframe.SetStatusText then
|
||||
user.rootframe:SetStatusText(validated)
|
||||
if not group.validatePopup and rootframe.SetStatusText then
|
||||
rootframe:SetStatusText(validated)
|
||||
else
|
||||
validationErrorPopup(validated)
|
||||
end
|
||||
PlaySound(882) -- SOUNDKIT.IG_PLAYER_INVITE_DECLINE || _DECLINE is actually missing from the table
|
||||
PlaySound("igPlayerInviteDecline")
|
||||
del(info)
|
||||
return true
|
||||
else
|
||||
@@ -794,14 +803,14 @@ local function ActivateControl(widget, event, ...)
|
||||
if type(confirm) == "boolean" then
|
||||
if confirm then
|
||||
if not confirmText then
|
||||
local option_name, desc = option.name, option.desc
|
||||
if type(option_name) == "function" then
|
||||
option_name = option_name(info)
|
||||
local name, desc = option.name, option.desc
|
||||
if type(name) == "function" then
|
||||
name = name(info)
|
||||
end
|
||||
if type(desc) == "function" then
|
||||
desc = desc(info)
|
||||
end
|
||||
confirmText = option_name
|
||||
confirmText = name
|
||||
if desc then
|
||||
confirmText = confirmText.." - "..desc
|
||||
end
|
||||
@@ -879,6 +888,11 @@ end
|
||||
local function ActivateSlider(widget, event, value)
|
||||
local option = widget:GetUserData("option")
|
||||
local min, max, step = option.min or (not option.softMin and 0 or nil), option.max or (not option.softMax and 100 or nil), option.step
|
||||
|
||||
-- checks added by elvui
|
||||
if type(min) == 'function' then min = min() end
|
||||
if type(max) == 'function' then max = max() end
|
||||
|
||||
if min then
|
||||
if step then
|
||||
value = math_floor((value - min) / step + 0.5) * step + min
|
||||
@@ -1083,11 +1097,6 @@ local function InjectInfo(control, options, option, path, rootframe, appName)
|
||||
control:SetCallback("OnRelease", CleanUserData)
|
||||
control:SetCallback("OnLeave", OptionOnMouseLeave)
|
||||
control:SetCallback("OnEnter", OptionOnMouseOver)
|
||||
|
||||
-- forward custom arg data directly
|
||||
if control.SetCustomData and option.arg then
|
||||
safecall(control.SetCustomData, control, option.arg)
|
||||
end
|
||||
end
|
||||
|
||||
local function CreateControl(userControlType, fallbackControlType)
|
||||
@@ -1108,6 +1117,11 @@ local function sortTblAsStrings(x,y)
|
||||
return tostring(x) < tostring(y) -- Support numbers as keys
|
||||
end
|
||||
|
||||
-- added by ElvUI
|
||||
local function sortTblByValue(x,y)
|
||||
return x[2] < y[2]
|
||||
end
|
||||
|
||||
--[[
|
||||
options - root of the options table being fed
|
||||
container - widget that controls will be placed in
|
||||
@@ -1148,13 +1162,15 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
||||
--Control to feed
|
||||
local control
|
||||
|
||||
local name = GetOptionsMemberValue("name", v, options, path, appName)
|
||||
|
||||
if v.type == "execute" then
|
||||
|
||||
local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
|
||||
local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
|
||||
|
||||
local iconControl = type(image) == "string" or type(image) == "number"
|
||||
control = CreateControl(v.dialogControl or v.control, iconControl and "Icon" or "Button")
|
||||
control = CreateControl(v.dialogControl or v.control, iconControl and "Icon" or "Button-ElvUI")
|
||||
if iconControl then
|
||||
if not width then
|
||||
width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
|
||||
@@ -1197,6 +1213,11 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
||||
elseif v.type == "toggle" then
|
||||
control = CreateControl(v.dialogControl or v.control, "CheckBox")
|
||||
control:SetLabel(name)
|
||||
control.textWidth = GetOptionsMemberValue("textWidth",v,options,path,appName)
|
||||
if control.textWidth and control.frame and control.text then
|
||||
local textWidth = control.text:GetWidth()+30
|
||||
control.customWidth = (textWidth>=width_multiplier and textWidth<=width_multiplier*1.5) and textWidth
|
||||
end
|
||||
control:SetTriState(v.tristate)
|
||||
local value = GetOptionsMemberValue("get",v, options, path, appName)
|
||||
control:SetValue(value)
|
||||
@@ -1210,7 +1231,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
||||
local image = GetOptionsMemberValue("image", v, options, path, appName)
|
||||
local imageCoords = GetOptionsMemberValue("imageCoords", v, options, path, appName)
|
||||
|
||||
if type(image) == "string" or type(image) == "number" then
|
||||
if type(image) == "string" then
|
||||
if type(imageCoords) == "table" then
|
||||
control:SetImage(image, unpack(imageCoords))
|
||||
else
|
||||
@@ -1250,7 +1271,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
||||
end
|
||||
tsort(sorting, sortTblAsStrings)
|
||||
end
|
||||
for _, value in ipairs(sorting) do
|
||||
for k, value in ipairs(sorting) do
|
||||
local text = values[value]
|
||||
local radio = gui:Create("CheckBox")
|
||||
radio:SetLabel(text)
|
||||
@@ -1278,13 +1299,15 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
||||
control:DoLayout()
|
||||
else
|
||||
control = CreateControl(v.dialogControl or v.control, "Dropdown")
|
||||
local sortByValue = GetOptionsMemberValue("sortByValue",v,options,path,appName)
|
||||
|
||||
local itemType = v.itemControl
|
||||
if itemType and not gui:GetWidgetVersion(itemType) then
|
||||
geterrorhandler()(("Invalid Custom Item Type - %s"):format(tostring(itemType)))
|
||||
itemType = nil
|
||||
end
|
||||
control:SetLabel(name)
|
||||
control:SetList(values, sorting, itemType)
|
||||
control:SetList(values, sorting, itemType, sortByValue)
|
||||
local value = GetOptionsMemberValue("get",v, options, path, appName)
|
||||
if not values[value] then
|
||||
value = nil
|
||||
@@ -1296,14 +1319,20 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
||||
elseif v.type == "multiselect" then
|
||||
local values = GetOptionsMemberValue("values", v, options, path, appName)
|
||||
local disabled = CheckOptionDisabled(v, options, path, appName)
|
||||
local sortByValue = GetOptionsMemberValue("sortByValue", v, options, path, appName)
|
||||
|
||||
local valuesort = new()
|
||||
if values then
|
||||
for value, text in pairs(values) do
|
||||
tinsert(valuesort, value)
|
||||
tinsert(valuesort, (sortByValue and {value, text}) or value)
|
||||
end
|
||||
end
|
||||
tsort(valuesort)
|
||||
|
||||
if sortByValue then
|
||||
tsort(valuesort, sortTblByValue)
|
||||
else
|
||||
tsort(valuesort)
|
||||
end
|
||||
|
||||
local controlType = v.dialogControl or v.control
|
||||
if controlType then
|
||||
@@ -1332,42 +1361,76 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
||||
control:SetWidth(width_multiplier)
|
||||
end
|
||||
--check:SetTriState(v.tristate)
|
||||
for s = 1, #valuesort do
|
||||
local key = valuesort[s]
|
||||
for i = 1, #valuesort do
|
||||
local key = (sortByValue and valuesort[i][1]) or valuesort[i]
|
||||
local value = GetOptionsMemberValue("get",v, options, path, appName, key)
|
||||
control:SetItemValue(key,value)
|
||||
end
|
||||
else
|
||||
local width = GetOptionsMemberValue("width",v,options,path,appName)
|
||||
local dragdrop = GetOptionsMemberValue("dragdrop",v,options,path,appName)
|
||||
|
||||
control = gui:Create("InlineGroup")
|
||||
control:SetLayout("Flow")
|
||||
control:SetTitle(name)
|
||||
control.width = "fill"
|
||||
|
||||
control:PauseLayout()
|
||||
local width = GetOptionsMemberValue("width",v,options,path,appName)
|
||||
for s = 1, #valuesort do
|
||||
local value = valuesort[s]
|
||||
|
||||
for i = 1, #valuesort do
|
||||
local value = (sortByValue and valuesort[i][1]) or valuesort[i]
|
||||
local text = values[value]
|
||||
local check = gui:Create("CheckBox")
|
||||
check:SetLabel(text)
|
||||
check:SetUserData("value", value)
|
||||
check:SetUserData("text", text)
|
||||
check:SetDisabled(disabled)
|
||||
check:SetTriState(v.tristate)
|
||||
check:SetValue(GetOptionsMemberValue("get",v, options, path, appName, value))
|
||||
check:SetCallback("OnValueChanged",ActivateMultiControl)
|
||||
InjectInfo(check, options, v, path, rootframe, appName)
|
||||
control:AddChild(check)
|
||||
if width == "double" then
|
||||
check:SetWidth(width_multiplier * 2)
|
||||
elseif width == "half" then
|
||||
check:SetWidth(width_multiplier / 2)
|
||||
elseif (type(width) == "number") then
|
||||
check:SetWidth(width_multiplier * width)
|
||||
elseif width == "full" then
|
||||
check.width = "fill"
|
||||
if dragdrop then
|
||||
local button = gui:Create("Button-ElvUI")
|
||||
button:SetDisabled(disabled)
|
||||
button:SetUserData("value", value)
|
||||
button:SetUserData("text", text)
|
||||
local state = v.stateSwitchGetText and v.stateSwitchGetText(button, text, value)
|
||||
button:SetText(format("|cFF888888%d|r %s", i, state or text))
|
||||
button.stateSwitchOnClick = v.stateSwitchOnClick
|
||||
button.dragOnMouseDown = v.dragOnMouseDown
|
||||
button.dragOnMouseUp = v.dragOnMouseUp
|
||||
button.dragOnEnter = v.dragOnEnter
|
||||
button.dragOnLeave = v.dragOnLeave
|
||||
button.dragOnClick = v.dragOnClick
|
||||
button.dragdrop = true
|
||||
button.ActivateMultiControl = ActivateMultiControl
|
||||
button.value = GetOptionsMemberValue("get",v, options, path, appName, value)
|
||||
InjectInfo(button, options, v, path, rootframe, appName)
|
||||
control:AddChild(button)
|
||||
if width == "double" then
|
||||
button:SetWidth(width_multiplier * 2)
|
||||
elseif width == "half" then
|
||||
button:SetWidth(width_multiplier / 2)
|
||||
elseif (type(width) == "number") then
|
||||
control:SetWidth(width_multiplier * width)
|
||||
elseif width == "full" then
|
||||
button.width = "fill"
|
||||
else
|
||||
button:SetWidth(width_multiplier)
|
||||
end
|
||||
else
|
||||
check:SetWidth(width_multiplier)
|
||||
local check = gui:Create("CheckBox")
|
||||
check:SetLabel(text)
|
||||
check:SetUserData("value", value)
|
||||
check:SetUserData("text", text)
|
||||
check:SetDisabled(disabled)
|
||||
check:SetTriState(v.tristate)
|
||||
check:SetValue(GetOptionsMemberValue("get",v, options, path, appName, value))
|
||||
check:SetCallback("OnValueChanged",ActivateMultiControl)
|
||||
InjectInfo(check, options, v, path, rootframe, appName)
|
||||
control:AddChild(check)
|
||||
if width == "double" then
|
||||
check:SetWidth(width_multiplier * 2)
|
||||
elseif width == "half" then
|
||||
check:SetWidth(width_multiplier / 2)
|
||||
elseif (type(width) == "number") then
|
||||
control:SetWidth(width_multiplier * width)
|
||||
elseif width == "full" then
|
||||
check.width = "fill"
|
||||
else
|
||||
check:SetWidth(width_multiplier)
|
||||
end
|
||||
end
|
||||
end
|
||||
control:ResumeLayout()
|
||||
@@ -1379,7 +1442,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
||||
del(valuesort)
|
||||
|
||||
elseif v.type == "color" then
|
||||
control = CreateControl(v.dialogControl or v.control, "ColorPicker")
|
||||
control = CreateControl(v.dialogControl or v.control, "ColorPicker-ElvUI")
|
||||
control:SetLabel(name)
|
||||
control:SetHasAlpha(GetOptionsMemberValue("hasAlpha",v, options, path, appName))
|
||||
control:SetColor(GetOptionsMemberValue("get",v, options, path, appName))
|
||||
@@ -1413,7 +1476,7 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
||||
local imageCoords = GetOptionsMemberValue("imageCoords",v, options, path, appName)
|
||||
local image, width, height = GetOptionsMemberValue("image",v, options, path, appName)
|
||||
|
||||
if type(image) == "string" or type(image) == "number" then
|
||||
if type(image) == "string" then
|
||||
if not width then
|
||||
width = GetOptionsMemberValue("imageWidth",v, options, path, appName)
|
||||
end
|
||||
@@ -1433,27 +1496,29 @@ local function FeedOptions(appName, options,container,rootframe,path,group,inlin
|
||||
end
|
||||
control:SetImageSize(width, height)
|
||||
end
|
||||
local controlWidth = GetOptionsMemberValue("width",v,options,path,appName)
|
||||
control.width = not controlWidth and "fill"
|
||||
local width = GetOptionsMemberValue("width",v,options,path,appName)
|
||||
control.width = not width and "fill"
|
||||
end
|
||||
|
||||
--Common Init
|
||||
if control then
|
||||
if control.width ~= "fill" then
|
||||
local width = GetOptionsMemberValue("width",v,options,path,appName)
|
||||
local relWidth = GetOptionsMemberValue("relWidth",v,options,path,appName)
|
||||
if width == "double" then
|
||||
control:SetWidth(width_multiplier * 2)
|
||||
elseif width == "half" then
|
||||
control:SetWidth(width_multiplier / 2)
|
||||
elseif (type(width) == "number") then
|
||||
control:SetWidth(width_multiplier * width)
|
||||
elseif width == "relative" and relWidth then
|
||||
control:SetRelativeWidth(relWidth)
|
||||
elseif width == "full" then
|
||||
control.width = "fill"
|
||||
local customWidth = control.customWidth or GetOptionsMemberValue("customWidth",v,options,path,appName)
|
||||
if control.width ~= "fill" or customWidth then
|
||||
if customWidth then
|
||||
control:SetWidth(customWidth)
|
||||
else
|
||||
control:SetWidth(width_multiplier)
|
||||
local width = GetOptionsMemberValue("width",v,options,path,appName)
|
||||
if width == "double" then
|
||||
control:SetWidth(width_multiplier * 2)
|
||||
elseif width == "half" then
|
||||
control:SetWidth(width_multiplier / 2)
|
||||
elseif (type(width) == "number") then
|
||||
control:SetWidth(width_multiplier * width)
|
||||
elseif width == "full" then
|
||||
control.width = "fill"
|
||||
else
|
||||
control:SetWidth(width_multiplier)
|
||||
end
|
||||
end
|
||||
end
|
||||
if control.SetDisabled then
|
||||
@@ -1489,7 +1554,6 @@ local function TreeOnButtonEnter(widget, event, uniquevalue, button)
|
||||
local option = user.option
|
||||
local path = user.path
|
||||
local appName = user.appName
|
||||
local tooltip = AceConfigDialog.tooltip
|
||||
|
||||
local feedpath = new()
|
||||
for i = 1, #path do
|
||||
@@ -1506,25 +1570,24 @@ local function TreeOnButtonEnter(widget, event, uniquevalue, button)
|
||||
local name = GetOptionsMemberValue("name", group, options, feedpath, appName)
|
||||
local desc = GetOptionsMemberValue("desc", group, options, feedpath, appName)
|
||||
|
||||
tooltip:SetOwner(button, "ANCHOR_NONE")
|
||||
tooltip:ClearAllPoints()
|
||||
if widget.type == "TabGroup" then
|
||||
tooltip:SetPoint("BOTTOM",button,"TOP")
|
||||
else
|
||||
tooltip:SetPoint("LEFT",button,"RIGHT")
|
||||
end
|
||||
|
||||
tooltip:SetText(name, 1, .82, 0, 1, true)
|
||||
|
||||
if type(desc) == "string" then
|
||||
tooltip:AddLine(desc, 1, 1, 1, true)
|
||||
end
|
||||
GameTooltip:SetOwner(button, "ANCHOR_CURSOR")
|
||||
if widget.type == "TabGroup" then
|
||||
GameTooltip:SetPoint("BOTTOM",button,"TOP")
|
||||
else
|
||||
GameTooltip:SetPoint("LEFT",button,"RIGHT")
|
||||
end
|
||||
|
||||
tooltip:Show()
|
||||
GameTooltip:SetText(name, 1, .82, 0, 1)
|
||||
|
||||
GameTooltip:AddLine(desc, 1, 1, 1, 1)
|
||||
|
||||
GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
|
||||
local function TreeOnButtonLeave(widget, event, value, button)
|
||||
AceConfigDialog.tooltip:Hide()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
|
||||
@@ -1692,29 +1755,29 @@ function AceConfigDialog:FeedGroup(appName,options,container,rootframe,path, isR
|
||||
|
||||
elseif grouptype == "select" then
|
||||
|
||||
local selectGroup = gui:Create("DropdownGroup")
|
||||
selectGroup:SetTitle(name)
|
||||
InjectInfo(selectGroup, options, group, path, rootframe, appName)
|
||||
selectGroup:SetCallback("OnGroupSelected", GroupSelected)
|
||||
local select = gui:Create("DropdownGroup")
|
||||
select:SetTitle(name)
|
||||
InjectInfo(select, options, group, path, rootframe, appName)
|
||||
select:SetCallback("OnGroupSelected", GroupSelected)
|
||||
local status = AceConfigDialog:GetStatusTable(appName, path)
|
||||
if not status.groups then
|
||||
status.groups = {}
|
||||
end
|
||||
selectGroup:SetStatusTable(status.groups)
|
||||
select:SetStatusTable(status.groups)
|
||||
local grouplist, orderlist = BuildSelect(group, options, path, appName)
|
||||
selectGroup:SetGroupList(grouplist, orderlist)
|
||||
selectGroup:SetUserData("grouplist", grouplist)
|
||||
selectGroup:SetUserData("orderlist", orderlist)
|
||||
select:SetGroupList(grouplist, orderlist)
|
||||
select:SetUserData("grouplist", grouplist)
|
||||
select:SetUserData("orderlist", orderlist)
|
||||
|
||||
local firstgroup = orderlist[1]
|
||||
if firstgroup then
|
||||
selectGroup:SetGroup((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or firstgroup)
|
||||
select:SetGroup((GroupExists(appName, options, path,status.groups.selected) and status.groups.selected) or firstgroup)
|
||||
end
|
||||
|
||||
selectGroup.width = "fill"
|
||||
selectGroup.height = "fill"
|
||||
select.width = "fill"
|
||||
select.height = "fill"
|
||||
|
||||
container:AddChild(selectGroup)
|
||||
container:AddChild(select)
|
||||
|
||||
--assume tree group by default
|
||||
--if parenttype is tree then this group is already a node on that tree
|
||||
@@ -1942,19 +2005,17 @@ end
|
||||
-- convert pre-39 BlizOptions structure to the new format
|
||||
if oldminor and oldminor < 39 and AceConfigDialog.BlizOptions then
|
||||
local old = AceConfigDialog.BlizOptions
|
||||
local newOpt = {}
|
||||
local new = {}
|
||||
for key, widget in pairs(old) do
|
||||
local appName = widget:GetUserData("appName")
|
||||
if not newOpt[appName] then newOpt[appName] = {} end
|
||||
newOpt[appName][key] = widget
|
||||
if not new[appName] then new[appName] = {} end
|
||||
new[appName][key] = widget
|
||||
end
|
||||
AceConfigDialog.BlizOptions = newOpt
|
||||
AceConfigDialog.BlizOptions = new
|
||||
else
|
||||
AceConfigDialog.BlizOptions = AceConfigDialog.BlizOptions or {}
|
||||
end
|
||||
|
||||
AceConfigDialog.BlizOptionsIDMap = AceConfigDialog.BlizOptionsIDMap or {}
|
||||
|
||||
local function FeedToBlizPanel(widget, event)
|
||||
local path = widget:GetUserData("path")
|
||||
AceConfigDialog:Open(widget:GetUserData("appName"), widget, unpack(path or emptyTbl))
|
||||
@@ -1976,17 +2037,15 @@ end
|
||||
-- has to be a head-level note.
|
||||
--
|
||||
-- This function returns a reference to the container frame registered with the Interface
|
||||
-- Options, as well as the registered ID. You can use the ID to open the options with
|
||||
-- the API function `Settings.OpenToCategory`.
|
||||
-- Options. You can use this reference to open the options with the API function
|
||||
-- `InterfaceOptionsFrame_OpenToCategory`.
|
||||
-- @param appName The application name as given to `:RegisterOptionsTable()`
|
||||
-- @param name A descriptive name to display in the options tree (defaults to appName)
|
||||
-- @param parent The parent to use in the interface options tree.
|
||||
-- @param ... The path in the options table to feed into the interface options panel.
|
||||
-- @return The reference to the frame registered into the Interface Options.
|
||||
-- @return The category ID to pass to Settings.OpenToCategory
|
||||
function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
|
||||
local BlizOptions = AceConfigDialog.BlizOptions
|
||||
local BlizOptionsIDMap = AceConfigDialog.BlizOptionsIDMap
|
||||
|
||||
local key = appName
|
||||
for n = 1, select("#", ...) do
|
||||
@@ -2000,6 +2059,7 @@ function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
|
||||
if not BlizOptions[appName][key] then
|
||||
local group = gui:Create("BlizOptionsGroup")
|
||||
BlizOptions[appName][key] = group
|
||||
group:SetName(name or appName, parent)
|
||||
|
||||
group:SetTitle(name or appName)
|
||||
group:SetUserData("appName", appName)
|
||||
@@ -2012,42 +2072,8 @@ function AceConfigDialog:AddToBlizOptions(appName, name, parent, ...)
|
||||
end
|
||||
group:SetCallback("OnShow", FeedToBlizPanel)
|
||||
group:SetCallback("OnHide", ClearBlizPanel)
|
||||
|
||||
local categoryName = name or appName
|
||||
-- CoA-compat: the Settings.* API (GetCategory / RegisterCanvasLayoutCategory /
|
||||
-- RegisterCanvasLayoutSubcategory / RegisterAddOnCategory) is a retail-only
|
||||
-- (Dragonflight+) replacement for the WotLK-era InterfaceOptions_AddCategory.
|
||||
-- On the 3.3.5-based CoA client Settings is nil, so fall back to the legacy API.
|
||||
if Settings and Settings.GetCategory then
|
||||
if parent then
|
||||
local parentID = BlizOptionsIDMap[parent] or parent
|
||||
local category = Settings.GetCategory(parentID)
|
||||
if not category then
|
||||
error(("The parent category '%s' was not found"):format(parent), 2)
|
||||
end
|
||||
local subcategory = Settings.RegisterCanvasLayoutSubcategory(category, group.frame, categoryName)
|
||||
group:SetName(subcategory.ID, parentID)
|
||||
else
|
||||
if BlizOptionsIDMap[categoryName] then
|
||||
error(("%s has already been added to the Blizzard Options Window with the given name: %s"):format(appName, categoryName), 2)
|
||||
end
|
||||
|
||||
local category = Settings.RegisterCanvasLayoutCategory(group.frame, categoryName)
|
||||
if not (C_SettingsUtil and C_SettingsUtil.OpenSettingsPanel) then
|
||||
-- override the ID so the name can be used in Settings.OpenToCategory
|
||||
-- unfortunately with incoming API changes in 12.0 (and likely classic at some point) this override is no longer possible
|
||||
category.ID = categoryName
|
||||
end
|
||||
group:SetName(category.ID)
|
||||
BlizOptionsIDMap[categoryName] = category.ID
|
||||
Settings.RegisterAddOnCategory(category)
|
||||
end
|
||||
else
|
||||
group:SetName(name or appName, parent)
|
||||
InterfaceOptions_AddCategory(group.frame)
|
||||
end
|
||||
|
||||
return group.frame, group.frame.name
|
||||
InterfaceOptions_AddCategory(group.frame)
|
||||
return group.frame
|
||||
else
|
||||
error(("%s has already been added to the Blizzard Options Window with the given path"):format(appName), 2)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user