ElvUI_OptionsUI/Core.lua

443 lines
18 KiB
Lua
Raw Normal View History

2020-11-13 14:29:13 -05:00
local E = unpack(ElvUI) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local D = E:GetModule('Distributor')
local Engine = select(2, ...)
Engine[1] = {}
Engine[2] = E.Libs.ACL:GetLocale('ElvUI', E.global.general.locale)
local C, L = Engine[1], Engine[2]
local _G, format, sort, tinsert, strmatch = _G, format, sort, tinsert, strmatch
C.Values = {
FontFlags = {
NONE = L["NONE"],
OUTLINE = 'Outline',
THICKOUTLINE = 'Thick',
MONOCHROME = '|cffaaaaaaMono|r',
MONOCHROMEOUTLINE = '|cffaaaaaaMono|r Outline',
MONOCHROMETHICKOUTLINE = '|cffaaaaaaMono|r Thick',
},
FontSize = { min = 8, max = 64, step = 1 },
Strata = { BACKGROUND = 'BACKGROUND', LOW = 'LOW', MEDIUM = 'MEDIUM', HIGH = 'HIGH', DIALOG = 'DIALOG', TOOLTIP = 'TOOLTIP' },
GrowthDirection = {
DOWN_RIGHT = format(L["%s and then %s"], L["Down"], L["Right"]),
DOWN_LEFT = format(L["%s and then %s"], L["Down"], L["Left"]),
UP_RIGHT = format(L["%s and then %s"], L["Up"], L["Right"]),
UP_LEFT = format(L["%s and then %s"], L["Up"], L["Left"]),
RIGHT_DOWN = format(L["%s and then %s"], L["Right"], L["Down"]),
RIGHT_UP = format(L["%s and then %s"], L["Right"], L["Up"]),
LEFT_DOWN = format(L["%s and then %s"], L["Left"], L["Down"]),
LEFT_UP = format(L["%s and then %s"], L["Left"], L["Up"]),
}
}
C.StateSwitchGetText = function(_, TEXT)
local friend, enemy = strmatch(TEXT, '^Friendly:([^,]*)'), strmatch(TEXT, '^Enemy:([^,]*)')
local text, blockB, blockS, blockT = friend or enemy or TEXT
local SF, localized = E.global.unitframe.specialFilters[text], L[text]
if SF and localized and text:match('^block') then blockB, blockS, blockT = localized:match('^%[(.-)](%s?)(.+)') end
local filterText = (blockB and format('|cFF999999%s|r%s%s', blockB, blockS, blockT)) or localized or text
return (friend and format('|cFF33FF33%s|r %s', _G.FRIEND, filterText)) or (enemy and format('|cFFFF3333%s|r %s', _G.ENEMY, filterText)) or filterText
end
E:AddLib('AceGUI', 'AceGUI-3.0')
E:AddLib('AceConfig', 'AceConfig-3.0-ElvUI')
E:AddLib('AceConfigDialog', 'AceConfigDialog-3.0-ElvUI')
E:AddLib('AceConfigRegistry', 'AceConfigRegistry-3.0-ElvUI')
E:AddLib('AceDBOptions', 'AceDBOptions-3.0')
E:AddLib('ACH', 'LibAceConfigHelper')
local UnitName = UnitName
local UnitExists = UnitExists
local UnitIsUnit = UnitIsUnit
local UnitIsFriend = UnitIsFriend
local UnitIsPlayer = UnitIsPlayer
local GameTooltip_Hide = GameTooltip_Hide
local GameFontHighlightSmall = _G.GameFontHighlightSmall
local ACH = E.Libs.ACH
--Function we can call on profile change to update GUI
function E:RefreshGUI()
E:RefreshCustomTextsConfigs()
E.Libs.AceConfigRegistry:NotifyChange('ElvUI')
end
E.Libs.AceConfig:RegisterOptionsTable('ElvUI', E.Options)
E.Libs.AceConfigDialog:SetDefaultSize('ElvUI', E:Config_GetDefaultSize())
E.Options.name = format('%s: |cff99ff33%s|r', L["Version"], E.version)
local DONATORS = {
'Dandruff',
'Tobur/Tarilya',
'Netu',
'Alluren',
'Thorgnir',
'Emalal',
'Bendmeova',
'Curl',
'Zarac',
'Emmo',
'Oz',
'Hawké',
'Aynya',
'Tahira',
'Karsten Lumbye Thomsen',
'Thomas B. aka Pitschiqüü',
'Sea Garnet',
'Paul Storry',
'Azagar',
'Archury',
'Donhorn',
'Woodson Harmon',
'Phoenyx',
'Feat',
'Konungr',
'Leyrin',
'Dragonsys',
'Tkalec',
'Paavi',
'Giorgio',
'Bearscantank',
'Eidolic',
'Cosmo',
'Adorno',
'Domoaligato',
'Smorg',
'Pyrokee',
'Portable',
'Ithilyn'
}
local DEVELOPERS = {
'Tukz',
'Haste',
'Nightcracker',
'Omega1970',
'Hydrazine',
'Blazeflack',
'|cff0070DEAzilroka|r',
'|cff9482c9Darth Predator|r',
'|T134297:15:15:0:0:64:64:5:59:5:59|t |cffff7d0aMerathilis|r',
'|TInterface/AddOns/ElvUI/Media/ChatLogos/FoxWarlock:15:15:0:0:64:64:5:59:5:59|t |cffff2020NihilisticPandemonium|r',
E:TextGradient('Simpy but my name needs to be longer.', 0.63,0.40,0.80, 0.63,0.40,0.80, 0.53,0.87,0.19, 0.53,0.87,0.19, 0.20,0.74,0.74, 0.20,0.74,0.74, 0.53,0.87,0.19, 0.53,0.87,0.19, 0.63,0.40,0.80, 0.63,0.40,0.80)
}
local TESTERS = {
'Tukui Community',
'Affinity',
'Modarch',
'Tirain',
'Phima',
'Veiled',
'Repooc',
'Alex',
'Nidra',
'Kurhyus',
'Shrom',
'BuG',
'Kringel',
'Botanica',
'Yachanay',
'Catok',
'|cff00c0faBenik|r',
'|T136012:15:15:0:0:64:64:5:59:5:59|t |cff006fdcRubgrsch|r |T656558:15:15:0:0:64:64:5:59:5:59|t',
'|TInterface/AddOns/ElvUI/Media/ChatLogos/Clover:15:15:0:0:64:64:5:59:5:59|t Luckyone',
'AcidWeb |TInterface/AddOns/ElvUI/Media/ChatLogos/Gem:15:15:-1:2:64:64:6:60:8:60|t',
'|T135167:15:15:0:0:64:64:5:59:5:59|t Loon - For being right',
'|T134297:15:15:0:0:64:64:5:59:5:59|t |cffFF7D0ABladesdruid|r - AKA SUPERBEAR',
}
local function SortList(a, b)
return E:StripString(a) < E:StripString(b)
end
sort(DONATORS, SortList)
sort(DEVELOPERS, SortList)
sort(TESTERS, SortList)
for _, name in pairs(DONATORS) do
tinsert(E.CreditsList, name)
end
local DONATOR_STRING = table.concat(DONATORS, '|n')
for _, name in pairs(DEVELOPERS) do
tinsert(E.CreditsList, name)
end
local DEVELOPER_STRING = table.concat(DEVELOPERS, '|n')
for _, name in pairs(TESTERS) do
tinsert(E.CreditsList, name)
end
local TESTER_STRING = table.concat(TESTERS, '|n')
E.Options.args.info = ACH:Group(L["Information"], nil, 4)
E.Options.args.info.args.header = ACH:Description(L["ELVUI_DESC"], 1, 'medium')
E.Options.args.info.args.spacer = ACH:Spacer(2)
E.Options.args.info.args.support = ACH:Group(L["Support & Download"], nil, 3)
E.Options.args.info.args.support.inline = true
E.Options.args.info.args.support.args.homepage = ACH:Execute(L["Support Forum"], nil, 1, function() E:StaticPopup_Show('ELVUI_EDITBOX', nil, nil, 'https://www.tukui.org/forum/viewforum.php?f=4') end)
E.Options.args.info.args.support.args.homepage.customWidth = 140
E.Options.args.info.args.support.args.git = ACH:Execute(L["Ticket Tracker"], nil, 2, function() E:StaticPopup_Show('ELVUI_EDITBOX', nil, nil, 'https://git.tukui.org/elvui/elvui/issues') end)
E.Options.args.info.args.support.args.git.customWidth = 140
E.Options.args.info.args.support.args.discord = ACH:Execute(L["Discord"], nil, 3, function() E:StaticPopup_Show('ELVUI_EDITBOX', nil, nil, 'https://discordapp.com/invite/xFWcfgE') end)
E.Options.args.info.args.support.args.discord.customWidth = 140
E.Options.args.info.args.support.args.changelog = ACH:Execute(L["Changelog"], nil, 4, function() E:StaticPopup_Show('ELVUI_EDITBOX', nil, nil, 'https://www.tukui.org/download.php?ui=elvui#changelog') end)
E.Options.args.info.args.support.args.changelog.customWidth = 140
E.Options.args.info.args.support.args.development = ACH:Execute(L["Development Version"], L["Link to the latest development version."], 5, function() E:StaticPopup_Show('ELVUI_EDITBOX', nil, nil, 'https://git.tukui.org/elvui/elvui/-/archive/development/elvui-development.zip') end)
E.Options.args.info.args.support.args.development.customWidth = 140
E.Options.args.info.args.credits = ACH:Group(L["Credits"], nil, 4)
E.Options.args.info.args.credits.inline = true
E.Options.args.info.args.credits.args.string = ACH:Description(L["ELVUI_CREDITS"], 1, 'medium')
E.Options.args.info.args.coding = ACH:Group(L["Coding:"], nil, 5)
E.Options.args.info.args.coding.inline = true
E.Options.args.info.args.coding.args.string = ACH:Description(DEVELOPER_STRING, 1, 'medium')
E.Options.args.info.args.testers = ACH:Group(L["Testing:"], nil, 6)
E.Options.args.info.args.testers.inline = true
E.Options.args.info.args.testers.args.string = ACH:Description(TESTER_STRING, 1, 'medium')
E.Options.args.info.args.donators = ACH:Group(L["Donations:"], nil, 7)
E.Options.args.info.args.donators.inline = true
E.Options.args.info.args.donators.args.string = ACH:Description(DONATOR_STRING, 1, 'medium')
local profileTypeItems = { profile = L["Profile"], private = L["Private (Character Settings)"], global = L["Global (Account Settings)"], filters = L["Aura Filters"], styleFilters = L["NamePlate Style Filters"] }
local profileTypeListOrder = { 'profile', 'private', 'global', 'filters', 'styleFilters' }
local exportTypeItems = { text = L["Text"], luaTable = L["Table"], luaPlugin = L["Plugin"] }
local exportTypeListOrder = { 'text', 'luaTable', 'luaPlugin' }
local exportString = ''
local function ExportImport_Open(mode)
local Frame = E.Libs.AceGUI:Create('Frame')
Frame:SetTitle('')
Frame:EnableResize(false)
Frame:SetWidth(800)
Frame:SetHeight(600)
Frame.frame:SetFrameStrata('FULLSCREEN_DIALOG')
Frame:SetLayout('flow')
local Box = E.Libs.AceGUI:Create('MultiLineEditBox-ElvUI')
Box:SetNumLines(30)
Box:DisableButton(true)
Box:SetWidth(800)
Box:SetLabel('')
Frame:AddChild(Box)
--Save original script so we can restore it later
Box.editBox.OnTextChangedOrig = Box.editBox:GetScript('OnTextChanged')
Box.editBox.OnCursorChangedOrig = Box.editBox:GetScript('OnCursorChanged')
--Remove OnCursorChanged script as it causes weird behaviour with long text
Box.editBox:SetScript('OnCursorChanged', nil)
Box.scrollFrame:UpdateScrollChildRect()
local Label1 = E.Libs.AceGUI:Create('Label')
local font = GameFontHighlightSmall:GetFont()
Label1:SetFont(font, 14)
Label1:SetText('.') --Set temporary text so height is set correctly
Label1:SetWidth(800)
Frame:AddChild(Label1)
local Label2 = E.Libs.AceGUI:Create('Label')
font = GameFontHighlightSmall:GetFont()
Label2:SetFont(font, 14)
Label2:SetText('.|n.')
Label2:SetWidth(800)
Frame:AddChild(Label2)
if mode == 'export' then
Frame:SetTitle(L["Export Profile"])
local ProfileTypeDropdown = E.Libs.AceGUI:Create('Dropdown')
ProfileTypeDropdown:SetMultiselect(false)
ProfileTypeDropdown:SetLabel(L["Choose What To Export"])
ProfileTypeDropdown:SetList(profileTypeItems, profileTypeListOrder)
ProfileTypeDropdown:SetValue('profile') --Default export
Frame:AddChild(ProfileTypeDropdown)
local ExportFormatDropdown = E.Libs.AceGUI:Create('Dropdown')
ExportFormatDropdown:SetMultiselect(false)
ExportFormatDropdown:SetLabel(L["Choose Export Format"])
ExportFormatDropdown:SetList(exportTypeItems, exportTypeListOrder)
ExportFormatDropdown:SetValue('text') --Default format
ExportFormatDropdown:SetWidth(150)
Frame:AddChild(ExportFormatDropdown)
local exportButton = E.Libs.AceGUI:Create('Button-ElvUI')
exportButton:SetText(L["Export Now"])
exportButton:SetAutoWidth(true)
exportButton:SetCallback('OnClick', function()
Label1:SetText('')
Label2:SetText('')
local profileType, exportFormat = ProfileTypeDropdown:GetValue(), ExportFormatDropdown:GetValue()
local profileKey, profileExport = D:ExportProfile(profileType, exportFormat)
if not profileKey or not profileExport then
Label1:SetText(L["Error exporting profile!"])
else
Label1:SetText(format('%s: %s%s|r', L["Exported"], E.media.hexvaluecolor, profileTypeItems[profileType]))
if profileType == 'profile' then
Label2:SetText(format('%s: %s%s|r', L["Profile Name"], E.media.hexvaluecolor, profileKey))
end
end
Box:SetText(profileExport)
Box.editBox:HighlightText()
Box:SetFocus()
exportString = profileExport
end)
Frame:AddChild(exportButton)
--Set scripts
Box.editBox:SetScript('OnChar', function()
Box:SetText(exportString)
Box.editBox:HighlightText()
end)
Box.editBox:SetScript('OnTextChanged', function(_, userInput)
if userInput then
--Prevent user from changing export string
Box:SetText(exportString)
Box.editBox:HighlightText()
else
--Scroll frame doesn't scroll to the bottom by itself, so let's do that now
Box.scrollFrame:SetVerticalScroll(Box.scrollFrame:GetVerticalScrollRange())
end
end)
elseif mode == 'import' then
Frame:SetTitle(L["Import Profile"])
local importButton = E.Libs.AceGUI:Create('Button-ElvUI') --This version changes text color on SetDisabled
importButton:SetDisabled(true)
importButton:SetText(L["Import Now"])
importButton:SetAutoWidth(true)
importButton:SetCallback('OnClick', function()
Label1:SetText('')
Label2:SetText('')
local success = D:ImportProfile(Box:GetText())
Label1:SetText((success and L["Profile imported successfully!"]) or L["Error decoding data. Import string may be corrupted!"])
end)
Frame:AddChild(importButton)
local decodeButton = E.Libs.AceGUI:Create('Button-ElvUI')
decodeButton:SetDisabled(true)
decodeButton:SetText(L["Decode Text"])
decodeButton:SetAutoWidth(true)
decodeButton:SetCallback('OnClick', function()
Label1:SetText('')
Label2:SetText('')
local profileType, profileKey, profileData = D:Decode(Box:GetText())
local decodedText = (profileData and E:TableToLuaString(profileData)) or nil
local importText = D:CreateProfileExport(decodedText, profileType, profileKey)
Box:SetText(importText)
end)
Frame:AddChild(decodeButton)
local oldText = ''
local function OnTextChanged()
local text = Box:GetText()
if text == '' then
Label1:SetText('')
Label2:SetText('')
importButton:SetDisabled(true)
decodeButton:SetDisabled(true)
elseif oldText ~= text then
local stringType = D:GetImportStringType(text)
if stringType == 'Base64' then
decodeButton:SetDisabled(false)
else
decodeButton:SetDisabled(true)
end
local profileType, profileKey = D:Decode(text)
if not profileType or (profileType and profileType == 'profile' and not profileKey) then
Label1:SetText(L["Error decoding data. Import string may be corrupted!"])
Label2:SetText('')
importButton:SetDisabled(true)
decodeButton:SetDisabled(true)
else
Label1:SetText(format('%s: %s%s|r', L["Importing"], E.media.hexvaluecolor, profileTypeItems[profileType] or ''))
if profileType == 'profile' then
Label2:SetText(format('%s: %s%s|r', L["Profile Name"], E.media.hexvaluecolor, profileKey))
end
--Scroll frame doesn't scroll to the bottom by itself, so let's do that now
Box.scrollFrame:UpdateScrollChildRect()
Box.scrollFrame:SetVerticalScroll(Box.scrollFrame:GetVerticalScrollRange())
importButton:SetDisabled(false)
end
oldText = text
end
end
Box.editBox:SetFocus()
Box.editBox:SetScript('OnChar', nil)
Box.editBox:SetScript('OnTextChanged', OnTextChanged)
end
Frame:SetCallback('OnClose', function(widget)
--Restore changed scripts
Box.editBox:SetScript('OnChar', nil)
Box.editBox:SetScript('OnTextChanged', Box.editBox.OnTextChangedOrig)
Box.editBox:SetScript('OnCursorChanged', Box.editBox.OnCursorChangedOrig)
Box.editBox.OnTextChangedOrig = nil
Box.editBox.OnCursorChangedOrig = nil
--Clear stored export string
exportString = ''
E.Libs.AceGUI:Release(widget)
E:Config_OpenWindow()
end)
--Clear default text
Label1:SetText('')
Label2:SetText('')
--Close ElvUI OptionsUI
E.Libs.AceConfigDialog:Close('ElvUI')
GameTooltip_Hide() --The tooltip from the Export/Import button stays on screen, so hide it
end
--Create Profiles Table
E.Options.args.profiles = ACH:Group(L["Profiles"], nil, 5, 'tab')
E.Options.args.profiles.args.desc = ACH:Description(L["This feature will allow you to transfer settings to other characters."], 0)
E.Options.args.profiles.args.distributeProfile = ACH:Execute(L["Share Current Profile"], L["Sends your current profile to your target."], 1, function() if not UnitExists('target') or not UnitIsPlayer('target') or not UnitIsFriend('player', 'target') or UnitIsUnit('player', 'target') then E:Print(L["You must be targeting a player."]) return end local name, server = UnitName('target') if name and (not server or server == '') then D:Distribute(name) elseif server then D:Distribute(name, true) end end, nil, nil, nil, nil, nil, function() return not E.global.general.allowDistributor end)
E.Options.args.profiles.args.distributeGlobal = ACH:Execute(L["Share Filters"], L["Sends your filter settings to your target."], 1, function() if not UnitExists('target') or not UnitIsPlayer('target') or not UnitIsFriend('player', 'target') or UnitIsUnit('player', 'target') then E:Print(L["You must be targeting a player."]) return end local name, server = UnitName('target') if name and (not server or server == '') then D:Distribute(name, false, true) elseif server then D:Distribute(name, true, true) end end, nil, nil, nil, nil, nil, function() return not E.global.general.allowDistributor end)
E.Options.args.profiles.args.exportProfile = ACH:Execute(L["Export Profile"], nil, 4, function() ExportImport_Open('export') end)
E.Options.args.profiles.args.importProfile = ACH:Execute(L["Import Profile"], nil, 5, function() ExportImport_Open('import') end)
E.Options.args.profiles.args.allowDistributor = ACH:Toggle(L["Allow Sharing"], L["Both users will need this option enabled."], 6, nil, nil, nil, function() return E.global.general.allowDistributor end, function(_, value) E.global.general.allowDistributor = value; D:UpdateSettings() end)
E.Options.args.profiles.args.spacer = ACH:Spacer(6)
E.Options.args.profiles.args.profile = E.Libs.AceDBOptions:GetOptionsTable(E.data)
E.Options.args.profiles.args.private = E.Libs.AceDBOptions:GetOptionsTable(E.charSettings)
E.Options.args.profiles.args.profile.name = L["Profile"]
E.Options.args.profiles.args.profile.order = 1
E.Options.args.profiles.args.private.name = L["Private"]
E.Options.args.profiles.args.private.order = 2
E.Libs.AceConfig:RegisterOptionsTable('ElvProfiles', E.Options.args.profiles.args.profile)
E.Libs.DualSpec:EnhanceOptions(E.Options.args.profiles.args.profile, E.data)
E.Libs.AceConfig:RegisterOptionsTable('ElvPrivates', E.Options.args.profiles.args.private)
E.Options.args.profiles.args.private.args.choose.confirm = function(info, value)
if info[#info-1] == 'private' then
return format(L["Choosing Settings %s. This will reload the UI.\n\n Are you sure?"], value)
else
return false
end
end
E.Options.args.profiles.args.private.args.copyfrom.confirm = function(info, value)
return format(L["Copy Settings from %s. This will overwrite %s profile.\n\n Are you sure?"], value, info.handler:GetCurrentProfile())
end
if GetAddOnEnableState(nil, 'ElvUI_Config') ~= 0 then
E:StaticPopup_Show('ELVUI_CONFIG_FOUND')
end