PageRenderTime 43ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/ShadowedUF_Options/config.lua

https://bitbucket.org/Ahmil/wowmodmods
Lua | 5522 lines | 5174 code | 262 blank | 86 comment | 417 complexity | 94ca66f69e608f728c52ba0b485f687c MD5 | raw file
  1. local Config = {}
  2. local AceDialog, AceRegistry, AceGUI, SML, registered, options
  3. local playerClass = select(2, UnitClass("player"))
  4. local modifyUnits, globalConfig = {}, {}
  5. local L = ShadowUF.L
  6. ShadowUF.Config = Config
  7. --[[
  8. The part that makes configuration a pain when you actually try is it gets unwieldly when you're adding special code to deal with
  9. showing help for certain cases, swapping tabs etc that makes it work smoothly.
  10. I'm going to have to split it out into separate files for each type to clean everything up but that takes time and I have other things
  11. I want to get done with first.
  12. ]]
  13. local unitCategories = {
  14. player = {"player", "pet"},
  15. general = {"target", "targettarget", "targettargettarget", "focus", "focustarget", "pettarget"},
  16. party = {"party", "partypet", "partytarget"},
  17. raid = {"raid", "raidpet", "boss", "bosstarget", "maintank", "maintanktarget", "mainassist", "mainassisttarget"},
  18. arena = {"arena", "arenapet", "arenatarget"}}
  19. local UNIT_DESC = {
  20. ["boss"] = L["Boss units are for only certain fights, such as Blood Princes or the Gunship battle, you will not see them for every boss fight."],
  21. ["mainassist"] = L["Main Assists's are set by the Blizzard Main Assist system or mods that use them such as oRA3."],
  22. ["maintank"] = L["Main Tank's are set by the Blizzard Main Tank system or mods that use them such as oRA3."],
  23. }
  24. local PAGE_DESC = {
  25. ["general"] = L["General configuration to all enabled units."],
  26. ["enableUnits"] = L["Various units can be enabled through this page, such as raid or party targets."],
  27. ["hideBlizzard"] = L["Hiding and showing various aspects of the default UI such as the player buff frames."],
  28. ["units"] = L["Configuration to specific unit frames."],
  29. ["visibility"] = L["Disabling unit modules in various instances."],
  30. ["tags"] = L["Advanced tag management, allows you to add your own custom tags."],
  31. ["filter"] = L["Simple aura filtering by whitelists and blacklists."],
  32. }
  33. local INDICATOR_NAMES = {["leader"] = L["Leader"], ["lfdRole"] = L["Dungeon role"], ["masterLoot"] = L["Master looter"], ["pvp"] = L["PvP Flag"], ["raidTarget"] = L["Raid target"], ["ready"] = L["Ready status"], ["role"] = L["Raid role"], ["status"] = L["Combat status"], ["class"] = L["Class icon"], ["resurrect"] = L["Resurrect status"], ["phase"] = L["Phase status"]}
  34. local AREA_NAMES = {["arena"] = L["Arenas"],["none"] = L["Everywhere else"], ["party"] = L["Party instances"], ["pvp"] = L["Battlegrounds"], ["raid"] = L["Raid instances"]}
  35. local INDICATOR_DESC = {
  36. ["leader"] = L["Crown indicator for group leaders."], ["lfdRole"] = L["Role the unit is playing in dungeons formed through the Looking For Dungeon system."],
  37. ["masterLoot"] = L["Bag indicator for master looters."], ["pvp"] = L["PVP flag indicator, Horde for Horde flagged pvpers and Alliance for Alliance flagged pvpers."],
  38. ["raidTarget"] = L["Raid target indicator."], ["ready"] = L["Ready status of group members."],
  39. ["role"] = L["Raid role indicator, adds a shield indicator for main tanks and a sword icon for main assists."], ["status"] = L["Status indicator, shows if the unit is currently in combat. For the player it will also show if you are rested."], ["class"] = L["Class icon for players."]}
  40. local TAG_GROUPS = {["classification"] = L["Classifications"], ["health"] = L["Health"], ["misc"] = L["Miscellaneous"], ["playerthreat"] = L["Player threat"], ["power"] = L["Power"], ["status"] = L["Status"], ["threat"] = L["Threat"], ["raid"] = L["Raid"], ["absorb"] = L["Absorb"]}
  41. local pointPositions = {["BOTTOM"] = L["Bottom"], ["TOP"] = L["Top"], ["LEFT"] = L["Left"], ["RIGHT"] = L["Right"], ["TOPLEFT"] = L["Top Left"], ["TOPRIGHT"] = L["Top Right"], ["BOTTOMLEFT"] = L["Bottom Left"], ["BOTTOMRIGHT"] = L["Bottom Right"], ["CENTER"] = L["Center"]}
  42. local positionList = {["C"] = L["Center"], ["RT"] = L["Right Top"], ["RC"] = L["Right Center"], ["RB"] = L["Right Bottom"], ["LT"] = L["Left Top"], ["LC"] = L["Left Center"], ["LB"] = L["Left Bottom"], ["BL"] = L["Bottom Left"], ["BC"] = L["Bottom Center"], ["BR"] = L["Bottom Right"], ["TR"] = L["Top Right"], ["TC"] = L["Top Center"], ["TL"] = L["Top Left"]}
  43. local unitOrder = {}
  44. for order, unit in pairs(ShadowUF.unitList) do unitOrder[unit] = order end
  45. local fullReload = {["bars"] = true, ["auras"] = true, ["backdrop"] = true, ["font"] = true, ["classColors"] = true, ["powerColors"] = true, ["healthColors"] = true, ["xpColors"] = true, ["omnicc"] = true}
  46. local quickIDMap = {}
  47. -- Helper functions
  48. local function getPageDescription(info)
  49. return PAGE_DESC[info[#(info)]]
  50. end
  51. local function getFrameName(unit)
  52. if( unit == "raidpet" or unit == "raid" or unit == "party" or unit == "maintank" or unit == "mainassist" or unit == "boss" or unit == "arena" ) then
  53. return string.format("#SUFHeader%s", unit)
  54. end
  55. return string.format("#SUFUnit%s", unit)
  56. end
  57. local anchorList = {}
  58. local function getAnchorParents(info)
  59. local unit = info[2]
  60. for k in pairs(anchorList) do anchorList[k] = nil end
  61. if( ShadowUF.Units.childUnits[unit] ) then
  62. anchorList["$parent"] = string.format(L["%s member"], L.units[ShadowUF.Units.childUnits[unit]])
  63. return anchorList
  64. end
  65. anchorList["UIParent"] = L["Screen"]
  66. -- Don't let a frame anchor to a frame thats anchored to it already (Stop infinite loops-o-doom)
  67. local currentName = getFrameName(unit)
  68. for _, unitID in pairs(ShadowUF.unitList) do
  69. if( unitID ~= unit and ShadowUF.db.profile.positions[unitID] and ShadowUF.db.profile.positions[unitID].anchorTo ~= currentName ) then
  70. anchorList[getFrameName(unitID)] = string.format(L["%s frames"], L.units[unitID] or unitID)
  71. end
  72. end
  73. return anchorList
  74. end
  75. local function selectDialogGroup(group, key)
  76. AceDialog.Status.ShadowedUF.children[group].status.groups.selected = key
  77. AceRegistry:NotifyChange("ShadowedUF")
  78. end
  79. local function selectTabGroup(group, subGroup, key)
  80. AceDialog.Status.ShadowedUF.children[group].status.groups.selected = subGroup
  81. AceDialog.Status.ShadowedUF.children[group].children[subGroup].status.groups.selected = key
  82. AceRegistry:NotifyChange("ShadowedUF")
  83. end
  84. local function hideAdvancedOption(info)
  85. return not ShadowUF.db.profile.advanced
  86. end
  87. local function hideBasicOption(info)
  88. return ShadowUF.db.profile.advanced
  89. end
  90. local function isUnitDisabled(info)
  91. local unit = info[#(info)]
  92. local enabled = ShadowUF.db.profile.units[unit].enabled
  93. for _, visibility in pairs(ShadowUF.db.profile.visibility) do
  94. if( visibility[unit] ) then
  95. enabled = visibility[unit]
  96. break
  97. end
  98. end
  99. return not enabled
  100. end
  101. local function mergeTables(parent, child)
  102. for key, value in pairs(child) do
  103. if( type(parent[key]) == "table" ) then
  104. parent[key] = mergeTables(parent[key], value)
  105. elseif( type(value) == "table" ) then
  106. parent[key] = CopyTable(value)
  107. elseif( parent[key] == nil ) then
  108. parent[key] = value
  109. end
  110. end
  111. return parent
  112. end
  113. local function getName(info)
  114. local key = info[#(info)]
  115. if( ShadowUF.modules[key] and ShadowUF.modules[key].moduleName ) then
  116. return ShadowUF.modules[key].moduleName
  117. end
  118. return LOCALIZED_CLASS_NAMES_MALE[key] or INDICATOR_NAMES[key] or L.units[key] or TAG_GROUPS[key] or L[key]
  119. end
  120. local function getUnitOrder(info)
  121. return unitOrder[info[#(info)]]
  122. end
  123. local function isModifiersSet(info)
  124. if( info[2] ~= "global" ) then return false end
  125. for k in pairs(modifyUnits) do return false end
  126. return true
  127. end
  128. -- These are for setting simple options like bars.texture = "Default" or locked = true
  129. local function set(info, value)
  130. local cat, key = string.split(".", info.arg)
  131. if( key == "$key" ) then key = info[#(info)] end
  132. if( not key ) then
  133. ShadowUF.db.profile[cat] = value
  134. else
  135. ShadowUF.db.profile[cat][key] = value
  136. end
  137. if( cat and fullReload[cat] ) then
  138. ShadowUF.Layout:CheckMedia()
  139. ShadowUF.Layout:Reload()
  140. end
  141. end
  142. local function get(info)
  143. local cat, key = string.split(".", info.arg)
  144. if( key == "$key" ) then key = info[#(info)] end
  145. if( not key ) then
  146. return ShadowUF.db.profile[cat]
  147. else
  148. return ShadowUF.db.profile[cat][key]
  149. end
  150. end
  151. local function setColor(info, r, g, b, a)
  152. local color = get(info)
  153. color.r, color.g, color.b, color.a = r, g, b, a
  154. set(info, color)
  155. end
  156. local function getColor(info)
  157. local color = get(info)
  158. return color.r, color.g, color.b, color.a
  159. end
  160. -- These are for setting complex options like units.player.auras.buffs.enabled = true or units.player.portrait.enabled = true
  161. local function setVariable(unit, moduleKey, moduleSubKey, key, value)
  162. local configTable = unit == "global" and globalConfig or ShadowUF.db.profile.units[unit]
  163. -- For setting options like units.player.auras.buffs.enabled = true
  164. if( moduleKey and moduleSubKey and configTable[moduleKey][moduleSubKey] ) then
  165. configTable[moduleKey][moduleSubKey][key] = value
  166. ShadowUF.Layout:Reload(unit)
  167. -- For setting options like units.player.portrait.enabled = true
  168. elseif( moduleKey and not moduleSubKey and configTable[moduleKey] ) then
  169. configTable[moduleKey][key] = value
  170. ShadowUF.Layout:Reload(unit)
  171. -- For setting options like units.player.height = 50
  172. elseif( not moduleKey and not moduleSubKey ) then
  173. configTable[key] = value
  174. ShadowUF.Layout:Reload(unit)
  175. end
  176. end
  177. local function specialRestricted(unit, moduleKey, moduleSubKey, key)
  178. if( ShadowUF.fakeUnits[unit] and ( key == "colorAggro" or key == "aggro" or moduleKey == "incHeal" or moduleKey == "castBar" ) ) then
  179. return true
  180. elseif( moduleKey == "healthBar" and unit == "player" and key == "reaction" ) then
  181. return true
  182. end
  183. end
  184. local function setDirectUnit(unit, moduleKey, moduleSubKey, key, value)
  185. if( unit == "global" ) then
  186. for unit in pairs(modifyUnits) do
  187. if( not specialRestricted(unit, moduleKey, moduleSubKey, key) ) then
  188. setVariable(unit, moduleKey, moduleSubKey, key, value)
  189. end
  190. end
  191. setVariable("global", moduleKey, moduleSubKey, key, value)
  192. else
  193. setVariable(unit, moduleKey, moduleSubKey, key, value)
  194. end
  195. end
  196. local function setUnit(info, value)
  197. local unit = info[2]
  198. -- auras, buffs, enabled / text, 1, text / portrait, enabled
  199. local moduleKey, moduleSubKey, key = string.split(".", info.arg)
  200. if( not moduleSubKey ) then key = moduleKey moduleKey = nil end
  201. if( moduleSubKey and not key ) then key = moduleSubKey moduleSubKey = nil end
  202. if( moduleSubKey == "$parent" ) then moduleSubKey = info[#(info) - 1] end
  203. if( moduleKey == "$parent" ) then moduleKey = info[#(info) - 1] end
  204. if( tonumber(moduleSubKey) ) then moduleSubKey = tonumber(moduleSubKey) end
  205. setDirectUnit(unit, moduleKey, moduleSubKey, key, value)
  206. end
  207. local function getVariable(unit, moduleKey, moduleSubKey, key)
  208. local configTbl = unit == "global" and globalConfig or ShadowUF.db.profile.units[unit]
  209. if( moduleKey and moduleSubKey ) then
  210. return configTbl[moduleKey][moduleSubKey] and configTbl[moduleKey][moduleSubKey][key]
  211. elseif( moduleKey and not moduleSubKey ) then
  212. return configTbl[moduleKey] and configTbl[moduleKey][key]
  213. end
  214. return configTbl[key]
  215. end
  216. local function getUnit(info)
  217. local moduleKey, moduleSubKey, key = string.split(".", info.arg)
  218. if( not moduleSubKey ) then key = moduleKey moduleKey = nil end
  219. if( moduleSubKey and not key ) then key = moduleSubKey moduleSubKey = nil end
  220. if( moduleSubKey == "$parent" ) then moduleSubKey = info[#(info) - 1] end
  221. if( moduleKey == "$parent" ) then moduleKey = info[#(info) - 1] end
  222. if( tonumber(moduleSubKey) ) then moduleSubKey = tonumber(moduleSubKey) end
  223. return getVariable(info[2], moduleKey, moduleSubKey, key)
  224. end
  225. -- Tag functions
  226. local function getTagName(info)
  227. local tag = info[#(info)]
  228. if( ShadowUF.db.profile.tags[tag] and ShadowUF.db.profile.tags[tag].name ) then
  229. return ShadowUF.db.profile.tags[tag].name
  230. end
  231. return ShadowUF.Tags.defaultNames[tag] or tag
  232. end
  233. local function getTagHelp(info)
  234. local tag = info[#(info)]
  235. return ShadowUF.Tags.defaultHelp[tag] or ShadowUF.db.profile.tags[tag] and ShadowUF.db.profile.tags[tag].help
  236. end
  237. -- Module functions
  238. local function hideRestrictedOption(info)
  239. local unit = type(info.arg) == "number" and info[#(info) - info.arg] or info[2]
  240. local key = info[#(info)]
  241. if( ShadowUF.modules[key] and ShadowUF.modules[key].moduleClass and ShadowUF.modules[key].moduleClass ~= playerClass ) then
  242. return true
  243. elseif( key == "incHeal" and not ShadowUF.modules.incHeal ) then
  244. return true
  245. -- Non-standard units do not support color by aggro or incoming heal
  246. elseif( key == "colorAggro" or key == "incHeal" or key == "aggro" ) then
  247. return string.match(unit, "%w+target" )
  248. -- Fall back for indicators, no variable table so it shouldn't be shown
  249. elseif( info[#(info) - 1] == "indicators" ) then
  250. if( ( unit == "global" and not globalConfig.indicators[key] ) or ( unit ~= "global" and not ShadowUF.db.profile.units[unit].indicators[key] ) ) then
  251. return true
  252. end
  253. -- Fall back, no variable table so it shouldn't be shown
  254. elseif( ( unit == "global" and not globalConfig[key] ) or ( unit ~= "global" and not ShadowUF.db.profile.units[unit][key] ) ) then
  255. return true
  256. end
  257. return false
  258. end
  259. local function getModuleOrder(info)
  260. local key = info[#(info)]
  261. return key == "healthBar" and 1 or key == "powerBar" and 2 or key == "castBar" and 3 or 4
  262. end
  263. -- Expose these for modules
  264. Config.getAnchorParents = getAnchorParents
  265. Config.hideAdvancedOption = hideAdvancedOption
  266. Config.isUnitDisabled = isUnitDisabled
  267. Config.selectDialogGroup = selectDialogGroup
  268. Config.selectTabGroup = selectTabGroup
  269. Config.getName = getName
  270. Config.getUnitOrder = getUnitOrder
  271. Config.isModifiersSet = isModifiersSet
  272. Config.set = set
  273. Config.get = get
  274. Config.setUnit = setUnit
  275. Config.setVariable = setVariable
  276. Config.getUnit = getUnit
  277. Config.getVariable = getVariable
  278. Config.hideRestrictedOption = hideRestrictedOption
  279. Config.hideBasicOption = hideBasicOption
  280. --------------------
  281. -- GENERAL CONFIGURATION
  282. ---------------------
  283. local function loadGeneralOptions()
  284. SML = SML or LibStub:GetLibrary("LibSharedMedia-3.0")
  285. local MediaList = {}
  286. local function getMediaData(info)
  287. local mediaType = info[#(info)]
  288. MediaList[mediaType] = MediaList[mediaType] or {}
  289. for k in pairs(MediaList[mediaType]) do MediaList[mediaType][k] = nil end
  290. for _, name in pairs(SML:List(mediaType)) do
  291. MediaList[mediaType][name] = name
  292. end
  293. return MediaList[mediaType]
  294. end
  295. local barModules = {}
  296. for key, module in pairs(ShadowUF.modules) do
  297. if( module.moduleHasBar ) then
  298. barModules["$" .. key] = module.moduleName
  299. end
  300. end
  301. local addTextParent = {
  302. order = 4,
  303. type = "group",
  304. inline = true,
  305. name = function(info) return barModules[info[#(info)]] or string.sub(info[#(info)], 2) end,
  306. hidden = function(info)
  307. for _, text in pairs(ShadowUF.db.profile.units.player.text) do
  308. if( text.anchorTo == info[#(info)] ) then
  309. return false
  310. end
  311. end
  312. return true
  313. end,
  314. args = {},
  315. }
  316. local addTextLabel = {
  317. order = function(info) return tonumber(string.match(info[#(info)], "(%d+)")) end,
  318. type = "description",
  319. width = "",
  320. fontSize = "medium",
  321. hidden = function(info)
  322. local id = tonumber(string.match(info[#(info)], "(%d+)"))
  323. if( not getVariable("player", "text", nil, id) ) then return true end
  324. return getVariable("player", "text", id, "anchorTo") ~= info[#(info) - 1]
  325. end,
  326. name = function(info)
  327. return getVariable("player", "text", tonumber(string.match(info[#(info)], "(%d+)")), "name")
  328. end,
  329. }
  330. local addTextSep = {
  331. order = function(info) return tonumber(string.match(info[#(info)], "(%d+)")) + 0.75 end,
  332. type = "description",
  333. width = "full",
  334. hidden = function(info)
  335. local id = tonumber(string.match(info[#(info)], "(%d+)"))
  336. if( not getVariable("player", "text", nil, id) ) then return true end
  337. return getVariable("player", "text", id, "anchorTo") ~= info[#(info) - 1]
  338. end,
  339. name = "",
  340. }
  341. local addText = {
  342. order = function(info) return info[#(info)] + 0.5 end,
  343. type = "execute",
  344. width = "half",
  345. name = L["Delete"],
  346. hidden = function(info)
  347. local id = tonumber(info[#(info)])
  348. if( not getVariable("player", "text", nil, id) ) then return true end
  349. return getVariable("player", "text", id, "anchorTo") ~= info[#(info) - 1]
  350. end,
  351. disabled = function(info) return tonumber(info[#(info)]) <= 5 end,
  352. confirmText = L["Are you sure you want to delete this text? All settings for it will be deleted."],
  353. confirm = true,
  354. func = function(info)
  355. local id = tonumber(info[#(info)])
  356. for _, unit in pairs(ShadowUF.unitList) do
  357. table.remove(ShadowUF.db.profile.units[unit].text, id)
  358. end
  359. addTextParent.args[info[#(info)]] = nil
  360. ShadowUF.Layout:Reload()
  361. end,
  362. }
  363. local function validateSpell(info, spell)
  364. if( spell and spell ~= "" and not GetSpellInfo(spell) ) then
  365. return string.format(L["Invalid spell \"%s\" entered."], spell or "")
  366. end
  367. return true
  368. end
  369. local function setRange(info, spell)
  370. ShadowUF.db.profile.range[info[#(info)] .. playerClass] = spell and spell ~= "" and spell or nil
  371. ShadowUF.Layout:Reload()
  372. end
  373. local function getRange(info, spell)
  374. local spell = ShadowUF.db.profile.range[info[#(info)] .. playerClass]
  375. return spell and spell ~= "" and spell or ShadowUF.modules.range[info[#(info)]][playerClass]
  376. end
  377. local textData = {}
  378. local function writeTable(tbl)
  379. local data = ""
  380. for key, value in pairs(tbl) do
  381. local valueType = type(value)
  382. -- Wrap the key in brackets if it's a number
  383. if( type(key) == "number" ) then
  384. key = string.format("[%s]", key)
  385. -- Wrap the string with quotes if it has a space in it
  386. elseif( string.match(key, "[%p%s%c]") ) then
  387. key = string.format("['%s']", string.gsub(key, "'", "\\'"))
  388. end
  389. -- foo = {bar = 5}
  390. if( valueType == "table" ) then
  391. data = string.format("%s%s=%s;", data, key, writeTable(value))
  392. -- foo = true / foo = 5
  393. elseif( valueType == "number" or valueType == "boolean" ) then
  394. data = string.format("%s%s=%s;", data, key, tostring(value))
  395. -- foo = "bar"
  396. else
  397. data = string.format("%s%s='%s';", data, key, string.gsub(tostring(value), "'", "\\'"))
  398. end
  399. end
  400. return "{" .. data .. "}"
  401. end
  402. local layoutData = {positions = true, visibility = true, modules = false}
  403. local layoutManager = {
  404. type = "group",
  405. order = 7,
  406. name = L["Layout manager"],
  407. childGroups = "tab",
  408. hidden = hideAdvancedOption,
  409. args = {
  410. import = {
  411. order = 1,
  412. type = "group",
  413. name = L["Import"],
  414. hidden = false,
  415. args = {
  416. help = {
  417. order = 1,
  418. type = "group",
  419. inline = true,
  420. name = function(info) return layoutData.error and L["Error"] or L["Help"] end,
  421. args = {
  422. help = {
  423. order = 1,
  424. type = "description",
  425. name = function(info)
  426. if( ShadowUF.db:GetCurrentProfile() == "Import Backup" ) then
  427. return L["Your active layout is the profile used for import backup, this cannot be overwritten by an import. Change your profiles to something else and try again."]
  428. end
  429. return layoutData.error or L["You can import another Shadowed Unit Frame users configuration by entering the export code they gave you below. This will backup your old layout to \"Import Backup\".|n|nIt will take 30-60 seconds for it to load your layout when you paste it in, please by patient."]
  430. end
  431. },
  432. },
  433. },
  434. positions = {
  435. order = 2,
  436. type = "toggle",
  437. name = L["Import unit frame positions"],
  438. set = function(info, value) layoutData[info[#(info)]] = value end,
  439. get = function(info) return layoutData[info[#(info)]] end,
  440. width = "double",
  441. },
  442. visibility = {
  443. order = 3,
  444. type = "toggle",
  445. name = L["Import visibility settings"],
  446. set = function(info, value) layoutData[info[#(info)]] = value end,
  447. get = function(info) return layoutData[info[#(info)]] end,
  448. width = "double",
  449. },
  450. modules = {
  451. order = 4,
  452. type = "toggle",
  453. name = L["Import non-standard module settings"],
  454. desc = L["Will not import settings of modules that are not included with Shadowed Unit Frames by default."],
  455. set = function(info, value) layoutData[info[#(info)]] = value end,
  456. get = function(info) return layoutData[info[#(info)]] end,
  457. width = "double",
  458. },
  459. import = {
  460. order = 5,
  461. type = "input",
  462. name = L["Code"],
  463. multiline = true,
  464. width = "full",
  465. get = false,
  466. disabled = function() return ShadowUF.db:GetCurrentProfile() == "Import Backup" end,
  467. set = function(info, import)
  468. local layout, err = loadstring(string.format([[return %s]], import))
  469. if( err ) then
  470. layoutData.error = string.format(L["Failed to import layout, error:|n|n%s"], err)
  471. return
  472. end
  473. layout = layout()
  474. -- Strip position settings
  475. if( not layoutData.positions ) then
  476. layout.positions = nil
  477. end
  478. -- Strip visibility settings
  479. if( not layoutData.visibility ) then
  480. layout.visibility = nil
  481. end
  482. -- Strip any units we don't have included by default
  483. for unit in pairs(layout.units) do
  484. if( not ShadowUF.defaults.profile.units[unit] ) then
  485. layout.units[unit] = nil
  486. end
  487. end
  488. -- Strip module settings that aren't with SUF by default
  489. if( not layoutData.modules ) then
  490. local validModules = {["healthBar"] = true, ["powerBar"] = true, ["portrait"] = true, ["range"] = true, ["text"] = true, ["indicators"] = true, ["auras"] = true, ["incHeal"] = true, ["castBar"] = true, ["combatText"] = true, ["highlight"] = true, ["runeBar"] = true, ["totemBar"] = true, ["xpBar"] = true, ["fader"] = true, ["comboPoints"] = true, ["eclipseBar"] = true, ["soulShards"] = true, ["holyPower"] = true, ["altPowerBar"] = true}
  491. for _, unitData in pairs(layout.units) do
  492. for key, data in pairs(unitData) do
  493. if( type(data) == "table" and not validModules[key] and ShadowUF.modules[key] ) then
  494. unitData[key] = nil
  495. end
  496. end
  497. end
  498. end
  499. -- Check if we need move over the visibility and positions info
  500. layout.positions = layout.positions or CopyTable(ShadowUF.db.profile.positions)
  501. layout.visibility = layout.visibility or CopyTable(ShadowUF.db.profile.positions)
  502. -- Now backup the profile
  503. local currentLayout = ShadowUF.db:GetCurrentProfile()
  504. ShadowUF.layoutImporting = true
  505. ShadowUF.db:SetProfile("Import Backup")
  506. ShadowUF.db:CopyProfile(currentLayout)
  507. ShadowUF.db:SetProfile(currentLayout)
  508. ShadowUF.db:ResetProfile()
  509. ShadowUF.layoutImporting = nil
  510. -- Overwrite everything we did import
  511. ShadowUF:LoadDefaultLayout()
  512. for key, data in pairs(layout) do
  513. if( type(data) == "table" ) then
  514. ShadowUF.db.profile[key] = CopyTable(data)
  515. else
  516. ShadowUF.db.profile[key] = data
  517. end
  518. end
  519. ShadowUF:ProfilesChanged()
  520. end,
  521. },
  522. },
  523. },
  524. export = {
  525. order = 2,
  526. type = "group",
  527. name = L["Export"],
  528. hidden = false,
  529. args = {
  530. help = {
  531. order = 1,
  532. type = "group",
  533. inline = true,
  534. name = L["Help"],
  535. args = {
  536. help = {
  537. order = 1,
  538. type = "description",
  539. name = L["After you hit export, you can give the below code to other Shadowed Unit Frames users and they will get your exact layout."],
  540. },
  541. },
  542. },
  543. doExport = {
  544. order = 2,
  545. type = "execute",
  546. name = L["Export"],
  547. func = function(info)
  548. layoutData.export = writeTable(ShadowUF.db.profile)
  549. end,
  550. },
  551. export = {
  552. order = 3,
  553. type = "input",
  554. name = L["Code"],
  555. multiline = true,
  556. width = "full",
  557. set = false,
  558. get = function(info) return layoutData[info[#(info)]] end,
  559. },
  560. },
  561. },
  562. },
  563. }
  564. options.args.general = {
  565. type = "group",
  566. childGroups = "tab",
  567. name = L["General"],
  568. args = {
  569. general = {
  570. type = "group",
  571. order = 1,
  572. name = L["General"],
  573. set = set,
  574. get = get,
  575. args = {
  576. general = {
  577. order = 1,
  578. type = "group",
  579. inline = true,
  580. name = L["General"],
  581. args = {
  582. locked = {
  583. order = 1,
  584. type = "toggle",
  585. name = L["Lock frames"],
  586. desc = L["Enables configuration mode, letting you move and giving you example frames to setup."],
  587. set = function(info, value)
  588. set(info, value)
  589. ShadowUF.modules.movers:Update()
  590. end,
  591. arg = "locked",
  592. },
  593. sep = {
  594. order = 1.5,
  595. type = "description",
  596. name = "",
  597. width = "full",
  598. hidden = hideAdvancedOption,
  599. },
  600. advanced = {
  601. order = 2,
  602. type = "toggle",
  603. name = L["Advanced"],
  604. desc = L["Enabling advanced settings will give you access to more configuration options. This is meant for people who want to tweak every single thing, and should not be enabled by default as it increases the options."],
  605. arg = "advanced",
  606. },
  607. omnicc = {
  608. order = 2.5,
  609. type = "toggle",
  610. name = L["Disable OmniCC"],
  611. desc = L["Disables showing OmniCC timers in all Shadowed Unit Frame auras."],
  612. arg = "omnicc",
  613. hidden = hideAdvancedOption,
  614. },
  615. hideCombat = {
  616. order = 3,
  617. type = "toggle",
  618. name = L["Hide tooltips in combat"],
  619. desc = L["Prevents unit tooltips from showing while in combat."],
  620. arg = "tooltipCombat",
  621. },
  622. auraBorder = {
  623. order = 5,
  624. type = "select",
  625. name = L["Aura border style"],
  626. desc = L["Style of borders to show for all auras."],
  627. values = {["dark"] = L["Dark"], ["light"] = L["Light"], ["blizzard"] = L["Blizzard"], [""] = L["None"]},
  628. arg = "auras.borderType",
  629. },
  630. statusbar = {
  631. order = 6,
  632. type = "select",
  633. name = L["Bar texture"],
  634. dialogControl = "LSM30_Statusbar",
  635. values = getMediaData,
  636. arg = "bars.texture",
  637. },
  638. spacing = {
  639. order = 7,
  640. type = "range",
  641. name = L["Bar spacing"],
  642. desc = L["How much spacing should be provided between all of the bars inside a unit frame, negative values move them farther apart, positive values bring them closer together. 0 for no spacing."],
  643. min = -10, max = 10, step = 0.05, softMin = -5, softMax = 5,
  644. arg = "bars.spacing",
  645. hidden = hideAdvancedOption,
  646. },
  647. },
  648. },
  649. backdrop = {
  650. order = 2,
  651. type = "group",
  652. inline = true,
  653. name = L["Background/border"],
  654. args = {
  655. backgroundColor = {
  656. order = 1,
  657. type = "color",
  658. name = L["Background color"],
  659. hasAlpha = true,
  660. set = setColor,
  661. get = getColor,
  662. arg = "backdrop.backgroundColor",
  663. },
  664. borderColor = {
  665. order = 2,
  666. type = "color",
  667. name = L["Border color"],
  668. hasAlpha = true,
  669. set = setColor,
  670. get = getColor,
  671. arg = "backdrop.borderColor",
  672. },
  673. sep = {
  674. order = 3,
  675. type = "description",
  676. name = "",
  677. width = "full",
  678. },
  679. background = {
  680. order = 4,
  681. type = "select",
  682. name = L["Background"],
  683. dialogControl = "LSM30_Background",
  684. values = getMediaData,
  685. arg = "backdrop.backgroundTexture",
  686. },
  687. border = {
  688. order = 5,
  689. type = "select",
  690. name = L["Border"],
  691. dialogControl = "LSM30_Border",
  692. values = getMediaData,
  693. arg = "backdrop.borderTexture",
  694. },
  695. inset = {
  696. order = 5.5,
  697. type = "range",
  698. name = L["Inset"],
  699. desc = L["How far the background should be from the unit frame border."],
  700. min = -10, max = 10, step = 1,
  701. hidden = hideAdvancedOption,
  702. arg = "backdrop.inset",
  703. },
  704. sep2 = {
  705. order = 6,
  706. type = "description",
  707. name = "",
  708. width = "full",
  709. hidden = hideAdvancedOption,
  710. },
  711. edgeSize = {
  712. order = 7,
  713. type = "range",
  714. name = L["Edge size"],
  715. desc = L["How large the edges should be."],
  716. hidden = hideAdvancedOption,
  717. min = 0, max = 20, step = 1,
  718. arg = "backdrop.edgeSize",
  719. },
  720. tileSize = {
  721. order = 8,
  722. type = "range",
  723. name = L["Tile size"],
  724. desc = L["How large the background should tile"],
  725. hidden = hideAdvancedOption,
  726. min = 0, max = 20, step = 1,
  727. arg = "backdrop.tileSize",
  728. },
  729. clip = {
  730. order = 9,
  731. type = "range",
  732. name = L["Clip"],
  733. desc = L["How close the frame should clip with the border."],
  734. hidden = hideAdvancedOption,
  735. min = 0, max = 20, step = 1,
  736. arg = "backdrop.clip",
  737. },
  738. },
  739. },
  740. font = {
  741. order = 3,
  742. type = "group",
  743. inline = true,
  744. name = L["Font"],
  745. args = {
  746. color = {
  747. order = 1,
  748. type = "color",
  749. name = L["Default color"],
  750. desc = L["Default font color, any color tags inside individual tag texts will override this."],
  751. hasAlpha = true,
  752. set = setColor,
  753. get = getColor,
  754. arg = "font.color",
  755. hidden = hideAdvancedOption,
  756. },
  757. sep = {order = 1.25, type = "description", name = "", hidden = hideAdvancedOption},
  758. font = {
  759. order = 1.5,
  760. type = "select",
  761. name = L["Font"],
  762. dialogControl = "LSM30_Font",
  763. values = getMediaData,
  764. arg = "font.name",
  765. },
  766. size = {
  767. order = 2,
  768. type = "range",
  769. name = L["Size"],
  770. min = 1, max = 50, step = 1, softMin = 1, softMax = 20,
  771. arg = "font.size",
  772. },
  773. outline = {
  774. order = 3,
  775. type = "select",
  776. name = L["Outline"],
  777. values = {["OUTLINE"] = L["Thin outline"], ["THICKOUTLINE"] = L["Thick outline"], ["MONOCHROME"] = L["Monochrome"], [""] = L["None"]},
  778. arg = "font.extra",
  779. hidden = hideAdvancedOption,
  780. },
  781. },
  782. },
  783. bar = {
  784. order = 4,
  785. type = "group",
  786. inline = true,
  787. name = L["Bars"],
  788. hidden = hideAdvancedOption,
  789. args = {
  790. override = {
  791. order = 0,
  792. type = "toggle",
  793. name = L["Override color"],
  794. desc = L["Forces a static color to be used for the background of all bars"],
  795. set = function(info, value)
  796. if( value and not ShadowUF.db.profile.bars.backgroundColor ) then
  797. ShadowUF.db.profile.bars.backgroundColor = {r = 0, g = 0, b = 0}
  798. elseif( not value ) then
  799. ShadowUF.db.profile.bars.backgroundColor = nil
  800. end
  801. ShadowUF.Layout:Reload()
  802. end,
  803. get = function(info)
  804. return ShadowUF.db.profile.bars.backgroundColor and true or false
  805. end,
  806. },
  807. color = {
  808. order = 1,
  809. type = "color",
  810. name = L["Background color"],
  811. desc = L["This will override all background colorings for bars including custom set ones."],
  812. set = setColor,
  813. get = function(info)
  814. if( not ShadowUF.db.profile.bars.backgroundColor ) then
  815. return {r = 0, g = 0, b = 0}
  816. end
  817. return getColor(info)
  818. end,
  819. disabled = function(info) return not ShadowUF.db.profile.bars.backgroundColor end,
  820. arg = "bars.backgroundColor",
  821. },
  822. sep = { order = 2, type = "description", name = "", width = "full"},
  823. barAlpha = {
  824. order = 3,
  825. type = "range",
  826. name = L["Bar alpha"],
  827. desc = L["Alpha to use for bar."],
  828. arg = "bars.alpha",
  829. min = 0, max = 1, step = 0.05,
  830. isPercent = true
  831. },
  832. backgroundAlpha = {
  833. order = 4,
  834. type = "range",
  835. name = L["Background alpha"],
  836. desc = L["Alpha to use for bar backgrounds."],
  837. arg = "bars.backgroundAlpha",
  838. min = 0, max = 1, step = 0.05,
  839. isPercent = true
  840. },
  841. },
  842. },
  843. range = {
  844. order = 5,
  845. type = "group",
  846. inline = true,
  847. name = L["Range spells"],
  848. args = {
  849. friendly = {
  850. order = 0,
  851. type = "input",
  852. name = L["Friendly spell"],
  853. desc = L["Name of a friendly spell to check range on friendlies.|n|nThis is automatically set for your current class only."],
  854. validate = validateSpell,
  855. set = setRange,
  856. get = getRange,
  857. },
  858. hostile = {
  859. order = 1,
  860. type = "input",
  861. name = L["Hostile spell"],
  862. desc = L["Name of a hostile spell to check range on enemies.|n|nThis is automatically set for your current class only."],
  863. validate = validateSpell,
  864. set = setRange,
  865. get = getRange,
  866. },
  867. },
  868. },
  869. },
  870. },
  871. color = {
  872. order = 2,
  873. type = "group",
  874. name = L["Colors"],
  875. args = {
  876. health = {
  877. order = 1,
  878. type = "group",
  879. inline = true,
  880. name = L["Health"],
  881. set = setColor,
  882. get = getColor,
  883. args = {
  884. green = {
  885. order = 1,
  886. type = "color",
  887. name = L["High health"],
  888. desc = L["Health bar color used as the transitional color for 100% -> 50% on players, as well as when your pet is happy."],
  889. arg = "healthColors.green",
  890. },
  891. yellow = {
  892. order = 2,
  893. type = "color",
  894. name = L["Half health"],
  895. desc = L["Health bar color used as the transitional color for 100% -> 0% on players, as well as when your pet is mildly unhappy."],
  896. arg = "healthColors.yellow",
  897. },
  898. red = {
  899. order = 3,
  900. type = "color",
  901. name = L["Low health"],
  902. desc = L["Health bar color used as the transitional color for 50% -> 0% on players, as well as when your pet is very unhappy."],
  903. arg = "healthColors.red",
  904. },
  905. friendly = {
  906. order = 4,
  907. type = "color",
  908. name = L["Friendly"],
  909. desc = L["Health bar color for friendly units."],
  910. arg = "healthColors.friendly",
  911. },
  912. neutral = {
  913. order = 5,
  914. type = "color",
  915. name = L["Neutral"],
  916. desc = L["Health bar color for neutral units."],
  917. arg = "healthColors.neutral",
  918. },
  919. hostile = {
  920. order = 6,
  921. type = "color",
  922. name = L["Hostile"],
  923. desc = L["Health bar color for hostile units."],
  924. arg = "healthColors.hostile",
  925. },
  926. static = {
  927. order = 7,
  928. type = "color",
  929. name = L["Static"],
  930. desc = L["Color to use for health bars that are set to be colored by a static color."],
  931. arg = "healthColors.static",
  932. },
  933. inc = {
  934. order = 8,
  935. type = "color",
  936. name = L["Incoming heal"],
  937. desc = L["Health bar color to use to show how much healing someone is about to receive."],
  938. arg = "healthColors.inc",
  939. },
  940. enemyUnattack = {
  941. order = 9,
  942. type = "color",
  943. name = L["Unattackable hostile"],
  944. desc = L["Health bar color to use for hostile units who you cannot attack, used for reaction coloring."],
  945. hidden = hideAdvancedOption,
  946. arg = "healthColors.enemyUnattack",
  947. }
  948. },
  949. },
  950. power = {
  951. order = 2,
  952. type = "group",
  953. inline = true,
  954. name = L["Power"],
  955. set = setColor,
  956. get = getColor,
  957. args = {
  958. MANA = {
  959. order = 0,
  960. type = "color",
  961. name = L["Mana"],
  962. hasAlpha = true,
  963. width = "half",
  964. arg = "powerColors.MANA",
  965. },
  966. RAGE = {
  967. order = 1,
  968. type = "color",
  969. name = L["Rage"],
  970. hasAlpha = true,
  971. width = "half",
  972. arg = "powerColors.RAGE",
  973. },
  974. FOCUS = {
  975. order = 2,
  976. type = "color",
  977. name = L["Focus"],
  978. hasAlpha = true,
  979. arg = "powerColors.FOCUS",
  980. width = "half",
  981. },
  982. ENERGY = {
  983. order = 3,
  984. type = "color",
  985. name = L["Energy"],
  986. hasAlpha = true,
  987. arg = "powerColors.ENERGY",
  988. width = "half",
  989. },
  990. RUNIC_POWER = {
  991. order = 6,
  992. type = "color",
  993. name = L["Runic Power"],
  994. hasAlpha = true,
  995. arg = "powerColors.RUNIC_POWER",
  996. },
  997. ECLIPSE_MOON = {
  998. order = 7,
  999. type = "color",
  1000. name = L["Eclipse (Moon)"],
  1001. desc = L["Bar coloring for the moon portion of the eclipse bar."],
  1002. hidden = function(info) return select(2, UnitClass("player")) ~= "DRUID" end,
  1003. hasAlpha = true,
  1004. arg = "powerColors.ECLIPSE_MOON",
  1005. },
  1006. ECLIPSE_SUN = {
  1007. order = 8,
  1008. type = "color",
  1009. name = L["Eclipse (Sun)"],
  1010. desc = L["Bar coloring for the moon portion of the eclipse bar."],
  1011. hidden = function(info) return select(2, UnitClass("player")) ~= "DRUID" end,
  1012. hasAlpha = true,
  1013. arg = "powerColors.ECLIPSE_SUN",
  1014. },
  1015. AMMOSLOT = {
  1016. order = 9,
  1017. type = "color",
  1018. name = L["Ammo"],
  1019. hasAlpha = true,
  1020. arg = "powerColors.AMMOSLOT",
  1021. hidden = hideAdvancedOption,
  1022. },
  1023. FUEL = {
  1024. order = 10,
  1025. type = "color",
  1026. name = L["Fuel"],
  1027. hasAlpha = true,
  1028. arg = "powerColors.FUEL",
  1029. hidden = hideAdvancedOption,
  1030. },
  1031. COMBOPOINTS = {
  1032. order = 11,
  1033. type = "color",
  1034. name = L["Combo points"],
  1035. hasAlpha = true,
  1036. arg = "powerColors.COMBOPOINTS",
  1037. },
  1038. HOLYPOWER = {
  1039. order = 12,
  1040. type = "color",
  1041. name = L["Holy Power"],
  1042. hasAlpha = true,
  1043. arg = "powerColors.HOLYPOWER",
  1044. hidden = function(info) return select(2, UnitClass("player")) ~= "PALADIN" end,
  1045. },
  1046. SOULSHARDS = {
  1047. order = 13,
  1048. type = "color",
  1049. name = L["Soul Shards"],
  1050. hasAlpha = true,
  1051. arg = "powerColors.SOULSHARDS",
  1052. hidden = function(info) return select(2, UnitClass("player")) ~= "WARLOCK" end,
  1053. },
  1054. },
  1055. },
  1056. cast = {
  1057. order = 3,
  1058. type = "group",
  1059. inline = true,
  1060. name = L["Cast"],
  1061. set = setColor,
  1062. get = getColor,
  1063. args = {
  1064. cast = {
  1065. order = 0,
  1066. type = "color",
  1067. name = L["Casting"],
  1068. desc = L["Color used when an unit is casting a spell."],
  1069. arg = "castColors.cast",
  1070. },
  1071. channel = {
  1072. order = 1,
  1073. type = "color",
  1074. name = L["Channelling"],
  1075. desc = L["Color used when a cast is a channel."],
  1076. arg = "castColors.channel",
  1077. },
  1078. sep = {
  1079. order = 2,
  1080. type = "description",
  1081. name = "",
  1082. hidden = hideAdvancedOption,
  1083. width = "full",
  1084. },
  1085. finished = {
  1086. order = 3,
  1087. type = "color",
  1088. name = L["Finished cast"],
  1089. desc = L["Color used when a cast is successfully finished."],
  1090. hidden = hideAdvancedOption,
  1091. arg = "castColors.finished",
  1092. },
  1093. interrupted = {
  1094. order = 4,
  1095. type = "color",
  1096. name = L["Cast interrupted"],
  1097. desc = L["Color used when a cast is interrupted either by the caster themselves or by another unit."],
  1098. hidden = hideAdvancedOption,
  1099. arg = "castColors.interrupted",
  1100. },
  1101. uninterruptible = {
  1102. order = 5,
  1103. type = "color",
  1104. name = L["Cast uninterruptible"],
  1105. desc = L["Color used when a cast cannot be interrupted, this is only used for PvE mobs."],
  1106. arg = "castColors.uninterruptible",
  1107. },
  1108. },
  1109. },
  1110. auras = {
  1111. order = 3.5,
  1112. type = "group",
  1113. inline = true,
  1114. name = L["Aura borders"],
  1115. set = setColor,
  1116. get = getColor,
  1117. hidden = hideAdvancedOption,
  1118. args = {
  1119. removableColor = {
  1120. order = 0,
  1121. type = "color",
  1122. name = L["Stealable or Removable"],
  1123. desc = L["Border coloring of stealable or removable auras."],
  1124. arg = "auraColors.removable",
  1125. }
  1126. }
  1127. },
  1128. classColors = {
  1129. order = 4,
  1130. type = "group",
  1131. inline = true,
  1132. name = L["Classes"],
  1133. set = setColor,
  1134. get = getColor,
  1135. args = {}
  1136. },
  1137. },
  1138. },
  1139. profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(ShadowUF.db, true),
  1140. text = {
  1141. type = "group",
  1142. order = 6,
  1143. name = L["Text management"],
  1144. hidden = false,
  1145. args = {
  1146. help = {
  1147. order = 0,
  1148. type = "group",
  1149. inline = true,
  1150. name = L["Help"],
  1151. args = {
  1152. help = {
  1153. order = 0,
  1154. type = "description",
  1155. name = L["You can add additional text with tags enabled using this configuration, note that any additional text added (or removed) effects all units, removing text will reset their settings as well.|n|nKeep in mind, you cannot delete the default text included with the units."],
  1156. },
  1157. },
  1158. },
  1159. add = {
  1160. order = 1,
  1161. name = L["Add new text"],
  1162. inline = true,
  1163. type = "group",
  1164. set = function(info, value) textData[info[#(info)] ] = value end,
  1165. get = function(info, value) return textData[info[#(info)] ] end,
  1166. args = {
  1167. name = {
  1168. order = 0,
  1169. type = "input",
  1170. name = L["Text name"],
  1171. desc = L["Text name that you can use to identify this text from others when configuring."],
  1172. },
  1173. parent = {
  1174. order = 1,
  1175. type = "select",
  1176. name = L["Text parent"],
  1177. desc = L["Where inside the frame the text should be anchored to."],
  1178. values = barModules,
  1179. },
  1180. add = {
  1181. order = 2,
  1182. type = "execute",
  1183. name = L["Add"],
  1184. disabled = function() return not textData.name or textData.name == "" or not textData.parent end,
  1185. func = function(info)
  1186. -- Verify we entered a good name
  1187. textData.name = string.trim(textData.name)
  1188. textData.name = textData.name ~= "" and textData.name or nil
  1189. -- Add the new entry
  1190. for _, unit in pairs(ShadowUF.unitList) do
  1191. table.insert(ShadowUF.db.profile.units[unit].text, {enabled = true, name = textData.name or "??", text = "", anchorTo = textData.parent, x = 0, y = 0, anchorPoint = "C", size = 0, width = 0.50})
  1192. end
  1193. -- Add it to the GUI
  1194. local id = tostring(#(ShadowUF.db.profile.units.player.text))
  1195. addTextParent.args[id .. ":label"] = addTextLabel
  1196. addTextParent.args[id] = addText
  1197. addTextParent.args[id .. ":sep"] = addTextSep
  1198. options.args.general.args.text.args[textData.parent] = options.args.general.args.text.args[textData.parent] or addTextParent
  1199. local parent = string.sub(textData.parent, 2)
  1200. Config.tagWizard[parent] = Config.tagWizard[parent] or Config.parentTable
  1201. Config.tagWizard[parent].args[id] = Config.tagTextTable
  1202. Config.tagWizard[parent].args[id .. ":adv"] = Config.advanceTextTable
  1203. quickIDMap[id .. ":adv"] = #(ShadowUF.db.profile.units.player.text)
  1204. -- Reset
  1205. textData.name = nil
  1206. textData.parent = nil
  1207. end,
  1208. },
  1209. },
  1210. },
  1211. },
  1212. },
  1213. layout = layoutManager,
  1214. },
  1215. }
  1216. -- Load text
  1217. for id, text in pairs(ShadowUF.db.profile.units.player.text) do
  1218. addTextParent.args[id .. ":label"] = addTextLabel
  1219. addTextParent.args[tostring(id)] = addText
  1220. addTextParent.args[id .. ":sep"] = addTextSep
  1221. options.args.general.args.text.args[text.anchorTo] = addTextParent
  1222. end
  1223. Config.classTable = {
  1224. order = 0,
  1225. type = "color",
  1226. name = getName,
  1227. hasAlpha = true,
  1228. width = "half",
  1229. arg = "classColors.$key",
  1230. }
  1231. for classToken in pairs(RAID_CLASS_COLORS) do
  1232. options.args.general.args.color.args.classColors.args[classToken] = Config.classTable
  1233. end
  1234. options.args.general.args.color.args.classColors.args.PET = Config.classTable
  1235. options.args.general.args.color.args.classColors.args.VEHICLE = Config.classTable
  1236. options.args.general.args.profile.order = 4
  1237. end
  1238. ---------------------
  1239. -- HIDE BLIZZARD FRAMES CONFIGURATION
  1240. ---------------------
  1241. local function loadHideOptions()
  1242. Config.hideTable = {
  1243. order = function(info) return info[#(info)] == "buffs" and 1 or 2 end,
  1244. type = "toggle",
  1245. name = function(info)
  1246. local key = info[#(info)]
  1247. return L.units[key] and string.format(L["Hide %s frames"], string.lower(L.units[key])) or string.format(L["Hide %s"], key == "cast" and L["player cast bar"] or key == "runes" and L["rune bar"] or key == "buffs" and L["buff frames"] or key == "playerAltPower" and L["player alt. power"])
  1248. end,
  1249. set = function(info, value)
  1250. set(info, value)
  1251. if( value ) then ShadowUF:HideBlizzardFrames() end
  1252. end,
  1253. hidden = false,
  1254. get = get,
  1255. arg = "hidden.$key",
  1256. }
  1257. options.args.hideBlizzard = {
  1258. type = "group",
  1259. name = L["Hide Blizzard"],
  1260. desc = getPageDescription,
  1261. args = {
  1262. help = {
  1263. order = 0,
  1264. type = "group",
  1265. name = L["Help"],
  1266. inline = true,
  1267. args = {
  1268. description = {
  1269. type = "description",
  1270. name = L["You will need to do a /console reloadui before a hidden frame becomes visible again.|nPlayer and other unit frames are automatically hidden depending on if you enable the unit in Shadowed Unit Frames."],
  1271. width = "full",
  1272. },
  1273. },
  1274. },
  1275. hide = {
  1276. order = 1,
  1277. type = "group",
  1278. name = L["Frames"],
  1279. inline = true,
  1280. args = {
  1281. buffs = Config.hideTable,
  1282. cast = Config.hideTable,
  1283. runes = Config.hideTable,
  1284. party = Config.hideTable,
  1285. raid = Config.hideTable,
  1286. player = Config.hideTable,
  1287. pet = Config.hideTable,
  1288. target = Config.hideTable,
  1289. focus = Config.hideTable,
  1290. boss = Config.hideTable,
  1291. arena = Config.hideTable,
  1292. playerAltPower = Config.hideTable,
  1293. },
  1294. },
  1295. }
  1296. }
  1297. end
  1298. ---------------------
  1299. -- UNIT CONFIGURATION
  1300. ---------------------
  1301. local function loadUnitOptions()
  1302. -- This makes sure we don't end up with any messed up positioning due to two different anchors being used
  1303. local function fixPositions(info)
  1304. local unit = info[2]
  1305. local key = info[#(info)]
  1306. if( key == "point" or key == "relativePoint" ) then
  1307. ShadowUF.db.profile.positions[unit].anchorPoint = ""
  1308. ShadowUF.db.profile.positions[unit].movedAnchor = nil
  1309. elseif( key == "anchorPoint" ) then
  1310. ShadowUF.db.profile.positions[unit].point = ""
  1311. ShadowUF.db.profile.positions[unit].relativePoint = ""
  1312. end
  1313. -- Reset offset if it was a manually positioned frame, and it got anchored
  1314. -- Why 100/-100 you ask? Because anything else requires some sort of logic applied to it
  1315. -- and this means the frames won't directly overlap too which is a nice bonus
  1316. if( key == "anchorTo" ) then
  1317. ShadowUF.db.profile.positions[unit].x = 100
  1318. ShadowUF.db.profile.positions[unit].y = -100
  1319. end
  1320. end
  1321. -- Hide raid option in party config
  1322. local function hideRaidOrAdvancedOption(info)
  1323. if( info[2] == "party" and ShadowUF.db.profile.advanced ) then return false end
  1324. return info[2] ~= "raid" and info[2] ~= "raidpet" and info[2] ~= "maintank" and info[2] ~= "mainassist"
  1325. end
  1326. local function hideRaidOption(info)
  1327. return info[2] ~= "raid" and info[2] ~= "raidpet" and info[2] ~= "maintank" and info[2] ~= "mainassist"
  1328. end
  1329. local function hideSplitOrRaidOption(info)
  1330. if( info[2] == "raid" and ShadowUF.db.profile.units.raid.frameSplit ) then
  1331. return true
  1332. end
  1333. return hideRaidOption(info)
  1334. end
  1335. -- Not every option should be changed via global settings
  1336. local function hideSpecialOptions(info)
  1337. local unit = info[2]
  1338. if( unit == "global" or unit == "partypet" ) then
  1339. return true
  1340. end
  1341. return hideAdvancedOption(info)
  1342. end
  1343. local function checkNumber(info, value)
  1344. return tonumber(value)
  1345. end
  1346. local function setPosition(info, value)
  1347. ShadowUF.db.profile.positions[info[2]][info[#(info)]] = value
  1348. fixPositions(info)
  1349. if( info[2] == "raid" or info[2] == "raidpet" or info[2] == "maintank" or info[2] == "mainassist" or info[2] == "party" or info[2] == "boss" or info[2] == "arena" ) then
  1350. ShadowUF.Units:ReloadHeader(info[2])
  1351. else
  1352. ShadowUF.Layout:Reload(info[2])
  1353. end
  1354. end
  1355. local function getPosition(info)
  1356. return ShadowUF.db.profile.positions[info[2]][info[#(info)]]
  1357. end
  1358. local function setNumber(info, value)
  1359. local unit = info[2]
  1360. local key = info[#(info)]
  1361. local id = unit .. key
  1362. -- Apply effective scaling if it's anchored to UIParent
  1363. if( ShadowUF.db.profile.positions[unit].anchorTo == "UIParent" ) then
  1364. value = value * (ShadowUF.db.profile.units[unit].scale * UIParent:GetScale())
  1365. end
  1366. setPosition(info, tonumber(value))
  1367. end
  1368. local function getString(info)
  1369. local unit = info[2]
  1370. local key = info[#(info)]
  1371. local id = unit .. key
  1372. local coord = getPosition(info)
  1373. -- If the frame is created and it's anchored to UIParent, will return the number modified by scale
  1374. if( ShadowUF.db.profile.positions[unit].anchorTo == "UIParent" ) then
  1375. coord = coord / (ShadowUF.db.profile.units[unit].scale * UIParent:GetScale())
  1376. end
  1377. -- OCD, most definitely.
  1378. -- Pain to check coord == math.floor(coord) because floats are handled oddly with frames and return 0.99999999999435
  1379. return string.gsub(string.format("%.2f", coord), "%.00$", "")
  1380. end
  1381. -- TAG WIZARD
  1382. local tagWizard = {}
  1383. Config.tagWizard = tagWizard
  1384. do
  1385. -- Load tag list
  1386. Config.advanceTextTable = {
  1387. order = 1,
  1388. name = function(info) return getVariable(info[2], "text", quickIDMap[info[#(info)]], "name") end,
  1389. type = "group",
  1390. inline = true,
  1391. hidden = function(info)
  1392. if( not getVariable(info[2], "text", nil, quickIDMap[info[#(info)]]) ) then return true end
  1393. return string.sub(getVariable(info[2], "text", quickIDMap[info[#(info)]], "anchorTo"), 2) ~= info[#(info) - 1]
  1394. end,
  1395. set = function(info, value)
  1396. info.arg = string.format("text.%s.%s", quickIDMap[info[#(info) - 1]], info[#(info)])
  1397. setUnit(info, value)
  1398. end,
  1399. get = function(info)
  1400. info.arg = string.format("text.%s.%s", quickIDMap[info[#(info) - 1]], info[#(info)])
  1401. return getUnit(info)
  1402. end,
  1403. args = {
  1404. anchorPoint = {
  1405. order = 1,
  1406. type = "select",
  1407. name = L["Anchor point"],
  1408. values = {["LC"] = L["Left Center"], ["RT"] = L["Right Top"], ["RB"] = L["Right Bottom"], ["LT"] = L["Left Top"], ["LB"] = L["Left Bottom"], ["RC"] = L["Right Center"],["TRI"] = L["Inside Top Right"], ["TLI"] = L["Inside Top Left"], ["CLI"] = L["Inside Center Left"], ["C"] = L["Inside Center"], ["CRI"] = L["Inside Center Right"], ["TR"] = L["Top Right"], ["TL"] = L["Top Left"], ["BR"] = L["Bottom Right"], ["BL"] = L["Bottom Left"]},
  1409. hidden = hideAdvancedOption,
  1410. },
  1411. sep = {
  1412. order = 2,
  1413. type = "description",
  1414. name = "",
  1415. width = "full",
  1416. hidden = hideAdvancedOption,
  1417. },
  1418. width = {
  1419. order = 3,
  1420. name = L["Width weight"],
  1421. desc = L["How much weight this should use when figuring out the total text width."],
  1422. type = "range",
  1423. min = 0, max = 10, step = 0.1,
  1424. hidden = false,
  1425. },
  1426. size = {
  1427. order = 4,
  1428. name = L["Size"],
  1429. desc = L["Let's you modify the base font size to either make it larger or smaller."],
  1430. type = "range",
  1431. min = -20, max = 20, step = 1, softMin = -5, softMax = 5,
  1432. hidden = false,
  1433. },
  1434. x = {
  1435. order = 5,
  1436. type = "range",
  1437. name = L["X Offset"],
  1438. min = -1000, max = 1000, step = 1, softMin = -100, softMax = 100,
  1439. hidden = false,
  1440. },
  1441. y = {
  1442. order = 6,
  1443. type = "range",
  1444. name = L["Y Offset"],
  1445. min = -1000, max = 1000, step = 1, softMin = -100, softMax = 100,
  1446. hidden = false,
  1447. },
  1448. },
  1449. }
  1450. Config.parentTable = {
  1451. order = 0,
  1452. type = "group",
  1453. hidden = false,
  1454. name = function(info) return getName(info) or string.sub(info[#(info)], 1) end,
  1455. hidden = function(info) return not getVariable(info[2], info[#(info)], nil, "enabled") end,
  1456. args = {}
  1457. }
  1458. local function hideBlacklistedTag(info)
  1459. local unit = info[2]
  1460. local tag = info[#(info)]
  1461. if( unit == "global" ) then
  1462. for unit in pairs(modifyUnits) do
  1463. if( ShadowUF.Tags.unitRestrictions[tag] == unit ) then
  1464. return false
  1465. end
  1466. end
  1467. end
  1468. if( ShadowUF.Tags.unitRestrictions[tag] and ShadowUF.Tags.unitRestrictions[tag] ~= unit ) then
  1469. return true
  1470. end
  1471. return false
  1472. end
  1473. local function hideBlacklistedGroup(info)
  1474. local unit = info[2]
  1475. local tagGroup = info[#(info)]
  1476. if( unit ~= "global" ) then
  1477. if( ShadowUF.Tags.unitBlacklist[tagGroup] and string.match(unit, ShadowUF.Tags.unitBlacklist[tagGroup]) ) then
  1478. return true
  1479. end
  1480. else
  1481. -- If the only units that are in the global configuration have the tag filtered, then don't bother showing it
  1482. for unit in pairs(modifyUnits) do
  1483. if( not ShadowUF.Tags.unitBlacklist[tagGroup] or not string.match(unit, ShadowUF.Tags.unitBlacklist[tagGroup]) ) then
  1484. return false
  1485. end
  1486. end
  1487. end
  1488. return false
  1489. end
  1490. local savedTagTexts = {}
  1491. local function selectTag(info, value)
  1492. local unit = info[2]
  1493. local id = tonumber(info[#(info) - 2])
  1494. local tag = info[#(info)]
  1495. local text = getVariable(unit, "text", id, "text")
  1496. local savedText
  1497. if( value ) then
  1498. if( unit == "global" ) then
  1499. table.wipe(savedTagTexts)
  1500. -- Set special tag texts based on the unit, so targettarget won't get a tag that will cause errors
  1501. local tagGroup = ShadowUF.Tags.defaultCategories[tag]
  1502. for unit in pairs(modifyUnits) do
  1503. savedTagTexts[unit] = getVariable(unit, "text", id, "text")
  1504. if( not ShadowUF.Tags.unitBlacklist[tagGroup] or not string.match(unit, ShadowUF.Tags.unitBlacklist[tagGroup]) ) then
  1505. if( not ShadowUF.Tags.unitRestrictions[tag] or ShadowUF.Tags.unitRestrictions[tag] == unit ) then
  1506. if( text == "" ) then
  1507. savedTagTexts[unit] = string.format("[%s]", tag)
  1508. else
  1509. savedTagTexts[unit] = string.format("%s[( )%s]", savedTagTexts[unit], tag)
  1510. end
  1511. savedTagTexts.global = savedTagTexts[unit]
  1512. end
  1513. end
  1514. end
  1515. else
  1516. if( text == "" ) then
  1517. text = string.format("[%s]", tag)
  1518. else
  1519. text = string.format("%s[( )%s]", text, tag)
  1520. end
  1521. end
  1522. -- Removing a tag from global config, need to make sure we can do it
  1523. -- Hack, clean up later
  1524. elseif( unit == "global" ) then
  1525. table.wipe(savedTagTexts)
  1526. for unit in pairs(modifyUnits) do
  1527. if( not ShadowUF.Tags.unitBlacklist[tagGroup] or not string.match(unit, ShadowUF.Tags.unitBlacklist[tagGroup]) ) then
  1528. if( not ShadowUF.Tags.unitRestrictions[tag] or ShadowUF.Tags.unitRestrictions[tag] == unit ) then
  1529. local text = getVariable(unit, "text", id, "text")
  1530. for matchedTag in string.gmatch(text, "%[(.-)%]") do
  1531. local safeTag = "[" .. matchedTag .. "]"
  1532. if( string.match(safeTag, "%[" .. tag .. "%]") or string.match(safeTag, "%)" .. tag .. "%]") or string.match(safeTag, "%[" .. tag .. "%(") or string.match(safeTag, "%)" .. tag .. "%(") ) then
  1533. text = string.gsub(text, "%[" .. string.gsub(string.gsub(matchedTag, "%)", "%%)"), "%(", "%%(") .. "%]", "")
  1534. text = string.gsub(text, " ", "")
  1535. text = string.trim(text)
  1536. break
  1537. end
  1538. end
  1539. savedTagTexts[unit] = text
  1540. savedTagTexts.global = text
  1541. end
  1542. end
  1543. end
  1544. -- Removing a tag from a single unit, super easy :<
  1545. else
  1546. -- Ugly, but it works
  1547. for matchedTag in string.gmatch(text, "%[(.-)%]") do
  1548. local safeTag = "[" .. matchedTag .. "]"
  1549. if( string.match(safeTag, "%[" .. tag .. "%]") or string.match(safeTag, "%)" .. tag .. "%]") or string.match(safeTag, "%[" .. tag .. "%(") or string.match(safeTag, "%)" .. tag .. "%(") ) then
  1550. text = string.gsub(text, "%[" .. string.gsub(string.gsub(matchedTag, "%)", "%%)"), "%(", "%%(") .. "%]", "")
  1551. text = string.gsub(text, " ", "")
  1552. text = string.trim(text)
  1553. break
  1554. end
  1555. end
  1556. end
  1557. if( unit == "global" ) then
  1558. for unit in pairs(modifyUnits) do
  1559. if( savedTagTexts[unit] ) then
  1560. setVariable(unit, "text", id, "text", savedTagTexts[unit])
  1561. end
  1562. end
  1563. setVariable("global", "text", id, "text", savedTagTexts.global)
  1564. else
  1565. setVariable(unit, "text", id, "text", text)
  1566. end
  1567. end
  1568. local function getTag(info)
  1569. local text = getVariable(info[2], "text", tonumber(info[#(info) - 2]), "text")
  1570. local tag = info[#(info)]
  1571. -- FUN WITH PATTERN MATCHING
  1572. if( string.match(text, "%[" .. tag .. "%]") or string.match(text, "%)" .. tag .. "%]") or string.match(text, "%[" .. tag .. "%(") or string.match(text, "%)" .. tag .. "%(") ) then
  1573. return true
  1574. end
  1575. return false
  1576. end
  1577. Config.tagTextTable = {
  1578. type = "group",
  1579. name = function(info) return getVariable(info[2], "text", nil, tonumber(info[#(info)])) and getVariable(info[2], "text", tonumber(info[#(info)]), "name") or "" end,
  1580. hidden = function(info)
  1581. if( not getVariable(info[2], "text", nil, tonumber(info[#(info)])) ) then return true end
  1582. return string.sub(getVariable(info[2], "text", tonumber(info[#(info)]), "anchorTo"), 2) ~= info[#(info) - 1] end,
  1583. set = false,
  1584. get = false,
  1585. args = {
  1586. text = {
  1587. order = 0,
  1588. type = "input",
  1589. name = L["Text"],
  1590. width = "full",
  1591. hidden = false,
  1592. set = function(info, value) setUnit(info, string.gsub(value, "||", "|")) end,
  1593. get = function(info) return string.gsub(getUnit(info), "|", "||") end,
  1594. arg = "text.$parent.text",
  1595. },
  1596. },
  1597. }
  1598. local function getCategoryOrder(info)
  1599. return info[#(info)] == "health" and 1 or info[#(info)] == "power" and 2 or info[#(info)] == "misc" and 3 or 4
  1600. end
  1601. for _, cat in pairs(ShadowUF.Tags.defaultCategories) do
  1602. Config.tagTextTable.args[cat] = Config.tagTextTable.args[cat] or {
  1603. order = getCategoryOrder,
  1604. type = "group",
  1605. inline = true,
  1606. name = getName,
  1607. hidden = hideBlacklistedGroup,
  1608. set = selectTag,
  1609. get = getTag,
  1610. args = {},
  1611. }
  1612. end
  1613. Config.tagTable = {
  1614. order = 0,
  1615. type = "toggle",
  1616. hidden = hideBlacklistedTag,
  1617. name = getTagName,
  1618. desc = getTagHelp,
  1619. }
  1620. local tagList = {}
  1621. for tag in pairs(ShadowUF.Tags.defaultTags) do
  1622. local category = ShadowUF.Tags.defaultCategories[tag] or "misc"
  1623. Config.tagTextTable.args[category].args[tag] = Config.tagTable
  1624. end
  1625. for tag, data in pairs(ShadowUF.db.profile.tags) do
  1626. local category = data.category or "misc"
  1627. Config.tagTextTable.args[category].args[tag] = Config.tagTable
  1628. end
  1629. local parentList = {}
  1630. for id, text in pairs(ShadowUF.db.profile.units.player.text) do
  1631. parentList[text.anchorTo] = parentList[text.anchorTo] or {}
  1632. parentList[text.anchorTo][id] = text
  1633. end
  1634. local nagityNagNagTable = {
  1635. order = 0,
  1636. type = "group",
  1637. name = L["Help"],
  1638. inline = true,
  1639. hidden = false,
  1640. args = {
  1641. help = {
  1642. order = 0,
  1643. type = "description",
  1644. name = L["Selecting a tag text from the left panel to change tags. Truncating width, sizing, and offsets can be done in the current panel."],
  1645. },
  1646. },
  1647. }
  1648. for parent, list in pairs(parentList) do
  1649. parent = string.sub(parent, 2)
  1650. tagWizard[parent] = Config.parentTable
  1651. Config.parentTable.args.help = nagityNagNagTable
  1652. for id in pairs(list) do
  1653. tagWizard[parent].args[tostring(id)] = Config.tagTextTable
  1654. tagWizard[parent].args[tostring(id) .. ":adv"] = Config.advanceTextTable
  1655. quickIDMap[tostring(id) .. ":adv"] = id
  1656. end
  1657. end
  1658. end
  1659. local function disableAnchoredTo(info)
  1660. local auras = getVariable(info[2], "auras", nil, info[#(info) - 1])
  1661. return auras.anchorOn or not auras.enabled
  1662. end
  1663. local function disableSameAnchor(info)
  1664. local buffs = getVariable(info[2], "auras", nil, "buffs")
  1665. local debuffs = getVariable(info[2], "auras", nil, "debuffs")
  1666. local anchor = buffs.enabled and buffs.prioritize and "buffs" or "debuffs"
  1667. if( not getVariable(info[2], "auras", info[#(info) - 1], "enabled") ) then
  1668. return true
  1669. end
  1670. if( ( info[#(info)] == "x" or info[#(info)] == "y" ) and ( info[#(info) - 1] == "buffs" and buffs.anchorOn or info[#(info) - 1] == "debuffs" and debuffs.anchorOn ) ) then
  1671. return true
  1672. end
  1673. if( anchor == info[#(info) - 1] or buffs.anchorOn or debuffs.anchorOn ) then
  1674. return false
  1675. end
  1676. return buffs.anchorPoint == debuffs.anchorPoint
  1677. end
  1678. local defaultAuraList = {["BL"] = L["Bottom"], ["TL"] = L["Top"], ["LT"] = L["Left"], ["RT"] = L["Right"]}
  1679. local advancedAuraList = {["BL"] = L["Bottom Left"], ["BR"] = L["Bottom Right"], ["TL"] = L["Top Left"], ["TR"] = L["Top Right"], ["RT"] = L["Right Top"], ["RB"] = L["Right Bottom"], ["LT"] = L["Left Top"], ["LB"] = L["Left Bottom"]}
  1680. local function getAuraAnchors()
  1681. return ShadowUF.db.profile.advanced and advancedAuraList or defaultAuraList
  1682. end
  1683. local function hideStealable(info)
  1684. if( not ShadowUF.db.profile.advanced ) then return true end
  1685. if( info[2] == "player" or info[2] == "pet" or info[#(info) - 1] == "debuffs" ) then return true end
  1686. return false
  1687. end
  1688. Config.auraTable = {
  1689. type = "group",
  1690. inline = true,
  1691. hidden = false,
  1692. name = function(info) return info[#(info)] == "buffs" and L["Buffs"] or L["Debuffs"] end,
  1693. order = function(info) return info[#(info)] == "buffs" and 1 or 2 end,
  1694. disabled = function(info) return not getVariable(info[2], "auras", info[#(info) - 1], "enabled") end,
  1695. args = {
  1696. enabled = {
  1697. order = 1,
  1698. type = "toggle",
  1699. name = function(info) if( info[#(info) - 1] == "buffs" ) then return L["Enable buffs"] end return L["Enable debuffs"] end,
  1700. disabled = false,
  1701. arg = "auras.$parent.enabled",
  1702. },
  1703. anchorOn = {
  1704. order = 2,
  1705. type = "toggle",
  1706. name = function(info) return info[#(info) - 1] == "buffs" and L["Anchor to debuffs"] or L["Anchor to buffs"] end,
  1707. desc = L["Allows you to anchor the aura group to another, you can then choose where it will be anchored using the position.|n|nUse this if you want to duplicate the default ui style where buffs and debuffs are separate groups."],
  1708. set = function(info, value)
  1709. setVariable(info[2], "auras", info[#(info) - 1] == "buffs" and "debuffs" or "buffs", "anchorOn", false)
  1710. setUnit(info, value)
  1711. end,
  1712. arg = "auras.$parent.anchorOn",
  1713. },
  1714. prioritize = {
  1715. order = 2.25,
  1716. type = "toggle",
  1717. name = L["Prioritize buffs"],
  1718. desc = L["Show buffs before debuffs when sharing the same anchor point."],
  1719. hidden = function(info) return info[#(info) - 1] == "debuffs" end,
  1720. disabled = function(info)
  1721. if( not getVariable(info[2], "auras", info[#(info) - 1], "enabled") ) then return true end
  1722. local buffs = getVariable(info[2], "auras", nil, "buffs")
  1723. local debuffs = getVariable(info[2], "auras", nil, "debuffs")
  1724. return buffs.anchorOn or debuffs.anchorOn or buffs.anchorPoint ~= debuffs.anchorPoint
  1725. end,
  1726. arg = "auras.$parent.prioritize",
  1727. },
  1728. sep2 = {
  1729. order = 6,
  1730. type = "description",
  1731. name = "",
  1732. width = "full",
  1733. },
  1734. enlargeStealable = {
  1735. order = 6.5,
  1736. type = "toggle",
  1737. name = L["Enlarge removable auras"],
  1738. desc = L["If you can Spellsteal or remove an aura, then it will be shown scaled using the scaled aura size option."],
  1739. arg = "auras.$parent.enlargeStealable",
  1740. hidden = hideStealable,
  1741. },
  1742. player = {
  1743. order = 7,
  1744. type = "toggle",
  1745. name = L["Show your auras only"],
  1746. desc = L["Filter out any auras that you did not cast yourself."],
  1747. arg = "auras.$parent.player",
  1748. },
  1749. raid = {
  1750. order = 8,
  1751. type = "toggle",
  1752. name = function(info) return info[#(info) - 1] == "buffs" and L["Show castable on other auras only"] or L["Show curable only"] end,
  1753. desc = function(info) return info[#(info) - 1] == "buffs" and L["Filter out any auras that you cannot cast on another player, or yourself."] or L["Filter out any aura that you cannot cure."] end,
  1754. width = "double",
  1755. arg = "auras.$parent.raid",
  1756. hidden = function(info) return not hideStealable(info) end,
  1757. },
  1758. raid2 = {
  1759. order = 8,
  1760. type = "toggle",
  1761. name = function(info) return info[#(info) - 1] == "buffs" and L["Show castable on other auras only"] or L["Show curable only"] end,
  1762. desc = function(info) return info[#(info) - 1] == "buffs" and L["Filter out any auras that you cannot cast on another player, or yourself."] or L["Filter out any aura that you cannot cure."] end,
  1763. arg = "auras.$parent.raid",
  1764. hidden = hideStealable,
  1765. },
  1766. sep3 = {
  1767. order = 9,
  1768. type = "description",
  1769. name = "",
  1770. width = "full",
  1771. },
  1772. selfTimers = {
  1773. order = 9.5,
  1774. type = "toggle",
  1775. name = L["Timers for self auras only"],
  1776. desc = L["Hides the cooldown ring for any auras that you did not cast."],
  1777. hidden = hideAdvancedOption,
  1778. arg = "auras.$parent.selfTimers",
  1779. },
  1780. enlargeSelf = {
  1781. order = 10,
  1782. type = "toggle",
  1783. name = L["Enlarge your auras"],
  1784. desc = L["If you casted the aura, then the buff icon will be increased in size to make it more visible."],
  1785. arg = "auras.$parent.enlargeSelf",
  1786. },
  1787. selfScale = {
  1788. order = 11,
  1789. type = "range",
  1790. name = L["Scaled aura size"],
  1791. desc = L["Scale for auras that you casted or can Spellsteal, any number above 100% is bigger than default, any number below 100% is smaller than default."],
  1792. min = 1, max = 3, step = 0.10,
  1793. isPercent = true,
  1794. disabled = function(info) return not getVariable(info[2], "auras", info[#(info) - 1], "enlargeSelf") end,
  1795. hidden = hideAdvancedOption,
  1796. arg = "auras.$parent.selfScale",
  1797. },
  1798. selfTimersDouble = {
  1799. order = 11,
  1800. type = "toggle",
  1801. name = L["Timers for self auras only"],
  1802. desc = L["Hides the cooldown ring for any auras that you did not cast."],
  1803. hidden = hideBasicOption,
  1804. arg = "auras.$parent.selfTimers",
  1805. width = "double",
  1806. },
  1807. sep4 = {
  1808. order = 12,
  1809. type = "description",
  1810. name = "",
  1811. width = "full",
  1812. },
  1813. perRow = {
  1814. order = 13,
  1815. type = "range",
  1816. name = function(info)
  1817. local anchorPoint = getVariable(info[2], "auras", info[#(info) - 1], "anchorPoint")
  1818. if( ShadowUF.Layout:GetColumnGrowth(anchorPoint) == "LEFT" or ShadowUF.Layout:GetColumnGrowth(anchorPoint) == "RIGHT" ) then
  1819. return L["Per column"]
  1820. end
  1821. return L["Per row"]
  1822. end,
  1823. desc = L["How many auras to show in a single row."],
  1824. min = 1, max = 100, step = 1, softMin = 1, softMax = 50,
  1825. disabled = disableSameAnchor,
  1826. arg = "auras.$parent.perRow",
  1827. },
  1828. maxRows = {
  1829. order = 14,
  1830. type = "range",
  1831. name = L["Max rows"],
  1832. desc = L["How many rows total should be used, rows will be however long the per row value is set at."],
  1833. min = 1, max = 10, step = 1, softMin = 1, softMax = 5,
  1834. disabled = disableSameAnchor,
  1835. hidden = function(info)
  1836. local anchorPoint = getVariable(info[2], "auras", info[#(info) - 1], "anchorPoint")
  1837. if( ShadowUF.Layout:GetColumnGrowth(anchorPoint) == "LEFT" or ShadowUF.Layout:GetColumnGrowth(anchorPoint) == "RIGHT" ) then
  1838. return true
  1839. end
  1840. return false
  1841. end,
  1842. arg = "auras.$parent.maxRows",
  1843. },
  1844. maxColumns = {
  1845. order = 14,
  1846. type = "range",
  1847. name = L["Max columns"],
  1848. desc = L["How many auras per a column for example, entering two her will create two rows that are filled up to whatever per row is set as."],
  1849. min = 1, max = 100, step = 1, softMin = 1, softMax = 50,
  1850. hidden = function(info)
  1851. local anchorPoint = getVariable(info[2], "auras", info[#(info) - 1], "anchorPoint")
  1852. if( ShadowUF.Layout:GetColumnGrowth(anchorPoint) == "LEFT" or ShadowUF.Layout:GetColumnGrowth(anchorPoint) == "RIGHT" ) then
  1853. return false
  1854. end
  1855. return true
  1856. end,
  1857. disabled = disableSameAnchor,
  1858. arg = "auras.$parent.maxRows",
  1859. },
  1860. size = {
  1861. order = 15,
  1862. type = "range",
  1863. name = L["Size"],
  1864. min = 1, max = 30, step = 1,
  1865. arg = "auras.$parent.size",
  1866. },
  1867. sep5 = {
  1868. order = 16,
  1869. type = "description",
  1870. name = "",
  1871. width = "full",
  1872. },
  1873. anchorPoint = {
  1874. order = 17,
  1875. type = "select",
  1876. name = L["Position"],
  1877. desc = L["How you want this aura to be anchored to the unit frame."],
  1878. values = getAuraAnchors,
  1879. disabled = disableAnchoredTo,
  1880. arg = "auras.$parent.anchorPoint",
  1881. },
  1882. x = {
  1883. order = 18,
  1884. type = "range",
  1885. name = L["X Offset"],
  1886. min = -1000, max = 1000, step = 1, softMin = -100, softMax = 100,
  1887. disabled = disableSameAnchor,
  1888. hidden = hideAdvancedOption,
  1889. arg = "auras.$parent.x",
  1890. },
  1891. y = {
  1892. order = 19,
  1893. type = "range",
  1894. name = L["Y Offset"],
  1895. min = -1000, max = 1000, step = 1, softMin = -100, softMax = 100,
  1896. disabled = disableSameAnchor,
  1897. hidden = hideAdvancedOption,
  1898. arg = "auras.$parent.y",
  1899. },
  1900. },
  1901. }
  1902. local function hideBarOption(info)
  1903. local module = info[#(info) - 1]
  1904. if( ShadowUF.modules[module].moduleHasBar or getVariable(info[2], module, nil, "isBar") ) then
  1905. return false
  1906. end
  1907. return true
  1908. end
  1909. local function disableIfCastName(info)
  1910. return not getVariable(info[2], "castBar", "name", "enabled")
  1911. end
  1912. Config.barTable = {
  1913. order = getModuleOrder,
  1914. name = getName,
  1915. type = "group",
  1916. inline = true,
  1917. hidden = function(info) return hideRestrictedOption(info) or not getVariable(info[2], info[#(info)], nil, "enabled") end,
  1918. args = {
  1919. enableBar = {
  1920. order = 1,
  1921. type = "toggle",
  1922. name = L["Show as bar"],
  1923. desc = L["Turns this widget into a bar that can be resized and ordered just like health and power bars."],
  1924. hidden = function(info) return ShadowUF.modules[info[#(info) - 1]].moduleHasBar end,
  1925. arg = "$parent.isBar",
  1926. width = "full",
  1927. },
  1928. background = {
  1929. order = 1.5,
  1930. type = "toggle",
  1931. name = L["Show background"],
  1932. desc = L["Show a background behind the bars with the same texture/color but faded out."],
  1933. hidden = hideBarOption,
  1934. arg = "$parent.background",
  1935. },
  1936. sep2 = {order = 1.75, type = "description", name = "", hidden = function(info)
  1937. local moduleKey = info[#(info) - 1]
  1938. return ( moduleKey ~= "healthBar" and moduleKey ~= "powerBar" and moduleKey ~= "druidBar" ) or not ShadowUF.db.profile.advanced
  1939. end},
  1940. invert = {
  1941. order = 2,
  1942. type = "toggle",
  1943. name = L["Invert colors"],
  1944. desc = L["Flips coloring so the bar color is shown as the background color and the background as the bar"],
  1945. hidden = function(info) return ( info[#(info) - 1] ~= "healthBar" and info[#(info) - 1] ~= "powerBar" and info[#(info) - 1] ~= "druidBar" ) or not ShadowUF.db.profile.advanced end,
  1946. arg = "$parent.invert",
  1947. },
  1948. order = {
  1949. order = 4,
  1950. type = "range",
  1951. name = L["Order"],
  1952. min = 0, max = 100, step = 5,
  1953. hidden = hideBarOption,
  1954. arg = "$parent.order",
  1955. },
  1956. height = {
  1957. order = 5,
  1958. type = "range",
  1959. name = L["Height"],
  1960. desc = L["How much of the frames total height this bar should get, this is a weighted value, the higher it is the more it gets."],
  1961. min = 0, max = 10, step = 0.1,
  1962. hidden = hideBarOption,
  1963. arg = "$parent.height",
  1964. },
  1965. },
  1966. }
  1967. Config.indicatorTable = {
  1968. order = 0,
  1969. name = function(info)
  1970. if( info[#(info)] == "status" and info[2] == "player" ) then
  1971. return L["Combat/resting status"]
  1972. end
  1973. return getName(info)
  1974. end,
  1975. desc = function(info) return INDICATOR_DESC[info[#(info)]] end,
  1976. type = "group",
  1977. hidden = hideRestrictedOption,
  1978. args = {
  1979. enabled = {
  1980. order = 0,
  1981. type = "toggle",
  1982. name = L["Enable indicator"],
  1983. hidden = false,
  1984. arg = "indicators.$parent.enabled",
  1985. },
  1986. sep1 = {
  1987. order = 1,
  1988. type = "description",
  1989. name = "",
  1990. width = "full",
  1991. hidden = function() return not ShadowUF.db.profile.advanced end,
  1992. },
  1993. anchorPoint = {
  1994. order = 2,
  1995. type = "select",
  1996. name = L["Anchor point"],
  1997. values = positionList,
  1998. hidden = false,
  1999. arg = "indicators.$parent.anchorPoint",
  2000. },
  2001. size = {
  2002. order = 4,
  2003. type = "range",
  2004. name = L["Size"],
  2005. min = 1, max = 40, step = 1,
  2006. hidden = hideAdvancedOption,
  2007. arg = "indicators.$parent.size",
  2008. },
  2009. x = {
  2010. order = 5,
  2011. type = "range",
  2012. name = L["X Offset"],
  2013. min = -100, max = 100, step = 1, softMin = -50, softMax = 50,
  2014. hidden = false,
  2015. arg = "indicators.$parent.x",
  2016. },
  2017. y = {
  2018. order = 6,
  2019. type = "range",
  2020. name = L["Y Offset"],
  2021. min = -100, max = 100, step = 1, softMin = -50, softMax = 50,
  2022. hidden = false,
  2023. arg = "indicators.$parent.y",
  2024. },
  2025. },
  2026. }
  2027. Config.unitTable = {
  2028. type = "group",
  2029. childGroups = "tab",
  2030. order = getUnitOrder,
  2031. name = getName,
  2032. hidden = isUnitDisabled,
  2033. args = {
  2034. general = {
  2035. order = 1,
  2036. name = L["General"],
  2037. type = "group",
  2038. hidden = isModifiersSet,
  2039. set = setUnit,
  2040. get = getUnit,
  2041. args = {
  2042. vehicle = {
  2043. order = 1,
  2044. type = "group",
  2045. inline = true,
  2046. name = L["Vehicles"],
  2047. hidden = function(info) return info[2] ~= "player" and info[2] ~= "party" or not ShadowUF.db.profile.advanced end,
  2048. args = {
  2049. disable = {
  2050. order = 0,
  2051. type = "toggle",
  2052. name = L["Disable vehicle swap"],
  2053. desc = L["Disables the unit frame from turning into a vehicle when the player enters one."],
  2054. set = function(info, value)
  2055. setUnit(info, value)
  2056. local unit = info[2]
  2057. if( unit == "player" ) then
  2058. if( ShadowUF.Units.unitFrames.pet ) then
  2059. ShadowUF.Units.unitFrames.pet:SetAttribute("disableVehicleSwap", ShadowUF.db.profile.units[unit].disableVehicle)
  2060. end
  2061. if( ShadowUF.Units.unitFrames.player ) then
  2062. ShadowUF.Units:CheckVehicleStatus(ShadowUF.Units.unitFrames.player)
  2063. end
  2064. elseif( unit == "party" ) then
  2065. for frame in pairs(ShadowUF.Units.unitFrames) do
  2066. if( frame.unitType == "partypet" ) then
  2067. frame:SetAttribute("disableVehicleSwap", ShadowUF.db.profile.units[unit].disableVehicle)
  2068. elseif( frame.unitType == "party" ) then
  2069. ShadowUF.Units:CheckVehicleStatus(frame)
  2070. end
  2071. end
  2072. end
  2073. end,
  2074. arg = "disableVehicle",
  2075. },
  2076. },
  2077. },
  2078. portrait = {
  2079. order = 2,
  2080. type = "group",
  2081. inline = true,
  2082. hidden = false,
  2083. name = L["Portrait"],
  2084. args = {
  2085. portrait = {
  2086. order = 0,
  2087. type = "toggle",
  2088. name = string.format(L["Enable %s"], L["Portrait"]),
  2089. arg = "portrait.enabled",
  2090. },
  2091. portraitType = {
  2092. order = 1,
  2093. type = "select",
  2094. name = L["Portrait type"],
  2095. values = {["class"] = L["Class icon"], ["2D"] = L["2D"], ["3D"] = L["3D"]},
  2096. arg = "portrait.type",
  2097. },
  2098. alignment = {
  2099. order = 2,
  2100. type = "select",
  2101. name = L["Position"],
  2102. values = {["LEFT"] = L["Left"], ["RIGHT"] = L["Right"]},
  2103. arg = "portrait.alignment",
  2104. },
  2105. },
  2106. },
  2107. fader = {
  2108. order = 3,
  2109. type = "group",
  2110. inline = true,
  2111. name = L["Combat fader"],
  2112. hidden = hideRestrictedOption,
  2113. args = {
  2114. fader = {
  2115. order = 0,
  2116. type = "toggle",
  2117. name = string.format(L["Enable %s"], L["Combat fader"]),
  2118. desc = L["Combat fader will fade out all your frames while they are inactive and fade them back in once you are in combat or active."],
  2119. hidden = false,
  2120. arg = "fader.enabled",
  2121. },
  2122. combatAlpha = {
  2123. order = 1,
  2124. type = "range",
  2125. name = L["Combat alpha"],
  2126. desc = L["Frame alpha while this unit is in combat."],
  2127. min = 0, max = 1.0, step = 0.1,
  2128. arg = "fader.combatAlpha",
  2129. hidden = false,
  2130. isPercent = true,
  2131. },
  2132. inactiveAlpha = {
  2133. order = 2,
  2134. type = "range",
  2135. name = L["Inactive alpha"],
  2136. desc = L["Frame alpha when you are out of combat while having no target and 100% mana or energy."],
  2137. min = 0, max = 1.0, step = 0.1,
  2138. arg = "fader.inactiveAlpha",
  2139. hidden = false,
  2140. isPercent = true,
  2141. },
  2142. }
  2143. },
  2144. range = {
  2145. order = 3,
  2146. type = "group",
  2147. inline = true,
  2148. name = L["Range indicator"],
  2149. hidden = hideRestrictedOption,
  2150. args = {
  2151. fader = {
  2152. order = 0,
  2153. type = "toggle",
  2154. name = string.format(L["Enable %s"], L["Range indicator"]),
  2155. desc = L["Fades out the unit frames of people who are not within range of you."],
  2156. arg = "range.enabled",
  2157. hidden = false,
  2158. },
  2159. inAlpha = {
  2160. order = 1,
  2161. type = "range",
  2162. name = L["In range alpha"],
  2163. desc = L["Frame alpha while this unit is in combat."],
  2164. min = 0, max = 1.0, step = 0.05,
  2165. arg = "range.inAlpha",
  2166. hidden = false,
  2167. isPercent = true,
  2168. },
  2169. oorAlpha = {
  2170. order = 2,
  2171. type = "range",
  2172. name = L["Out of range alpha"],
  2173. min = 0, max = 1.0, step = 0.05,
  2174. arg = "range.oorAlpha",
  2175. hidden = false,
  2176. isPercent = true,
  2177. },
  2178. }
  2179. },
  2180. highlight = {
  2181. order = 3.5,
  2182. type = "group",
  2183. inline = true,
  2184. name = L["Border highlighting"],
  2185. hidden = hideRestrictedOption,
  2186. args = {
  2187. mouseover = {
  2188. order = 3,
  2189. type = "toggle",
  2190. name = L["On mouseover"],
  2191. desc = L["Highlight units when you mouse over them."],
  2192. arg = "highlight.mouseover",
  2193. hidden = false,
  2194. },
  2195. target = { -- hypehuman
  2196. order = 4,
  2197. type = "toggle",
  2198. name = L["For target"], -- hypehuman
  2199. desc = L["Highlight units that you are targeting."], -- hypehuman
  2200. arg = "highlight.target", -- hypehuman
  2201. hidden = function(info) return info[2] == "target" end, -- hypehuman
  2202. },
  2203. focus = { -- hypehuman
  2204. order = 4.5, -- hypehuman
  2205. type = "toggle", -- hypehuman
  2206. name = L["For focus"], -- hypehuman
  2207. desc = L["Highlight units that you have focused."], -- hypehuman
  2208. arg = "highlight.focus", -- hypehuman
  2209. hidden = function(info) return info[2] == "focus" end, -- hypehuman
  2210. },
  2211. aggro = {
  2212. order = 5,
  2213. type = "toggle",
  2214. name = L["On aggro"],
  2215. desc = L["Highlight units that have aggro on any mob."],
  2216. arg = "highlight.aggro",
  2217. hidden = function(info) return info[2] == "arena" or info[2] == "arenapet" or ShadowUF.fakeUnits[info[2]] end,
  2218. },
  2219. debuff = {
  2220. order = 6,
  2221. type = "toggle",
  2222. name = L["On curable debuff"],
  2223. desc = L["Highlight units that are debuffed with something you can cure."],
  2224. arg = "highlight.debuff",
  2225. hidden = function(info) return string.match(info[2], "^arena") or string.match(info[2], "^boss") end,
  2226. },
  2227. alpha = {
  2228. order = 7,
  2229. type = "range",
  2230. name = L["Border alpha"],
  2231. min = 0, max = 1, step = 0.05,
  2232. isPercent = true,
  2233. hidden = false,
  2234. arg = "highlight.alpha",
  2235. },
  2236. size = {
  2237. order = 8,
  2238. type = "range",
  2239. name = L["Border thickness"],
  2240. min = 0, max = 50, step = 1,
  2241. arg = "highlight.size",
  2242. hidden = false,
  2243. },
  2244. },
  2245. },
  2246. -- SOUL SHARDS
  2247. barSouls = {
  2248. order = 4,
  2249. type = "group",
  2250. inline = true,
  2251. name = L["Soul Shards"],
  2252. hidden = function(info) return playerClass ~= "WARLOCK" or not getVariable(info[2], "soulShards", nil, "isBar") or not getVariable(info[2], nil, nil, "soulShards") end,
  2253. args = {
  2254. enabled = {
  2255. order = 1,
  2256. type = "toggle",
  2257. name = string.format(L["Enable %s"], L["Soul Shards"]),
  2258. hidden = false,
  2259. arg = "soulShards.enabled",
  2260. },
  2261. growth = {
  2262. order = 2,
  2263. type = "select",
  2264. name = L["Growth"],
  2265. values = {["LEFT"] = L["Left"], ["RIGHT"] = L["Right"]},
  2266. hidden = false,
  2267. arg = "soulShards.growth",
  2268. },
  2269. showAlways = {
  2270. order = 3,
  2271. type = "toggle",
  2272. name = L["Don't hide when empty"],
  2273. hidden = false,
  2274. arg = "soulShards.showAlways",
  2275. },
  2276. },
  2277. },
  2278. soulShards = {
  2279. order = 4,
  2280. type = "group",
  2281. inline = true,
  2282. name = L["Soul Shards"],
  2283. hidden = function(info) if( info[2] == "global" or getVariable(info[2], "soulShards", nil, "isBar") ) then return true end return hideRestrictedOption(info) end,
  2284. args = {
  2285. enabled = {
  2286. order = 0,
  2287. type = "toggle",
  2288. name = string.format(L["Enable %s"], L["Soul Shards"]),
  2289. hidden = false,
  2290. arg = "soulShards.enabled",
  2291. },
  2292. sep1 = {
  2293. order = 1,
  2294. type = "description",
  2295. name = "",
  2296. width = "full",
  2297. hidden = hideAdvancedOption,
  2298. },
  2299. growth = {
  2300. order = 2,
  2301. type = "select",
  2302. name = L["Growth"],
  2303. values = {["UP"] = L["Up"], ["LEFT"] = L["Left"], ["RIGHT"] = L["Right"], ["DOWN"] = L["Down"]},
  2304. hidden = false,
  2305. arg = "soulShards.growth",
  2306. },
  2307. size = {
  2308. order = 2,
  2309. type = "range",
  2310. name = L["Size"],
  2311. min = 0, max = 50, step = 1, softMin = 0, softMax = 20,
  2312. hidden = hideAdvancedOption,
  2313. arg = "soulShards.size",
  2314. },
  2315. spacing = {
  2316. order = 3,
  2317. type = "range",
  2318. name = L["Spacing"],
  2319. min = -30, max = 30, step = 1, softMin = -15, softMax = 15,
  2320. hidden = hideAdvancedOption,
  2321. arg = "soulShards.spacing",
  2322. },
  2323. sep2 = {
  2324. order = 4,
  2325. type = "description",
  2326. name = "",
  2327. width = "full",
  2328. hidden = hideAdvancedOption,
  2329. },
  2330. anchorPoint = {
  2331. order = 5,
  2332. type = "select",
  2333. name = L["Anchor point"],
  2334. values = positionList,
  2335. hidden = false,
  2336. arg = "soulShards.anchorPoint",
  2337. },
  2338. x = {
  2339. order = 6,
  2340. type = "range",
  2341. name = L["X Offset"],
  2342. min = -30, max = 30, step = 1,
  2343. hidden = false,
  2344. arg = "soulShards.x",
  2345. },
  2346. y = {
  2347. order = 7,
  2348. type = "range",
  2349. name = L["Y Offset"],
  2350. min = -30, max = 30, step = 1,
  2351. hidden = false,
  2352. arg = "soulShards.y",
  2353. },
  2354. },
  2355. },
  2356. -- HOLY POWER
  2357. barHolyPower = {
  2358. order = 4,
  2359. type = "group",
  2360. inline = true,
  2361. name = L["Holy Power"],
  2362. hidden = function(info) return playerClass ~= "PALADIN" or not getVariable(info[2], "soulShards", nil, "isBar") or not getVariable(info[2], nil, nil, "soulShards") end,
  2363. args = {
  2364. enabled = {
  2365. order = 1,
  2366. type = "toggle",
  2367. name = string.format(L["Enable %s"], L["Holy Power"]),
  2368. hidden = false,
  2369. arg = "holyPower.enabled",
  2370. },
  2371. growth = {
  2372. order = 2,
  2373. type = "select",
  2374. name = L["Growth"],
  2375. values = {["LEFT"] = L["Left"], ["RIGHT"] = L["Right"]},
  2376. hidden = false,
  2377. arg = "holyPower.growth",
  2378. },
  2379. showAlways = {
  2380. order = 3,
  2381. type = "toggle",
  2382. name = L["Don't hide when empty"],
  2383. hidden = false,
  2384. arg = "holyPower.showAlways",
  2385. },
  2386. },
  2387. },
  2388. holyPower = {
  2389. order = 4,
  2390. type = "group",
  2391. inline = true,
  2392. name = L["Holy Power"],
  2393. hidden = function(info) if( info[2] == "global" or getVariable(info[2], "holyPower", nil, "isBar") ) then return true end return hideRestrictedOption(info) end,
  2394. args = {
  2395. enabled = {
  2396. order = 0,
  2397. type = "toggle",
  2398. name = string.format(L["Enable %s"], L["Holy Power"]),
  2399. hidden = false,
  2400. arg = "holyPower.enabled",
  2401. },
  2402. sep1 = {
  2403. order = 1,
  2404. type = "description",
  2405. name = "",
  2406. width = "full",
  2407. hidden = hideAdvancedOption,
  2408. },
  2409. growth = {
  2410. order = 2,
  2411. type = "select",
  2412. name = L["Growth"],
  2413. values = {["UP"] = L["Up"], ["LEFT"] = L["Left"], ["RIGHT"] = L["Right"], ["DOWN"] = L["Down"]},
  2414. hidden = false,
  2415. arg = "holyPower.growth",
  2416. },
  2417. size = {
  2418. order = 2,
  2419. type = "range",
  2420. name = L["Size"],
  2421. min = 0, max = 50, step = 1, softMin = 0, softMax = 20,
  2422. hidden = hideAdvancedOption,
  2423. arg = "holyPower.size",
  2424. },
  2425. spacing = {
  2426. order = 3,
  2427. type = "range",
  2428. name = L["Spacing"],
  2429. min = -30, max = 30, step = 1, softMin = -15, softMax = 15,
  2430. hidden = hideAdvancedOption,
  2431. arg = "holyPower.spacing",
  2432. },
  2433. sep2 = {
  2434. order = 4,
  2435. type = "description",
  2436. name = "",
  2437. width = "full",
  2438. hidden = hideAdvancedOption,
  2439. },
  2440. anchorPoint = {
  2441. order = 5,
  2442. type = "select",
  2443. name = L["Anchor point"],
  2444. values = positionList,
  2445. hidden = false,
  2446. arg = "holyPower.anchorPoint",
  2447. },
  2448. x = {
  2449. order = 6,
  2450. type = "range",
  2451. name = L["X Offset"],
  2452. min = -30, max = 30, step = 1,
  2453. hidden = false,
  2454. arg = "holyPower.x",
  2455. },
  2456. y = {
  2457. order = 7,
  2458. type = "range",
  2459. name = L["Y Offset"],
  2460. min = -30, max = 30, step = 1,
  2461. hidden = false,
  2462. arg = "holyPower.y",
  2463. },
  2464. },
  2465. },
  2466. -- COMBO POINTS
  2467. barComboPoints = {
  2468. order = 4,
  2469. type = "group",
  2470. inline = true,
  2471. name = L["Combo points"],
  2472. hidden = function(info) return not getVariable(info[2], "comboPoints", nil, "isBar") or not getVariable(info[2], nil, nil, "comboPoints") end,
  2473. args = {
  2474. enabled = {
  2475. order = 1,
  2476. type = "toggle",
  2477. name = string.format(L["Enable %s"], L["Combo points"]),
  2478. hidden = false,
  2479. arg = "comboPoints.enabled",
  2480. },
  2481. growth = {
  2482. order = 2,
  2483. type = "select",
  2484. name = L["Growth"],
  2485. values = {["LEFT"] = L["Left"], ["RIGHT"] = L["Right"]},
  2486. hidden = false,
  2487. arg = "comboPoints.growth",
  2488. },
  2489. showAlways = {
  2490. order = 3,
  2491. type = "toggle",
  2492. name = L["Don't hide when empty"],
  2493. hidden = false,
  2494. arg = "comboPoints.showAlways",
  2495. },
  2496. },
  2497. },
  2498. comboPoints = {
  2499. order = 4,
  2500. type = "group",
  2501. inline = true,
  2502. name = L["Combo points"],
  2503. hidden = function(info) if( info[2] == "global" or getVariable(info[2], "comboPoints", nil, "isBar") ) then return true end return hideRestrictedOption(info) end,
  2504. args = {
  2505. enabled = {
  2506. order = 0,
  2507. type = "toggle",
  2508. name = string.format(L["Enable %s"], L["Combo points"]),
  2509. hidden = false,
  2510. arg = "comboPoints.enabled",
  2511. },
  2512. sep1 = {
  2513. order = 1,
  2514. type = "description",
  2515. name = "",
  2516. width = "full",
  2517. hidden = hideAdvancedOption,
  2518. },
  2519. growth = {
  2520. order = 2,
  2521. type = "select",
  2522. name = L["Growth"],
  2523. values = {["UP"] = L["Up"], ["LEFT"] = L["Left"], ["RIGHT"] = L["Right"], ["DOWN"] = L["Down"]},
  2524. hidden = false,
  2525. arg = "comboPoints.growth",
  2526. },
  2527. size = {
  2528. order = 2,
  2529. type = "range",
  2530. name = L["Size"],
  2531. min = 0, max = 50, step = 1, softMin = 0, softMax = 20,
  2532. hidden = hideAdvancedOption,
  2533. arg = "comboPoints.size",
  2534. },
  2535. spacing = {
  2536. order = 3,
  2537. type = "range",
  2538. name = L["Spacing"],
  2539. min = -30, max = 30, step = 1, softMin = -15, softMax = 15,
  2540. hidden = hideAdvancedOption,
  2541. arg = "comboPoints.spacing",
  2542. },
  2543. sep2 = {
  2544. order = 4,
  2545. type = "description",
  2546. name = "",
  2547. width = "full",
  2548. hidden = hideAdvancedOption,
  2549. },
  2550. anchorPoint = {
  2551. order = 5,
  2552. type = "select",
  2553. name = L["Anchor point"],
  2554. values = positionList,
  2555. hidden = false,
  2556. arg = "comboPoints.anchorPoint",
  2557. },
  2558. x = {
  2559. order = 6,
  2560. type = "range",
  2561. name = L["X Offset"],
  2562. min = -30, max = 30, step = 1,
  2563. hidden = false,
  2564. arg = "comboPoints.x",
  2565. },
  2566. y = {
  2567. order = 7,
  2568. type = "range",
  2569. name = L["Y Offset"],
  2570. min = -30, max = 30, step = 1,
  2571. hidden = false,
  2572. arg = "comboPoints.y",
  2573. },
  2574. },
  2575. },
  2576. combatText = {
  2577. order = 5,
  2578. type = "group",
  2579. inline = true,
  2580. name = L["Combat text"],
  2581. hidden = hideRestrictedOption,
  2582. args = {
  2583. combatText = {
  2584. order = 0,
  2585. type = "toggle",
  2586. name = string.format(L["Enable %s"], L["Combat text"]),
  2587. desc = L["Shows combat feedback, last healing the unit received, last hit did it miss, resist, dodged and so on."],
  2588. arg = "combatText.enabled",
  2589. hidden = false,
  2590. },
  2591. sep = {
  2592. order = 1,
  2593. type = "description",
  2594. name = "",
  2595. width = "full",
  2596. hidden = hideAdvancedOption,
  2597. },
  2598. anchorPoint = {
  2599. order = 3,
  2600. type = "select",
  2601. name = L["Anchor point"],
  2602. values = positionList,
  2603. arg = "combatText.anchorPoint",
  2604. hidden = hideAdvancedOption,
  2605. },
  2606. x = {
  2607. order = 4,
  2608. type = "range",
  2609. name = L["X Offset"],
  2610. min = -50, max = 50, step = 1,
  2611. arg = "combatText.x",
  2612. hidden = hideAdvancedOption,
  2613. },
  2614. y = {
  2615. order = 5,
  2616. type = "range",
  2617. name = L["Y Offset"],
  2618. min = -50, max = 50, step = 1,
  2619. arg = "combatText.y",
  2620. hidden = hideAdvancedOption,
  2621. },
  2622. },
  2623. },
  2624. },
  2625. },
  2626. attributes = {
  2627. order = 1.5,
  2628. type = "group",
  2629. name = function(info) return L.units[info[#(info) - 1]] end,
  2630. hidden = function(info)
  2631. local unit = info[#(info) - 1]
  2632. return unit ~= "raid" and unit ~= "raidpet" and unit ~= "party" and unit ~= "mainassist" and unit ~= "maintank" and unit ~= "boss" and unit ~= "arena"
  2633. end,
  2634. set = function(info, value)
  2635. setUnit(info, value)
  2636. ShadowUF.Units:ReloadHeader(info[2])
  2637. ShadowUF.modules.movers:Update()
  2638. end,
  2639. get = getUnit,
  2640. args = {
  2641. show = {
  2642. order = 0.5,
  2643. type = "group",
  2644. inline = true,
  2645. name = L["Visibility"],
  2646. hidden = function(info) return info[2] ~= "party" and info[2] ~= "raid" end,
  2647. args = {
  2648. showPlayer = {
  2649. order = 0,
  2650. type = "toggle",
  2651. name = L["Show player in party"],
  2652. desc = L["The player frame will not be hidden regardless, you will have to manually disable it either entirely or per zone type."],
  2653. hidden = function(info) return info[2] ~= "party" end,
  2654. arg = "showPlayer",
  2655. },
  2656. hideSemiRaidParty = {
  2657. order = 1,
  2658. type = "toggle",
  2659. name = L["Hide in >5-man raids"],
  2660. desc = L["Party frames are hidden while in a raid group with more than 5 people inside."],
  2661. hidden = function(info) return info[2] ~= "party" end,
  2662. set = function(info, value)
  2663. if( value ) then
  2664. setVariable(info[2], nil, nil, "hideAnyRaid", false)
  2665. end
  2666. setVariable(info[2], nil, nil, "hideSemiRaid", value)
  2667. ShadowUF.Units:ReloadHeader(info[#(info) - 3])
  2668. end,
  2669. arg = "hideSemiRaid",
  2670. },
  2671. hideRaid = {
  2672. order = 2,
  2673. type = "toggle",
  2674. name = L["Hide in any raid"],
  2675. desc = L["Party frames are hidden while in any sort of raid no matter how many people."],
  2676. hidden = function(info) return info[2] ~= "party" end,
  2677. set = function(info, value)
  2678. if( value ) then
  2679. setVariable(info[2], nil, nil, "hideSemiRaid", false)
  2680. end
  2681. setVariable(info[2], nil, nil, "hideAnyRaid", value)
  2682. ShadowUF.Units:ReloadHeader(info[#(info) - 3])
  2683. end,
  2684. arg = "hideAnyRaid",
  2685. },
  2686. separateFrames = {
  2687. order = 3,
  2688. type = "toggle",
  2689. name = L["Separate raid frames"],
  2690. desc = L["Splits raid frames into individual frames for each raid group instead of one single frame.|nNOTE! You cannot drag each group frame individualy, but how they grow is set through the column and row growth options."],
  2691. hidden = function(info) return info[2] ~= "raid" end,
  2692. arg = "frameSplit",
  2693. },
  2694. hideSemiRaidRaid = {
  2695. order = 3.5,
  2696. type = "toggle",
  2697. name = L["Hide in <=5-man raids"],
  2698. desc = L["Raid frames are hidden while in a raid group with 5 or less people inside."],
  2699. hidden = function(info) return info[2] ~= "raid" end,
  2700. set = function(info, value)
  2701. setVariable(info[2], nil, nil, "hideSemiRaid", value)
  2702. ShadowUF.Units:ReloadHeader(info[#(info) - 3])
  2703. end,
  2704. arg = "hideSemiRaid"
  2705. },
  2706. showInRaid = {
  2707. order = 4,
  2708. type = "toggle",
  2709. name = L["Show party as raid"],
  2710. hidden = hideRaidOption,
  2711. set = function(info, value)
  2712. setUnit(info, value)
  2713. ShadowUF.Units:ReloadHeader("party")
  2714. ShadowUF.Units:ReloadHeader("raid")
  2715. ShadowUF.modules.movers:Update()
  2716. end,
  2717. arg = "showParty",
  2718. },
  2719. },
  2720. },
  2721. general = {
  2722. order = 1,
  2723. type = "group",
  2724. inline = true,
  2725. name = L["General"],
  2726. hidden = false,
  2727. args = {
  2728. offset = {
  2729. order = 2,
  2730. type = "range",
  2731. name = L["Row offset"],
  2732. desc = L["Spacing between each row"],
  2733. min = -10, max = 100, step = 1,
  2734. arg = "offset",
  2735. },
  2736. attribPoint = {
  2737. order = 3,
  2738. type = "select",
  2739. name = L["Row growth"],
  2740. desc = L["How the rows should grow when new group members are added."],
  2741. values = {["TOP"] = L["Down"], ["BOTTOM"] = L["Up"], ["LEFT"] = L["Right"], ["RIGHT"] = L["Left"]},
  2742. arg = "attribPoint",
  2743. set = function(info, value)
  2744. -- If you set the frames to grow left, the columns have to grow down or up as well
  2745. local attribAnchorPoint = getVariable(info[2], nil, nil, "attribAnchorPoint")
  2746. if( ( value == "LEFT" or value == "RIGHT" ) and attribAnchorPoint ~= "BOTTOM" and attribAnchorPoint ~= "TOP" ) then
  2747. ShadowUF.db.profile.units[info[2]].attribAnchorPoint = "BOTTOM"
  2748. elseif( ( value == "TOP" or value == "BOTTOM" ) and attribAnchorPoint ~= "LEFT" and attribAnchorPoint ~= "RIGHT" ) then
  2749. ShadowUF.db.profile.units[info[2]].attribAnchorPoint = "RIGHT"
  2750. end
  2751. setUnit(info, value)
  2752. local position = ShadowUF.db.profile.positions[info[2]]
  2753. if( position.top and position.bottom ) then
  2754. local point = ShadowUF.db.profile.units[info[2]].attribAnchorPoint == "RIGHT" and "RIGHT" or "LEFT"
  2755. position.point = (ShadowUF.db.profile.units[info[2]].attribPoint == "BOTTOM" and "BOTTOM" or "TOP") .. point
  2756. position.y = ShadowUF.db.profile.units[info[2]].attribPoint == "BOTTOM" and position.bottom or position.top
  2757. end
  2758. ShadowUF.Units:ReloadHeader(info[2])
  2759. ShadowUF.modules.movers:Update()
  2760. end,
  2761. },
  2762. sep2 = {
  2763. order = 4,
  2764. type = "description",
  2765. name = "",
  2766. width = "full",
  2767. hidden = false,
  2768. },
  2769. columnSpacing = {
  2770. order = 5,
  2771. type = "range",
  2772. name = L["Column spacing"],
  2773. min = -30, max = 100, step = 1,
  2774. hidden = hideRaidOrAdvancedOption,
  2775. arg = "columnSpacing",
  2776. },
  2777. attribAnchorPoint = {
  2778. order = 6,
  2779. type = "select",
  2780. name = L["Column growth"],
  2781. desc = L["How the frames should grow when a new column is added."],
  2782. values = function(info)
  2783. local attribPoint = getVariable(info[2], nil, nil, "attribPoint")
  2784. if( attribPoint == "LEFT" or attribPoint == "RIGHT" ) then
  2785. return {["TOP"] = L["Down"], ["BOTTOM"] = L["Up"]}
  2786. end
  2787. return {["LEFT"] = L["Right"], ["RIGHT"] = L["Left"]}
  2788. end,
  2789. hidden = hideRaidOrAdvancedOption,
  2790. set = function(info, value)
  2791. -- If you set the frames to grow left, the columns have to grow down or up as well
  2792. local attribPoint = getVariable(info[2], nil, nil, "attribPoint")
  2793. if( ( value == "LEFT" or value == "RIGHT" ) and attribPoint ~= "BOTTOM" and attribPoint ~= "TOP" ) then
  2794. ShadowUF.db.profile.units[info[2]].attribPoint = "BOTTOM"
  2795. end
  2796. setUnit(info, value)
  2797. ShadowUF.Units:ReloadHeader(info[2])
  2798. ShadowUF.modules.movers:Update()
  2799. end,
  2800. arg = "attribAnchorPoint",
  2801. },
  2802. sep3 = {
  2803. order = 7,
  2804. type = "description",
  2805. name = "",
  2806. width = "full",
  2807. hidden = false,
  2808. },
  2809. maxColumns = {
  2810. order = 8,
  2811. type = "range",
  2812. name = L["Max columns"],
  2813. min = 1, max = 20, step = 1,
  2814. arg = "maxColumns",
  2815. hidden = function(info) return info[2] == "boss" or info[2] == "arena" or hideSplitOrRaidOption(info) end,
  2816. },
  2817. unitsPerColumn = {
  2818. order = 8,
  2819. type = "range",
  2820. name = L["Units per column"],
  2821. min = 1, max = 40, step = 1,
  2822. arg = "unitsPerColumn",
  2823. hidden = function(info) return info[2] == "boss" or info[2] == "arena" or hideSplitOrRaidOption(info) end,
  2824. },
  2825. partyPerColumn = {
  2826. order = 9,
  2827. type = "range",
  2828. name = L["Units per column"],
  2829. min = 1, max = 5, step = 1,
  2830. arg = "unitsPerColumn",
  2831. hidden = function(info) return info[2] ~= "party" or not ShadowUF.db.profile.advanced end,
  2832. },
  2833. groupsPerRow = {
  2834. order = 8,
  2835. type = "range",
  2836. name = L["Groups per row"],
  2837. desc = L["How many groups should be shown per row."],
  2838. min = 1, max = 8, step = 1,
  2839. arg = "groupsPerRow",
  2840. hidden = function(info) return info[2] ~= "raid" or not ShadowUF.db.profile.units.raid.frameSplit end,
  2841. },
  2842. groupSpacing = {
  2843. order = 9,
  2844. type = "range",
  2845. name = L["Group row spacing"],
  2846. desc = L["How much spacing should be between each new row of groups."],
  2847. min = -50, max = 50, step = 1,
  2848. arg = "groupSpacing",
  2849. hidden = function(info) return info[2] ~= "raid" or not ShadowUF.db.profile.units.raid.frameSplit end,
  2850. },
  2851. },
  2852. },
  2853. sort = {
  2854. order = 2,
  2855. type = "group",
  2856. inline = true,
  2857. name = L["Sorting"],
  2858. hidden = function(info) return info[2] == "boss" or info[2] == "arena" or ( info[2] ~= "raid" and not ShadowUF.db.profile.advanced ) end,
  2859. args = {
  2860. sortMethod = {
  2861. order = 2,
  2862. type = "select",
  2863. name = L["Sort method"],
  2864. values = {["INDEX"] = L["Index"], ["NAME"] = L["Name"]},
  2865. arg = "sortMethod",
  2866. hidden = false,
  2867. },
  2868. sortOrder = {
  2869. order = 2,
  2870. type = "select",
  2871. name = L["Sort order"],
  2872. values = {["ASC"] = L["Ascending"], ["DESC"] = L["Descending"]},
  2873. arg = "sortOrder",
  2874. hidden = false,
  2875. },
  2876. },
  2877. },
  2878. raid = {
  2879. order = 3,
  2880. type = "group",
  2881. inline = true,
  2882. name = L["Groups"],
  2883. hidden = hideRaidOption,
  2884. args = {
  2885. groupBy = {
  2886. order = 4,
  2887. type = "select",
  2888. name = L["Group by"],
  2889. values = {["GROUP"] = L["Group number"], ["CLASS"] = L["Class"]},
  2890. arg = "groupBy",
  2891. hidden = hideSplitOrRaidOption,
  2892. },
  2893. sortMethod = {
  2894. order = 5,
  2895. type = "select",
  2896. name = L["Sort method"],
  2897. values = {["INDEX"] = L["Index"], ["NAME"] = L["Name"]},
  2898. arg = "sortMethod",
  2899. hidden = false,
  2900. },
  2901. sortOrder = {
  2902. order = 6,
  2903. type = "select",
  2904. name = L["Sort order"],
  2905. values = {["ASC"] = L["Ascending"], ["DESC"] = L["Descending"]},
  2906. arg = "sortOrder",
  2907. hidden = false,
  2908. },
  2909. selectedGroups = {
  2910. order = 7,
  2911. type = "multiselect",
  2912. name = L["Groups to show"],
  2913. values = {string.format(L["Group %d"], 1), string.format(L["Group %d"], 2), string.format(L["Group %d"], 3), string.format(L["Group %d"], 4), string.format(L["Group %d"], 5), string.format(L["Group %d"], 6), string.format(L["Group %d"], 7), string.format(L["Group %d"], 8)},
  2914. set = function(info, key, value)
  2915. local tbl = getVariable(info[2], nil, nil, "filters")
  2916. tbl[key] = value
  2917. setVariable(info[2], "filters", nil, tbl)
  2918. ShadowUF.Units:ReloadHeader(info[2])
  2919. ShadowUF.modules.movers:Update()
  2920. end,
  2921. get = function(info, key)
  2922. return getVariable(info[2], nil, nil, "filters")[key]
  2923. end,
  2924. hidden = function(info) return info[2] ~= "raid" and info[2] ~= "raidpet" end,
  2925. },
  2926. },
  2927. },
  2928. },
  2929. },
  2930. frame = {
  2931. order = 2,
  2932. name = L["Frame"],
  2933. type = "group",
  2934. hidden = isModifiersSet,
  2935. set = setUnit,
  2936. get = getUnit,
  2937. args = {
  2938. size = {
  2939. order = 0,
  2940. type = "group",
  2941. inline = true,
  2942. name = L["Size"],
  2943. hidden = false,
  2944. set = function(info, value)
  2945. setUnit(info, value)
  2946. ShadowUF.modules.movers:Update()
  2947. end,
  2948. args = {
  2949. scale = {
  2950. order = 0,
  2951. type = "range",
  2952. name = L["Scale"],
  2953. min = 0.25, max = 2, step = 0.01,
  2954. isPercent = true,
  2955. arg = "scale",
  2956. },
  2957. height = {
  2958. order = 1,
  2959. type = "range",
  2960. name = L["Height"],
  2961. min = 0, softMax = 100, step = 1,
  2962. arg = "height",
  2963. },
  2964. width = {
  2965. order = 2,
  2966. type = "range",
  2967. name = L["Width"],
  2968. min = 0, softMax = 300, step = 1,
  2969. arg = "width",
  2970. },
  2971. },
  2972. },
  2973. anchor = {
  2974. order = 1,
  2975. type = "group",
  2976. inline = true,
  2977. hidden = function(info) return info[2] == "global" end,
  2978. name = L["Anchor to another frame"],
  2979. set = setPosition,
  2980. get = getPosition,
  2981. args = {
  2982. anchorPoint = {
  2983. order = 0.50,
  2984. type = "select",
  2985. name = L["Anchor point"],
  2986. values = positionList,
  2987. hidden = false,
  2988. get = function(info)
  2989. local position = ShadowUF.db.profile.positions[info[2]]
  2990. if( ShadowUF.db.profile.advanced ) then
  2991. return position[info[#(info)]]
  2992. end
  2993. return position.movedAnchor or position[info[#(info)]]
  2994. end,
  2995. },
  2996. anchorTo = {
  2997. order = 1,
  2998. type = "select",
  2999. name = L["Anchor to"],
  3000. values = getAnchorParents,
  3001. hidden = false,
  3002. },
  3003. sep = {
  3004. order = 2,
  3005. type = "description",
  3006. name = "",
  3007. width = "full",
  3008. hidden = false,
  3009. },
  3010. x = {
  3011. order = 3,
  3012. type = "input",
  3013. name = L["X Offset"],
  3014. validate = checkNumber,
  3015. set = setNumber,
  3016. get = getString,
  3017. hidden = false,
  3018. },
  3019. y = {
  3020. order = 4,
  3021. type = "input",
  3022. name = L["Y Offset"],
  3023. validate = checkNumber,
  3024. set = setNumber,
  3025. get = getString,
  3026. hidden = false,
  3027. },
  3028. },
  3029. },
  3030. orHeader = {
  3031. order = 1.5,
  3032. type = "header",
  3033. name = L["Or you can set a position manually"],
  3034. hidden = function(info) if( info[2] == "global" or hideAdvancedOption() ) then return true else return false end end,
  3035. },
  3036. position = {
  3037. order = 2,
  3038. type = "group",
  3039. hidden = function(info) if( info[2] == "global" or hideAdvancedOption() ) then return true else return false end end,
  3040. inline = true,
  3041. name = L["Manual position"],
  3042. set = setPosition,
  3043. get = getPosition,
  3044. args = {
  3045. point = {
  3046. order = 0,
  3047. type = "select",
  3048. name = L["Point"],
  3049. values = pointPositions,
  3050. hidden = false,
  3051. },
  3052. anchorTo = {
  3053. order = 0.50,
  3054. type = "select",
  3055. name = L["Anchor to"],
  3056. values = getAnchorParents,
  3057. hidden = false,
  3058. },
  3059. relativePoint = {
  3060. order = 1,
  3061. type = "select",
  3062. name = L["Relative point"],
  3063. values = pointPositions,
  3064. hidden = false,
  3065. },
  3066. sep = {
  3067. order = 2,
  3068. type = "description",
  3069. name = "",
  3070. width = "full",
  3071. hidden = false,
  3072. },
  3073. x = {
  3074. order = 3,
  3075. type = "input",
  3076. name = L["X Offset"],
  3077. validate = checkNumber,
  3078. set = setNumber,
  3079. get = getString,
  3080. hidden = false,
  3081. },
  3082. y = {
  3083. order = 4,
  3084. type = "input",
  3085. name = L["Y Offset"],
  3086. validate = checkNumber,
  3087. set = setNumber,
  3088. get = getString,
  3089. hidden = false,
  3090. },
  3091. },
  3092. },
  3093. },
  3094. },
  3095. bars = {
  3096. order = 3,
  3097. name = L["Bars"],
  3098. type = "group",
  3099. hidden = isModifiersSet,
  3100. set = setUnit,
  3101. get = getUnit,
  3102. args = {
  3103. powerbar = {
  3104. order = 1,
  3105. type = "group",
  3106. inline = true,
  3107. name = L["Power bar"],
  3108. hidden = false,
  3109. args = {
  3110. powerBar = {
  3111. order = 1,
  3112. type = "toggle",
  3113. name = string.format(L["Enable %s"], L["Power bar"]),
  3114. arg = "powerBar.enabled",
  3115. },
  3116. predictPower = {
  3117. order = 2,
  3118. type = "toggle",
  3119. name = L["Enable quick power"],
  3120. desc = L["Turns fast updating of the power bar on giving you more up to date power information than normal."],
  3121. arg = "powerBar.predicted",
  3122. },
  3123. altPowerBar = {
  3124. order = 3,
  3125. type = "toggle",
  3126. name = string.format(L["Enable %s"], L["Alt. Power bar"]),
  3127. desc = L["Shows a bar for alternate power info (used in some encounters)"],
  3128. hidden = hideRestrictedOption,
  3129. arg = "altPowerBar.enabled",
  3130. },
  3131. sep = {
  3132. order = 4,
  3133. type = "description",
  3134. name = "",
  3135. width = "full",
  3136. hidden = false,
  3137. },
  3138. colorType = {
  3139. order = 5,
  3140. type = "select",
  3141. name = L["Color power by"],
  3142. desc = L["Primary means of coloring the power bar. Coloring by class only applies to players, for non-players it will default to the power type."],
  3143. values = {["class"] = L["Class"], ["type"] = L["Power Type"]},
  3144. arg = "powerBar.colorType",
  3145. }
  3146. },
  3147. },
  3148. classmiscbars = {
  3149. order = 2,
  3150. type = "group",
  3151. inline = true,
  3152. name = L["Class/misc bars"],
  3153. hidden = function(info)
  3154. local unit = info[2]
  3155. if( unit == "global" ) then
  3156. return not globalConfig.runeBar and not globalConfig.eclipseBar and not globalConfig.totemBar and not globalConfig.druidBar and not globalConfig.xpBar
  3157. else
  3158. return unit ~= "player"
  3159. end
  3160. end,
  3161. args = {
  3162. runeBar = {
  3163. order = 1,
  3164. type = "toggle",
  3165. name = string.format(L["Enable %s"], L["Rune bar"]),
  3166. desc = L["Adds rune bars and timers before runes refresh to the player frame."],
  3167. hidden = hideRestrictedOption,
  3168. arg = "runeBar.enabled",
  3169. },
  3170. eclipseBar = {
  3171. order = 1.25,
  3172. type = "toggle",
  3173. name = string.format(L["Enable %s"], L["Eclipse bar"]),
  3174. desc = L["Adds eclipse bars and how far into sun or moon eclipse is.."],
  3175. hidden = hideRestrictedOption,
  3176. arg = "eclipseBar.enabled",
  3177. },
  3178. totemBar = {
  3179. order = 1.5,
  3180. type = "toggle",
  3181. name = string.format(L["Enable %s"], ShadowUF.modules.totemBar.moduleName),
  3182. desc = function(info)
  3183. return select(2, UnitClass("player")) == "SHAMAN" and L["Adds totem bars with timers before they expire to the player frame."] or select(2, UnitClass("player")) == "DEATHKNIGHT" and L["Adds a bar indicating how much time is left on your ghoul timer, only used if you do not have a permanent ghoul."] or L["Adds a bar indicating how much time is left on your mushrooms."]
  3184. end,
  3185. hidden = hideRestrictedOption,
  3186. arg = "totemBar.enabled",
  3187. },
  3188. druidBar = {
  3189. order = 3,
  3190. type = "toggle",
  3191. name = string.format(L["Enable %s"], L["Druid mana bar"]),
  3192. desc = L["Adds another mana bar to the player frame when you are in Bear or Cat form showing you how much mana you have."],
  3193. hidden = hideRestrictedOption,
  3194. arg = "druidBar.enabled",
  3195. },
  3196. xpBar = {
  3197. order = 4,
  3198. type = "toggle",
  3199. name = string.format(L["Enable %s"], L["XP/Rep bar"]),
  3200. desc = L["This bar will automatically hide when you are at the level cap, or you do not have any reputations tracked."],
  3201. hidden = hideRestrictedOption,
  3202. arg = "xpBar.enabled",
  3203. },
  3204. },
  3205. },
  3206. healthBar = {
  3207. order = 2,
  3208. type = "group",
  3209. inline = true,
  3210. name = L["Health bar"],
  3211. hidden = false,
  3212. args = {
  3213. enabled = {
  3214. order = 1,
  3215. type = "toggle",
  3216. name = string.format(L["Enable %s"], L["Health bar"]),
  3217. arg = "healthBar.enabled",
  3218. },
  3219. sep = {
  3220. order = 3.5,
  3221. type = "description",
  3222. name = "",
  3223. },
  3224. healthColor = {
  3225. order = 4,
  3226. type = "select",
  3227. name = L["Color health by"],
  3228. desc = L["Primary means of coloring the health bar, color on aggro and color by reaction will override this if necessary."],
  3229. values = {["class"] = L["Class"], ["static"] = L["Static"], ["percent"] = L["Health percent"]},
  3230. arg = "healthBar.colorType",
  3231. },
  3232. reaction = {
  3233. order = 5,
  3234. type = "select",
  3235. name = L["Color by reaction on"],
  3236. desc = L["When to color the health bar by the units reaction, overriding the color health by option."],
  3237. arg = "healthBar.reactionType",
  3238. values = {["none"] = L["Never (Disabled)"], ["player"] = L["Players only"], ["npc"] = L["NPCs only"], ["both"] = L["Both"]},
  3239. hidden = function(info) return info[2] == "player" or info[2] == "pet" end,
  3240. },
  3241. colorAggro = {
  3242. order = 6,
  3243. type = "toggle",
  3244. name = L["Color on aggro"],
  3245. desc = L["Changes the health bar to the set hostile color (Red by default) when the unit takes aggro."],
  3246. arg = "healthBar.colorAggro",
  3247. hidden = hideRestrictedOption,
  3248. },
  3249. },
  3250. },
  3251. incHeal = {
  3252. order = 3,
  3253. type = "group",
  3254. inline = true,
  3255. -- name = L["Incoming heals and absorbs"],
  3256. name = L["Incoming heals"],
  3257. hidden = hideRestrictedOption,
  3258. disabled = function(info) return not getVariable(info[2], "healthBar", nil, "enabled") end,
  3259. args = {
  3260. heals = {
  3261. order = 1,
  3262. type = "toggle",
  3263. name = L["Show incoming heals"],
  3264. desc = L["Adds a bar inside the health bar indicating how much healing someone will receive."],
  3265. arg = "incHeal.heals",
  3266. hidden = false,
  3267. set = function(info, value)
  3268. setUnit(info, value)
  3269. setDirectUnit(info[2], "incHeal", nil, "enabled", getVariable(info[2], "incHeal", nil, "absorbs") or getVariable(info[2], "incHeal", nil, "heals"))
  3270. end
  3271. },
  3272. -- absorbs = {
  3273. -- order = 2,
  3274. -- type = "toggle",
  3275. -- name = L["Show current absorbs"],
  3276. -- desc = L["Adds a bar inside the health bar indicating how much damage absorbed they have."],
  3277. -- arg = "incHeal.absorbs",
  3278. -- hidden = false,
  3279. -- set = function(info, value)
  3280. -- setUnit(info, value)
  3281. -- setDirectUnit(info[2], "incHeal", nil, "enabled", getVariable(info[2], "incHeal", nil, "absorbs") or getVariable(info[2], "incHeal", nil, "heals"))
  3282. -- end
  3283. -- },
  3284. cap = {
  3285. order = 3,
  3286. type = "range",
  3287. name = L["Outside bar limit"],
  3288. desc = L["Percentage value of how far outside the unit frame the incoming heal bar can go. 130% means it will go 30% outside the frame, 100% means it will not go outside."],
  3289. min = 1, max = 1.50, step = 0.05, isPercent = true,
  3290. arg = "incHeal.cap",
  3291. hidden = false,
  3292. },
  3293. },
  3294. },
  3295. emptyBar = {
  3296. order = 4,
  3297. type = "group",
  3298. inline = true,
  3299. name = L["Empty bar"],
  3300. hidden = false,
  3301. args = {
  3302. enabled = {
  3303. order = 1,
  3304. type = "toggle",
  3305. name = string.format(L["Enable %s"], L["Empty bar"]),
  3306. desc = L["Adds an empty bar that you can put text into as a way of uncluttering other bars."],
  3307. arg = "emptyBar.enabled",
  3308. width = "full",
  3309. },
  3310. reaction = {
  3311. order = 2,
  3312. type = "select",
  3313. name = L["Color by reaction on"],
  3314. desc = L["When to color the empty bar by reaction, overriding the default color by option."],
  3315. arg = "emptyBar.reactionType",
  3316. values = {["none"] = L["Never (Disabled)"], ["player"] = L["Players only"], ["npc"] = L["NPCs only"], ["both"] = L["Both"]},
  3317. },
  3318. colorType = {
  3319. order = 3,
  3320. type = "toggle",
  3321. name = L["Color by class"],
  3322. desc = L["Players will be colored by class."],
  3323. arg = "emptyBar.class",
  3324. },
  3325. overrideColor = {
  3326. order = 4,
  3327. type = "color",
  3328. name = L["Background color"],
  3329. disabled = function(info)
  3330. local emptyBar = getVariable(info[2], nil, nil, "emptyBar")
  3331. return emptyBar.class and emptyBar.reaciton
  3332. end,
  3333. set = function(info, r, g, b)
  3334. local color = getUnit(info) or {}
  3335. color.r = r
  3336. color.g = g
  3337. color.b = b
  3338. setUnit(info, color)
  3339. end,
  3340. get = function(info)
  3341. local color = getUnit(info)
  3342. if( not color ) then
  3343. return 0, 0, 0
  3344. end
  3345. return color.r, color.g, color.b
  3346. end,
  3347. arg = "emptyBar.backgroundColor",
  3348. },
  3349. },
  3350. },
  3351. castBar = {
  3352. order = 5,
  3353. type = "group",
  3354. inline = true,
  3355. name = L["Cast bar"],
  3356. hidden = hideRestrictedOption,
  3357. args = {
  3358. enabled = {
  3359. order = 1,
  3360. type = "toggle",
  3361. name = string.format(L["Enable %s"], L["Cast bar"]),
  3362. desc = function(info) return ShadowUF.fakeUnits[info[2]] and string.format(L["Due to the nature of fake units, cast bars for %s are not super efficient and can take at most 0.10 seconds to notice a change in cast."], L.units[info[2]] or info[2]) end,
  3363. hidden = false,
  3364. arg = "castBar.enabled",
  3365. },
  3366. autoHide = {
  3367. order = 2,
  3368. type = "toggle",
  3369. name = L["Hide bar when empty"],
  3370. desc = L["Hides the cast bar if there is no cast active."],
  3371. hidden = false,
  3372. arg = "castBar.autoHide",
  3373. },
  3374. castIcon = {
  3375. order = 2.5,
  3376. type = "select",
  3377. name = L["Cast icon"],
  3378. arg = "castBar.icon",
  3379. values = {["LEFT"] = L["Left"], ["RIGHT"] = L["Right"], ["HIDE"] = L["Disabled"]},
  3380. hidden = false,
  3381. },
  3382. castName = {
  3383. order = 3,
  3384. type = "header",
  3385. name = L["Cast name"],
  3386. hidden = hideAdvancedOption,
  3387. },
  3388. nameEnabled = {
  3389. order = 4,
  3390. type = "toggle",
  3391. name = L["Show cast name"],
  3392. arg = "castBar.name.enabled",
  3393. hidden = hideAdvancedOption,
  3394. },
  3395. rankEnabled = {
  3396. order = 4.5,
  3397. type = "toggle",
  3398. name = L["Show cast rank"],
  3399. arg = "castBar.name.rank",
  3400. hidden = hideAdvancedOption,
  3401. disabled = disableIfCastName,
  3402. },
  3403. nameAnchor = {
  3404. order = 5,
  3405. type = "select",
  3406. name = L["Anchor point"],
  3407. desc = L["Where to anchor the cast name text."],
  3408. values = {["CLI"] = L["Inside Center Left"], ["CRI"] = L["Inside Center Right"]},
  3409. hidden = hideAdvancedOption,
  3410. arg = "castBar.name.anchorPoint",
  3411. },
  3412. nameSep = {
  3413. order = 6,
  3414. type = "description",
  3415. name = "",
  3416. width = "full",
  3417. hidden = hideAdvancedOption,
  3418. },
  3419. nameSize = {
  3420. order = 7,
  3421. type = "range",
  3422. name = L["Size"],
  3423. desc = L["Let's you modify the base font size to either make it larger or smaller."],
  3424. type = "range",
  3425. min = -10, max = 10, step = 1, softMin = -5, softMax = 5,
  3426. hidden = hideAdvancedOption,
  3427. arg = "castBar.name.size",
  3428. },
  3429. nameX = {
  3430. order = 8,
  3431. type = "range",
  3432. name = L["X Offset"],
  3433. min = -20, max = 20, step = 1,
  3434. hidden = hideAdvancedOption,
  3435. arg = "castBar.name.x",
  3436. },
  3437. nameY = {
  3438. order = 9,
  3439. type = "range",
  3440. name = L["Y Offset"],
  3441. min = -20, max = 20, step = 1,
  3442. hidden = hideAdvancedOption,
  3443. arg = "castBar.name.y",
  3444. },
  3445. castTime = {
  3446. order = 10,
  3447. type = "header",
  3448. name = L["Cast time"],
  3449. hidden = hideAdvancedOption,
  3450. },
  3451. timeEnabled = {
  3452. order = 11,
  3453. type = "toggle",
  3454. name = L["Show cast time"],
  3455. arg = "castBar.time.enabled",
  3456. hidden = hideAdvancedOption,
  3457. },
  3458. timeAnchor = {
  3459. order = 12,
  3460. type = "select",
  3461. name = L["Anchor point"],
  3462. desc = L["Where to anchor the cast time text."],
  3463. values = {["CLI"] = L["Inside Center Left"], ["CRI"] = L["Inside Center Right"]},
  3464. hidden = hideAdvancedOption,
  3465. arg = "castBar.time.anchorPoint",
  3466. },
  3467. timeSep = {
  3468. order = 13,
  3469. type = "description",
  3470. name = "",
  3471. width = "full",
  3472. hidden = hideAdvancedOption,
  3473. },
  3474. timeSize = {
  3475. order = 14,
  3476. type = "range",
  3477. name = L["Size"],
  3478. desc = L["Let's you modify the base font size to either make it larger or smaller."],
  3479. type = "range",
  3480. min = -10, max = 10, step = 1, softMin = -5, softMax = 5,
  3481. hidden = hideAdvancedOption,
  3482. arg = "castBar.time.size",
  3483. },
  3484. timeX = {
  3485. order = 15,
  3486. type = "range",
  3487. name = L["X Offset"],
  3488. min = -20, max = 20, step = 1,
  3489. hidden = hideAdvancedOption,
  3490. arg = "castBar.time.x",
  3491. },
  3492. timeY = {
  3493. order = 16,
  3494. type = "range",
  3495. name = L["Y Offset"],
  3496. min = -20, max = 20, step = 1,
  3497. hidden = hideAdvancedOption,
  3498. arg = "castBar.time.y",
  3499. },
  3500. },
  3501. },
  3502. },
  3503. },
  3504. widgetSize = {
  3505. order = 4,
  3506. name = L["Widget size"],
  3507. type = "group",
  3508. hidden = isModifiersSet,
  3509. set = setUnit,
  3510. get = getUnit,
  3511. args = {
  3512. help = {
  3513. order = 0,
  3514. type = "group",
  3515. name = L["Help"],
  3516. inline = true,
  3517. hidden = false,
  3518. args = {
  3519. help = {
  3520. order = 0,
  3521. type = "description",
  3522. name = L["Bars with an order higher or lower than the full size options will use the entire unit frame width.|n|nBar orders between those two numbers are shown next to the portrait."],
  3523. },
  3524. },
  3525. },
  3526. portrait = {
  3527. order = 0.5,
  3528. type = "group",
  3529. name = L["Portrait"],
  3530. inline = true,
  3531. hidden = false,
  3532. args = {
  3533. enableBar = {
  3534. order = 1,
  3535. type = "toggle",
  3536. name = L["Show as bar"],
  3537. desc = L["Changes this widget into a bar, you will be able to change the height and ordering like you can change health and power bars."],
  3538. arg = "$parent.isBar",
  3539. },
  3540. sep = {
  3541. order = 1.5,
  3542. type = "description",
  3543. name = "",
  3544. width = "full",
  3545. hidden = function(info) return getVariable(info[2], "portrait", nil, "isBar") end,
  3546. },
  3547. width = {
  3548. order = 2,
  3549. type = "range",
  3550. name = L["Width percent"],
  3551. desc = L["Percentage of width the portrait should use."],
  3552. min = 0, max = 1.0, step = 0.01, isPercent = true,
  3553. hidden = function(info) return getVariable(info[2], "portrait", nil, "isBar") end,
  3554. arg = "$parent.width",
  3555. },
  3556. before = {
  3557. order = 3,
  3558. type = "range",
  3559. name = L["Full size before"],
  3560. min = 0, max = 100, step = 5,
  3561. hidden = function(info) return getVariable(info[2], "portrait", nil, "isBar") end,
  3562. arg = "$parent.fullBefore",
  3563. },
  3564. after = {
  3565. order = 4,
  3566. type = "range",
  3567. name = L["Full size after"],
  3568. min = 0, max = 100, step = 5,
  3569. hidden = function(info) return getVariable(info[2], "portrait", nil, "isBar") end,
  3570. arg = "$parent.fullAfter",
  3571. },
  3572. order = {
  3573. order = 3,
  3574. type = "range",
  3575. name = L["Order"],
  3576. min = 0, max = 100, step = 5,
  3577. hidden = hideBarOption,
  3578. arg = "portrait.order",
  3579. },
  3580. height = {
  3581. order = 4,
  3582. type = "range",
  3583. name = L["Height"],
  3584. desc = L["How much of the frames total height this bar should get, this is a weighted value, the higher it is the more it gets."],
  3585. min = 0, max = 10, step = 0.1,
  3586. hidden = hideBarOption,
  3587. arg = "portrait.height",
  3588. },
  3589. },
  3590. },
  3591. },
  3592. },
  3593. auras = {
  3594. order = 5,
  3595. name = L["Auras"],
  3596. type = "group",
  3597. hidden = isModifiersSet,
  3598. set = setUnit,
  3599. get = getUnit,
  3600. args = {
  3601. temp = {
  3602. order = 0,
  3603. type = "group",
  3604. inline = true,
  3605. name = L["Temporary enchants"],
  3606. hidden = function(info) return info[2] ~= "player" end,
  3607. args = {
  3608. temporary = {
  3609. order = 0,
  3610. type = "toggle",
  3611. name = L["Enable temporary enchants"],
  3612. desc = L["Adds temporary enchants to the buffs for the player."],
  3613. disabled = function(info) return not getVariable(info[2], "auras", "buffs", "enabled") end,
  3614. arg = "auras.buffs.temporary",
  3615. width = "double",
  3616. },
  3617. },
  3618. },
  3619. buffs = Config.auraTable,
  3620. debuffs = Config.auraTable,
  3621. },
  3622. },
  3623. indicators = {
  3624. order = 5.5,
  3625. type = "group",
  3626. name = L["Indicators"],
  3627. hidden = isModifiersSet,
  3628. childGroups = "tree",
  3629. set = setUnit,
  3630. get = getUnit,
  3631. args = {
  3632. },
  3633. },
  3634. tag = {
  3635. order = 7,
  3636. name = L["Text/Tags"],
  3637. type = "group",
  3638. hidden = isModifiersSet,
  3639. childGroups = "tree",
  3640. args = tagWizard,
  3641. },
  3642. },
  3643. }
  3644. for _, indicator in pairs(ShadowUF.modules.indicators.list) do
  3645. Config.unitTable.args.indicators.args[indicator] = Config.indicatorTable
  3646. end
  3647. -- Check for unit conflicts
  3648. local function hideZoneConflict()
  3649. for _, zone in pairs(ShadowUF.db.profile.visibility) do
  3650. for unit, status in pairs(zone) do
  3651. if( L.units[unit] and ( not status and ShadowUF.db.profile.units[unit].enabled or status and not ShadowUF.db.profile.units[unit].enabled ) ) then
  3652. return nil
  3653. end
  3654. end
  3655. end
  3656. return true
  3657. end
  3658. options.args.enableUnits = {
  3659. type = "group",
  3660. name = L["Enabled units"],
  3661. desc = getPageDescription,
  3662. args = {
  3663. help = {
  3664. order = 1,
  3665. type = "group",
  3666. inline = true,
  3667. name = L["Help"],
  3668. hidden = function()
  3669. if( not hideZoneConflict() or hideBasicOption() ) then
  3670. return true
  3671. end
  3672. return nil
  3673. end,
  3674. args = {
  3675. help = {
  3676. order = 0,
  3677. type = "description",
  3678. name = L["The check boxes below will allow you to enable or disable units."],
  3679. },
  3680. },
  3681. },
  3682. zoneenabled = {
  3683. order = 1.5,
  3684. type = "group",
  3685. inline = true,
  3686. name = L["Zone configuration units"],
  3687. hidden = hideZoneConflict,
  3688. args = {
  3689. help = {
  3690. order = 1,
  3691. type = "description",
  3692. name = L["|cffff2020Warning!|r Some units have overrides set in zone configuration, and may show (or not show up) in certain zone. Regardless of the settings below."]
  3693. },
  3694. sep = {
  3695. order = 2,
  3696. type = "header",
  3697. name = "",
  3698. },
  3699. units = {
  3700. order = 3,
  3701. type = "description",
  3702. name = function()
  3703. local text = {}
  3704. for zoneType, zone in pairs(ShadowUF.db.profile.visibility) do
  3705. local errors = {}
  3706. for unit, status in pairs(zone) do
  3707. if( L.units[unit] ) then
  3708. if ( not status and ShadowUF.db.profile.units[unit].enabled ) then
  3709. table.insert(errors, string.format(L["|cffff2020%s|r units disabled"], L.units[unit]))
  3710. elseif( status and not ShadowUF.db.profile.units[unit].enabled ) then
  3711. table.insert(errors, string.format(L["|cff20ff20%s|r units enabled"], L.units[unit]))
  3712. end
  3713. end
  3714. end
  3715. if( #(errors) > 1 ) then
  3716. table.insert(text, string.format("|cfffed000%s|r have the following overrides: %s", AREA_NAMES[zoneType], table.concat(errors, ", ")))
  3717. elseif( #(errors) == 1 ) then
  3718. table.insert(text, string.format("|cfffed000%s|r has the override: %s", AREA_NAMES[zoneType], errors[1]))
  3719. end
  3720. end
  3721. return #(text) > 0 and table.concat(text, "|n") or ""
  3722. end,
  3723. },
  3724. },
  3725. },
  3726. enabled = {
  3727. order = 2,
  3728. type = "group",
  3729. inline = true,
  3730. name = L["Enable units"],
  3731. args = {},
  3732. },
  3733. },
  3734. }
  3735. local sort_units = function(a, b)
  3736. return a < b
  3737. end
  3738. options.args.units = {
  3739. type = "group",
  3740. name = L["Unit configuration"],
  3741. desc = getPageDescription,
  3742. args = {
  3743. help = {
  3744. order = 1,
  3745. type = "group",
  3746. inline = true,
  3747. name = L["Help"],
  3748. args = {
  3749. help = {
  3750. order = 0,
  3751. type = "description",
  3752. name = L["Wondering what all of the tabs for the unit configuration mean? Here's some information:|n|n|cfffed000General:|r Portrait, range checker, combat fader, border highlighting|n|cfffed000Frame:|r Unit positioning and frame anchoring|n|cfffed000Bars:|r Health, power, empty and cast bar, and combo point configuration|n|cfffed000Widget size:|r All bar and portrait sizing and ordering options|n|cfffed000Auras:|r All aura configuration for enabling/disabling/enlarging self/etc|n|cfffed000Indicators:|r All indicator configuration|n|cfffed000Text/Tags:|r Tag management as well as text positioning and width settings.|n|n|n*** Frequently looked for options ***|n|n|cfffed000Raid frames by group|r - Unit configuration -> Raid -> Raid -> Separate raid frames|n|cfffed000Class coloring:|r Bars -> Color health by|n|cfffed000Timers on auras:|r You need OmniCC for that|n|cfffed000Showing/Hiding default buff frames:|r Hide Blizzard -> Hide buff frames|n|cfffed000Percentage HP/MP text:|r Tags/Text tab, use the [percenthp] or [percentpp] tags|n|cfffed000Hiding party based on raid|r - Unit configuration -> Party -> Party -> Hide in 6-man raid/Hide in any raid"],
  3753. fontSize = "medium",
  3754. },
  3755. },
  3756. },
  3757. global = {
  3758. type = "group",
  3759. childGroups = "tab",
  3760. order = 0,
  3761. name = L["Global"],
  3762. args = {
  3763. test = {
  3764. order = 0,
  3765. type = "group",
  3766. name = L["Currently modifying"],
  3767. inline = true,
  3768. hidden = function()
  3769. for k in pairs(modifyUnits) do return false end
  3770. return true
  3771. end,
  3772. args = {
  3773. info = {
  3774. order = 0,
  3775. type = "description",
  3776. name = function()
  3777. local units = {};
  3778. for unit, enabled in pairs(modifyUnits) do
  3779. if( enabled ) then
  3780. table.insert(units, L.units[unit])
  3781. end
  3782. end
  3783. table.sort(units, sort_units)
  3784. return table.concat(units, ", ")
  3785. end,
  3786. }
  3787. }
  3788. },
  3789. units = {
  3790. order = 1,
  3791. type = "group",
  3792. name = L["Units"],
  3793. set = function(info, value)
  3794. local unit = info[#(info)]
  3795. if( IsShiftKeyDown() ) then
  3796. for _, unit in pairs(ShadowUF.unitList) do
  3797. if( ShadowUF.db.profile.units[unit].enabled ) then
  3798. modifyUnits[unit] = value and true or nil
  3799. if( value ) then
  3800. globalConfig = mergeTables(globalConfig, ShadowUF.db.profile.units[unit])
  3801. end
  3802. end
  3803. end
  3804. else
  3805. modifyUnits[unit] = value and true or nil
  3806. if( value ) then
  3807. globalConfig = mergeTables(globalConfig, ShadowUF.db.profile.units[unit])
  3808. end
  3809. end
  3810. -- Check if we have nothing else selected, if so wipe it
  3811. local hasUnit
  3812. for k in pairs(modifyUnits) do hasUnit = true break end
  3813. if( not hasUnit ) then
  3814. globalConfig = {}
  3815. end
  3816. AceRegistry:NotifyChange("ShadowedUF")
  3817. end,
  3818. get = function(info) return modifyUnits[info[#(info)]] end,
  3819. args = {
  3820. help = {
  3821. order = 0,
  3822. type = "group",
  3823. name = L["Help"],
  3824. inline = true,
  3825. args = {
  3826. help = {
  3827. order = 0,
  3828. type = "description",
  3829. name = L["Select the units that you want to modify, any settings changed will change every unit you selected. If you want to anchor or change raid/party unit specific settings you will need to do that through their options.|n|nShift click a unit to select all/unselect all."],
  3830. },
  3831. },
  3832. },
  3833. units = {
  3834. order = 1,
  3835. type = "group",
  3836. name = L["Units"],
  3837. inline = true,
  3838. args = {},
  3839. },
  3840. },
  3841. },
  3842. },
  3843. },
  3844. },
  3845. }
  3846. -- Load modules into the unit table
  3847. for key, module in pairs(ShadowUF.modules) do
  3848. local canHaveBar = module.moduleHasBar
  3849. for _, data in pairs(ShadowUF.defaults.profile.units) do
  3850. if( data[key] and data[key].isBar ~= nil ) then
  3851. canHaveBar = true
  3852. end
  3853. end
  3854. if( canHaveBar ) then
  3855. Config.unitTable.args.widgetSize.args[key] = Config.barTable
  3856. end
  3857. end
  3858. -- Load global unit
  3859. for k, v in pairs(Config.unitTable.args) do
  3860. options.args.units.args.global.args[k] = v
  3861. end
  3862. -- Load all of the per unit settings
  3863. local perUnitList = {
  3864. order = getUnitOrder,
  3865. type = "toggle",
  3866. name = getName,
  3867. hidden = isUnitDisabled,
  3868. desc = function(info)
  3869. return string.format(L["Adds %s to the list of units to be modified when you change values in this tab."], L.units[info[#(info)]])
  3870. end,
  3871. }
  3872. -- Enabled units list
  3873. local unitCatOrder = {}
  3874. local enabledUnits = {
  3875. order = function(info) return unitCatOrder[info[#(info)]] + getUnitOrder(info) end,
  3876. type = "toggle",
  3877. name = getName,
  3878. set = function(info, value)
  3879. local unit = info[#(info)]
  3880. for child, parent in pairs(ShadowUF.Units.childUnits) do
  3881. if( unit == parent and not value ) then
  3882. ShadowUF.db.profile.units[child].enabled = false
  3883. end
  3884. end
  3885. ShadowUF.modules.movers:Update()
  3886. ShadowUF.db.profile.units[unit].enabled = value
  3887. ShadowUF:LoadUnits()
  3888. -- Update party frame visibility
  3889. if( unit == "raid" and ShadowUF.Units.headerFrames.party ) then
  3890. ShadowUF.Units:SetHeaderAttributes(ShadowUF.Units.headerFrames.party, "party")
  3891. end
  3892. ShadowUF.modules.movers:Update()
  3893. end,
  3894. get = function(info)
  3895. return ShadowUF.db.profile.units[info[#(info)]].enabled
  3896. end,
  3897. desc = function(info)
  3898. local unit = info[#(info)]
  3899. local unitDesc = UNIT_DESC[unit] or ""
  3900. if( ShadowUF.db.profile.units[unit].enabled and ShadowUF.Units.childUnits[unit] ) then
  3901. if( unitDesc ~= "" ) then unitDesc = unitDesc .. "\n\n" end
  3902. return unitDesc .. string.format(L["This unit depends on another to work, disabling %s will disable %s."], L.units[ShadowUF.Units.childUnits[unit]], L.units[unit])
  3903. elseif( not ShadowUF.db.profile.units[unit].enabled ) then
  3904. for child, parent in pairs(ShadowUF.Units.childUnits) do
  3905. if( parent == unit ) then
  3906. if( unitDesc ~= "" ) then unitDesc = unitDesc .. "\n\n" end
  3907. return unitDesc .. L["This unit has child units that depend on it, you need to enable this unit before you can enable its children."]
  3908. end
  3909. end
  3910. end
  3911. return unitDesc ~= "" and unitDesc
  3912. end,
  3913. disabled = function(info)
  3914. local unit = info[#(info)]
  3915. if( ShadowUF.Units.childUnits[unit] ) then
  3916. return not ShadowUF.db.profile.units[ShadowUF.Units.childUnits[unit]].enabled
  3917. end
  3918. return false
  3919. end,
  3920. }
  3921. local unitCategory = {
  3922. order = function(info)
  3923. local cat = info[#(info)]
  3924. return cat == "playercat" and 50 or cat == "generalcat" and 100 or cat == "partycat" and 200 or cat == "raidcat" and 300 or 400
  3925. end,
  3926. type = "header",
  3927. name = function(info)
  3928. local cat = info[#(info)]
  3929. return cat == "playercat" and L["Player"] or cat == "generalcat" and L["General"] or cat == "raidcat" and L["Raid"] or cat == "partycat" and L["Party"] or cat == "arenacat" and L["Arena"]
  3930. end,
  3931. width = "full",
  3932. }
  3933. for cat, list in pairs(unitCategories) do
  3934. options.args.enableUnits.args.enabled.args[cat .. "cat"] = unitCategory
  3935. for _, unit in pairs(list) do
  3936. unitCatOrder[unit] = cat == "player" and 50 or cat == "general" and 100 or cat == "party" and 200 or cat == "raid" and 300 or 400
  3937. end
  3938. end
  3939. for order, unit in pairs(ShadowUF.unitList) do
  3940. options.args.enableUnits.args.enabled.args[unit] = enabledUnits
  3941. options.args.units.args.global.args.units.args.units.args[unit] = perUnitList
  3942. options.args.units.args[unit] = Config.unitTable
  3943. unitCatOrder[unit] = unitCatOrder[unit] or 100
  3944. end
  3945. end
  3946. ---------------------
  3947. -- FILTER CONFIGURATION
  3948. ---------------------
  3949. local function loadFilterOptions()
  3950. local hasWhitelist, hasBlacklist, rebuildFilters
  3951. local filterMap, spellMap = {}, {}
  3952. local manageFiltersTable = {
  3953. order = function(info) return info[#(info)] == "whitelists" and 1 or 2 end,
  3954. type = "group",
  3955. name = function(info) return info[#(info)] == "whitelists" and L["Whitelists"] or L["Blacklists"] end,
  3956. args = {
  3957. },
  3958. }
  3959. local function reloadUnitAuras()
  3960. for _, frame in pairs(ShadowUF.Units.unitFrames) do
  3961. if( UnitExists(frame.unit) and frame.visibility.auras ) then
  3962. ShadowUF.modules.auras:UpdateFilter(frame)
  3963. frame:FullUpdate()
  3964. end
  3965. end
  3966. end
  3967. local function setFilterType(info, value)
  3968. local filter = filterMap[info[#(info) - 2]]
  3969. local filterType = info[#(info) - 3]
  3970. ShadowUF.db.profile.filters[filterType][filter][info[#(info)]] = value
  3971. reloadUnitAuras()
  3972. end
  3973. local function getFilterType(info)
  3974. local filter = filterMap[info[#(info) - 2]]
  3975. local filterType = info[#(info) - 3]
  3976. return ShadowUF.db.profile.filters[filterType][filter][info[#(info)]]
  3977. end
  3978. --- Container widget for the filter listing
  3979. local filterEditTable = {
  3980. order = 0,
  3981. type = "group",
  3982. name = function(info) return filterMap[info[#(info)]] end,
  3983. hidden = function(info) return not ShadowUF.db.profile.filters[info[#(info) - 1]][filterMap[info[#(info)]]] end,
  3984. args = {
  3985. general = {
  3986. order = 0,
  3987. type = "group",
  3988. name = function(info) return filterMap[info[#(info) - 1]] end,
  3989. hidden = false,
  3990. inline = true,
  3991. args = {
  3992. add = {
  3993. order = 0,
  3994. type = "input",
  3995. name = L["Aura name"],
  3996. --dialogControl = "Aura_EditBox",
  3997. hidden = false,
  3998. set = function(info, value)
  3999. local filterType = info[#(info) - 3]
  4000. local filter = filterMap[info[#(info) - 2]]
  4001. ShadowUF.db.profile.filters[filterType][filter][value] = true
  4002. reloadUnitAuras()
  4003. rebuildFilters()
  4004. end,
  4005. },
  4006. delete = {
  4007. order = 1,
  4008. type = "execute",
  4009. name = L["Delete filter"],
  4010. hidden = false,
  4011. confirmText = L["Are you sure you want to delete this filter?"],
  4012. confirm = true,
  4013. func = function(info, value)
  4014. local filterType = info[#(info) - 3]
  4015. local filter = filterMap[info[#(info) - 2]]
  4016. ShadowUF.db.profile.filters[filterType][filter] = nil
  4017. -- Delete anything that used this filter too
  4018. local filterList = filterType == "whitelist" and ShadowUF.db.profile.filters.zonewhite or filterType == "blacklist" and ShadowUF.db.profile.filters.zoneblack
  4019. for id, filterUsed in pairs(filterList) do
  4020. if( filterUsed == filter ) then
  4021. filterList[id] = nil
  4022. end
  4023. end
  4024. reloadUnitAuras()
  4025. rebuildFilters()
  4026. end,
  4027. },
  4028. },
  4029. },
  4030. filters = {
  4031. order = 2,
  4032. type = "group",
  4033. inline = true,
  4034. hidden = false,
  4035. name = L["Aura types to filter"],
  4036. args = {
  4037. buffs = {
  4038. order = 4,
  4039. type = "toggle",
  4040. name = L["Buffs"],
  4041. desc = L["When this filter is active, apply the filter to buffs."],
  4042. set = setFilterType,
  4043. get = getFilterType,
  4044. },
  4045. debuffs = {
  4046. order = 5,
  4047. type = "toggle",
  4048. name = L["Debuffs"],
  4049. desc = L["When this filter is active, apply the filter to debuffs."],
  4050. set = setFilterType,
  4051. get = getFilterType,
  4052. },
  4053. },
  4054. },
  4055. spells = {
  4056. order = 3,
  4057. type = "group",
  4058. inline = true,
  4059. name = L["Auras"],
  4060. hidden = false,
  4061. args = {
  4062. },
  4063. },
  4064. },
  4065. }
  4066. -- Spell list for manage aura filters
  4067. local spellLabel = {
  4068. order = function(info) return tonumber(string.match(info[#(info)], "(%d+)")) end,
  4069. type = "description",
  4070. -- Odd I know, AceConfigDialog-3.0 expands descriptions to full width if width is nil
  4071. -- on the other hand we can't set width to "normal" so tricking it
  4072. width = "",
  4073. fontSize = "medium",
  4074. name = function(info) return spellMap[info[#(info)]] end,
  4075. }
  4076. local spellRow = {
  4077. order = function(info) return tonumber(string.match(info[#(info)], "(%d+)")) + 0.5 end,
  4078. type = "execute",
  4079. name = L["Delete"],
  4080. width = "half",
  4081. func = function(info)
  4082. local spell = spellMap[info[#(info)]]
  4083. local filter = filterMap[info[#(info) - 2]]
  4084. local filterType = info[#(info) - 3]
  4085. ShadowUF.db.profile.filters[filterType][filter][spell] = nil
  4086. rebuildFilters()
  4087. end
  4088. }
  4089. local noSpells = {
  4090. order = 0,
  4091. type = "description",
  4092. name = L["This filter has no auras in it, you will have to add some using the dialog above."],
  4093. }
  4094. -- The filter [View] widgets for manage aura filters
  4095. local filterLabel = {
  4096. order = function(info) return tonumber(string.match(info[#(info)], "(%d+)")) end,
  4097. type = "description",
  4098. width = "", -- Odd I know, AceConfigDialog-3.0 expands descriptions to full width if width is nil
  4099. fontSize = "medium",
  4100. name = function(info) return filterMap[info[#(info)]] end,
  4101. }
  4102. local filterRow = {
  4103. order = function(info) return tonumber(string.match(info[#(info)], "(%d+)")) + 0.5 end,
  4104. type = "execute",
  4105. name = L["View"],
  4106. width = "half",
  4107. func = function(info)
  4108. local filterType = info[#(info) - 2]
  4109. AceDialog.Status.ShadowedUF.children.filter.children.filters.status.groups.groups[filterType] = true
  4110. selectTabGroup("filter", "filters", filterType .. "\001" .. string.match(info[#(info)], "(%d+)"))
  4111. end
  4112. }
  4113. local noFilters = {
  4114. order = 0,
  4115. type = "description",
  4116. name = L["You do not have any filters of this type added yet, you will have to create one in the management panel before this page is useful."],
  4117. }
  4118. -- Container table for a filter zone
  4119. local globalSettings = {}
  4120. local zoneList = {"none", "pvp", "arena", "party", "raid"}
  4121. local filterTable = {
  4122. order = function(info) return info[#(info)] == "global" and 1 or info[#(info)] == "none" and 2 or 3 end,
  4123. type = "group",
  4124. inline = true,
  4125. hidden = function() return not hasWhitelist and not hasBlacklist end,
  4126. name = function(info) return AREA_NAMES[info[#(info)]] or L["Global"] end,
  4127. set = function(info, value)
  4128. local filter = filterMap[info[#(info)]]
  4129. local zone = info[#(info) - 1]
  4130. local unit = info[#(info) - 2]
  4131. local filterKey = ShadowUF.db.profile.filters.whitelists[filter] and "zonewhite" or "zoneblack"
  4132. for _, zoneConfig in pairs(zoneList) do
  4133. if( zone == "global" or zoneConfig == zone ) then
  4134. if( unit == "global" ) then
  4135. globalSettings[zoneConfig .. filterKey] = value and filter or false
  4136. for _, unit in pairs(ShadowUF.unitList) do
  4137. ShadowUF.db.profile.filters[filterKey][zoneConfig .. unit] = value and filter or nil
  4138. end
  4139. else
  4140. ShadowUF.db.profile.filters[filterKey][zoneConfig .. unit] = value and filter or nil
  4141. end
  4142. end
  4143. end
  4144. if( zone == "global" ) then
  4145. globalSettings[zone .. unit .. filterKey] = value and filter or false
  4146. end
  4147. reloadUnitAuras()
  4148. end,
  4149. get = function(info)
  4150. local filter = filterMap[info[#(info)]]
  4151. local zone = info[#(info) - 1]
  4152. local unit = info[#(info) - 2]
  4153. if( unit == "global" or zone == "global" ) then
  4154. local id = zone == "global" and zone .. unit or zone
  4155. local filterKey = ShadowUF.db.profile.filters.whitelists[filter] and "zonewhite" or "zoneblack"
  4156. if( info[#(info)] == "nofilter" ) then
  4157. return globalSettings[id .. "zonewhite"] == false and globalSettings[id .. "zoneblack"] == false
  4158. end
  4159. return globalSettings[id .. filterKey] == filter
  4160. end
  4161. if( info[#(info)] == "nofilter" ) then
  4162. return not ShadowUF.db.profile.filters.zonewhite[zone .. unit] and not ShadowUF.db.profile.filters.zoneblack[zone .. unit]
  4163. end
  4164. return ShadowUF.db.profile.filters.zonewhite[zone .. unit] == filter or ShadowUF.db.profile.filters.zoneblack[zone .. unit] == filter
  4165. end,
  4166. args = {
  4167. nofilter = {
  4168. order = 0,
  4169. type = "toggle",
  4170. name = L["Don't use a filter"],
  4171. hidden = false,
  4172. set = function(info, value)
  4173. local filter = filterMap[info[#(info)]]
  4174. local zone = info[#(info) - 1]
  4175. local unit = info[#(info) - 2]
  4176. for _, zoneConfig in pairs(zoneList) do
  4177. if( zone == "global" or zoneConfig == zone ) then
  4178. if( unit == "global" ) then
  4179. globalSettings[zoneConfig .. "zonewhite"] = false
  4180. globalSettings[zoneConfig .. "zoneblack"] = false
  4181. for _, unit in pairs(ShadowUF.unitList) do
  4182. ShadowUF.db.profile.filters.zonewhite[zoneConfig .. unit] = nil
  4183. ShadowUF.db.profile.filters.zoneblack[zoneConfig .. unit] = nil
  4184. end
  4185. else
  4186. ShadowUF.db.profile.filters.zonewhite[zoneConfig .. unit] = nil
  4187. ShadowUF.db.profile.filters.zoneblack[zoneConfig .. unit] = nil
  4188. end
  4189. end
  4190. end
  4191. if( zone == "global" ) then
  4192. globalSettings[zone .. unit .. "zonewhite"] = false
  4193. globalSettings[zone .. unit .. "zoneblack"] = false
  4194. end
  4195. reloadUnitAuras()
  4196. end,
  4197. },
  4198. white = {
  4199. order = 1,
  4200. type = "header",
  4201. name = "|cffffffff" .. L["Whitelists"] .. "|r",
  4202. hidden = function(info) return not hasWhitelist end
  4203. },
  4204. black = {
  4205. order = 3,
  4206. type = "header",
  4207. name = L["Blacklists"], -- In theory I would make this black, but as black doesn't work with a black background I'll skip that
  4208. hidden = function(info) return not hasBlacklist end
  4209. },
  4210. },
  4211. }
  4212. -- Toggle used for set filter zones to enable filters
  4213. local filterToggle = {
  4214. order = function(info) return ShadowUF.db.profile.filters.whitelists[filterMap[info[#(info)]]] and 2 or 4 end,
  4215. type = "toggle",
  4216. name = function(info) return filterMap[info[#(info)]] end,
  4217. desc = function(info)
  4218. local filter = filterMap[info[#(info)]]
  4219. filter = ShadowUF.db.profile.filters.whitelists[filter] or ShadowUF.db.profile.filters.blacklists[filter]
  4220. if( filter.buffs and filter.debuffs ) then
  4221. return L["Filtering both buffs and debuffs"]
  4222. elseif( filter.buffs ) then
  4223. return L["Filtering buffs only"]
  4224. elseif( filter.debuffs ) then
  4225. return L["Filtering debuffs only"]
  4226. end
  4227. return L["This filter has no aura types set to filter out."]
  4228. end,
  4229. }
  4230. -- Load existing filters in
  4231. -- This needs to be cleaned up later
  4232. local filterID, spellID = 0, 0
  4233. local function buildList(type)
  4234. local manageFiltersTable = {
  4235. order = type == "whitelists" and 1 or 2,
  4236. type = "group",
  4237. name = type == "whitelists" and L["Whitelists"] or L["Blacklists"],
  4238. args = {
  4239. groups = {
  4240. order = 0,
  4241. type = "group",
  4242. inline = true,
  4243. name = function(info) return info[#(info) - 1] == "whitelists" and L["Whitelist filters"] or L["Blacklist filters"] end,
  4244. args = {
  4245. },
  4246. },
  4247. },
  4248. }
  4249. local hasFilters
  4250. for name, spells in pairs(ShadowUF.db.profile.filters[type]) do
  4251. hasFilters = true
  4252. filterID = filterID + 1
  4253. filterMap[tostring(filterID)] = name
  4254. filterMap[filterID .. "label"] = name
  4255. filterMap[filterID .. "row"] = name
  4256. manageFiltersTable.args[tostring(filterID)] = CopyTable(filterEditTable)
  4257. manageFiltersTable.args.groups.args[filterID .. "label"] = filterLabel
  4258. manageFiltersTable.args.groups.args[filterID .. "row"] = filterRow
  4259. filterTable.args[tostring(filterID)] = filterToggle
  4260. local hasSpells
  4261. for spellName in pairs(spells) do
  4262. if( spellName ~= "buffs" and spellName ~= "debuffs" ) then
  4263. hasSpells = true
  4264. spellID = spellID + 1
  4265. spellMap[tostring(spellID)] = spellName
  4266. spellMap[spellID .. "label"] = spellName
  4267. manageFiltersTable.args[tostring(filterID)].args.spells.args[spellID .. "label"] = spellLabel
  4268. manageFiltersTable.args[tostring(filterID)].args.spells.args[tostring(spellID)] = spellRow
  4269. end
  4270. end
  4271. if( not hasSpells ) then
  4272. manageFiltersTable.args[tostring(filterID)].args.spells.args.noSpells = noSpells
  4273. end
  4274. end
  4275. if( not hasFilters ) then
  4276. if( type == "whitelists" ) then hasWhitelist = nil else hasBlacklist = nil end
  4277. manageFiltersTable.args.groups.args.noFilters = noFilters
  4278. end
  4279. return manageFiltersTable
  4280. end
  4281. rebuildFilters = function()
  4282. for id in pairs(filterMap) do filterTable.args[id] = nil end
  4283. spellID = 0
  4284. filterID = 0
  4285. hasBlacklist = true
  4286. hasWhitelist = true
  4287. table.wipe(filterMap)
  4288. table.wipe(spellMap)
  4289. options.args.filter.args.filters.args.whitelists = buildList("whitelists")
  4290. options.args.filter.args.filters.args.blacklists = buildList("blacklists")
  4291. end
  4292. local unitFilterSelection = {
  4293. order = function(info) return info[#(info)] == "global" and 1 or (getUnitOrder(info) + 1) end,
  4294. type = "group",
  4295. name = function(info) return info[#(info)] == "global" and L["Global"] or getName(info) end,
  4296. disabled = function(info)
  4297. if( info[#(info)] == "global" ) then
  4298. return false
  4299. end
  4300. return not hasWhitelist and not hasBlacklist
  4301. end,
  4302. args = {
  4303. help = {
  4304. order = 0,
  4305. type = "group",
  4306. inline = true,
  4307. name = L["Help"],
  4308. hidden = function() return hasWhitelist or hasBlacklist end,
  4309. args = {
  4310. help = {
  4311. type = "description",
  4312. name = L["You will need to create an aura filter before you can set which unit to enable aura filtering on."],
  4313. width = "full",
  4314. }
  4315. },
  4316. },
  4317. header = {
  4318. order = 0,
  4319. type = "header",
  4320. name = function(info) return (info[#(info) - 1] == "global" and L["Global"] or L.units[info[#(info) - 1]]) end,
  4321. hidden = function() return not hasWhitelist and not hasBlacklist end,
  4322. },
  4323. global = filterTable,
  4324. none = filterTable,
  4325. pvp = filterTable,
  4326. arena = filterTable,
  4327. party = filterTable,
  4328. raid = filterTable,
  4329. }
  4330. }
  4331. local addFilter = {type = "whitelists"}
  4332. options.args.filter = {
  4333. type = "group",
  4334. name = L["Aura filters"],
  4335. childGroups = "tab",
  4336. desc = getPageDescription,
  4337. args = {
  4338. groups = {
  4339. order = 1,
  4340. type = "group",
  4341. name = L["Set filter zones"],
  4342. args = {
  4343. help = {
  4344. order = 0,
  4345. type = "group",
  4346. inline = true,
  4347. name = L["Help"],
  4348. args = {
  4349. help = {
  4350. type = "description",
  4351. name = L["You can set what unit frame should use what filter group and in what zone type here, if you want to change what auras goes into what group then see the \"Manage aura groups\" option."],
  4352. width = "full",
  4353. }
  4354. },
  4355. },
  4356. }
  4357. },
  4358. filters = {
  4359. order = 2,
  4360. type = "group",
  4361. name = L["Manage aura filters"],
  4362. childGroups = "tree",
  4363. args = {
  4364. manage = {
  4365. order = 1,
  4366. type = "group",
  4367. name = L["Management"],
  4368. args = {
  4369. help = {
  4370. order = 0,
  4371. type = "group",
  4372. inline = true,
  4373. name = L["Help"],
  4374. args = {
  4375. help = {
  4376. type = "description",
  4377. name = L["Whitelists will hide any aura not in the filter group.|nBlacklists will hide auras that are in the filter group."],
  4378. width = "full",
  4379. }
  4380. },
  4381. },
  4382. error = {
  4383. order = 1,
  4384. type = "group",
  4385. inline = true,
  4386. hidden = function() return not addFilter.error end,
  4387. name = L["Error"],
  4388. args = {
  4389. error = {
  4390. order = 0,
  4391. type = "description",
  4392. name = function() return addFilter.error end,
  4393. width = "full",
  4394. },
  4395. },
  4396. },
  4397. add = {
  4398. order = 2,
  4399. type = "group",
  4400. inline = true,
  4401. name = L["New filter"],
  4402. get = function(info) return addFilter[info[#(info)]] end,
  4403. args = {
  4404. name = {
  4405. order = 0,
  4406. type = "input",
  4407. name = L["Name"],
  4408. set = function(info, value)
  4409. addFilter[info[#(info)]] = string.trim(value) ~= "" and value or nil
  4410. addFilter.error = nil
  4411. end,
  4412. get = function(info) return addFilter.errorName or addFilter.name end,
  4413. validate = function(info, value)
  4414. local name = string.lower(string.trim(value))
  4415. for filter in pairs(ShadowUF.db.profile.filters.whitelists) do
  4416. if( string.lower(filter) == name ) then
  4417. addFilter.error = string.format(L["The whitelist \"%s\" already exists."], value)
  4418. addFilter.errorName = value
  4419. AceRegistry:NotifyChange("ShadowedUF")
  4420. return ""
  4421. end
  4422. end
  4423. for filter in pairs(ShadowUF.db.profile.filters.blacklists) do
  4424. if( string.lower(filter) == name ) then
  4425. addFilter.error = string.format(L["The blacklist \"%s\" already exists."], value)
  4426. addFilter.errorName = value
  4427. AceRegistry:NotifyChange("ShadowedUF")
  4428. return ""
  4429. end
  4430. end
  4431. addFilter.error = nil
  4432. addFilter.errorName = nil
  4433. return true
  4434. end,
  4435. },
  4436. type = {
  4437. order = 1,
  4438. type = "select",
  4439. name = L["Filter type"],
  4440. set = function(info, value) addFilter[info[#(info)]] = value end,
  4441. values = {["whitelists"] = L["Whitelist"], ["blacklists"] = L["Blacklist"]},
  4442. },
  4443. add = {
  4444. order = 2,
  4445. type = "execute",
  4446. name = L["Create"],
  4447. disabled = function(info) return not addFilter.name end,
  4448. func = function(info)
  4449. ShadowUF.db.profile.filters[addFilter.type][addFilter.name] = {buffs = true, debuffs = true}
  4450. rebuildFilters()
  4451. local id
  4452. for key, value in pairs(filterMap) do
  4453. if( value == addFilter.name ) then
  4454. id = key
  4455. break
  4456. end
  4457. end
  4458. AceDialog.Status.ShadowedUF.children.filter.children.filters.status.groups.groups[addFilter.type] = true
  4459. selectTabGroup("filter", "filters", addFilter.type .. "\001" .. id)
  4460. table.wipe(addFilter)
  4461. addFilter.type = "whitelists"
  4462. end,
  4463. },
  4464. },
  4465. },
  4466. },
  4467. },
  4468. },
  4469. },
  4470. },
  4471. }
  4472. options.args.filter.args.groups.args.global = unitFilterSelection
  4473. for _, unit in pairs(ShadowUF.unitList) do
  4474. options.args.filter.args.groups.args[unit] = unitFilterSelection
  4475. end
  4476. rebuildFilters()
  4477. end
  4478. ---------------------
  4479. -- TAG CONFIGURATION
  4480. ---------------------
  4481. local function loadTagOptions()
  4482. local tagData = {search = ""}
  4483. local function set(info, value, key)
  4484. local key = key or info[#(info)]
  4485. if( ShadowUF.Tags.defaultHelp[tagData.name] ) then
  4486. return
  4487. end
  4488. -- Reset loaded function + reload tags
  4489. if( key == "funct" ) then
  4490. ShadowUF.tagFunc[tagData.name] = nil
  4491. ShadowUF.Tags:Reload()
  4492. elseif( key == "category" ) then
  4493. local cat = ShadowUF.db.profile.tags[tagData.name][key]
  4494. if( cat and cat ~= value ) then
  4495. Config.tagTextTable.args[cat].args[tagData.name] = nil
  4496. Config.tagTextTable.args[value].args[tagData.name] = Config.tagTable
  4497. end
  4498. end
  4499. ShadowUF.db.profile.tags[tagData.name][key] = value
  4500. end
  4501. local function stripCode(text)
  4502. if( not text ) then
  4503. return ""
  4504. end
  4505. return string.gsub(string.gsub(text, "|", "||"), "\t", "")
  4506. end
  4507. local function get(info, key)
  4508. local key = key or info[#(info)]
  4509. if( key == "help" and ShadowUF.Tags.defaultHelp[tagData.name] ) then
  4510. return ShadowUF.Tags.defaultHelp[tagData.name] or ""
  4511. elseif( key == "events" and ShadowUF.Tags.defaultEvents[tagData.name] ) then
  4512. return ShadowUF.Tags.defaultEvents[tagData.name] or ""
  4513. elseif( key == "frequency" and ShadowUF.Tags.defaultFrequents[tagData.name] ) then
  4514. return ShadowUF.Tags.defaultFrequents[tagData.name] or ""
  4515. elseif( key == "category" and ShadowUF.Tags.defaultCategories[tagData.name] ) then
  4516. return ShadowUF.Tags.defaultCategories[tagData.name] or ""
  4517. elseif( key == "name" and ShadowUF.Tags.defaultNames[tagData.name] ) then
  4518. return ShadowUF.Tags.defaultNames[tagData.name] or ""
  4519. elseif( key == "funct" and ShadowUF.Tags.defaultTags[tagData.name] ) then
  4520. return ShadowUF.Tags.defaultTags[tagData.name] or ""
  4521. end
  4522. return ShadowUF.db.profile.tags[tagData.name] and ShadowUF.db.profile.tags[tagData.name][key] or ""
  4523. end
  4524. local function isSearchHidden(info)
  4525. return tagData.search ~= "" and not string.match(info[#(info)], tagData.search) or false
  4526. end
  4527. local function editTag(info)
  4528. tagData.name = info[#(info)]
  4529. if( ShadowUF.Tags.defaultHelp[tagData.name] ) then
  4530. tagData.error = L["You cannot edit this tag because it is one of the default ones included in this mod. This function is here to provide an example for your own custom tags."]
  4531. end
  4532. selectDialogGroup("tags", "edit")
  4533. end
  4534. -- Create all of the tag editor options, if it's a default tag will show it after any custom ones
  4535. local tagTable = {
  4536. type = "execute",
  4537. order = function(info) return ShadowUF.Tags.defaultTags[info[#(info)]] and 100 or 1 end,
  4538. name = getTagName,
  4539. desc = getTagHelp,
  4540. hidden = isSearchHidden,
  4541. func = editTag,
  4542. }
  4543. local tagCategories = {}
  4544. local function getTagCategories(info)
  4545. for k in pairs(tagCategories) do tagCategories[k] = nil end
  4546. for _, cat in pairs(ShadowUF.Tags.defaultCategories) do
  4547. tagCategories[cat] = TAG_GROUPS[cat]
  4548. end
  4549. return tagCategories
  4550. end
  4551. -- Tag configuration
  4552. options.args.tags = {
  4553. type = "group",
  4554. childGroups = "tab",
  4555. name = L["Add tags"],
  4556. desc = getPageDescription,
  4557. hidden = hideAdvancedOption,
  4558. args = {
  4559. general = {
  4560. order = 0,
  4561. type = "group",
  4562. name = L["Tag list"],
  4563. args = {
  4564. help = {
  4565. order = 0,
  4566. type = "group",
  4567. inline = true,
  4568. name = L["Help"],
  4569. hidden = function() return ShadowUF.db.profile.advanced end,
  4570. args = {
  4571. description = {
  4572. order = 0,
  4573. type = "description",
  4574. name = L["You can add new custom tags through this page, if you're looking to change what tags are used in text look under the Text tab for an Units configuration."],
  4575. },
  4576. },
  4577. },
  4578. search = {
  4579. order = 1,
  4580. type = "group",
  4581. inline = true,
  4582. name = L["Search"],
  4583. args = {
  4584. search = {
  4585. order = 1,
  4586. type = "input",
  4587. name = L["Search tags"],
  4588. set = function(info, text) tagData.search = text end,
  4589. get = function(info) return tagData.search end,
  4590. },
  4591. },
  4592. },
  4593. list = {
  4594. order = 2,
  4595. type = "group",
  4596. inline = true,
  4597. name = L["Tags"],
  4598. args = {},
  4599. },
  4600. },
  4601. },
  4602. add = {
  4603. order = 1,
  4604. type = "group",
  4605. name = L["Add new tag"],
  4606. args = {
  4607. help = {
  4608. order = 0,
  4609. type = "group",
  4610. inline = true,
  4611. name = L["Help"],
  4612. args = {
  4613. help = {
  4614. order = 0,
  4615. type = "description",
  4616. name = L["You can find more information on creating your own custom tags in the \"Help\" tab above."],
  4617. },
  4618. },
  4619. },
  4620. add = {
  4621. order = 1,
  4622. type = "group",
  4623. inline = true,
  4624. name = L["Add new tag"],
  4625. args = {
  4626. error = {
  4627. order = 0,
  4628. type = "description",
  4629. name = function() return tagData.addError or "" end,
  4630. hidden = function() return not tagData.addError end,
  4631. },
  4632. errorHeader = {
  4633. order = 0.50,
  4634. type = "header",
  4635. name = "",
  4636. hidden = function() return not tagData.addError end,
  4637. },
  4638. tag = {
  4639. order = 1,
  4640. type = "input",
  4641. name = L["Tag name"],
  4642. desc = L["Tag that you will use to access this code, do not wrap it in brackets or parenthesis it's automatically done. For example, you would enter \"foobar\" and then access it with [foobar]."],
  4643. validate = function(info, text)
  4644. if( text == "" ) then
  4645. tagData.addError = L["You must enter a tag name."]
  4646. elseif( string.match(text, "[%[%]%(%)]") ) then
  4647. tagData.addError = string.format(L["You cannot name a tag \"%s\", tag names should contain no brackets or parenthesis."], text)
  4648. elseif( ShadowUF.tagFunc[text] ) then
  4649. tagData.addError = string.format(L["The tag \"%s\" already exists."], text)
  4650. else
  4651. tagData.addError = nil
  4652. end
  4653. AceRegistry:NotifyChange("ShadowedUF")
  4654. return tagData.addError and "" or true
  4655. end,
  4656. set = function(info, tag)
  4657. tagData.name = tag
  4658. tagData.error = nil
  4659. tagData.addError = nil
  4660. ShadowUF.db.profile.tags[tag] = {func = "function(unit, unitOwner)\n\nend", category = "misc"}
  4661. options.args.tags.args.general.args.list.args[tag] = tagTable
  4662. Config.tagTextTable.args.misc.args[tag] = Config.tagTable
  4663. selectDialogGroup("tags", "edit")
  4664. end,
  4665. },
  4666. },
  4667. },
  4668. },
  4669. },
  4670. edit = {
  4671. order = 2,
  4672. type = "group",
  4673. name = L["Edit tag"],
  4674. hidden = function() return not tagData.name end,
  4675. args = {
  4676. help = {
  4677. order = 0,
  4678. type = "group",
  4679. inline = true,
  4680. name = L["Help"],
  4681. args = {
  4682. help = {
  4683. order = 0,
  4684. type = "description",
  4685. name = L["You can find more information on creating your own custom tags in the \"Help\" tab above.|nSUF will attempt to automatically detect what events your tag will need, so you do not generally need to fill out the events field."],
  4686. },
  4687. },
  4688. },
  4689. tag = {
  4690. order = 1,
  4691. type = "group",
  4692. inline = true,
  4693. name = function() return string.format(L["Editing %s"], tagData.name or "") end,
  4694. args = {
  4695. error = {
  4696. order = 0,
  4697. type = "description",
  4698. name = function()
  4699. if( tagData.error ) then
  4700. return "|cffff0000" .. tagData.error .. "|r"
  4701. end
  4702. return ""
  4703. end,
  4704. hidden = function() return not tagData.error end,
  4705. },
  4706. errorHeader = {
  4707. order = 1,
  4708. type = "header",
  4709. name = "",
  4710. hidden = function() return not tagData.error end,
  4711. },
  4712. discovery = {
  4713. order = 1,
  4714. type = "toggle",
  4715. name = L["Disable event discovery"],
  4716. desc = L["This will disable the automatic detection of what events this tag will need, you should leave this unchecked unless you know what you are doing."],
  4717. set = function(info, value) tagData.discovery = value end,
  4718. get = function() return tagData.discovery end,
  4719. width = "full",
  4720. },
  4721. frequencyEnable = {
  4722. order = 1.10,
  4723. type = "toggle",
  4724. name = L["Enable frequent updates"],
  4725. desc = L["Flags the tag for frequent updating, it will update the tag on a timer regardless of any events firing."],
  4726. set = function(info, value)
  4727. tagData.frequency = value and 5 or nil
  4728. set(info, tagData.frequency, "frequency")
  4729. end,
  4730. get = function(info) return get(info, "frequency") ~= "" and true or false end,
  4731. width = "full",
  4732. },
  4733. frequency = {
  4734. order = 1.20,
  4735. type = "input",
  4736. name = L["Update interval"],
  4737. desc = L["How many seconds between updates.|n[WARNING] By setting the frequency to 0 it will update every single frame redraw, if you want to disable frequent updating uncheck it don't set this to 0."],
  4738. disabled = function(info) return get(info) == "" end,
  4739. validate = function(info, value)
  4740. value = tonumber(value)
  4741. if( not value ) then
  4742. tagData.error = L["Invalid interval entered, must be a number."]
  4743. elseif( value < 0 ) then
  4744. tagData.error = L["You must enter a number that is 0 or higher, negative numbers are not allowed."]
  4745. else
  4746. tagData.error = nil
  4747. end
  4748. if( tagData.error ) then
  4749. AceRegistry:NotifyChange("ShadowedUF")
  4750. return ""
  4751. end
  4752. return true
  4753. end,
  4754. set = function(info, value)
  4755. tagData.frequency = tonumber(value)
  4756. tagData.frequency = tagData.frequency < 0 and 0 or tagData.frequency
  4757. set(info, tagData.frequency)
  4758. end,
  4759. get = function(info) return tostring(get(info) or "") end,
  4760. width = "half",
  4761. },
  4762. name = {
  4763. order = 2,
  4764. type = "input",
  4765. name = L["Tag name"],
  4766. set = set,
  4767. get = get,
  4768. },
  4769. category = {
  4770. order = 2.5,
  4771. type = "select",
  4772. name = L["Category"],
  4773. values = getTagCategories,
  4774. set = set,
  4775. get = get,
  4776. },
  4777. sep = {
  4778. order = 2.75,
  4779. type = "description",
  4780. name = "",
  4781. width = "full",
  4782. },
  4783. events = {
  4784. order = 3,
  4785. type = "input",
  4786. name = L["Events"],
  4787. desc = L["Events that should be used to trigger an update of this tag. Separate each event with a single space."],
  4788. width = "full",
  4789. validate = function(info, text)
  4790. if( ShadowUF.Tags.defaultTags[tagData.name] ) then
  4791. return true
  4792. end
  4793. if( text == "" or string.match(text, "[^_%a%s]") ) then
  4794. tagData.error = L["You have to set the events to fire, you can only enter letters and underscores, \"FOO_BAR\" for example is valid, \"APPLE_5_ORANGE\" is not because it contains a number."]
  4795. tagData.eventError = text
  4796. AceRegistry:NotifyChange("ShadowedUF")
  4797. return ""
  4798. end
  4799. tagData.eventError = text
  4800. tagData.error = nil
  4801. return true
  4802. end,
  4803. set = set,
  4804. get = function(info)
  4805. if( tagData.eventError ) then
  4806. return tagData.eventError
  4807. end
  4808. return get(info)
  4809. end,
  4810. },
  4811. func = {
  4812. order = 4,
  4813. type = "input",
  4814. multiline = true,
  4815. name = L["Code"],
  4816. desc = L["Your code must be wrapped in a function, for example, if you were to make a tag to return the units name you would do:|n|nfunction(unit, unitOwner)|nreturn UnitName(unitOwner)|nend"],
  4817. width = "full",
  4818. validate = function(info, text)
  4819. if( ShadowUF.Tags.defaultTags[tagData.name] ) then
  4820. return true
  4821. end
  4822. local funct, msg = loadstring("return " .. text)
  4823. if( not string.match(text, "function") ) then
  4824. tagData.error = L["You must wrap your code in a function."]
  4825. tagData.funcError = text
  4826. elseif( not funct and msg ) then
  4827. tagData.error = string.format(L["Failed to save tag, error:|n %s"], msg)
  4828. tagData.funcError = text
  4829. else
  4830. tagData.error = nil
  4831. tagData.funcError = nil
  4832. end
  4833. AceRegistry:NotifyChange("ShadowedUF")
  4834. return tagData.error and "" or true
  4835. end,
  4836. set = function(info, value)
  4837. value = string.gsub(value, "||", "|")
  4838. set(info, value)
  4839. -- Try and automatically identify the events this tag is going to want to use
  4840. if( not tagData.discovery ) then
  4841. tagData.eventError = nil
  4842. ShadowUF.db.profile.tags[tagData.name].events = ShadowUF.Tags:IdentifyEvents(value) or ""
  4843. end
  4844. ShadowUF.Tags:Reload(tagData.name)
  4845. end,
  4846. get = function(info)
  4847. if( tagData.funcError ) then
  4848. return stripCode(tagData.funcError)
  4849. end
  4850. return stripCode(ShadowUF.Tags.defaultTags[tagData.name] or ( ShadowUF.db.profile.tags[tagData.name] and ShadowUF.db.profile.tags[tagData.name].func))
  4851. end,
  4852. },
  4853. delete = {
  4854. order = 5,
  4855. type = "execute",
  4856. name = L["Delete"],
  4857. hidden = function() return ShadowUF.Tags.defaultTags[tagData.name] end,
  4858. confirm = true,
  4859. confirmText = L["Are you sure you want to delete this tag?"],
  4860. func = function(info)
  4861. local category = ShadowUF.db.profile.tags[tagData.name].category
  4862. if( category ) then
  4863. Config.tagTextTable.args[category].args[tagData.name] = nil
  4864. end
  4865. options.args.tags.args.general.args.list.args[tagData.name] = nil
  4866. ShadowUF.db.profile.tags[tagData.name] = nil
  4867. ShadowUF.tagFunc[tagData.name] = nil
  4868. ShadowUF.Tags:Reload(tagData.name)
  4869. tagData.name = nil
  4870. tagData.error = nil
  4871. selectDialogGroup("tags", "general")
  4872. end,
  4873. },
  4874. },
  4875. },
  4876. },
  4877. },
  4878. help = {
  4879. order = 3,
  4880. type = "group",
  4881. name = L["Help"],
  4882. args = {
  4883. general = {
  4884. order = 0,
  4885. type = "group",
  4886. name = L["General"],
  4887. inline = true,
  4888. args = {
  4889. general = {
  4890. order = 0,
  4891. type = "description",
  4892. name = L["See the documentation below for information and examples on creating tags, if you just want basic Lua or WoW API information then see the Programming in Lua and WoW Programming links."],
  4893. },
  4894. },
  4895. },
  4896. documentation = {
  4897. order = 1,
  4898. type = "group",
  4899. name = L["Documentation"],
  4900. inline = true,
  4901. args = {
  4902. doc = {
  4903. order = 0,
  4904. type = "input",
  4905. name = L["Documentation"],
  4906. set = false,
  4907. get = function() return "http://wiki.github.com/Shadowed/ShadowedUnitFrames/tag-documentation" end,
  4908. width = "full",
  4909. },
  4910. },
  4911. },
  4912. resources = {
  4913. order = 2,
  4914. type = "group",
  4915. inline = true,
  4916. name = L["Resources"],
  4917. args = {
  4918. lua = {
  4919. order = 0,
  4920. type = "input",
  4921. name = L["Programming in Lua"],
  4922. desc = L["This is a good guide on how to get started with programming in Lua, while you do not need to read the entire thing it is a helpful for understanding the basics of Lua syntax and API's."],
  4923. set = false,
  4924. get = function() return "http://www.lua.org/pil/" end,
  4925. width = "full",
  4926. },
  4927. wow = {
  4928. order = 1,
  4929. type = "input",
  4930. name = L["WoW Programming"],
  4931. desc = L["WoW Programming is a good resource for finding out what difference API's do and how to call them."],
  4932. set = false,
  4933. get = function() return "http://wowprogramming.com/docs" end,
  4934. width = "full",
  4935. },
  4936. },
  4937. },
  4938. },
  4939. },
  4940. },
  4941. }
  4942. -- Load the initial tag list
  4943. for tag in pairs(ShadowUF.Tags.defaultTags) do
  4944. options.args.tags.args.general.args.list.args[tag] = tagTable
  4945. end
  4946. for tag, data in pairs(ShadowUF.db.profile.tags) do
  4947. options.args.tags.args.general.args.list.args[tag] = tagTable
  4948. end
  4949. end
  4950. ---------------------
  4951. -- VISIBILITY OPTIONS
  4952. ---------------------
  4953. local function loadVisibilityOptions()
  4954. -- As zone units are only enabled in a certain zone... it's pointless to provide visibility options for them
  4955. local unitBlacklist = {}
  4956. for unit in pairs(ShadowUF.Units.zoneUnits) do unitBlacklist[unit] = true end
  4957. for unit, parent in pairs(ShadowUF.Units.childUnits) do
  4958. if( ShadowUF.Units.zoneUnits[parent] ) then
  4959. unitBlacklist[unit] = true
  4960. end
  4961. end
  4962. local globalVisibility = {}
  4963. local function set(info, value)
  4964. local key = info[#(info)]
  4965. local unit = info[#(info) - 1]
  4966. local area = info[#(info) - 2]
  4967. if( key == "enabled" ) then
  4968. key = ""
  4969. end
  4970. if( value == nil ) then
  4971. value = false
  4972. elseif( value == false ) then
  4973. value = nil
  4974. end
  4975. for _, configUnit in pairs(ShadowUF.unitList) do
  4976. if( ( configUnit == unit or unit == "global" ) and not unitBlacklist[configUnit] ) then
  4977. ShadowUF.db.profile.visibility[area][configUnit .. key] = value
  4978. end
  4979. end
  4980. -- Annoying yes, but only way that works
  4981. ShadowUF.Units:CheckPlayerZone(true)
  4982. if( unit == "global" ) then
  4983. globalVisibility[area .. key] = value
  4984. end
  4985. end
  4986. local function get(info)
  4987. local key = info[#(info)]
  4988. local unit = info[#(info) - 1]
  4989. local area = info[#(info) - 2]
  4990. if( key == "enabled" ) then
  4991. key = ""
  4992. end
  4993. if( unit == "global" ) then
  4994. if( globalVisibility[area .. key] == false ) then
  4995. return nil
  4996. elseif( globalVisibility[area .. key] == nil ) then
  4997. return false
  4998. end
  4999. return globalVisibility[area .. key]
  5000. elseif( ShadowUF.db.profile.visibility[area][unit .. key] == false ) then
  5001. return nil
  5002. elseif( ShadowUF.db.profile.visibility[area][unit .. key] == nil ) then
  5003. return false
  5004. end
  5005. return ShadowUF.db.profile.visibility[area][unit .. key]
  5006. end
  5007. local function getHelp(info)
  5008. local unit = info[#(info) - 1]
  5009. local area = info[#(info) - 2]
  5010. local key = info[#(info)]
  5011. if( key == "enabled" ) then
  5012. key = ""
  5013. end
  5014. local current
  5015. if( unit == "global" ) then
  5016. current = globalVisibility[area .. key]
  5017. else
  5018. current = ShadowUF.db.profile.visibility[area][unit .. key]
  5019. end
  5020. if( current == false ) then
  5021. return string.format(L["Disabled in %s"], AREA_NAMES[area])
  5022. elseif( current == true ) then
  5023. return string.format(L["Enabled in %s"], AREA_NAMES[area])
  5024. end
  5025. return L["Using unit settings"]
  5026. end
  5027. local areaTable = {
  5028. type = "group",
  5029. order = function(info) return info[#(info)] == "none" and 2 or 1 end,
  5030. childGroups = "tree",
  5031. name = function(info)
  5032. return AREA_NAMES[info[#(info)]]
  5033. end,
  5034. get = get,
  5035. set = set,
  5036. args = {},
  5037. }
  5038. Config.visibilityTable = {
  5039. type = "group",
  5040. order = function(info) return info[#(info)] == "global" and 1 or (getUnitOrder(info) + 1) end,
  5041. name = function(info) return info[#(info)] == "global" and L["Global"] or getName(info) end,
  5042. args = {
  5043. help = {
  5044. order = 0,
  5045. type = "group",
  5046. name = L["Help"],
  5047. inline = true,
  5048. hidden = hideBasicOption,
  5049. args = {
  5050. help = {
  5051. order = 0,
  5052. type = "description",
  5053. name = function(info)
  5054. return string.format(L["Disabling a module on this page disables it while inside %s. Do not disable a module here if you do not want this to happen!."], string.lower(AREA_NAMES[info[2]]))
  5055. end,
  5056. },
  5057. },
  5058. },
  5059. enabled = {
  5060. order = 0.25,
  5061. type = "toggle",
  5062. name = function(info)
  5063. local unit = info[#(info) - 1]
  5064. if( unit == "global" ) then return "" end
  5065. return string.format(L["%s frames"], L.units[unit])
  5066. end,
  5067. hidden = function(info) return info[#(info) - 1] == "global" end,
  5068. desc = getHelp,
  5069. tristate = true,
  5070. width = "double",
  5071. },
  5072. sep = {
  5073. order = 0.5,
  5074. type = "description",
  5075. name = "",
  5076. width = "full",
  5077. hidden = function(info) return info[#(info) - 1] == "global" end,
  5078. },
  5079. }
  5080. }
  5081. local moduleTable = {
  5082. order = 1,
  5083. type = "toggle",
  5084. name = getName,
  5085. desc = getHelp,
  5086. tristate = true,
  5087. hidden = function(info)
  5088. if( info[#(info) - 1] == "global" ) then return false end
  5089. return hideRestrictedOption(info)
  5090. end,
  5091. arg = 1,
  5092. }
  5093. for key, module in pairs(ShadowUF.modules) do
  5094. if( module.moduleName ) then
  5095. Config.visibilityTable.args[key] = moduleTable
  5096. end
  5097. end
  5098. areaTable.args.global = Config.visibilityTable
  5099. for _, unit in pairs(ShadowUF.unitList) do
  5100. if( not unitBlacklist[unit] ) then
  5101. areaTable.args[unit] = Config.visibilityTable
  5102. end
  5103. end
  5104. options.args.visibility = {
  5105. type = "group",
  5106. childGroups = "tab",
  5107. name = L["Zone configuration"],
  5108. desc = getPageDescription,
  5109. args = {
  5110. start = {
  5111. order = 0,
  5112. type = "group",
  5113. name = L["Help"],
  5114. inline = true,
  5115. hidden = hideBasicOption,
  5116. args = {
  5117. help = {
  5118. order = 0,
  5119. type = "description",
  5120. name = L["Gold checkmark - Enabled in this zone / Grey checkmark - Disabled in this zone / No checkmark - Use the default unit settings"],
  5121. },
  5122. },
  5123. },
  5124. pvp = areaTable,
  5125. arena = areaTable,
  5126. party = areaTable,
  5127. raid = areaTable,
  5128. },
  5129. }
  5130. end
  5131. local function loadOptions()
  5132. options = {
  5133. type = "group",
  5134. name = "Shadowed UF",
  5135. args = {}
  5136. }
  5137. loadGeneralOptions()
  5138. loadUnitOptions()
  5139. loadHideOptions()
  5140. loadTagOptions()
  5141. loadFilterOptions()
  5142. loadVisibilityOptions()
  5143. -- Ordering
  5144. options.args.general.order = 1
  5145. options.args.enableUnits.order = 2
  5146. options.args.units.order = 3
  5147. options.args.filter.order = 4
  5148. options.args.hideBlizzard.order = 5
  5149. options.args.visibility.order = 6
  5150. options.args.tags.order = 7
  5151. -- So modules can access it easier/debug
  5152. Config.options = options
  5153. -- Options finished loading, fire callback for any non-default modules that want to be included
  5154. ShadowUF:FireModuleEvent("OnConfigurationLoad")
  5155. end
  5156. function Config:Open()
  5157. AceDialog = AceDialog or LibStub("AceConfigDialog-3.0")
  5158. AceRegistry = AceRegistry or LibStub("AceConfigRegistry-3.0")
  5159. if( not registered ) then
  5160. loadOptions()
  5161. LibStub("AceConfig-3.0"):RegisterOptionsTable("ShadowedUF", options)
  5162. AceDialog:SetDefaultSize("ShadowedUF", 845, 550)
  5163. registered = true
  5164. end
  5165. AceDialog:Open("ShadowedUF")
  5166. end