From 02d25b5ac1035a48273427708a465c3d4535263c Mon Sep 17 00:00:00 2001 From: Gitea Date: Fri, 13 Nov 2020 14:29:13 -0500 Subject: [PATCH] initial commit --- ActionBars.lua | 478 ++ Auras.lua | 76 + Bags.lua | 777 ++ Chat.lua | 857 +++ Cooldown.lua | 90 + Core.lua | 442 ++ DataBars.lua | 112 + DataTexts.lua | 923 +++ ElvUI_OptionsUI.toc | 27 + Filters.lua | 745 ++ General.lua | 971 +++ .../Ace3/AceConfig-3.0/AceConfig-3.0.lua | 58 + .../Ace3/AceConfig-3.0/AceConfig-3.0.xml | 8 + .../AceConfigCmd-3.0/AceConfigCmd-3.0.lua | 794 ++ .../AceConfigCmd-3.0/AceConfigCmd-3.0.xml | 4 + .../AceConfigDialog-3.0.lua | 2117 ++++++ .../AceConfigDialog-3.0.xml | 4 + .../AceConfigRegistry-3.0.lua | 386 + .../AceConfigRegistry-3.0.xml | 4 + .../AceDBOptions-3.0/AceDBOptions-3.0.lua | 460 ++ .../AceDBOptions-3.0/AceDBOptions-3.0.xml | 4 + Libraries/Ace3/AceGUI-3.0/AceGUI-3.0.lua | 1026 +++ Libraries/Ace3/AceGUI-3.0/AceGUI-3.0.xml | 28 + .../AceGUIContainer-BlizOptionsGroup.lua | 138 + .../widgets/AceGUIContainer-DropDownGroup.lua | 157 + .../widgets/AceGUIContainer-Frame.lua | 316 + .../widgets/AceGUIContainer-InlineGroup.lua | 103 + .../widgets/AceGUIContainer-ScrollFrame.lua | 215 + .../widgets/AceGUIContainer-SimpleGroup.lua | 69 + .../widgets/AceGUIContainer-TabGroup.lua | 349 + .../widgets/AceGUIContainer-TreeGroup.lua | 717 ++ .../widgets/AceGUIContainer-Window.lua | 336 + .../widgets/AceGUIWidget-Button-ElvUI.lua | 192 + .../widgets/AceGUIWidget-CheckBox.lua | 296 + .../widgets/AceGUIWidget-ColorPicker.lua | 205 + .../widgets/AceGUIWidget-DropDown-Items.lua | 471 ++ .../widgets/AceGUIWidget-DropDown.lua | 763 ++ .../widgets/AceGUIWidget-EditBox.lua | 263 + .../widgets/AceGUIWidget-Heading.lua | 78 + .../AceGUI-3.0/widgets/AceGUIWidget-Icon.lua | 140 + .../widgets/AceGUIWidget-InteractiveLabel.lua | 94 + .../widgets/AceGUIWidget-Keybinding.lua | 249 + .../AceGUI-3.0/widgets/AceGUIWidget-Label.lua | 179 + .../AceGUIWidget-MultiLineEditBox-ElvUI.lua | 372 + .../widgets/AceGUIWidget-Slider-ElvUI.lua | 287 + Libraries/Ace3/LICENSE.txt | 29 + .../BackgroundWidget.lua | 235 + .../BorderWidget.lua | 230 + .../FontWidget.lua | 216 + .../SoundWidget.lua | 264 + .../StatusbarWidget.lua | 233 + .../prototypes.lua | 266 + .../AceGUI-3.0-SharedMediaWidgets/widget.xml | 9 + Libraries/FAIAP/FAIAP.lua | 1253 +++ .../LibAceConfigHelper/LibAceConfigHelper.lua | 158 + Libraries/Load_Libraries.xml | 8 + Locales/Load_Locales.xml | 12 + Locales/deDE.lua | 1671 ++++ Locales/enUS.lua | 1660 ++++ Locales/esMX.lua | 1667 ++++ Locales/frFR.lua | 1666 ++++ Locales/itIT.lua | 1656 ++++ Locales/koKR.lua | 1708 +++++ Locales/ptBR.lua | 1667 ++++ Locales/ruRU.lua | 1664 ++++ Locales/zhCN.lua | 1672 ++++ Locales/zhTW.lua | 1665 ++++ Maps.lua | 102 + ModuleControl.lua | 254 + Nameplates.lua | 6702 +++++++++++++++++ Skins.lua | 141 + Tags.lua | 50 + Tooltip.lua | 66 + UnitFrames.lua | 6270 +++++++++++++++ 74 files changed, 49574 insertions(+) create mode 100644 ActionBars.lua create mode 100644 Auras.lua create mode 100644 Bags.lua create mode 100644 Chat.lua create mode 100644 Cooldown.lua create mode 100644 Core.lua create mode 100644 DataBars.lua create mode 100644 DataTexts.lua create mode 100644 ElvUI_OptionsUI.toc create mode 100644 Filters.lua create mode 100644 General.lua create mode 100644 Libraries/Ace3/AceConfig-3.0/AceConfig-3.0.lua create mode 100644 Libraries/Ace3/AceConfig-3.0/AceConfig-3.0.xml create mode 100644 Libraries/Ace3/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua create mode 100644 Libraries/Ace3/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml create mode 100644 Libraries/Ace3/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua create mode 100644 Libraries/Ace3/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml create mode 100644 Libraries/Ace3/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua create mode 100644 Libraries/Ace3/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml create mode 100644 Libraries/Ace3/AceDBOptions-3.0/AceDBOptions-3.0.lua create mode 100644 Libraries/Ace3/AceDBOptions-3.0/AceDBOptions-3.0.xml create mode 100644 Libraries/Ace3/AceGUI-3.0/AceGUI-3.0.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/AceGUI-3.0.xml create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIContainer-Window.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Button-ElvUI.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Label.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox-ElvUI.lua create mode 100644 Libraries/Ace3/AceGUI-3.0/widgets/AceGUIWidget-Slider-ElvUI.lua create mode 100644 Libraries/Ace3/LICENSE.txt create mode 100644 Libraries/AceGUI-3.0-SharedMediaWidgets/BackgroundWidget.lua create mode 100644 Libraries/AceGUI-3.0-SharedMediaWidgets/BorderWidget.lua create mode 100644 Libraries/AceGUI-3.0-SharedMediaWidgets/FontWidget.lua create mode 100644 Libraries/AceGUI-3.0-SharedMediaWidgets/SoundWidget.lua create mode 100644 Libraries/AceGUI-3.0-SharedMediaWidgets/StatusbarWidget.lua create mode 100644 Libraries/AceGUI-3.0-SharedMediaWidgets/prototypes.lua create mode 100644 Libraries/AceGUI-3.0-SharedMediaWidgets/widget.xml create mode 100644 Libraries/FAIAP/FAIAP.lua create mode 100644 Libraries/LibAceConfigHelper/LibAceConfigHelper.lua create mode 100644 Libraries/Load_Libraries.xml create mode 100644 Locales/Load_Locales.xml create mode 100644 Locales/deDE.lua create mode 100644 Locales/enUS.lua create mode 100644 Locales/esMX.lua create mode 100644 Locales/frFR.lua create mode 100644 Locales/itIT.lua create mode 100644 Locales/koKR.lua create mode 100644 Locales/ptBR.lua create mode 100644 Locales/ruRU.lua create mode 100644 Locales/zhCN.lua create mode 100644 Locales/zhTW.lua create mode 100644 Maps.lua create mode 100644 ModuleControl.lua create mode 100644 Nameplates.lua create mode 100644 Skins.lua create mode 100644 Tags.lua create mode 100644 Tooltip.lua create mode 100644 UnitFrames.lua diff --git a/ActionBars.lua b/ActionBars.lua new file mode 100644 index 0000000..bbad225 --- /dev/null +++ b/ActionBars.lua @@ -0,0 +1,478 @@ +local E, _, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB +local C, L = unpack(select(2, ...)) +local AB = E:GetModule('ActionBars') +local ACH = E.Libs.ACH + +local _G = _G +local pairs = pairs +local format = format +local SetCVar = SetCVar +local GameTooltip = _G.GameTooltip + +-- GLOBALS: NUM_ACTIONBAR_BUTTONS, NUM_PET_ACTION_SLOTS, LOCK_ACTIONBAR, MICRO_BUTTONS, AceGUIWidgetLSMlists + +local SharedBarOptions = { + enabled = ACH:Toggle(L["Enable"], nil, 0), + restorePosition = ACH:Execute(L["Restore Bar"], L["Restore the actionbars default settings"], 1), + generalOptions = ACH:MultiSelect('', nil, 3, { backdrop = L["Backdrop"], mouseover = L["Mouse Over"], clickThrough = L["Click Through"], inheritGlobalFade = L["Inherit Global Fade"] }), + barGroup = ACH:Group(L["Bar Settings"], nil, 4), + buttonGroup = ACH:Group(L["Button Settings"], nil, 5), + backdropGroup = ACH:Group(L["Backdrop Settings"], nil, 6), + visibility = ACH:Input(L["Visibility State"], L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] show;hide'"], 8, 4, 'full') +} + +SharedBarOptions.barGroup.inline = true +SharedBarOptions.barGroup.args.point = ACH:Select(L["Anchor Point"], L["The first button anchors itself to this point on the bar."], 1, { TOPLEFT = 'TOPLEFT', TOPRIGHT = 'TOPRIGHT', BOTTOMLEFT = 'BOTTOMLEFT', BOTTOMRIGHT = 'BOTTOMRIGHT' }) +SharedBarOptions.barGroup.args.alpha = ACH:Range(L["Alpha"], nil, 3, { min = 0, max = 1, step = 0.01, isPercent = true }) +SharedBarOptions.barGroup.args.spacer1 = ACH:Spacer(19, 'full') +SharedBarOptions.barGroup.args.countFont = ACH:SharedMediaFont(L["Font"], nil, 21) +SharedBarOptions.barGroup.args.countFontOutline = ACH:FontFlags(L["Font Outline"], nil, 21) +SharedBarOptions.barGroup.args.countFontSize = ACH:Range(L["Font Size"], nil, 21, C.Values.FontSize) +SharedBarOptions.barGroup.args.countTextPosition = ACH:Select(L["Text Anchor"], nil, 21, { TOPLEFT = 'TOPLEFT', TOPRIGHT = 'TOPRIGHT', BOTTOMLEFT = 'BOTTOMLEFT', BOTTOMRIGHT = 'BOTTOMRIGHT' }) +SharedBarOptions.barGroup.args.countTextXOffset = ACH:Range(L["X-Offset"], nil, 21, { min = -10, max = 10, step = 1 }) +SharedBarOptions.barGroup.args.countTextYOffset = ACH:Range(L["Y-Offset"], nil, 21, { min = -10, max = 10, step = 1 }) +SharedBarOptions.barGroup.args.customCountFont = ACH:Toggle(L["Custom Count Font"], nil, 20) +SharedBarOptions.barGroup.args.spacer2 = ACH:Spacer(22, 'full') +SharedBarOptions.barGroup.args.customHotkeyFont = ACH:Toggle(L["Custom Keybind Font"], nil, 23) +SharedBarOptions.barGroup.args.hotkeyFont = ACH:SharedMediaFont(L["Font"], nil, 24) +SharedBarOptions.barGroup.args.hotkeyFontOutline = ACH:FontFlags(L["Font Outline"], nil, 24) +SharedBarOptions.barGroup.args.hotkeyFontSize = ACH:Range(L["Font Size"], nil, 24, C.Values.FontSize) +SharedBarOptions.barGroup.args.hotkeyTextPosition = ACH:Select(L["Text Anchor"], nil, 24, { TOPLEFT = 'TOPLEFT', TOPRIGHT = 'TOPRIGHT', BOTTOMLEFT = 'BOTTOMLEFT', BOTTOMRIGHT = 'BOTTOMRIGHT' }) +SharedBarOptions.barGroup.args.hotkeyTextXOffset = ACH:Range(L["X-Offset"], nil, 24, { min = -10, max = 10, step = 1 }) +SharedBarOptions.barGroup.args.hotkeyTextYOffset = ACH:Range(L["Y-Offset"], nil, 24, { min = -10, max = 10, step = 1 }) + + +SharedBarOptions.buttonGroup.inline = true +SharedBarOptions.buttonGroup.args.buttons = ACH:Range(L["Buttons"], L["The amount of buttons to display."], 1, { min = 1, max = NUM_ACTIONBAR_BUTTONS, step = 1 }) +SharedBarOptions.buttonGroup.args.buttonsPerRow = ACH:Range(L["Buttons Per Row"], L["The amount of buttons to display per row."], 2, { min = 1, max = NUM_ACTIONBAR_BUTTONS, step = 1 }) +SharedBarOptions.buttonGroup.args.buttonspacing = ACH:Range(L["Button Spacing"], L["The spacing between buttons."], 3, { min = -3, max = 20, step = 1 }) +SharedBarOptions.buttonGroup.args.buttonsize = ACH:Range('', nil, 4, { softMin = 14, softMax = 64, min = 12, max = 128, step = 1 }) +SharedBarOptions.buttonGroup.args.buttonHeight = ACH:Range(L["Button Height"], L["The height of the action buttons."], 5, { softMin = 14, softMax = 64, min = 12, max = 128, step = 1 }) + +SharedBarOptions.backdropGroup.inline = true +SharedBarOptions.backdropGroup.args.backdropSpacing = ACH:Range(L["Backdrop Spacing"], L["The spacing between the backdrop and the buttons."], 1, { min = 0, max = 10, step = 1 }) +SharedBarOptions.backdropGroup.args.heightMult = ACH:Range(L["Height Multiplier"], L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."], 2, { min = 1, max = 5, step = 1 }) +SharedBarOptions.backdropGroup.args.widthMult = ACH:Range(L["Width Multiplier"], L["Multiply the backdrops height or width by this value. This is usefull if you wish to have more than one bar behind a backdrop."], 2, { min = 1, max = 5, step = 1 }) + +-- Start ActionBar Config + +E.Options.args.actionbar = ACH:Group(L["ActionBars"], nil, 2, 'tab', function(info) return E.db.actionbar[info[#info]] end, function(info, value) E.db.actionbar[info[#info]] = value; AB:UpdateButtonSettings() end) +E.Options.args.actionbar.args.intro = ACH:Description(L["ACTIONBARS_DESC"], 0) +E.Options.args.actionbar.args.enable = ACH:Toggle(L["Enable"], nil, 1, nil, nil, nil, function(info) return E.private.actionbar[info[#info]] end, function(info, value) E.private.actionbar[info[#info]] = value; E:StaticPopup_Show('PRIVATE_RL') end) + +E.Options.args.actionbar.args.general = { + order = 3, + type = 'group', + name = L["General"], + disabled = function() return not E.ActionBars.Initialized; end, + args = { + toggleKeybind = { + order = 0, + type = 'execute', + name = L["Keybind Mode"], + func = function() AB:ActivateBindMode(); E:ToggleOptionsUI(); GameTooltip:Hide(); end, + }, + movementModifier = { + order = 1, + type = 'select', + name = L["PICKUP_ACTION_KEY_TEXT"], + desc = L["The button you must hold down in order to drag an ability to another action button."], + hidden = function() return not E.db.actionbar.lockActionBars end, + values = { + NONE = L["NONE"], + SHIFT = L["SHIFT_KEY_TEXT"], + ALT = L["ALT_KEY_TEXT"], + CTRL = L["CTRL_KEY_TEXT"], + }, + }, + flyoutSize = { + order = 2, + type = 'range', + name = L["Flyout Button Size"], + min = 15, max = 60, step = 1, + }, + globalFadeAlpha = { + order = 3, + type = 'range', + name = L["Global Fade Transparency"], + desc = L["Transparency level when not in combat, no target exists, full health, not casting, and no focus target exists."], + min = 0, max = 1, step = 0.01, + isPercent = true, + set = function(info, value) E.db.actionbar[info[#info]] = value; AB.fadeParent:SetAlpha(1-value) end, + }, + generalGroup = { + order = 20, + type = 'group', + name = L["General"], + inline = true, + get = function(info) return E.db.actionbar[info[#info]] end, + set = function(info, value) E.db.actionbar[info[#info]] = value; AB:UpdateButtonSettings() end, + args = { + keyDown = { + order = 13, + type = 'toggle', + name = L["Key Down"], + desc = L["OPTION_TOOLTIP_ACTION_BUTTON_USE_KEY_DOWN"], + }, + lockActionBars = { + order = 14, + type = 'toggle', + name = L["LOCK_ACTIONBAR_TEXT"], + desc = L["If you unlock actionbars then trying to move a spell might instantly cast it if you cast spells on key press instead of key release."], + set = function(info, value) + E.db.actionbar[info[#info]] = value; + AB:UpdateButtonSettings() + + --Make it work for PetBar too + SetCVar('lockActionBars', (value == true and 1 or 0)) + LOCK_ACTIONBAR = (value == true and '1' or '0') + end, + }, + hideCooldownBling = { + order = 15, + type = 'toggle', + name = L["Hide Cooldown Bling"], + desc = L["Hides the bling animation on buttons at the end of the global cooldown."], + get = function() return E.db.actionbar.hideCooldownBling end, + set = function(_, value) E.db.actionbar.hideCooldownBling = value; + for _, bar in pairs(AB.handledBars) do + AB:UpdateButtonConfig(bar, bar.bindButtons) + end + AB:UpdatePetCooldownSettings() + end, + }, + addNewSpells = { + order = 16, + type = 'toggle', + name = L["Auto Add New Spells"], + desc = L["Allow newly learned spells to be automatically placed on an empty actionbar slot."], + set = function(_, value) E.db.actionbar.addNewSpells = value; AB:IconIntroTracker_Toggle() end, + }, + rightClickSelfCast = { + order = 17, + type = 'toggle', + name = L["RightClick Self-Cast"], + set = function(_, value) + E.db.actionbar.rightClickSelfCast = value; + for _, bar in pairs(AB.handledBars) do + AB:UpdateButtonConfig(bar, bar.bindButtons) + end + end, + }, + useDrawSwipeOnCharges = { + order = 18, + type = 'toggle', + name = L["Charge Draw Swipe"], + desc = L["Shows a swipe animation when a spell is recharging but still has charges left."], + get = function() return E.db.actionbar.useDrawSwipeOnCharges end, + set = function(_, value) + E.db.actionbar.useDrawSwipeOnCharges = value; + for _, bar in pairs(AB.handledBars) do + AB:UpdateButtonConfig(bar, bar.bindButtons) + end + end, + }, + chargeCooldown = { + order = 19, + type = 'toggle', + name = L["Charge Cooldown Text"], + set = function(_, value) + E.db.actionbar.chargeCooldown = value; + AB:ToggleCooldownOptions() + end, + }, + desaturateOnCooldown = { + order = 20, + type = 'toggle', + name = L["Desaturate Cooldowns"], + set = function(_, value) + E.db.actionbar.desaturateOnCooldown = value; + AB:ToggleCooldownOptions() + end, + }, + transparent = { + order = 21, + type = 'toggle', + name = L["Transparent"], + set = function(_, value) + E.db.actionbar.transparent = value + E:StaticPopup_Show('PRIVATE_RL') + end, + }, + flashAnimation = { + order = 22, + type = 'toggle', + name = L["Button Flash"], + desc = L["Use a more visible flash animation for Auto Attacks."], + set = function(_, value) + E.db.actionbar.flashAnimation = value + E:StaticPopup_Show('PRIVATE_RL') + end, + }, + equippedItem = { + order = 23, + type = 'toggle', + name = L["Equipped Item"], + }, + macrotext = { + order = 24, + type = 'toggle', + name = L["Macro Text"], + desc = L["Display macro names on action buttons."], + }, + hotkeytext = { + order = 25, + type = 'toggle', + name = L["Keybind Text"], + desc = L["Display bind names on action buttons."], + }, + useRangeColorText = { + order = 26, + type = 'toggle', + name = L["Color Keybind Text"], + desc = L["Color Keybind Text when Out of Range, instead of the button."], + }, + handleOverlay = { + order = 27, + type = 'toggle', + name = L["Action Button Glow"], + }, + } + }, + textGroup = { + type = 'group', + order = 50, + name = L["Text Position"], + disabled = function() return (E.Masque and E.private.actionbar.masque.actionbars) end, + inline = true, + args = { + countTextPosition = { + type = 'select', + order = 1, + name = L["Stack Text Position"], + values = { + BOTTOMRIGHT = 'BOTTOMRIGHT', + BOTTOMLEFT = 'BOTTOMLEFT', + TOPRIGHT = 'TOPRIGHT', + TOPLEFT = 'TOPLEFT', + BOTTOM = 'BOTTOM', + TOP = 'TOP', + }, + }, + countTextXOffset = { + type = 'range', + order = 2, + name = L["Stack Text X-Offset"], + min = -10, max = 10, step = 1, + }, + countTextYOffset = { + type = 'range', + order = 3, + name = L["Stack Text Y-Offset"], + min = -10, max = 10, step = 1, + }, + hotkeyTextPosition = { + type = 'select', + order = 4, + name = L["Keybind Text Position"], + values = { + BOTTOMRIGHT = 'BOTTOMRIGHT', + BOTTOMLEFT = 'BOTTOMLEFT', + TOPRIGHT = 'TOPRIGHT', + TOPLEFT = 'TOPLEFT', + BOTTOM = 'BOTTOM', + TOP = 'TOP', + }, + }, + hotkeyTextXOffset = { + type = 'range', + order = 5, + name = L["Keybind Text X-Offset"], + min = -10, max = 10, step = 1, + }, + hotkeyTextYOffset = { + type = 'range', + order = 6, + name = L["Keybind Text Y-Offset"], + min = -10, max = 10, step = 1, + }, + }, + }, + }, + } + +E.Options.args.actionbar.args.general.args.colorGroup = ACH:Group(L["COLORS"], nil, 30, nil, function(info) local t = E.db.actionbar[info[#info]] local d = P.actionbar[info[#info]] return t.r, t.g, t.b, t.a, d.r, d.g, d.b, d.a end, function(info, r, g, b, a) local t = E.db.actionbar[info[#info]] t.r, t.g, t.b, t.a = r, g, b, a AB:UpdateButtonSettings() end, function() return (E.Masque and E.private.actionbar.masque.actionbars) end) +E.Options.args.actionbar.args.general.args.colorGroup.inline = true +E.Options.args.actionbar.args.general.args.colorGroup.args.fontColor = ACH:Color(L["Text"], nil, 0) +E.Options.args.actionbar.args.general.args.colorGroup.args.noRangeColor = ACH:Color(L["Out of Range"], L["Color of the actionbutton when out of range."], 1) +E.Options.args.actionbar.args.general.args.colorGroup.args.noPowerColor = ACH:Color(L["Out of Power"], L["Color of the actionbutton when out of power (Mana, Rage, Focus, Holy Power)."], 2) +E.Options.args.actionbar.args.general.args.colorGroup.args.usableColor = ACH:Color(L["Usable"], L["Color of the actionbutton when usable."], 3) +E.Options.args.actionbar.args.general.args.colorGroup.args.notUsableColor = ACH:Color(L["Not Usable"], L["Color of the actionbutton when not usable."], 4) +E.Options.args.actionbar.args.general.args.colorGroup.args.colorSwipeNormal = ACH:Color(L["Swipe: Normal"], nil, 5, true) +E.Options.args.actionbar.args.general.args.colorGroup.args.colorSwipeLOC = ACH:Color(L["Swipe: Loss of Control"], nil, 6, true) +E.Options.args.actionbar.args.general.args.colorGroup.args.equippedItemColor = ACH:Color(L["Equipped Item Color"], nil, 7) + +E.Options.args.actionbar.args.general.args.fontGroup = ACH:Group(L["Fonts"], nil, 40) +E.Options.args.actionbar.args.general.args.fontGroup.inline = true +E.Options.args.actionbar.args.general.args.fontGroup.args.font = ACH:SharedMediaFont(L["Font"], nil, 1) +E.Options.args.actionbar.args.general.args.fontGroup.args.fontSize = ACH:Range(L["Font Size"], nil, 2, C.Values.FontSize) +E.Options.args.actionbar.args.general.args.fontGroup.args.fontOutline = ACH:FontFlags(L["Font Outline"], nil, 3) + +E.Options.args.actionbar.args.general.args.masqueGroup = ACH:Group(L["Masque Support"], nil, -1, nil, function(info) return E.private.actionbar.masque[info[#info]] end, function(info, value) E.private.actionbar.masque[info[#info]] = value; E:StaticPopup_Show('PRIVATE_RL') end, function() return not E.Masque end) +E.Options.args.actionbar.args.general.args.masqueGroup.inline = true +E.Options.args.actionbar.args.general.args.masqueGroup.args.actionbars = ACH:Toggle(L["ActionBars"], nil, 1) +E.Options.args.actionbar.args.general.args.masqueGroup.args.petBar = ACH:Toggle(L["Pet Bar"], nil, 2) +E.Options.args.actionbar.args.general.args.masqueGroup.args.stanceBar = ACH:Toggle(L["Stance Bar"], nil, 3) + +E.Options.args.actionbar.args.barPet = ACH:Group(L["Pet Bar"], nil, 14, nil, function(info) return E.db.actionbar.barPet[info[#info]] end, function(info, value) E.db.actionbar.barPet[info[#info]] = value; AB:PositionAndSizeBarPet() end, function() return not E.ActionBars.Initialized end) +E.Options.args.actionbar.args.barPet.args = CopyTable(SharedBarOptions) +E.Options.args.actionbar.args.barPet.args.restorePosition.func = function() E:CopyTable(E.db.actionbar.barPet, P.actionbar.barPet); E:ResetMovers('Pet Bar'); AB:PositionAndSizeBarPet() end +E.Options.args.actionbar.args.barPet.args.generalOptions = ACH:MultiSelect('', nil, 3, { backdrop = L["Backdrop"], mouseover = L["Mouse Over"], clickThrough = L["Click Through"], inheritGlobalFade = L["Inherit Global Fade"], keepSizeRatio = L["Keep Size Ratio"] }, nil, nil, function(_, key) return E.db.actionbar.barPet[key] end, function(_, key, value) E.db.actionbar.barPet[key] = value; AB:PositionAndSizeBarPet() end) +E.Options.args.actionbar.args.barPet.args.buttonGroup.args.buttonsize.name = function() return E.db.actionbar.barPet.keepSizeRatio and L["Button Size"] or L["Button Width"] end +E.Options.args.actionbar.args.barPet.args.buttonGroup.args.buttonsize.desc = function() return E.db.actionbar.barPet.keepSizeRatio and L["The size of the action buttons."] or L["The width of the action buttons."] end +E.Options.args.actionbar.args.barPet.args.buttonGroup.args.buttonHeight.hidden = function() return E.db.actionbar.barPet.keepSizeRatio end +E.Options.args.actionbar.args.barPet.args.buttonGroup.args.buttonsPerRow.max = NUM_PET_ACTION_SLOTS +E.Options.args.actionbar.args.barPet.args.buttonGroup.args.buttons.max = NUM_PET_ACTION_SLOTS +E.Options.args.actionbar.args.barPet.args.visibility.set = function(_, value) if value and value:match('[\n\r]') then value = value:gsub('[\n\r]','') end E.db.actionbar.barPet.visibility = value; AB:UpdateButtonSettings() end +E.Options.args.actionbar.args.barPet.args.barGroup.args.countFont.hidden = function() return not E.db.actionbar.barPet.customCountFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.countFontOutline.hidden = function() return not E.db.actionbar.barPet.customCountFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.countFontSize.hidden = function() return not E.db.actionbar.barPet.customCountFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.countTextPosition.hidden = function() return not E.db.actionbar.barPet.customCountFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.countTextXOffset.hidden = function() return not E.db.actionbar.barPet.customCountFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.countTextYOffset.hidden = function() return not E.db.actionbar.barPet.customCountFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.hotkeyFont.hidden = function() return not E.db.actionbar.barPet.customHotkeyFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.hotkeyFontOutline.hidden = function() return not E.db.actionbar.barPet.customHotkeyFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.hotkeyFontSize.hidden = function() return not E.db.actionbar.barPet.customHotkeyFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.hotkeyTextPosition.hidden = function() return not E.db.actionbar.barPet.customHotkeyFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.hotkeyTextXOffset.hidden = function() return not E.db.actionbar.barPet.customHotkeyFont end +E.Options.args.actionbar.args.barPet.args.barGroup.args.hotkeyTextYOffset.hidden = function() return not E.db.actionbar.barPet.customHotkeyFont end + + +E.Options.args.actionbar.args.stanceBar = ACH:Group(L["Stance Bar"], nil, 15, nil, function(info) return E.db.actionbar.stanceBar[info[#info]] end, function(info, value) E.db.actionbar.stanceBar[info[#info]] = value; AB:PositionAndSizeBarShapeShift() end, function() return not E.ActionBars.Initialized end) +E.Options.args.actionbar.args.stanceBar.args = CopyTable(SharedBarOptions) +E.Options.args.actionbar.args.stanceBar.args.restorePosition.func = function() E:CopyTable(E.db.actionbar.stanceBar, P.actionbar.stanceBar); E:ResetMovers('Stance Bar'); AB:PositionAndSizeBarShapeShift() end +E.Options.args.actionbar.args.stanceBar.args.generalOptions = ACH:MultiSelect('', nil, 3, { backdrop = L["Backdrop"], mouseover = L["Mouse Over"], clickThrough = L["Click Through"], inheritGlobalFade = L["Inherit Global Fade"], keepSizeRatio = L["Keep Size Ratio"] }, nil, nil, function(_, key) return E.db.actionbar.stanceBar[key] end, function(_, key, value) E.db.actionbar.stanceBar[key] = value; AB:PositionAndSizeBarShapeShift() end) +E.Options.args.actionbar.args.stanceBar.args.buttonGroup.args.buttonsize.name = function() return E.db.actionbar.stanceBar.keepSizeRatio and L["Button Size"] or L["Button Width"] end +E.Options.args.actionbar.args.stanceBar.args.buttonGroup.args.buttonsize.desc = function() return E.db.actionbar.stanceBar.keepSizeRatio and L["The size of the action buttons."] or L["The width of the action buttons."] end +E.Options.args.actionbar.args.stanceBar.args.buttonGroup.args.buttonHeight.hidden = function() return E.db.actionbar.stanceBar.keepSizeRatio end +E.Options.args.actionbar.args.stanceBar.args.buttonGroup.args.buttonsPerRow.max = NUM_STANCE_SLOTS +E.Options.args.actionbar.args.stanceBar.args.buttonGroup.args.buttons.max = NUM_STANCE_SLOTS +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.style = ACH:Select(L["Style"], L["This setting will be updated upon changing stances."], 12, { darkenInactive = L["Darken Inactive"], classic = L["Classic"] }) +E.Options.args.actionbar.args.stanceBar.args.visibility.set = function(_, value) if value and value:match('[\n\r]') then value = value:gsub('[\n\r]','') end E.db.actionbar.stanceBar.visibility = value; AB:UpdateButtonSettings() end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.countFont.hidden = function() return not E.db.actionbar.stanceBar.customCountFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.countFontOutline.hidden = function() return not E.db.actionbar.stanceBar.customCountFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.countFontSize.hidden = function() return not E.db.actionbar.stanceBar.customCountFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.countTextPosition.hidden = function() return not E.db.actionbar.stanceBar.customCountFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.countTextXOffset.hidden = function() return not E.db.actionbar.stanceBar.customCountFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.countTextYOffset.hidden = function() return not E.db.actionbar.stanceBar.customCountFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.hotkeyFont.hidden = function() return not E.db.actionbar.stanceBar.customHotkeyFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.hotkeyFontOutline.hidden = function() return not E.db.actionbar.stanceBar.customHotkeyFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.hotkeyFontSize.hidden = function() return not E.db.actionbar.stanceBar.customHotkeyFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.hotkeyTextPosition.hidden = function() return not E.db.actionbar.stanceBar.customHotkeyFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.hotkeyTextXOffset.hidden = function() return not E.db.actionbar.stanceBar.customHotkeyFont end +E.Options.args.actionbar.args.stanceBar.args.barGroup.args.hotkeyTextYOffset.hidden = function() return not E.db.actionbar.stanceBar.customHotkeyFont end + +E.Options.args.actionbar.args.microbar = ACH:Group(L["Micro Bar"], nil, 16, nil, function(info) return E.db.actionbar.microbar[info[#info]] end, function(info, value) E.db.actionbar.microbar[info[#info]] = value; AB:UpdateMicroPositionDimensions() end, function() return not E.ActionBars.Initialized end) +E.Options.args.actionbar.args.microbar.args = CopyTable(SharedBarOptions) +E.Options.args.actionbar.args.microbar.args.restorePosition.func = function() E:CopyTable(E.db.actionbar.microbar, P.actionbar.microbar); E:ResetMovers('Micro Bar'); AB:UpdateMicroPositionDimensions() end +E.Options.args.actionbar.args.microbar.args.generalOptions = ACH:MultiSelect('', nil, 3, { backdrop = L["Backdrop"], mouseover = L["Mouse Over"], keepSizeRatio = L["Keep Size Ratio"] }, nil, nil, function(_, key) return E.db.actionbar.microbar[key] end, function(_, key, value) E.db.actionbar.microbar[key] = value; AB:UpdateMicroPositionDimensions() end) +E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttons = nil +E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttonSize = CopyTable(E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttonsize) +E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttonsize = nil +E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttonSpacing = CopyTable(E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttonspacing) +E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttonspacing = nil +E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttonsPerRow.max = #MICRO_BUTTONS-1 +E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttonSize.name = function() return E.db.actionbar.microbar.keepSizeRatio and L["Button Size"] or L["Button Width"] end +E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttonSize.desc = function() return E.db.actionbar.microbar.keepSizeRatio and L["The size of the action buttons."] or L["The width of the action buttons."] end +E.Options.args.actionbar.args.microbar.args.buttonGroup.args.buttonHeight.hidden = function() return E.db.actionbar.microbar.keepSizeRatio end +E.Options.args.actionbar.args.microbar.args.visibility.set = function(_, value) if value and value:match('[\n\r]') then value = value:gsub('[\n\r]','') end E.db.actionbar.microbar.visibility = value; AB:UpdateMicroPositionDimensions() end +--Remove these as the microbar doesnt show either texts +E.Options.args.actionbar.args.microbar.args.barGroup.args.countFont = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.countFontOutline = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.countFontSize = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.countTextXOffset = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.countTextYOffset = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.countTextPosition = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.customCountFont = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.customHotkeyFont = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.hotkeyFont = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.hotkeyFontOutline = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.hotkeyFontSize = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.hotkeyTextPosition = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.hotkeyTextXOffset = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.hotkeyTextYOffset = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.spacer1 = nil +E.Options.args.actionbar.args.microbar.args.barGroup.args.spacer2 = nil + +local SharedButtonOptions = { + alpha = ACH:Range(L["Alpha"], L["Change the alpha level of the frame."], 1, { min = 0, max = 1, step = 0.01, isPercent = true }), + scale = ACH:Range(L["Scale"], nil, 2, { min = 0.2, max = 2, step = 0.01, isPercent = true }), + inheritGlobalFade = ACH:Toggle(L["Inherit Global Fade"], nil, 3), + clean = ACH:Toggle(L["Clean Button"], nil, 4), +} + +E.Options.args.actionbar.args.extraButtons = ACH:Group(L["Extra Buttons"], nil, 18, nil, nil, nil, function() return not E.ActionBars.Initialized end) + +E.Options.args.actionbar.args.extraButtons.args.extraActionButton = ACH:Group(L["Boss Button"], nil, 1, nil, function(info) return E.db.actionbar.extraActionButton[info[#info]] end, function(info, value) local key = info[#info] E.db.actionbar.extraActionButton[key] = value; if key == 'inheritGlobalFade' then AB:ExtraButtons_GlobalFade() elseif key == 'scale' then AB:ExtraButtons_UpdateScale() else AB:ExtraButtons_UpdateAlpha() end end) +E.Options.args.actionbar.args.extraButtons.args.extraActionButton.inline = true +E.Options.args.actionbar.args.extraButtons.args.extraActionButton.args = CopyTable(SharedButtonOptions) + +E.Options.args.actionbar.args.extraButtons.args.zoneButton = ACH:Group(L["Zone Button"], nil, 2, nil, function(info) return E.db.actionbar.zoneActionButton[info[#info]] end, function(info, value) local key = info[#info] E.db.actionbar.zoneActionButton[key] = value; if key == 'inheritGlobalFade' then AB:ExtraButtons_GlobalFade() elseif key == 'scale' then AB:ExtraButtons_UpdateScale() else AB:ExtraButtons_UpdateAlpha() end end) +E.Options.args.actionbar.args.extraButtons.args.zoneButton.inline = true +E.Options.args.actionbar.args.extraButtons.args.zoneButton.args = CopyTable(SharedButtonOptions) + +E.Options.args.actionbar.args.extraButtons.args.vehicleExitButton = ACH:Group(L["Vehicle Exit"], nil, 3, nil, function(info) return E.db.actionbar.vehicleExitButton[info[#info]] end, function(info, value) E.db.actionbar.vehicleExitButton[info[#info]] = value; AB:UpdateVehicleLeave() end) +E.Options.args.actionbar.args.extraButtons.args.vehicleExitButton.inline = true +E.Options.args.actionbar.args.extraButtons.args.vehicleExitButton.args.enable = ACH:Toggle(L["Enable"], nil, 1, nil, nil, nil, nil, function(info, value) E.db.actionbar.vehicleExitButton[info[#info]] = value; E:StaticPopup_Show('PRIVATE_RL') end) +E.Options.args.actionbar.args.extraButtons.args.vehicleExitButton.args.size = ACH:Range(L["Size"], nil, 2, { min = 16, max = 50, step = 1 }) +E.Options.args.actionbar.args.extraButtons.args.vehicleExitButton.args.strata = ACH:Select(L["Frame Strata"], nil, 3, { BACKGROUND = 'BACKGROUND', LOW = 'LOW', MEDIUM = 'MEDIUM', HIGH = 'HIGH' }) +E.Options.args.actionbar.args.extraButtons.args.vehicleExitButton.args.level = ACH:Range(L["Frame Level"], nil, 4, { min = 1, max = 128, step = 1 }) + +E.Options.args.actionbar.args.playerBars = ACH:Group(L["Player Bars"], nil, 4, 'tree', nil, nil, function() return not E.ActionBars.Initialized end) + +for i = 1, 10 do + local bar = ACH:Group(L["Bar "]..i, nil, i, 'group', function(info) return E.db.actionbar['bar'..i][info[#info]] end, function(info, value) E.db.actionbar['bar'..i][info[#info]] = value; AB:PositionAndSizeBar('bar'..i) end) + + E.Options.args.actionbar.args.playerBars.args['bar'..i] = bar + bar.args = CopyTable(SharedBarOptions) + + bar.args.enabled.set = function(info, value) E.db.actionbar['bar'..i][info[#info]] = value AB:PositionAndSizeBar('bar'..i) end + bar.args.restorePosition.set = function() E:CopyTable(E.db.actionbar['bar'..i], P.actionbar['bar'..i]) E:ResetMovers('Bar '..i) AB:PositionAndSizeBar('bar'..i) end + + bar.args.generalOptions.get = function(_, key) return E.db.actionbar['bar'..i][key] end + bar.args.generalOptions.set = function(_, key, value) E.db.actionbar['bar'..i][key] = value AB:PositionAndSizeBar('bar'..i) AB:UpdateButtonSettingsForBar('bar'..i) end + bar.args.generalOptions.values.showGrid = L["Show Empty Buttons"] + bar.args.generalOptions.values.keepSizeRatio = L["Keep Size Ratio"] + + bar.args.barGroup.args.flyoutDirection = ACH:Select(L["Flyout Direction"], nil, 2, { UP = L["Up"], DOWN = L["Down"], LEFT = L["Left"], RIGHT = L["Right"], AUTOMATIC = L["Automatic"] }, nil, nil, nil, function(info, value) E.db.actionbar['bar'..i][info[#info]] = value AB:PositionAndSizeBar('bar'..i) AB:UpdateButtonSettingsForBar('bar'..i) end) + + bar.args.buttonGroup.args.buttonsize.name = function() return E.db.actionbar['bar'..i].keepSizeRatio and L["Button Size"] or L["Button Width"] end + bar.args.buttonGroup.args.buttonsize.desc = function() return E.db.actionbar['bar'..i].keepSizeRatio and L["The size of the action buttons."] or L["The width of the action buttons."] end + bar.args.buttonGroup.args.buttonHeight.hidden = function() return E.db.actionbar['bar'..i].keepSizeRatio end + + bar.args.backdropGroup.hidden = function() return not E.db.actionbar['bar'..i].backdrop end + + bar.args.paging = ACH:Input(L["Action Paging"], L["This works like a macro, you can run different situations to get the actionbar to page differently.\n Example: '[combat] 2;'"], 7, 4, 'full', function() return E.db.actionbar['bar'..i].paging[E.myclass] end, function(_, value) if value and value:match('[\n\r]') then value = value:gsub('[\n\r]','') end E.db.actionbar['bar'..i].paging[E.myclass] = value AB:UpdateButtonSettings() end) + + bar.args.visibility.set = function(_, value) if value and value:match('[\n\r]') then value = value:gsub('[\n\r]','') end E.db.actionbar['bar'..i].visibility = value AB:UpdateButtonSettings() end + + bar.args.barGroup.args.countFont.hidden = function() return not E.db.actionbar['bar'..i].customCountFont end + bar.args.barGroup.args.countFontOutline.hidden = function() return not E.db.actionbar['bar'..i].customCountFont end + bar.args.barGroup.args.countFontSize.hidden = function() return not E.db.actionbar['bar'..i].customCountFont end + bar.args.barGroup.args.countTextXOffset.hidden = function() return not E.db.actionbar['bar'..i].customCountFont end + bar.args.barGroup.args.countTextYOffset.hidden = function() return not E.db.actionbar['bar'..i].customCountFont end + bar.args.barGroup.args.countTextPosition.hidden = function() return not E.db.actionbar['bar'..i].customCountFont end + bar.args.barGroup.args.hotkeyFont.hidden = function() return not E.db.actionbar['bar'..i].customHotkeyFont end + bar.args.barGroup.args.hotkeyFontOutline.hidden = function() return not E.db.actionbar['bar'..i].customHotkeyFont end + bar.args.barGroup.args.hotkeyFontSize.hidden = function() return not E.db.actionbar['bar'..i].customHotkeyFont end + bar.args.barGroup.args.hotkeyTextPosition.hidden = function() return not E.db.actionbar['bar'..i].customHotkeyFont end + bar.args.barGroup.args.hotkeyTextXOffset.hidden = function() return not E.db.actionbar['bar'..i].customHotkeyFont end + bar.args.barGroup.args.hotkeyTextYOffset.hidden = function() return not E.db.actionbar['bar'..i].customHotkeyFont end + + if (E.myclass == 'DRUID' and i >= 7 or E.myclass == 'ROGUE' and i == 7) then + bar.args.enabled.confirm = function() return format(L["Bar %s is used for stance or forms.|N You will have to adjust paging to use this bar.|N Are you sure?"], i) end + end +end + +E.Options.args.actionbar.args.playerBars.args.bar1.args.pagingReset = ACH:Execute(L["Reset Action Paging"], nil, 2, function() E.db.actionbar.bar1.paging[E.myclass] = P.actionbar.bar1.paging[E.myclass] AB:UpdateButtonSettings() end, nil, L["You are about to reset paging. Are you sure?"]) +E.Options.args.actionbar.args.playerBars.args.bar6.args.enabled.set = function(_, value) E.db.actionbar.bar6.enabled = value; AB:PositionAndSizeBar('bar6') AB:UpdateBar1Paging() AB:PositionAndSizeBar('bar1') end diff --git a/Auras.lua b/Auras.lua new file mode 100644 index 0000000..864e18c --- /dev/null +++ b/Auras.lua @@ -0,0 +1,76 @@ +local E, _, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB +local C, L = unpack(select(2, ...)) +local A = E:GetModule('Auras') +local ACH = E.Libs.ACH + +E.Options.args.auras = ACH:Group(L["BUFFOPTIONS_LABEL"], nil, 2, 'tab', function(info) return E.private.auras[info[#info]] end, function(info, value) E.private.auras[info[#info]] = value; E:StaticPopup_Show('PRIVATE_RL') end) +E.Options.args.auras.args.intro = ACH:Description(L["AURAS_DESC"], 0) +E.Options.args.auras.args.enable = ACH:Toggle(L["Enable"], nil, 1) +E.Options.args.auras.args.disableBlizzard = ACH:Toggle(L["Disabled Blizzard"], nil, 2) +E.Options.args.auras.args.buffsHeader = ACH:Toggle(L["Buffs"], nil, 3) +E.Options.args.auras.args.debuffsHeader = ACH:Toggle(L["Debuffs"], nil, 4) +E.Options.args.auras.args.masque = ACH:MultiSelect(L["Masque Support"], nil, 10, { buffs = L["Buffs"], debuffs = L["Debuffs"] }, nil, nil, function(_, key) return E.private.auras.masque[key] end, function(_, key, value) E.private.auras.masque[key] = value; E:StaticPopup_Show('PRIVATE_RL') end, function() return not E.Masque or not E.private.auras.enable end) + +local SharedOptions = { + general = ACH:Group(L["General"], nil, 1, nil), + + size = ACH:Range(L["Size"], L["Set the size of the individual auras."], 2, { min = 16, max = 60, step = 2 }), + growthDirection = ACH:Select(L["Growth Direction"], L["The direction the auras will grow and then the direction they will grow after they reach the wrap after limit."], 4, C.Values.GrowthDirection), + wrapAfter = ACH:Range(L["Wrap After"], L["Begin a new row or column after this many auras."], 5, { min = 1, max = 32, step = 1 }), + maxWraps = ACH:Range(L["Max Wraps"], L["Limit the number of rows or columns."], 6, { min = 1, max = 32, step = 1 }), + horizontalSpacing = ACH:Range(L["Horizontal Spacing"], nil, 7, { min = 0, max = 50, step = 1 }), + verticalSpacing = ACH:Range(L["Vertical Spacing"], nil, 8, { min = 0, max = 50, step = 1 }), + sortMethod = ACH:Select(L["Sort Method"], L["Defines how the group is sorted."], 9, { INDEX = L["Index"], TIME = L["Time"], NAME = L["Name"] }), + sortDir = ACH:Select(L["Sort Direction"], L["Defines the sort order of the selected sort method."], 10, { ['+'] = L["Ascending"], ['-'] = L["Descending"] }), + seperateOwn = ACH:Select(L["Seperate"], L["Indicate whether buffs you cast yourself should be separated before or after."], 11, { [-1] = L["Other's First"], [0] = L["No Sorting"], [1] = L["Your Auras First"] }), + + statusBar = ACH:Group(L["Statusbar"], nil, -3), + timeGroup = ACH:Group(L['Time'], nil, -2), + countGroup = ACH:Group(L['Count'], nil, -1), +} + +SharedOptions.general.inline = true +SharedOptions.general.args.fadeThreshold = ACH:Range(L["Fade Threshold"], L["Threshold before the icon will fade out and back in. Set to -1 to disable."], 1, { min = -1, max = 30, step = 1 }) +SharedOptions.general.args.showDuration = ACH:Toggle(L["Duration Enable"], nil, 3) + +SharedOptions.timeGroup.inline = true +SharedOptions.timeGroup.args.timeFont = ACH:SharedMediaFont(L["Font"], nil, 1) +SharedOptions.timeGroup.args.timeFontOutline = ACH:FontFlags(L["Font Outline"], L["Set the font outline."], 2) +SharedOptions.timeGroup.args.timeFontSize = ACH:Range(L["Font Size"], nil, 3, C.Values.FontSize) +SharedOptions.timeGroup.args.timeXOffset = ACH:Range(L["X-Offset"], nil, 4, { min = -60, max = 60, step = 1 }) +SharedOptions.timeGroup.args.timeYOffset = ACH:Range(L["Y-Offset"], nil, 5, { min = -60, max = 60, step = 1 }) + +SharedOptions.countGroup.inline = true +SharedOptions.countGroup.args.countFont = ACH:SharedMediaFont(L["Font"], nil, 1) +SharedOptions.countGroup.args.countFontOutline = ACH:FontFlags(L["Font Outline"], L["Set the font outline."], 2) +SharedOptions.countGroup.args.countFontSize = ACH:Range(L["Font Size"], nil, 3, C.Values.FontSize) +SharedOptions.countGroup.args.countXOffset = ACH:Range(L["X-Offset"], nil, 4, { min = -60, max = 60, step = 1 }) +SharedOptions.countGroup.args.countYOffset = ACH:Range(L["Y-Offset"], nil, 5, { min = -60, max = 60, step = 1 }) + +SharedOptions.statusBar.inline = true +SharedOptions.statusBar.args.barShow = ACH:Toggle(L["Enable"], nil, 1, nil, nil, nil, nil, nil, false) +SharedOptions.statusBar.args.barNoDuration = ACH:Toggle(L["No Duration"], nil, 2) +SharedOptions.statusBar.args.barTexture = ACH:SharedMediaStatusbar(L["Texture"], nil, 3) +SharedOptions.statusBar.args.barColor = ACH:Color(L.COLOR, nil, 4, true) +SharedOptions.statusBar.args.barColorGradient = ACH:Toggle(L["Color by Value"], nil, 5) +SharedOptions.statusBar.args.barPosition = ACH:Select(L["Position"], nil, 6, { TOP = L["Top"], BOTTOM = L["Bottom"], LEFT = L["Left"], RIGHT = L["Right"] }) +SharedOptions.statusBar.args.barSize = ACH:Range(L["Size"], nil, 7, { min = 1, max = 10, step = 1 }) +SharedOptions.statusBar.args.barSpacing = ACH:Range(L["Spacing"], nil, 8, { min = -10, max = 10, step = 1 }) + +E.Options.args.auras.args.buffs = ACH:Group(L["Buffs"], nil, 2, nil, function(info) return E.db.auras.buffs[info[#info]] end, function(info, value) E.db.auras.buffs[info[#info]] = value; A:UpdateHeader(A.BuffFrame) end, function() return not E.private.auras.buffsHeader end) +E.Options.args.auras.args.buffs.args = CopyTable(SharedOptions) +E.Options.args.auras.args.buffs.args.general.get = function(info) return E.db.auras.buffs[info[#info]] end +E.Options.args.auras.args.buffs.args.general.set = function(info, value) E.db.auras.buffs[info[#info]] = value; A:UpdateHeader(A.BuffFrame) end +E.Options.args.auras.args.buffs.args.statusBar.disabled = function() return not E.db.auras.buffs.barShow end +E.Options.args.auras.args.buffs.args.statusBar.args.barColor.get = function() local t = E.db.auras.buffs.barColor local d = P.auras.buffs.barColor return t.r, t.g, t.b, t.a, d.r, d.g, d.b, d.a end +E.Options.args.auras.args.buffs.args.statusBar.args.barColor.set = function(_, r, g, b) local t = E.db.auras.buffs.barColor t.r, t.g, t.b = r, g, b end +E.Options.args.auras.args.buffs.args.statusBar.args.barColor.disabled = function() return not E.db.auras.buffs.barShow or (E.db.auras.buffs.barColorGradient or not E.db.auras.buffs.barShow) end + +E.Options.args.auras.args.debuffs = ACH:Group(L["Debuffs"], nil, 3, nil, function(info) return E.db.auras.debuffs[info[#info]] end, function(info, value) E.db.auras.debuffs[info[#info]] = value; A:UpdateHeader(A.DebuffFrame) end, function() return not E.private.auras.debuffsHeader end) +E.Options.args.auras.args.debuffs.args = CopyTable(SharedOptions) +E.Options.args.auras.args.debuffs.args.general.get = function(info) return E.db.auras.debuffs[info[#info]] end +E.Options.args.auras.args.debuffs.args.general.set = function(info, value) E.db.auras.debuffs[info[#info]] = value; A:UpdateHeader(A.DebuffFrame) end +E.Options.args.auras.args.debuffs.args.statusBar.disabled = function() return not E.db.auras.debuffs.barShow end +E.Options.args.auras.args.debuffs.args.statusBar.args.barColor.get = function() local t = E.db.auras.debuffs.barColor local d = P.auras.debuffs.barColor return t.r, t.g, t.b, t.a, d.r, d.g, d.b, d.a end +E.Options.args.auras.args.debuffs.args.statusBar.args.barColor.set = function(_, r, g, b) local t = E.db.auras.debuffs.barColor t.r, t.g, t.b = r, g, b end +E.Options.args.auras.args.debuffs.args.statusBar.args.barColor.disabled = function() return not E.db.auras.debuffs.barShow or (E.db.auras.debuffs.barColorGradient or not E.db.auras.debuffs.barShow) end diff --git a/Bags.lua b/Bags.lua new file mode 100644 index 0000000..1a96a3d --- /dev/null +++ b/Bags.lua @@ -0,0 +1,777 @@ +local E, _, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB +local C, L = unpack(select(2, ...)) +local B = E:GetModule('Bags') +local ACH = E.Libs.ACH + +local _G = _G +local gsub = gsub +local strmatch = strmatch +local SetInsertItemsLeftToRight = SetInsertItemsLeftToRight +local GameTooltip = _G.GameTooltip + +E.Options.args.bags = { + type = 'group', + name = L["BAGSLOT"], + childGroups = 'tab', + order = 2, + get = function(info) return E.db.bags[info[#info]] end, + set = function(info, value) E.db.bags[info[#info]] = value end, + args = { + intro = ACH:Description(L["BAGS_DESC"], 1), + enable = { + order = 2, + type = 'toggle', + name = L["Enable"], + desc = L["Enable/Disable the all-in-one bag."], + get = function() return E.private.bags.enable end, + set = function(_, value) E.private.bags.enable = value; E:StaticPopup_Show('PRIVATE_RL') end + }, + general = { + order = 3, + type = 'group', + name = L["General"], + disabled = function() return not E.Bags.Initialized end, + args = { + currencyFormat = { + order = 1, + type = 'select', + name = L["Currency Format"], + desc = L["The display format of the currency icons that get displayed below the main bag. (You have to be watching a currency for this to display)"], + values = { + ICON = L["Icons Only"], + ICON_TEXT = L["Icons and Text"], + ICON_TEXT_ABBR = L["Icons and Text (Short)"], + }, + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateTokens(); end, + }, + moneyFormat = { + order = 2, + type = 'select', + name = L["Money Format"], + desc = L["The display format of the money text that is shown at the top of the main bag."], + values = { + SMART = L["Smart"], + FULL = L["Full"], + SHORT = L["SHORT"], + SHORTINT = L["Short (Whole Numbers)"], + CONDENSED = L["Condensed"], + BLIZZARD = L["Blizzard Style"], + BLIZZARD2 = L["Blizzard Style"]..' 2', + }, + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateGoldText(); end, + }, + strata = { + order = 3, + type = 'select', + name = L["Frame Strata"], + set = function(info, value) E.db.bags[info[#info]] = value; E:StaticPopup_Show('PRIVATE_RL') end, + values = { + BACKGROUND = 'BACKGROUND', + LOW = 'LOW', + MEDIUM = 'MEDIUM', + HIGH = 'HIGH', + }, + }, + spacer = ACH:Spacer(4, 'full'), + moneyCoins = { + order = 10, + type = 'toggle', + name = L["Show Coins"], + desc = L["Use coin icons instead of colored text."], + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateGoldText(); end, + }, + transparent = { + order = 11, + type = 'toggle', + name = L["Transparent Buttons"], + set = function(info, value) E.db.bags[info[#info]] = value; E:StaticPopup_Show('PRIVATE_RL'); end, + }, + junkIcon = { + order = 12, + type = 'toggle', + name = L["Show Junk Icon"], + desc = L["Display the junk icon on all grey items that can be vendored."], + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateAllBagSlots(); end, + }, + junkDesaturate = { + order = 13, + type = 'toggle', + name = L["Desaturate Junk Items"], + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateAllBagSlots(); end, + }, + upgradeIcon = { + order = 14, + type = 'toggle', + name = L["Show Upgrade Icon"], + desc = L["Display the upgrade icon on items that WoW considers an upgrade for your character."], + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateAllBagSlots(); end, + }, + scrapIcon = { + order = 15, + type = 'toggle', + name = L["Show Scrap Icon"], + desc = L["Display the scrap icon on items that can be scrapped."], + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateAllBagSlots(); end, + }, + newItemGlow = { + order = 16, + type = 'toggle', + name = L["Show New Item Glow"], + desc = L["Display the New Item Glow"], + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateAllBagSlots(); end, + }, + showAssignedColor = { + order = 17, + type = 'toggle', + name = L["Show Assigned Color"], + desc = L["Colors the border according to the type of items assigned to the bag."], + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateAllBagSlots(); end, + }, + showAssignedIcon = { + order = 18, + type = 'toggle', + name = L["Show Assigned Icon"], + set = function(info, value) E.db.bags[info[#info]] = value; B:Layout(); B:SizeAndPositionBagBar() end, + }, + qualityColors = { + order = 19, + type = 'toggle', + name = L["Show Quality Color"], + desc = L["Colors the border according to the Quality of the Item."], + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateAllBagSlots(); end, + }, + specialtyColors = { + order = 20, + type = 'toggle', + name = L["Show Special Bags Color"], + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateAllBagSlots(); end, + }, + showBindType = { + order = 21, + type = 'toggle', + name = L["Show Bind on Equip/Use Text"], + set = function(info, value) E.db.bags[info[#info]] = value; B:UpdateAllBagSlots(); end, + }, + clearSearchOnClose = { + order = 22, + type = 'toggle', + name = L["Clear Search On Close"], + set = function(info, value) E.db.bags[info[#info]] = value; end + }, + reverseLoot = { + order = 23, + type = 'toggle', + name = L["REVERSE_NEW_LOOT_TEXT"], + set = function(info, value) + E.db.bags.reverseLoot = value; + SetInsertItemsLeftToRight(value) + end, + }, + reverseSlots = { + order = 24, + type = 'toggle', + name = L["Reverse Bag Slots"], + set = function(info, value) E.db.bags[info[#info]] = value B:UpdateAll() end, + }, + disableBagSort = { + order = 25, + type = 'toggle', + name = L["Disable Bag Sort"], + set = function(info, value) E.db.bags[info[#info]] = value; B:ToggleSortButtonState(false); end + }, + disableBankSort = { + order = 26, + type = 'toggle', + name = L["Disable Bank Sort"], + set = function(info, value) E.db.bags[info[#info]] = value; B:ToggleSortButtonState(true); end + }, + useBlizzardCleanup = { + order = 27, + type = 'toggle', + name = L["Use Blizzard Cleanup"], + desc = L["Use Blizzards method of cleaning up bags instead of the ElvUI sorting."], + set = function(info, value) E.db.bags[info[#info]] = value; end + }, + auctionToggle = { + order = 28, + type = 'toggle', + name = L["Auction Toggle"], + desc = L["This will toggle your bags while visiting the Auction House."], + set = function(info, value) E.db.bags[info[#info]] = value; end + }, + countGroup = { + order = 50, + type = 'group', + name = L["Item Count Font"], + inline = true, + args = { + countFont = { + order = 1, + type = 'select', + dialogControl = 'LSM30_Font', + name = L["Font"], + values = AceGUIWidgetLSMlists.font, + set = function(info, value) E.db.bags.countFont = value; B:UpdateCountDisplay() end, + }, + countFontColor = { + order = 2, + type = 'color', + name = L["COLOR"], + get = function(info) + local t = E.db.bags[info[#info]] + local d = P.bags[info[#info]] + return t.r, t.g, t.b, t.a, d.r, d.g, d.b + end, + set = function(info, r, g, b) + local t = E.db.bags[info[#info]] + t.r, t.g, t.b = r, g, b + B:UpdateCountDisplay() + end, + }, + countFontSize = { + order = 3, + type = 'range', + name = L["FONT_SIZE"], + min = 6, max = 64, step = 1, + set = function(info, value) E.db.bags.countFontSize = value; B:UpdateCountDisplay() end, + }, + countFontOutline = { + order = 4, + type = 'select', + name = L["Font Outline"], + set = function(info, value) E.db.bags.countFontOutline = value; B:UpdateCountDisplay() end, + values = C.Values.FontFlags, + }, + }, + }, + itemLevelGroup = { + order = 55, + type = 'group', + name = L["Item Level"], + inline = true, + args = { + itemLevel = { + order = 1, + type = 'toggle', + name = L["Display Item Level"], + desc = L["Displays item level on equippable items."], + set = function(info, value) E.db.bags.itemLevel = value; B:UpdateItemLevelDisplay() end, + }, + itemLevelCustomColorEnable = { + order = 2, + type = 'toggle', + name = L["Enable Custom Color"], + set = function(info, value) E.db.bags.itemLevelCustomColorEnable = value; B:UpdateItemLevelDisplay() end, + }, + itemLevelCustomColor = { + order = 3, + type = 'color', + name = L["Custom Color"], + disabled = function() return not E.db.bags.itemLevelCustomColorEnable end, + get = function(info) + local t = E.db.bags.itemLevelCustomColor + local d = P.bags.itemLevelCustomColor + return t.r, t.g, t.b, t.a, d.r, d.g, d.b + end, + set = function(info, r, g, b) + local t = E.db.bags.itemLevelCustomColor + t.r, t.g, t.b = r, g, b + B:UpdateItemLevelDisplay() + end, + }, + itemLevelThreshold = { + order = 4, + name = L["Item Level Threshold"], + desc = L["The minimum item level required for it to be shown."], + type = 'range', + min = 1, max = 1000, step = 1, + disabled = function() return not E.db.bags.itemLevel end, + set = function(info, value) E.db.bags.itemLevelThreshold = value; B:UpdateItemLevelDisplay() end, + }, + itemLevelFont = { + order = 5, + type = 'select', + dialogControl = 'LSM30_Font', + name = L["Font"], + values = AceGUIWidgetLSMlists.font, + disabled = function() return not E.db.bags.itemLevel end, + set = function(info, value) E.db.bags.itemLevelFont = value; B:UpdateItemLevelDisplay() end, + }, + itemLevelFontSize = { + order = 6, + type = 'range', + name = L["FONT_SIZE"], + min = 6, max = 64, step = 1, + disabled = function() return not E.db.bags.itemLevel end, + set = function(info, value) E.db.bags.itemLevelFontSize = value; B:UpdateItemLevelDisplay() end, + }, + itemLevelFontOutline = { + order = 7, + type = 'select', + name = L["Font Outline"], + disabled = function() return not E.db.bags.itemLevel end, + set = function(info, value) E.db.bags.itemLevelFontOutline = value; B:UpdateItemLevelDisplay() end, + values = C.Values.FontFlags, + }, + }, + }, + }, + }, + sizeGroup = { + order = 4, + type = 'group', + name = L["Size"], + disabled = function() return not E.Bags.Initialized end, + args = { + bagSize = { + order = 2, + type = 'range', + name = L["Button Size (Bag)"], + desc = L["The size of the individual buttons on the bag frame."], + min = 15, max = 45, step = 1, + set = function(info, value) E.db.bags[info[#info]] = value; B:Layout(); end, + }, + bankSize = { + order = 3, + type = 'range', + name = L["Button Size (Bank)"], + desc = L["The size of the individual buttons on the bank frame."], + min = 15, max = 45, step = 1, + set = function(info, value) E.db.bags[info[#info]] = value; B:Layout(true) end, + }, + bagWidth = { + order = 4, + type = 'range', + name = L["Panel Width (Bags)"], + desc = L["Adjust the width of the bag frame."], + min = 150, max = 1400, step = 1, + set = function(info, value) E.db.bags[info[#info]] = value; B:Layout();end, + }, + bankWidth = { + order = 5, + type = 'range', + name = L["Panel Width (Bank)"], + desc = L["Adjust the width of the bank frame."], + min = 150, max = 1400, step = 1, + set = function(info, value) E.db.bags[info[#info]] = value; B:Layout(true) end, + }, + }, + }, + colorGroup = { + order = 5, + type = 'group', + name = L["COLORS"], + disabled = function() return not E.Bags.Initialized end, + args = { + bags = { + order = 2, + type = 'group', + name = L["Bags"], + inline = true, + args = { + profession = { + order = 1, + type = 'group', + name = L["Profession Bags"], + inline = true, + get = function(info) + local t = E.db.bags.colors.profession[info[#info]] + local d = P.bags.colors.profession[info[#info]] + return t.r, t.g, t.b, t.a, d.r, d.g, d.b + end, + set = function(info, r, g, b) + local t = E.db.bags.colors.profession[info[#info]] + t.r, t.g, t.b = r, g, b + B:UpdateBagColors('ProfessionColors', info[#info], r, g, b) + B:UpdateAllBagSlots() + end, + args = { + leatherworking = { + order = 1, + type = 'color', + name = L["Leatherworking"], + }, + inscription = { + order = 2, + type = 'color', + name = L["INSCRIPTION"], + }, + herbs = { + order = 3, + type = 'color', + name = L["Herbalism"], + }, + enchanting = { + order = 4, + type = 'color', + name = L["Enchanting"], + }, + engineering = { + order = 5, + type = 'color', + name = L["Engineering"], + }, + gems = { + order = 6, + type = 'color', + name = L["Gems"], + }, + mining = { + order = 7, + type = 'color', + name = L["Mining"], + }, + fishing = { + order = 8, + type = 'color', + name = L["PROFESSIONS_FISHING"], + }, + cooking = { + order = 9, + type = 'color', + name = L["PROFESSIONS_COOKING"], + }, + }, + }, + assignment = { + order = 2, + type = 'group', + name = L["Bag Assignment"], + inline = true, + get = function(info) + local t = E.db.bags.colors.assignment[info[#info]] + local d = P.bags.colors.assignment[info[#info]] + return t.r, t.g, t.b, t.a, d.r, d.g, d.b + end, + set = function(info, r, g, b) + local t = E.db.bags.colors.assignment[info[#info]] + t.r, t.g, t.b = r, g, b + B:UpdateBagColors('AssignmentColors', info[#info], r, g, b) + B:UpdateAllBagSlots() + end, + args = { + equipment = { + order = 1, + type = 'color', + name = L["BAG_FILTER_EQUIPMENT"], + }, + consumables = { + order = 2, + type = 'color', + name = L["BAG_FILTER_CONSUMABLES"], + }, + tradegoods = { + order = 3, + type = 'color', + name = L["BAG_FILTER_TRADE_GOODS"], + }, + }, + }, + }, + }, + items = { + order = 3, + type = 'group', + name = L["ITEMS"], + inline = true, + get = function(info) + local t = E.db.bags.colors.items[info[#info]] + local d = P.bags.colors.items[info[#info]] + return t.r, t.g, t.b, t.a, d.r, d.g, d.b + end, + set = function(info, r, g, b) + local t = E.db.bags.colors.items[info[#info]] + t.r, t.g, t.b = r, g, b + B:UpdateQuestColors('QuestColors', info[#info], r, g, b) + B:UpdateAllBagSlots() + end, + args = { + questStarter = { + order = 1, + type = 'color', + name = L["Quest Starter"] + }, + questItem = { + order = 2, + type = 'color', + name = L["ITEM_BIND_QUEST"], + } + } + } + } + }, + bagBar = { + order = 6, + type = 'group', + name = L["Bag-Bar"], + get = function(info) return E.db.bags.bagBar[info[#info]] end, + set = function(info, value) E.db.bags.bagBar[info[#info]] = value; B:SizeAndPositionBagBar() end, + args = { + enable = { + order = 1, + type = 'toggle', + name = L["Enable"], + desc = L["Enable/Disable the Bag-Bar."], + get = function() return E.private.bags.bagBar end, + set = function(_, value) E.private.bags.bagBar = value; E:StaticPopup_Show('PRIVATE_RL') end + }, + showBackdrop = { + order = 2, + type = 'toggle', + name = L["Backdrop"], + }, + mouseover = { + order = 3, + name = L["Mouse Over"], + desc = L["The frame is not shown unless you mouse over the frame."], + type = 'toggle', + }, + size = { + order = 4, + type = 'range', + name = L["Button Size"], + desc = L["Set the size of your bag buttons."], + min = 24, max = 60, step = 1, + }, + spacing = { + order = 5, + type = 'range', + name = L["Button Spacing"], + desc = L["The spacing between buttons."], + min = -1, max = 10, step = 1, + }, + backdropSpacing = { + order = 6, + type = 'range', + name = L["Backdrop Spacing"], + desc = L["The spacing between the backdrop and the buttons."], + min = 0, max = 10, step = 1, + disabled = function() return not E.private.actionbar.enable end, + }, + sortDirection = { + order = 7, + type = 'select', + name = L["Sort Direction"], + desc = L["The direction that the bag frames will grow from the anchor."], + values = { + ASCENDING = L["Ascending"], + DESCENDING = L["Descending"], + }, + }, + growthDirection = { + order = 7, + type = 'select', + name = L["Bar Direction"], + desc = L["The direction that the bag frames be (Horizontal or Vertical)."], + values = { + VERTICAL = L["Vertical"], + HORIZONTAL = L["Horizontal"], + }, + }, + visibility = { + type = 'input', + order = 8, + name = L["Visibility State"], + desc = L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] show;hide'"], + width = 'full', + multiline = true, + set = function(_, value) + if value and value:match('[\n\r]') then + value = value:gsub('[\n\r]','') + end + E.db.bags.bagBar.visibility = value; + B:SizeAndPositionBagBar() + end, + }, + }, + }, + split = { + order = 7, + type = 'group', + name = L["Split"], + get = function(info) return E.db.bags.split[info[#info]] end, + set = function(info, value) E.db.bags.split[info[#info]] = value B:UpdateAll() end, + disabled = function() return not E.Bags.Initialized end, + args = { + bagSpacing = { + order = 1, + type = 'range', + name = L["Bag Spacing"], + min = 0, max = 20, step = 1, + }, + player = { + order = 2, + type = 'toggle', + set = function(info, value) E.db.bags.split[info[#info]] = value B:Layout() end, + name = L["Bag"], + }, + bank = { + order = 3, + type = 'toggle', + set = function(info, value) E.db.bags.split[info[#info]] = value B:Layout(true) end, + name = L["Bank"], + }, + splitbags = { + order = 4, + type = 'multiselect', + name = L["Player"], + get = function(_, key) return E.db.bags.split[key] end, + set = function(_, key, value) E.db.bags.split[key] = value B:Layout() end, + values = { + bag1 = L["Bag 1"], + bag2 = L["Bag 2"], + bag3 = L["Bag 3"], + bag4 = L["Bag 4"], + }, + disabled = function() return not E.db.bags.split.player end, + }, + splitbank = { + order = 5, + type = 'multiselect', + name = L["Bank"], + get = function(_, key) return E.db.bags.split[key] end, + set = function(_, key, value) E.db.bags.split[key] = value B:Layout(true) end, + sortByValue = true, + values = { + bag5 = L["Bank 1"], + bag6 = L["Bank 2"], + bag7 = L["Bank 3"], + bag8 = L["Bank 4"], + bag9 = L["Bank 5"], + bag10 = L["Bank 6"], + bag11 = L["Bank 7"], + }, + disabled = function() return not E.db.bags.split.bank end, + }, + }, + }, + vendorGrays = { + order = 8, + type = 'group', + name = L["Vendor Grays"], + get = function(info) return E.db.bags.vendorGrays[info[#info]] end, + set = function(info, value) E.db.bags.vendorGrays[info[#info]] = value; B:UpdateSellFrameSettings() end, + args = { + enable = { + order = 1, + type = 'toggle', + name = L["Enable"], + desc = L["Automatically vendor gray items when visiting a vendor."], + }, + interval = { + order = 2, + type = 'range', + name = L["Sell Interval"], + desc = L["Will attempt to sell another item in set interval after previous one was sold."], + min = 0.1, max = 1, step = 0.1, + }, + details = { + order = 3, + name = L["Vendor Gray Detailed Report"], + desc = L["Displays a detailed report of every item sold when enabled."], + type = 'toggle', + }, + progressBar = { + order = 4, + name = L["Progress Bar"], + type = 'toggle', + }, + }, + }, + bagSortingGroup = { + order = 9, + type = 'group', + name = L["Bag Sorting"], + disabled = function() return (not E.Bags.Initialized) or E.db.bags.useBlizzardCleanup end, + args = { + sortInverted = { + order = 1, + type = 'toggle', + name = L["Sort Inverted"], + desc = L["Direction the bag sorting will use to allocate the items."], + }, + description = ACH:Description(L["Here you can add items or search terms that you want to be excluded from sorting. To remove an item just click on its name in the list."], 3), + addEntryGroup = { + order = 4, + type = 'group', + name = L["Add Item or Search Syntax"], + inline = true, + args = { + addEntryProfile = { + order = 1, + name = L["Profile"], + desc = L["Add an item or search syntax to the ignored list. Items matching the search syntax will be ignored."], + type = 'input', + get = function() return '' end, + set = function(_, value) + if value == '' or gsub(value, '%s+', '') == '' then return; end --Don't allow empty entries + + --Store by itemID if possible + local itemID = strmatch(value, 'item:(%d+)') + E.db.bags.ignoredItems[(itemID or value)] = value + end, + }, + addEntryGlobal = { + order = 3, + name = L["Global"], + desc = L["Add an item or search syntax to the ignored list. Items matching the search syntax will be ignored."], + type = 'input', + get = function() return '' end, + set = function(_, value) + if value == '' or gsub(value, '%s+', '') == '' then return; end --Don't allow empty entries + + --Store by itemID if possible + local itemID = strmatch(value, 'item:(%d+)') + E.global.bags.ignoredItems[(itemID or value)] = value + + --Remove from profile list if we just added the same item to global list + if E.db.bags.ignoredItems[(itemID or value)] then + E.db.bags.ignoredItems[(itemID or value)] = nil + end + end, + }, + }, + }, + ignoredEntriesProfile = { + order = 5, + type = 'multiselect', + name = L["Ignored Items and Search Syntax (Profile)"], + values = function() return E.db.bags.ignoredItems end, + get = function(_, value) return E.db.bags.ignoredItems[value] end, + set = function(_, value) + E.db.bags.ignoredItems[value] = nil + GameTooltip:Hide()--Make sure tooltip is properly hidden + end, + }, + ignoredEntriesGlobal = { + order = 6, + type = 'multiselect', + name = L["Ignored Items and Search Syntax (Global)"], + values = function() return E.global.bags.ignoredItems end, + get = function(_, value) return E.global.bags.ignoredItems[value] end, + set = function(_, value) + E.global.bags.ignoredItems[value] = nil + GameTooltip:Hide()--Make sure tooltip is properly hidden + end, + }, + }, + }, + search_syntax = { + order = 10, + type = 'group', + name = L["Search Syntax"], + disabled = function() return not E.Bags.Initialized end, + args = { + text = { + order = 1, + type = 'input', + multiline = 26, + width = 'full', + name = '', + get = function() return L["SEARCH_SYNTAX_DESC"]; end, + set = E.noop, + }, + }, + }, + }, +} diff --git a/Chat.lua b/Chat.lua new file mode 100644 index 0000000..ea2b009 --- /dev/null +++ b/Chat.lua @@ -0,0 +1,857 @@ +local E, _, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB +local C, L = unpack(select(2, ...)) +local CH = E:GetModule('Chat') +local Bags = E:GetModule('Bags') +local Layout = E:GetModule('Layout') +local ACH = E.Libs.ACH + +local _G = _G +local gsub = gsub +local wipe = wipe +local pairs = pairs +local format = format +local strlower = strlower +local GameTooltip = _G.GameTooltip + +local tabSelectorTable = {} + +E.Options.args.chat = { + type = 'group', + name = L["Chat"], + childGroups = 'tab', + order = 2, + get = function(info) return E.db.chat[info[#info]] end, + set = function(info, value) E.db.chat[info[#info]] = value end, + args = { + intro = ACH:Description(L["CHAT_DESC"], 1), + enable = { + order = 2, + type = 'toggle', + name = L["Enable"], + get = function() return E.private.chat.enable end, + set = function(_, value) E.private.chat.enable = value; E:StaticPopup_Show('PRIVATE_RL') end + }, + general = { + order = 3, + type = 'group', + name = L["General"], + disabled = function() return not E.Chat.Initialized end, + args = { + url = { + order = 1, + type = 'toggle', + name = L["URL Links"], + desc = L["Attempt to create URL links inside the chat."], + }, + shortChannels = { + order = 2, + type = 'toggle', + name = L["Short Channels"], + desc = L["Shorten the channel names in chat."], + }, + hyperlinkHover = { + order = 3, + type = 'toggle', + name = L["Hyperlink Hover"], + desc = L["Display the hyperlink tooltip while hovering over a hyperlink."], + set = function(info, value) + E.db.chat[info[#info]] = value + CH:ToggleHyperlink(value) + end, + }, + sticky = { + order = 3, + type = 'toggle', + name = L["Sticky Chat"], + desc = L["When opening the Chat Editbox to type a message having this option set means it will retain the last channel you spoke in. If this option is turned off opening the Chat Editbox should always default to the SAY channel."], + }, + emotionIcons = { + order = 5, + type = 'toggle', + name = L["Emotion Icons"], + desc = L["Display emotion icons in chat."], + }, + lfgIcons = { + order = 6, + type = 'toggle', + name = L["Role Icon"], + desc = L["Display LFG Icons in group chat."], + set = function(self, value) + E.db.chat.lfgIcons = value; + CH:CheckLFGRoles() + end, + }, + useAltKey = { + order = 12, + type = 'toggle', + name = L["Use Alt Key"], + desc = L["Require holding the Alt key down to move cursor or cycle through messages in the editbox."], + set = function(self, value) + E.db.chat.useAltKey = value; + CH:UpdateSettings() + end, + }, + autoClosePetBattleLog = { + order = 13, + type = 'toggle', + name = L["Auto-Close Pet Battle Log"], + }, + useBTagName = { + order = 14, + type = 'toggle', + name = L["Use Real ID BattleTag"], + desc = L["Use BattleTag instead of Real ID names in chat. Chat History will always use BattleTag."], + }, + socialQueueMessages = { + order = 15, + type = 'toggle', + name = L["Quick Join Messages"], + desc = L["Show clickable Quick Join messages inside of the chat."], + }, + copyChatLines = { + order = 16, + type = 'toggle', + name = L["Copy Chat Lines"], + desc = L["Adds an arrow infront of the chat lines to copy the entire line."], + }, + hideCopyButton = { + order = 17, + type = 'toggle', + name = L["Hide Copy Button"], + set = function(self, value) + E.db.chat.hideCopyButton = value + CH:ToggleCopyChatButtons() + end, + }, + spacer = ACH:Spacer(18, 'full'), + numAllowedCombatRepeat = { + order = 19, + type = 'range', + name = L["Allowed Combat Repeat"], + desc = L["Number of repeat characters while in combat before the chat editbox is automatically closed."], + min = 2, max = 10, step = 1, + }, + throttleInterval = { + order = 20, + type = 'range', + name = L["Spam Interval"], + desc = L["Prevent the same messages from displaying in chat more than once within this set amount of seconds, set to zero to disable."], + min = 0, max = 120, step = 1, + set = function(info, value) + E.db.chat[info[#info]] = value + if value == 0 then + CH:DisableChatThrottle() + end + end, + }, + scrollDownInterval = { + order = 21, + type = 'range', + name = L["Scroll Interval"], + desc = L["Number of time in seconds to scroll down to the bottom of the chat window if you are not scrolled down completely."], + min = 0, max = 120, step = 5, + }, + numScrollMessages = { + order = 22, + type = 'range', + name = L["Scroll Messages"], + desc = L["Number of messages you scroll for each step."], + min = 1, max = 10, step = 1, + }, + maxLines = { + order = 23, + type = 'range', + name = L["Max Lines"], + min = 10, max = 5000, step = 1, + set = function(info, value) E.db.chat[info[#info]] = value; CH:SetupChat() end, + }, + editboxHistorySize = { + order = 24, + type = 'range', + name = L["Editbox History"], + min = 5, max = 50, step = 1, + }, + resetHistory = { + order = 25, + type = 'execute', + name = L["Reset Editbox History"], + func = function() CH:ResetEditboxHistory() end + }, + editBoxPosition = { + order = 26, + type = 'select', + name = L["Chat EditBox Position"], + desc = L["Position of the Chat EditBox, if datatexts are disabled this will be forced to be above chat."], + values = { + BELOW_CHAT = L["Below Chat"], + ABOVE_CHAT = L["Above Chat"], + }, + set = function(info, value) + E.db.chat[info[#info]] = value; + CH:UpdateEditboxAnchors() + end, + }, + tabSelection = { + order = 65, + type = 'group', + name = L["Tab Selector"], + set = function(info, value) + E.db.chat[info[#info]] = value; + CH:UpdateChatTabColors(); + end, + args = { + tabSelectedTextEnabled = { + order = 1, + type = 'toggle', + name = L["Colorize Selected Text"], + }, + tabSelectedTextColor = { + order = 2, + type = 'color', + hasAlpha = false, + name = L["Selected Text Color"], + disabled = function() return not E.db.chat.tabSelectedTextEnabled end, + get = function() + local t = E.db.chat.tabSelectedTextColor + local d = P.chat.tabSelectedTextColor + return t.r, t.g, t.b, t.a, d.r, d.g, d.b + end, + set = function(_, r, g, b) + local t = E.db.chat.tabSelectedTextColor + t.r, t.g, t.b = r, g, b + CH:UpdateChatTabColors(); + end, + }, + tabSelector = { + order = 3, + type = 'select', + name = L["Selector Style"], + values = function() + wipe(tabSelectorTable) + + for key, value in pairs(CH.TabStyles) do + if key == 'NONE' then + tabSelectorTable[key] = 'None' + else + local color = CH.db.tabSelectorColor + local hexColor = E:RGBToHex(color.r, color.g, color.b) + + local selectedColor = E.media.hexvaluecolor + if CH.db.tabSelectedTextEnabled then + color = E.db.chat.tabSelectedTextColor + selectedColor = E:RGBToHex(color.r, color.g, color.b) + end + + tabSelectorTable[key] = format(value, hexColor, format('%sName|r', selectedColor), hexColor) + end + end + + return tabSelectorTable + end, + }, + tabSelectorColor = { + order = 4, + type = 'color', + hasAlpha = false, + name = L["Selector Color"], + disabled = function() return E.db.chat.tabSelector == 'NONE' end, + get = function() + local t = E.db.chat.tabSelectorColor + local d = P.chat.tabSelectorColor + return t.r, t.g, t.b, t.a, d.r, d.g, d.b + end, + set = function(_, r, g, b) + local t = E.db.chat.tabSelectorColor + t.r, t.g, t.b = r, g, b + E:UpdateMedia(); + end, + }, + } + }, + historyGroup = { + order = 70, + type = 'group', + name = L["History"], + set = function(info, value) E.db.chat[info[#info]] = value end, + args = { + chatHistory = { + order = 1, + type = 'toggle', + name = L["Enable"], + desc = L["Log the main chat frames history. So when you reloadui or log in and out you see the history from your last session."], + }, + resetHistory = { + order = 2, + type = 'execute', + name = L["Reset History"], + func = function() CH:ResetHistory() end + }, + historySize = { + order = 3, + type = 'range', + name = L["History Size"], + min = 10, max = 500, step = 1, + disabled = function() return not E.db.chat.chatHistory end, + }, + historyTypes = { + order = 4, + type = 'multiselect', + name = L["Display Types"], + get = function(info, key) return + E.db.chat.showHistory[key] + end, + set = function(info, key, value) + E.db.chat.showHistory[key] = value + end, + disabled = function() return not E.db.chat.chatHistory end, + values = { + WHISPER = L["Whisper"], + GUILD = L["Guild"], + OFFICER = L["Officer"], + PARTY = L["Party"], + RAID = L["Raid"], + INSTANCE = L["Instance"], + CHANNEL = L["Channel"], + SAY = L["Say"], + YELL = L["Yell"], + EMOTE = L["Emote"] + }, + } + } + }, + fadingGroup = { + order = 75, + type = 'group', + name = L["Text Fade"], + disabled = function() return not E.Chat.Initialized end, + set = function(info, value) E.db.chat[info[#info]] = value; CH:UpdateFading() end, + args = { + fade = { + order = 1, + type = 'toggle', + name = L["Enable"], + desc = L["Fade the chat text when there is no activity."], + }, + inactivityTimer = { + order = 2, + type = 'range', + name = L["Inactivity Timer"], + desc = L["Controls how many seconds of inactivity has to pass before chat is faded."], + disabled = function() return not CH.db.fade end, + min = 5, softMax = 120, step = 1, + }, + }, + }, + fontGroup = { + order = 80, + type = 'group', + name = L["Fonts"], + disabled = function() return not E.Chat.Initialized end, + set = function(info, value) E.db.chat[info[#info]] = value; CH:SetupChat() end, + args = { + font = { + type = 'select', dialogControl = 'LSM30_Font', + order = 1, + name = L["Font"], + values = AceGUIWidgetLSMlists.font, + }, + fontOutline = { + order = 2, + name = L["Font Outline"], + desc = L["Set the font outline."], + type = 'select', + values = C.Values.FontFlags, + }, + tabFont = { + type = 'select', dialogControl = 'LSM30_Font', + order = 4, + name = L["Tab Font"], + values = AceGUIWidgetLSMlists.font, + }, + tabFontOutline = { + order = 5, + name = L["Tab Font Outline"], + desc = L["Set the font outline."], + type = 'select', + values = C.Values.FontFlags, + }, + tabFontSize = { + order = 6, + name = L["Tab Font Size"], + type = 'range', + min = 4, max = 60, step = 1, + }, + }, + }, + alerts = { + order = 85, + type = 'group', + name = L["Alerts"], + disabled = function() return not E.Chat.Initialized end, + args = { + noAlertInCombat = { + order = 1, + type = 'toggle', + name = L["No Alert In Combat"], + }, + keywordAlerts = { + order = 2, + type = 'group', + name = L["Keyword Alerts"], + inline = true, + args = { + keywordSound = { + order = 1, + type = 'select', dialogControl = 'LSM30_Sound', + name = L["Keyword Alert"], + width = 'double', + values = AceGUIWidgetLSMlists.sound, + }, + keywords = { + order = 2, + name = L["Keywords"], + desc = L["List of words to color in chat if found in a message. If you wish to add multiple words you must seperate the word with a comma. To search for your current name you can use %MYNAME%.\n\nExample:\n%MYNAME%, ElvUI, RBGs, Tank"], + type = 'input', + width = 'full', + set = function(info, value) E.db.chat[info[#info]] = value; CH:UpdateChatKeywords() end, + }, + }, + }, + channelAlerts = { + order = 3, + type = 'group', + name = L["Channel Alerts"], + inline = true, + get = function(info) return E.db.chat.channelAlerts[info[#info]] end, + set = function(info, value) E.db.chat.channelAlerts[info[#info]] = value end, + args = { + GUILD = { + type = 'select', dialogControl = 'LSM30_Sound', + name = L["Guild"], + width = 'double', + values = AceGUIWidgetLSMlists.sound, + }, + OFFICER = { + type = 'select', dialogControl = 'LSM30_Sound', + name = L["Officer"], + width = 'double', + values = AceGUIWidgetLSMlists.sound, + }, + INSTANCE = { + type = 'select', dialogControl = 'LSM30_Sound', + name = L["Instance"], + width = 'double', + values = AceGUIWidgetLSMlists.sound, + }, + PARTY = { + type = 'select', dialogControl = 'LSM30_Sound', + name = L["Party"], + width = 'double', + values = AceGUIWidgetLSMlists.sound, + }, + RAID = { + type = 'select', dialogControl = 'LSM30_Sound', + name = L["Raid"], + width = 'double', + values = AceGUIWidgetLSMlists.sound, + }, + WHISPER = { + type = 'select', dialogControl = 'LSM30_Sound', + name = L["Whisper"], + width = 'double', + values = AceGUIWidgetLSMlists.sound, + }, + }, + }, + }, + }, + voicechatGroup = { + order = 90, + type = 'group', + name = L["BINDING_HEADER_VOICE_CHAT"], + args = { + hideVoiceButtons = { + order = 1, + type = 'toggle', + name = L["Hide Voice Buttons"], + desc = L["Completely hide the voice buttons."], + set = function(info, value) + E.db.chat[info[#info]] = value + E:StaticPopup_Show('CONFIG_RL') + end, + }, + pinVoiceButtons = { + order = 2, + type = 'toggle', + name = L["Pin Voice Buttons"], + desc = L["This will pin the voice buttons to the chat's tab panel. Unchecking it will create a voice button panel with a mover."], + disabled = function() return E.db.chat.hideVoiceButtons end, + set = function(info, value) + E.db.chat[info[#info]] = value + E:StaticPopup_Show('CONFIG_RL') + end, + }, + desaturateVoiceIcons = { + order = 3, + type = 'toggle', + name = L["Desaturate Voice Icons"], + disabled = function() return E.db.chat.hideVoiceButtons end, + set = function(info, value) + E.db.chat[info[#info]] = value + CH:UpdateVoiceChatIcons() + end, + }, + }, + }, + timestampGroup = { + order = 95, + type = 'group', + name = L["TIMESTAMPS_LABEL"], + args = { + useCustomTimeColor = { + order = 1, + type = 'toggle', + name = L["Custom Timestamp Color"], + disabled = function() return not E.db.chat.timeStampFormat == 'NONE' end, + }, + customTimeColor = { + order = 2, + type = 'color', + hasAlpha = false, + name = L["Timestamp Color"], + disabled = function() return (not E.db.chat.timeStampFormat == 'NONE' or not E.db.chat.useCustomTimeColor) end, + get = function(info) + local t = E.db.chat.customTimeColor + local d = P.chat.customTimeColor + return t.r, t.g, t.b, t.a, d.r, d.g, d.b + end, + set = function(info, r, g, b) + local t = E.db.chat.customTimeColor + t.r, t.g, t.b = r, g, b + end, + }, + timeStampLocalTime = { + order = 3, + type = 'toggle', + name = L["Local Time"], + desc = L["If not set to true then the server time will be displayed instead."], + }, + timeStampFormat = { + order = 4, + type = 'select', + name = L["TIMESTAMPS_LABEL"], + desc = L["OPTION_TOOLTIP_TIMESTAMPS"], + values = { + ['NONE'] = L["NONE"], + ['%I:%M '] = '03:27', + ['%I:%M:%S '] = '03:27:32', + ['%I:%M %p '] = '03:27 PM', + ['%I:%M:%S %p '] = '03:27:32 PM', + ['%H:%M '] = '15:27', + ['%H:%M:%S '] = '15:27:32' + }, + }, + }, + }, + classColorMentionGroup = { + order = 100, + type = 'group', + name = L["Class Color Mentions"], + disabled = function() return not E.Chat.Initialized end, + args = { + classColorMentionsChat = { + order = 1, + type = 'toggle', + name = L["Chat"], + desc = L["Use class color for the names of players when they are mentioned."], + get = function(info) return E.db.chat.classColorMentionsChat end, + set = function(info, value) E.db.chat.classColorMentionsChat = value end, + disabled = function() return not E.private.chat.enable end, + }, + classColorMentionsSpeech = { + order = 2, + type = 'toggle', + name = L["Chat Bubbles"], + desc = L["Use class color for the names of players when they are mentioned."], + get = function(info) return E.private.general.classColorMentionsSpeech end, + set = function(info, value) E.private.general.classColorMentionsSpeech = value; E:StaticPopup_Show('PRIVATE_RL') end, + disabled = function() return (E.private.general.chatBubbles == 'disabled' or not E.private.chat.enable) end, + }, + classColorMentionExcludeName = { + order = 21, + name = L["Exclude Name"], + desc = L["Excluded names will not be class colored."], + type = 'input', + get = function(info) return '' end, + set = function(info, value) + if value == '' or gsub(value, '%s+', '') == '' then return; end --Don't allow empty entries + E.global.chat.classColorMentionExcludedNames[strlower(value)] = value + end, + }, + classColorMentionExcludedNames = { + order = 22, + type = 'multiselect', + name = L["Excluded Names"], + values = function() return E.global.chat.classColorMentionExcludedNames end, + get = function(info, value) return E.global.chat.classColorMentionExcludedNames[value] end, + set = function(info, value) + E.global.chat.classColorMentionExcludedNames[value] = nil + GameTooltip:Hide()--Make sure tooltip is properly hidden + end, + }, + }, + }, + }, + }, + panels = { + order = 5, + type = 'group', + name = L["Panels"], + args = { + fadeUndockedTabs = { + order = 1, + type = 'toggle', + name = L["Fade Undocked Tabs"], + desc = L["Fades the text on chat tabs that are not docked at the left or right chat panel."], + hidden = function() return not E.Chat.Initialized end, + set = function(self, value) + E.db.chat.fadeUndockedTabs = value; + CH:UpdateChatTabs() + end, + }, + fadeTabsNoBackdrop = { + order = 2, + type = 'toggle', + name = L["Fade Tabs No Backdrop"], + desc = L["Fades the text on chat tabs that are docked in a panel where the backdrop is disabled."], + hidden = function() return not E.Chat.Initialized end, + set = function(self, value) + E.db.chat.fadeTabsNoBackdrop = value; + CH:UpdateChatTabs() + end, + }, + hideChatToggles = { + order = 3, + type = 'toggle', + name = L["Hide Chat Toggles"], + set = function(self, value) + E.db.chat.hideChatToggles = value; + CH:RefreshToggleButtons() + Layout:RepositionChatDataPanels() + end, + }, + fadeChatToggles = { + order = 4, + type = 'toggle', + name = L["Fade Chat Toggles"], + desc = L["Fades the buttons that toggle chat windows when that window has been toggled off."], + disabled = function() return E.db.chat.hideChatToggles end, + set = function(self, value) + E.db.chat.fadeChatToggles = value; + CH:RefreshToggleButtons() + end, + }, + tabGroup = { + order = 10, + type = 'group', + inline = true, + name = L["Tab Panels"], + hidden = function() return not E.Chat.Initialized end, + args = { + panelTabTransparency = { + order = 1, + type = 'toggle', + name = L["Tab Panel Transparency"], + customWidth = 250, + disabled = function() return not E.db.chat.panelTabBackdrop end, + set = function(info, value) E.db.chat.panelTabTransparency = value; Layout:SetChatTabStyle(); end, + }, + panelTabBackdrop = { + order = 2, + type = 'toggle', + name = L["Tab Panel"], + desc = L["Toggle the chat tab panel backdrop."], + set = function(info, value) + E.db.chat.panelTabBackdrop = value + Layout:ToggleChatPanels() + + if E.db.chat.pinVoiceButtons and not E.db.chat.hideVoiceButtons then + CH:ReparentVoiceChatIcon() + end + end, + }, + } + }, + datatextGroup = { + order = 15, + type = 'group', + inline = true, + name = L["DataText Panels"], + args = { + LeftChatDataPanelAnchor = { + order = 1, + type = 'select', + name = L["Left Position"], + values = { + BELOW_CHAT = L["Below Chat"], + ABOVE_CHAT = L["Above Chat"], + }, + set = function(info, value) E.db.chat[info[#info]] = value; Layout:RepositionChatDataPanels() end, + }, + RightChatDataPanelAnchor = { + order = 2, + type = 'select', + name = L["Right Position"], + values = { + BELOW_CHAT = L["Below Chat"], + ABOVE_CHAT = L["Above Chat"], + }, + set = function(info, value) E.db.chat[info[#info]] = value; Layout:RepositionChatDataPanels() end, + } + } + }, + panels = { + order = 20, + type = 'group', + inline = true, + name = L["Chat Panels"], + args = { + panelColor = { + order = 1, + type = 'color', + name = L["Backdrop Color"], + hasAlpha = true, + get = function(info) + local t = E.db.chat.panelColor + local d = P.chat.panelColor + return t.r, t.g, t.b, t.a, d.r, d.g, d.b, d.a + end, + set = function(info, r, g, b, a) + local t = E.db.chat.panelColor + t.r, t.g, t.b, t.a = r, g, b, a + CH:Panels_ColorUpdate() + end, + }, + separateSizes = { + order = 2, + type = 'toggle', + name = L["Separate Panel Sizes"], + desc = L["Enable the use of separate size options for the right chat panel."], + set = function(info, value) + E.db.chat.separateSizes = value + CH:PositionChats() + Bags:Layout() + end, + }, + panelHeight = { + order = 3, + type = 'range', + name = L["Panel Height"], + desc = L["PANEL_DESC"], + min = 60, max = 600, step = 1, + set = function(info, value) + E.db.chat.panelHeight = value + CH:PositionChats() + end, + }, + panelWidth = { + order = 4, + type = 'range', + name = L["Panel Width"], + desc = L["PANEL_DESC"], + set = function(info, value) + E.db.chat.panelWidth = value + CH:PositionChats() + + if not E.db.chat.separateSizes then + Bags:Layout() + end + + Bags:Layout(true) + end, + min = 50, max = 1000, step = 1, + }, + panelBackdrop = { + order = 5, + type = 'select', + name = L["Panel Backdrop"], + desc = L["Toggle showing of the left and right chat panels."], + values = { + HIDEBOTH = L["Hide Both"], + SHOWBOTH = L["Show Both"], + LEFT = L["Left Only"], + RIGHT = L["Right Only"], + }, + set = function(info, value) + E.db.chat.panelBackdrop = value + Layout:ToggleChatPanels() + CH:PositionChats() + CH:UpdateEditboxAnchors() + end, + }, + panelSnapping = { + order = 6, + type = 'toggle', + name = L["Panel Snapping"], + desc = L["When disabled the Chat Background color has to be set via Blizzards Chat Tabs Background setting."], + hidden = function() return not E.Chat.Initialized end, + set = function(info, value) + E.db.chat.panelSnapping = value + CH:PositionChats() + end + }, + panelHeightRight = { + order = 6, + type = 'range', + name = L["Right Panel Height"], + desc = L["Adjust the height of your right chat panel."], + min = 60, max = 600, step = 1, + disabled = function() return not E.db.chat.separateSizes end, + hidden = function() return not E.db.chat.separateSizes end, + set = function(info, value) + E.db.chat.panelHeightRight = value + CH:PositionChats() + end, + }, + panelWidthRight = { + order = 7, + type = 'range', + name = L["Right Panel Width"], + desc = L["Adjust the width of your right chat panel."], + disabled = function() return not E.db.chat.separateSizes end, + hidden = function() return not E.db.chat.separateSizes end, + set = function(info, value) + E.db.chat.panelWidthRight = value + CH:PositionChats() + Bags:Layout() + end, + min = 50, max = 1000, step = 1, + }, + panelBackdropNameLeft = { + order = 8, + type = 'input', + width = 'full', + name = L["Panel Texture (Left)"], + desc = L["Specify a filename located inside the World of Warcraft directory. Textures folder that you wish to have set as a panel background.\n\nPlease Note:\n-The image size recommended is 256x128\n-You must do a complete game restart after adding a file to the folder.\n-The file type must be tga format.\n\nExample: Interface\\AddOns\\ElvUI\\Media\\Textures\\Copy\n\nOr for most users it would be easier to simply put a tga file into your WoW folder, then type the name of the file here."], + set = function(info, value) + E.db.chat[info[#info]] = value + E:UpdateMedia() + end, + }, + panelBackdropNameRight = { + order = 9, + type = 'input', + width = 'full', + name = L["Panel Texture (Right)"], + desc = L["Specify a filename located inside the World of Warcraft directory. Textures folder that you wish to have set as a panel background.\n\nPlease Note:\n-The image size recommended is 256x128\n-You must do a complete game restart after adding a file to the folder.\n-The file type must be tga format.\n\nExample: Interface\\AddOns\\ElvUI\\Media\\Textures\\Copy\n\nOr for most users it would be easier to simply put a tga file into your WoW folder, then type the name of the file here."], + set = function(info, value) + E.db.chat[info[#info]] = value + E:UpdateMedia() + end, + }, + } + }, + }, + }, + }, +} diff --git a/Cooldown.lua b/Cooldown.lua new file mode 100644 index 0000000..21e76ea --- /dev/null +++ b/Cooldown.lua @@ -0,0 +1,90 @@ +local E, _, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB +local C, L = unpack(select(2, ...)) +local ACH = E.Libs.ACH + +-- GLOBALS: AceGUIWidgetLSMlists + +local function profile(db) + return (db == 'global' and E.db.cooldown) or E.db[db].cooldown +end + +local function private(db) + return (db == 'global' and P.cooldown) or P[db].cooldown +end + +local function group(order, db, label) + local main = ACH:Group(label, nil, order, nil, function(info) local t = (profile(db))[info[#info]] local d = (private(db))[info[#info]] return t.r, t.g, t.b, t.a, d.r, d.g, d.b; end, function(info, r, g, b) local t = (profile(db))[info[#info]] t.r, t.g, t.b = r, g, b; E:UpdateCooldownSettings(db); end) + E.Options.args.cooldown.args[db] = main + + local mainArgs = main.args + mainArgs.reverse = ACH:Toggle(L["Reverse Toggle"], L["Reverse Toggle will enable Cooldown Text on this module when the global setting is disabled and disable them when the global setting is enabled."], 1, nil, nil, nil, function(info) return (profile(db))[info[#info]] end, function(info, value) (profile(db))[info[#info]] = value; E:UpdateCooldownSettings(db); end) + mainArgs.hideBlizzard = ACH:Toggle(L["Force Hide Blizzard Text"], L["This option will force hide Blizzard's cooldown text if it is enabled at [Interface > ActionBars > Show Numbers on Cooldown]."], 2, nil, nil, nil, function(info) return (profile(db))[info[#info]] end, function(info, value) (profile(db))[info[#info]] = value; E:UpdateCooldownSettings(db); end, nil, function() if db == 'global' then return E.db.cooldown.enable else return (E.db.cooldown.enable and not profile(db).reverse) or (not E.db.cooldown.enable and profile(db).reverse) end end) + + local seconds = ACH:Group(L["Text Threshold"], nil, 3, nil, function(info) return (profile(db))[info[#info]] end, function(info, value) (profile(db))[info[#info]] = value; E:UpdateCooldownSettings(db); end, function() return not (profile(db)).checkSeconds end) + seconds.inline = true + seconds.args.checkSeconds = ACH:Toggle(L["Enable"], L["This will override the global cooldown settings."], 1, nil, nil, nil, nil, nil, false) + seconds.args.mmssThreshold = ACH:Range(L["MM:SS Threshold"], L["Threshold (in seconds) before text is shown in the MM:SS format. Set to -1 to never change to this format."], 2, { min = -1, max = 10800, step = 1 }) + seconds.args.hhmmThreshold = ACH:Range(L["HH:MM Threshold"], L["Threshold (in minutes) before text is shown in the HH:MM format. Set to -1 to never change to this format."], 3, { min = -1, max = 1440, step = 1 }) + mainArgs.secondsGroup = seconds + + local fonts = ACH:Group(L["Fonts"], nil, 4, nil, function(info) return (profile(db)).fonts[info[#info]] end, function(info, value) (profile(db)).fonts[info[#info]] = value; E:UpdateCooldownSettings(db); end, function() return not (profile(db)).fonts.enable end) + fonts.inline = true + fonts.args.enable = ACH:Toggle(L["Enable"], L["This will override the global cooldown settings."], 1, nil, nil, nil, nil, nil, false) + fonts.args.font = ACH:SharedMediaFont(L["Font"], nil, 2) + fonts.args.fontSize = ACH:Range(L["Font Size"], nil, 3, { min = 10, max = 50, step = 1 }) + fonts.args.fontOutline = ACH:Select(L["Font Outline"], nil, 4, C.Values.FontFlags) + mainArgs.fontGroup = fonts + + local colors = ACH:Group(L["Color Override"], nil, 5, nil, nil, nil, function() return not (profile(db)).override end) + colors.inline = true + colors.args.override = ACH:Toggle(L["Enable"], L["This will override the global cooldown settings."], 1, nil, nil, nil, function(info) return (profile(db))[info[#info]] end, function(info, value) (profile(db))[info[#info]] = value; E:UpdateCooldownSettings(db); end, false) + colors.args.threshold = ACH:Range(L["Low Threshold"], L["Threshold before text turns red and is in decimal form. Set to -1 for it to never turn red"], 2, { min = -1, max = 20, step = 1 }, nil, function(info) return (profile(db))[info[#info]] end, function(info, value) (profile(db))[info[#info]] = value; E:UpdateCooldownSettings(db); end) + mainArgs.colorGroup = colors + + local tColors = ACH:Group(L["Threshold Colors"], nil, 3) + tColors.args.expiringColor = ACH:Color(L["Expiring"], L["Color when the text is about to expire"], 1) + tColors.args.secondsColor = ACH:Color(L["Seconds"], L["Color when the text is in the seconds format."], 2) + tColors.args.minutesColor = ACH:Color(L["Minutes"], L["Color when the text is in the minutes format."], 3) + tColors.args.hoursColor = ACH:Color(L["Hours"], L["Color when the text is in the hours format."], 4) + tColors.args.daysColor = ACH:Color(L["Days"], L["Color when the text is in the days format."], 5) + tColors.args.mmssColor = ACH:Color(L["MM:SS"], nil, 6) + tColors.args.hhmmColor = ACH:Color(L["HH:MM"], nil, 7) + mainArgs.colorGroup.args.timeColors = tColors + + local iColors = ACH:Group(L["Time Indicator Colors"], nil, 4, nil, nil, nil, function() return not (profile(db)).useIndicatorColor end) + iColors.args.useIndicatorColor = ACH:Toggle(L["Use Indicator Color"], nil, 0, nil, nil, nil, function(info) return (profile(db))[info[#info]] end, function(info, value) (profile(db))[info[#info]] = value; E:UpdateCooldownSettings(db); end, false) + iColors.args.expireIndicator = ACH:Color(L["Expiring"], L["Color when the text is about to expire"], 1) + iColors.args.secondsIndicator = ACH:Color(L["Seconds"], L["Color when the text is in the seconds format."], 2) + iColors.args.minutesIndicator = ACH:Color(L["Minutes"], L["Color when the text is in the minutes format."], 3) + iColors.args.hoursIndicator = ACH:Color(L["Hours"], L["Color when the text is in the hours format."], 4) + iColors.args.daysIndicator = ACH:Color(L["Days"], L["Color when the text is in the days format."], 5) + iColors.args.hhmmColorIndicator = ACH:Color(L["MM:SS"], nil, 6) + iColors.args.mmssColorIndicator = ACH:Color(L["HH:MM"], nil, 7) + mainArgs.colorGroup.args.indicatorColors = iColors + + if db == 'global' then + mainArgs.reverse = nil + mainArgs.colorGroup.args.override = nil + mainArgs.colorGroup.disabled = nil + mainArgs.colorGroup.name = L["COLORS"] + + -- keep these two in this order + E.Options.args.cooldown.args.hideBlizzard = mainArgs.hideBlizzard + mainArgs.hideBlizzard = nil + elseif db == 'auras' then + mainArgs.reverse = nil + mainArgs.hideBlizzard = nil + mainArgs.fontGroup = nil + end +end + +E.Options.args.cooldown = ACH:Group(L["Cooldown Text"], nil, 2, 'tab', function(info) return E.db.cooldown[info[#info]] end, function(info, value) E.db.cooldown[info[#info]] = value; E:UpdateCooldownSettings('global'); end) +E.Options.args.cooldown.args.intro = ACH:Description(L["COOLDOWN_DESC"], 0) +E.Options.args.cooldown.args.enable = ACH:Toggle(L["Enable"], L["Display cooldown text on anything with the cooldown spiral."], 1) + +group(5, 'global', L["Global"]) +group(6, 'auras', L["BUFFOPTIONS_LABEL"]) +group(7, 'actionbar', L["ActionBars"]) +group(8, 'bags', L["Bags"]) +group(9, 'nameplates', L["NamePlates"]) +group(10, 'unitframe', L["UnitFrames"]) diff --git a/Core.lua b/Core.lua new file mode 100644 index 0000000..46db275 --- /dev/null +++ b/Core.lua @@ -0,0 +1,442 @@ +local E = unpack(ElvUI) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB +local D = E:GetModule('Distributor') + +local Engine = select(2, ...) +Engine[1] = {} +Engine[2] = E.Libs.ACL:GetLocale('ElvUI', E.global.general.locale) +local C, L = Engine[1], Engine[2] + +local _G, format, sort, tinsert, strmatch = _G, format, sort, tinsert, strmatch + +C.Values = { + FontFlags = { + NONE = L["NONE"], + OUTLINE = 'Outline', + THICKOUTLINE = 'Thick', + MONOCHROME = '|cffaaaaaaMono|r', + MONOCHROMEOUTLINE = '|cffaaaaaaMono|r Outline', + MONOCHROMETHICKOUTLINE = '|cffaaaaaaMono|r Thick', + }, + FontSize = { min = 8, max = 64, step = 1 }, + Strata = { BACKGROUND = 'BACKGROUND', LOW = 'LOW', MEDIUM = 'MEDIUM', HIGH = 'HIGH', DIALOG = 'DIALOG', TOOLTIP = 'TOOLTIP' }, + GrowthDirection = { + DOWN_RIGHT = format(L["%s and then %s"], L["Down"], L["Right"]), + DOWN_LEFT = format(L["%s and then %s"], L["Down"], L["Left"]), + UP_RIGHT = format(L["%s and then %s"], L["Up"], L["Right"]), + UP_LEFT = format(L["%s and then %s"], L["Up"], L["Left"]), + RIGHT_DOWN = format(L["%s and then %s"], L["Right"], L["Down"]), + RIGHT_UP = format(L["%s and then %s"], L["Right"], L["Up"]), + LEFT_DOWN = format(L["%s and then %s"], L["Left"], L["Down"]), + LEFT_UP = format(L["%s and then %s"], L["Left"], L["Up"]), + } +} + +C.StateSwitchGetText = function(_, TEXT) + local friend, enemy = strmatch(TEXT, '^Friendly:([^,]*)'), strmatch(TEXT, '^Enemy:([^,]*)') + local text, blockB, blockS, blockT = friend or enemy or TEXT + local SF, localized = E.global.unitframe.specialFilters[text], L[text] + if SF and localized and text:match('^block') then blockB, blockS, blockT = localized:match('^%[(.-)](%s?)(.+)') end + local filterText = (blockB and format('|cFF999999%s|r%s%s', blockB, blockS, blockT)) or localized or text + return (friend and format('|cFF33FF33%s|r %s', _G.FRIEND, filterText)) or (enemy and format('|cFFFF3333%s|r %s', _G.ENEMY, filterText)) or filterText +end + +E:AddLib('AceGUI', 'AceGUI-3.0') +E:AddLib('AceConfig', 'AceConfig-3.0-ElvUI') +E:AddLib('AceConfigDialog', 'AceConfigDialog-3.0-ElvUI') +E:AddLib('AceConfigRegistry', 'AceConfigRegistry-3.0-ElvUI') +E:AddLib('AceDBOptions', 'AceDBOptions-3.0') +E:AddLib('ACH', 'LibAceConfigHelper') + +local UnitName = UnitName +local UnitExists = UnitExists +local UnitIsUnit = UnitIsUnit +local UnitIsFriend = UnitIsFriend +local UnitIsPlayer = UnitIsPlayer +local GameTooltip_Hide = GameTooltip_Hide +local GameFontHighlightSmall = _G.GameFontHighlightSmall +local ACH = E.Libs.ACH + +--Function we can call on profile change to update GUI +function E:RefreshGUI() + E:RefreshCustomTextsConfigs() + E.Libs.AceConfigRegistry:NotifyChange('ElvUI') +end + +E.Libs.AceConfig:RegisterOptionsTable('ElvUI', E.Options) +E.Libs.AceConfigDialog:SetDefaultSize('ElvUI', E:Config_GetDefaultSize()) +E.Options.name = format('%s: |cff99ff33%s|r', L["Version"], E.version) + +local DONATORS = { + 'Dandruff', + 'Tobur/Tarilya', + 'Netu', + 'Alluren', + 'Thorgnir', + 'Emalal', + 'Bendmeova', + 'Curl', + 'Zarac', + 'Emmo', + 'Oz', + 'Hawké', + 'Aynya', + 'Tahira', + 'Karsten Lumbye Thomsen', + 'Thomas B. aka Pitschiqüü', + 'Sea Garnet', + 'Paul Storry', + 'Azagar', + 'Archury', + 'Donhorn', + 'Woodson Harmon', + 'Phoenyx', + 'Feat', + 'Konungr', + 'Leyrin', + 'Dragonsys', + 'Tkalec', + 'Paavi', + 'Giorgio', + 'Bearscantank', + 'Eidolic', + 'Cosmo', + 'Adorno', + 'Domoaligato', + 'Smorg', + 'Pyrokee', + 'Portable', + 'Ithilyn' +} + +local DEVELOPERS = { + 'Tukz', + 'Haste', + 'Nightcracker', + 'Omega1970', + 'Hydrazine', + 'Blazeflack', + '|cff0070DEAzilroka|r', + '|cff9482c9Darth Predator|r', + '|T134297:15:15:0:0:64:64:5:59:5:59|t |cffff7d0aMerathilis|r', + '|TInterface/AddOns/ElvUI/Media/ChatLogos/FoxWarlock:15:15:0:0:64:64:5:59:5:59|t |cffff2020NihilisticPandemonium|r', + E:TextGradient('Simpy but my name needs to be longer.', 0.63,0.40,0.80, 0.63,0.40,0.80, 0.53,0.87,0.19, 0.53,0.87,0.19, 0.20,0.74,0.74, 0.20,0.74,0.74, 0.53,0.87,0.19, 0.53,0.87,0.19, 0.63,0.40,0.80, 0.63,0.40,0.80) +} + +local TESTERS = { + 'Tukui Community', + 'Affinity', + 'Modarch', + 'Tirain', + 'Phima', + 'Veiled', + 'Repooc', + 'Alex', + 'Nidra', + 'Kurhyus', + 'Shrom', + 'BuG', + 'Kringel', + 'Botanica', + 'Yachanay', + 'Catok', + '|cff00c0faBenik|r', + '|T136012:15:15:0:0:64:64:5:59:5:59|t |cff006fdcRubgrsch|r |T656558:15:15:0:0:64:64:5:59:5:59|t', + '|TInterface/AddOns/ElvUI/Media/ChatLogos/Clover:15:15:0:0:64:64:5:59:5:59|t Luckyone', + 'AcidWeb |TInterface/AddOns/ElvUI/Media/ChatLogos/Gem:15:15:-1:2:64:64:6:60:8:60|t', + '|T135167:15:15:0:0:64:64:5:59:5:59|t Loon - For being right', + '|T134297:15:15:0:0:64:64:5:59:5:59|t |cffFF7D0ABladesdruid|r - AKA SUPERBEAR', +} + +local function SortList(a, b) + return E:StripString(a) < E:StripString(b) +end + +sort(DONATORS, SortList) +sort(DEVELOPERS, SortList) +sort(TESTERS, SortList) + +for _, name in pairs(DONATORS) do + tinsert(E.CreditsList, name) +end +local DONATOR_STRING = table.concat(DONATORS, '|n') +for _, name in pairs(DEVELOPERS) do + tinsert(E.CreditsList, name) +end +local DEVELOPER_STRING = table.concat(DEVELOPERS, '|n') +for _, name in pairs(TESTERS) do + tinsert(E.CreditsList, name) +end +local TESTER_STRING = table.concat(TESTERS, '|n') + +E.Options.args.info = ACH:Group(L["Information"], nil, 4) +E.Options.args.info.args.header = ACH:Description(L["ELVUI_DESC"], 1, 'medium') +E.Options.args.info.args.spacer = ACH:Spacer(2) + +E.Options.args.info.args.support = ACH:Group(L["Support & Download"], nil, 3) +E.Options.args.info.args.support.inline = true +E.Options.args.info.args.support.args.homepage = ACH:Execute(L["Support Forum"], nil, 1, function() E:StaticPopup_Show('ELVUI_EDITBOX', nil, nil, 'https://www.tukui.org/forum/viewforum.php?f=4') end) +E.Options.args.info.args.support.args.homepage.customWidth = 140 +E.Options.args.info.args.support.args.git = ACH:Execute(L["Ticket Tracker"], nil, 2, function() E:StaticPopup_Show('ELVUI_EDITBOX', nil, nil, 'https://git.tukui.org/elvui/elvui/issues') end) +E.Options.args.info.args.support.args.git.customWidth = 140 +E.Options.args.info.args.support.args.discord = ACH:Execute(L["Discord"], nil, 3, function() E:StaticPopup_Show('ELVUI_EDITBOX', nil, nil, 'https://discordapp.com/invite/xFWcfgE') end) +E.Options.args.info.args.support.args.discord.customWidth = 140 +E.Options.args.info.args.support.args.changelog = ACH:Execute(L["Changelog"], nil, 4, function() E:StaticPopup_Show('ELVUI_EDITBOX', nil, nil, 'https://www.tukui.org/download.php?ui=elvui#changelog') end) +E.Options.args.info.args.support.args.changelog.customWidth = 140 +E.Options.args.info.args.support.args.development = ACH:Execute(L["Development Version"], L["Link to the latest development version."], 5, function() E:StaticPopup_Show('ELVUI_EDITBOX', nil, nil, 'https://git.tukui.org/elvui/elvui/-/archive/development/elvui-development.zip') end) +E.Options.args.info.args.support.args.development.customWidth = 140 + +E.Options.args.info.args.credits = ACH:Group(L["Credits"], nil, 4) +E.Options.args.info.args.credits.inline = true +E.Options.args.info.args.credits.args.string = ACH:Description(L["ELVUI_CREDITS"], 1, 'medium') + +E.Options.args.info.args.coding = ACH:Group(L["Coding:"], nil, 5) +E.Options.args.info.args.coding.inline = true +E.Options.args.info.args.coding.args.string = ACH:Description(DEVELOPER_STRING, 1, 'medium') + +E.Options.args.info.args.testers = ACH:Group(L["Testing:"], nil, 6) +E.Options.args.info.args.testers.inline = true +E.Options.args.info.args.testers.args.string = ACH:Description(TESTER_STRING, 1, 'medium') + +E.Options.args.info.args.donators = ACH:Group(L["Donations:"], nil, 7) +E.Options.args.info.args.donators.inline = true +E.Options.args.info.args.donators.args.string = ACH:Description(DONATOR_STRING, 1, 'medium') + +local profileTypeItems = { profile = L["Profile"], private = L["Private (Character Settings)"], global = L["Global (Account Settings)"], filters = L["Aura Filters"], styleFilters = L["NamePlate Style Filters"] } +local profileTypeListOrder = { 'profile', 'private', 'global', 'filters', 'styleFilters' } +local exportTypeItems = { text = L["Text"], luaTable = L["Table"], luaPlugin = L["Plugin"] } +local exportTypeListOrder = { 'text', 'luaTable', 'luaPlugin' } + +local exportString = '' +local function ExportImport_Open(mode) + local Frame = E.Libs.AceGUI:Create('Frame') + Frame:SetTitle('') + Frame:EnableResize(false) + Frame:SetWidth(800) + Frame:SetHeight(600) + Frame.frame:SetFrameStrata('FULLSCREEN_DIALOG') + Frame:SetLayout('flow') + + local Box = E.Libs.AceGUI:Create('MultiLineEditBox-ElvUI') + Box:SetNumLines(30) + Box:DisableButton(true) + Box:SetWidth(800) + Box:SetLabel('') + Frame:AddChild(Box) + --Save original script so we can restore it later + Box.editBox.OnTextChangedOrig = Box.editBox:GetScript('OnTextChanged') + Box.editBox.OnCursorChangedOrig = Box.editBox:GetScript('OnCursorChanged') + --Remove OnCursorChanged script as it causes weird behaviour with long text + Box.editBox:SetScript('OnCursorChanged', nil) + Box.scrollFrame:UpdateScrollChildRect() + + local Label1 = E.Libs.AceGUI:Create('Label') + local font = GameFontHighlightSmall:GetFont() + Label1:SetFont(font, 14) + Label1:SetText('.') --Set temporary text so height is set correctly + Label1:SetWidth(800) + Frame:AddChild(Label1) + + local Label2 = E.Libs.AceGUI:Create('Label') + font = GameFontHighlightSmall:GetFont() + Label2:SetFont(font, 14) + Label2:SetText('.|n.') + Label2:SetWidth(800) + Frame:AddChild(Label2) + + if mode == 'export' then + Frame:SetTitle(L["Export Profile"]) + + local ProfileTypeDropdown = E.Libs.AceGUI:Create('Dropdown') + ProfileTypeDropdown:SetMultiselect(false) + ProfileTypeDropdown:SetLabel(L["Choose What To Export"]) + ProfileTypeDropdown:SetList(profileTypeItems, profileTypeListOrder) + ProfileTypeDropdown:SetValue('profile') --Default export + Frame:AddChild(ProfileTypeDropdown) + + local ExportFormatDropdown = E.Libs.AceGUI:Create('Dropdown') + ExportFormatDropdown:SetMultiselect(false) + ExportFormatDropdown:SetLabel(L["Choose Export Format"]) + ExportFormatDropdown:SetList(exportTypeItems, exportTypeListOrder) + ExportFormatDropdown:SetValue('text') --Default format + ExportFormatDropdown:SetWidth(150) + Frame:AddChild(ExportFormatDropdown) + + local exportButton = E.Libs.AceGUI:Create('Button-ElvUI') + exportButton:SetText(L["Export Now"]) + exportButton:SetAutoWidth(true) + exportButton:SetCallback('OnClick', function() + Label1:SetText('') + Label2:SetText('') + + local profileType, exportFormat = ProfileTypeDropdown:GetValue(), ExportFormatDropdown:GetValue() + local profileKey, profileExport = D:ExportProfile(profileType, exportFormat) + if not profileKey or not profileExport then + Label1:SetText(L["Error exporting profile!"]) + else + Label1:SetText(format('%s: %s%s|r', L["Exported"], E.media.hexvaluecolor, profileTypeItems[profileType])) + + if profileType == 'profile' then + Label2:SetText(format('%s: %s%s|r', L["Profile Name"], E.media.hexvaluecolor, profileKey)) + end + end + + Box:SetText(profileExport) + Box.editBox:HighlightText() + Box:SetFocus() + + exportString = profileExport + end) + Frame:AddChild(exportButton) + + --Set scripts + Box.editBox:SetScript('OnChar', function() + Box:SetText(exportString) + Box.editBox:HighlightText() + end) + Box.editBox:SetScript('OnTextChanged', function(_, userInput) + if userInput then + --Prevent user from changing export string + Box:SetText(exportString) + Box.editBox:HighlightText() + else + --Scroll frame doesn't scroll to the bottom by itself, so let's do that now + Box.scrollFrame:SetVerticalScroll(Box.scrollFrame:GetVerticalScrollRange()) + end + end) + elseif mode == 'import' then + Frame:SetTitle(L["Import Profile"]) + local importButton = E.Libs.AceGUI:Create('Button-ElvUI') --This version changes text color on SetDisabled + importButton:SetDisabled(true) + importButton:SetText(L["Import Now"]) + importButton:SetAutoWidth(true) + importButton:SetCallback('OnClick', function() + Label1:SetText('') + Label2:SetText('') + + local success = D:ImportProfile(Box:GetText()) + Label1:SetText((success and L["Profile imported successfully!"]) or L["Error decoding data. Import string may be corrupted!"]) + end) + Frame:AddChild(importButton) + + local decodeButton = E.Libs.AceGUI:Create('Button-ElvUI') + decodeButton:SetDisabled(true) + decodeButton:SetText(L["Decode Text"]) + decodeButton:SetAutoWidth(true) + decodeButton:SetCallback('OnClick', function() + Label1:SetText('') + Label2:SetText('') + + local profileType, profileKey, profileData = D:Decode(Box:GetText()) + local decodedText = (profileData and E:TableToLuaString(profileData)) or nil + local importText = D:CreateProfileExport(decodedText, profileType, profileKey) + Box:SetText(importText) + end) + Frame:AddChild(decodeButton) + + local oldText = '' + local function OnTextChanged() + local text = Box:GetText() + if text == '' then + Label1:SetText('') + Label2:SetText('') + importButton:SetDisabled(true) + decodeButton:SetDisabled(true) + elseif oldText ~= text then + local stringType = D:GetImportStringType(text) + if stringType == 'Base64' then + decodeButton:SetDisabled(false) + else + decodeButton:SetDisabled(true) + end + + local profileType, profileKey = D:Decode(text) + if not profileType or (profileType and profileType == 'profile' and not profileKey) then + Label1:SetText(L["Error decoding data. Import string may be corrupted!"]) + Label2:SetText('') + importButton:SetDisabled(true) + decodeButton:SetDisabled(true) + else + Label1:SetText(format('%s: %s%s|r', L["Importing"], E.media.hexvaluecolor, profileTypeItems[profileType] or '')) + if profileType == 'profile' then + Label2:SetText(format('%s: %s%s|r', L["Profile Name"], E.media.hexvaluecolor, profileKey)) + end + + --Scroll frame doesn't scroll to the bottom by itself, so let's do that now + Box.scrollFrame:UpdateScrollChildRect() + Box.scrollFrame:SetVerticalScroll(Box.scrollFrame:GetVerticalScrollRange()) + + importButton:SetDisabled(false) + end + + oldText = text + end + end + + Box.editBox:SetFocus() + Box.editBox:SetScript('OnChar', nil) + Box.editBox:SetScript('OnTextChanged', OnTextChanged) + end + + Frame:SetCallback('OnClose', function(widget) + --Restore changed scripts + Box.editBox:SetScript('OnChar', nil) + Box.editBox:SetScript('OnTextChanged', Box.editBox.OnTextChangedOrig) + Box.editBox:SetScript('OnCursorChanged', Box.editBox.OnCursorChangedOrig) + Box.editBox.OnTextChangedOrig = nil + Box.editBox.OnCursorChangedOrig = nil + + --Clear stored export string + exportString = '' + + E.Libs.AceGUI:Release(widget) + E:Config_OpenWindow() + end) + + --Clear default text + Label1:SetText('') + Label2:SetText('') + + --Close ElvUI OptionsUI + E.Libs.AceConfigDialog:Close('ElvUI') + + GameTooltip_Hide() --The tooltip from the Export/Import button stays on screen, so hide it +end + +--Create Profiles Table +E.Options.args.profiles = ACH:Group(L["Profiles"], nil, 5, 'tab') +E.Options.args.profiles.args.desc = ACH:Description(L["This feature will allow you to transfer settings to other characters."], 0) +E.Options.args.profiles.args.distributeProfile = ACH:Execute(L["Share Current Profile"], L["Sends your current profile to your target."], 1, function() if not UnitExists('target') or not UnitIsPlayer('target') or not UnitIsFriend('player', 'target') or UnitIsUnit('player', 'target') then E:Print(L["You must be targeting a player."]) return end local name, server = UnitName('target') if name and (not server or server == '') then D:Distribute(name) elseif server then D:Distribute(name, true) end end, nil, nil, nil, nil, nil, function() return not E.global.general.allowDistributor end) +E.Options.args.profiles.args.distributeGlobal = ACH:Execute(L["Share Filters"], L["Sends your filter settings to your target."], 1, function() if not UnitExists('target') or not UnitIsPlayer('target') or not UnitIsFriend('player', 'target') or UnitIsUnit('player', 'target') then E:Print(L["You must be targeting a player."]) return end local name, server = UnitName('target') if name and (not server or server == '') then D:Distribute(name, false, true) elseif server then D:Distribute(name, true, true) end end, nil, nil, nil, nil, nil, function() return not E.global.general.allowDistributor end) +E.Options.args.profiles.args.exportProfile = ACH:Execute(L["Export Profile"], nil, 4, function() ExportImport_Open('export') end) +E.Options.args.profiles.args.importProfile = ACH:Execute(L["Import Profile"], nil, 5, function() ExportImport_Open('import') end) +E.Options.args.profiles.args.allowDistributor = ACH:Toggle(L["Allow Sharing"], L["Both users will need this option enabled."], 6, nil, nil, nil, function() return E.global.general.allowDistributor end, function(_, value) E.global.general.allowDistributor = value; D:UpdateSettings() end) +E.Options.args.profiles.args.spacer = ACH:Spacer(6) + +E.Options.args.profiles.args.profile = E.Libs.AceDBOptions:GetOptionsTable(E.data) +E.Options.args.profiles.args.private = E.Libs.AceDBOptions:GetOptionsTable(E.charSettings) + +E.Options.args.profiles.args.profile.name = L["Profile"] +E.Options.args.profiles.args.profile.order = 1 +E.Options.args.profiles.args.private.name = L["Private"] +E.Options.args.profiles.args.private.order = 2 + +E.Libs.AceConfig:RegisterOptionsTable('ElvProfiles', E.Options.args.profiles.args.profile) +E.Libs.DualSpec:EnhanceOptions(E.Options.args.profiles.args.profile, E.data) + +E.Libs.AceConfig:RegisterOptionsTable('ElvPrivates', E.Options.args.profiles.args.private) + +E.Options.args.profiles.args.private.args.choose.confirm = function(info, value) + if info[#info-1] == 'private' then + return format(L["Choosing Settings %s. This will reload the UI.\n\n Are you sure?"], value) + else + return false + end +end + +E.Options.args.profiles.args.private.args.copyfrom.confirm = function(info, value) + return format(L["Copy Settings from %s. This will overwrite %s profile.\n\n Are you sure?"], value, info.handler:GetCurrentProfile()) +end + +if GetAddOnEnableState(nil, 'ElvUI_Config') ~= 0 then + E:StaticPopup_Show('ELVUI_CONFIG_FOUND') +end diff --git a/DataBars.lua b/DataBars.lua new file mode 100644 index 0000000..372e1cf --- /dev/null +++ b/DataBars.lua @@ -0,0 +1,112 @@ +local E, _, V, P, G = unpack(ElvUI) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB +local C, L = unpack(select(2, ...)) +local DB = E:GetModule('DataBars') +local ACH = E.Libs.ACH + +local tonumber = tonumber + +local SharedOptions = { + enable = ACH:Toggle(L["Enable"], nil, 1), + textFormat = ACH:Select(L["Text Format"], nil, 2, { NONE = L["NONE"], CUR = L["Current"], REM = L["Remaining"], PERCENT = L["Percent"], CURMAX = L["Current - Max"], CURPERC = L["Current - Percent"], CURREM = L["Current - Remaining"], CURPERCREM = L["Current - Percent (Remaining)"] }), + mouseover = ACH:Toggle(L["Mouseover"], nil, 3), + clickThrough = ACH:Toggle(L["Click Through"], nil, 4), + showBubbles = ACH:Toggle(L["Show Bubbles"], nil, 5), + sizeGroup = ACH:Group(L["Size"], nil, -3), + conditionGroup = ACH:MultiSelect(L["Conditions"], nil, -2), + fontGroup = ACH:Group(L["Fonts"], nil, -1), +} + +SharedOptions.sizeGroup.inline = true +SharedOptions.sizeGroup.args.width = ACH:Range(L["Width"], nil, 1, { min = 5, max = ceil(GetScreenWidth() or 800), step = 1 }) +SharedOptions.sizeGroup.args.height = ACH:Range(L["Height"], nil, 2, { min = 5, max = ceil(GetScreenWidth() or 800), step = 1 }) +SharedOptions.sizeGroup.args.orientation = ACH:Select(L["Statusbar Fill Orientation"], L["Direction the bar moves on gains/losses"], 3, { AUTOMATIC = L["Automatic"], HORIZONTAL = L["Horizontal"], VERTICAL = L["Vertical"] }) +SharedOptions.sizeGroup.args.reverseFill = ACH:Toggle(L["Reverse Fill Direction"], nil, 4) + +SharedOptions.fontGroup.inline = true +SharedOptions.fontGroup.args.font = ACH:SharedMediaFont(L["Font"], nil, 1) +SharedOptions.fontGroup.args.fontSize = ACH:Range(L["Font Size"], nil, 2, C.Values.FontSize) +SharedOptions.fontGroup.args.fontOutline = ACH:Select(L["Font Outline"], nil, 3, C.Values.FontFlags) + +E.Options.args.databars = ACH:Group(L["DataBars"], nil, 2, 'tab', function(info) return E.db.databars[info[#info]] end, function(info, value) E.db.databars[info[#info]] = value DB:UpdateAll() end) +E.Options.args.databars.args.intro = ACH:Description(L["Setup on-screen display of information bars."], 1) +E.Options.args.databars.args.spacer = ACH:Spacer(2) + +E.Options.args.databars.args.general = ACH:Group(L["General"], nil, 3, nil, function(info) return E.db.databars[info[#info]] end, function(info, value) E.db.databars[info[#info]] = value DB:UpdateAll() end) +E.Options.args.databars.args.general.inline = true +E.Options.args.databars.args.general.args.transparent = ACH:Toggle(L["Transparent"], nil, 1) +E.Options.args.databars.args.general.args.customTexture = ACH:Toggle(L["Custom StatusBar"], nil, 2) +E.Options.args.databars.args.general.args.statusbar = ACH:SharedMediaStatusbar(L["StatusBar Texture"], nil, 3, nil, nil, nil, function() return not E.db.databars.customTexture end) + +E.Options.args.databars.args.colorGroup = ACH:Group(L["COLORS"], nil, 4, nil, function(info) local t = E.db.databars.colors[info[#info]] local d = P.databars.colors[info[#info]] return t.r, t.g, t.b, t.a, d.r, d.g, d.b, d.a end) +E.Options.args.databars.args.colorGroup.inline = true +E.Options.args.databars.args.colorGroup.args.experience = ACH:Color(L["Experience"], nil, 1, true, nil, nil, function(info, r, g, b, a) local t = E.db.databars.colors[info[#info]] t.r, t.g, t.b, t.a = r, g, b, a DB:ExperienceBar_Update() end) +E.Options.args.databars.args.colorGroup.args.rested = ACH:Color(L["Rested Experience"], nil, 2, true, nil, nil, function(info, r, g, b, a) local t = E.db.databars.colors[info[#info]] t.r, t.g, t.b, t.a = r, g, b, a DB:ExperienceBar_Update() end) +E.Options.args.databars.args.colorGroup.args.quest = ACH:Color(L["Quest Experience"], nil, 3, true, nil, nil, function(info, r, g, b, a) local t = E.db.databars.colors[info[#info]] t.r, t.g, t.b, t.a = r, g, b, a DB:ExperienceBar_QuestXP() end) +E.Options.args.databars.args.colorGroup.args.honor = ACH:Color(L["Honor"], nil, 4, true, nil, nil, function(info, r, g, b, a) local t = E.db.databars.colors[info[#info]] t.r, t.g, t.b, t.a = r, g, b, a DB:HonorBar_Update() end) +E.Options.args.databars.args.colorGroup.args.azerite = ACH:Color(L["Azerite"], nil, 5, true, nil, nil, function(info, r, g, b, a) local t = E.db.databars.colors[info[#info]] t.r, t.g, t.b, t.a = r, g, b, a DB:AzeriteBar_Update() end) +E.Options.args.databars.args.colorGroup.args.useCustomFactionColors = ACH:Toggle(L["Custom Faction Colors"], L["Reputation"], 6, nil, nil, nil, function() return E.db.databars.colors.useCustomFactionColors end, function(_, value) E.db.databars.colors.useCustomFactionColors = value end) + +E.Options.args.databars.args.colorGroup.args.factionColors = ACH:Group(' ', nil, nil, nil, function(info) local v = tonumber(info[#info]) local t = E.db.databars.colors.factionColors[v] local d = P.databars.colors.factionColors[v] return t.r, t.g, t.b, t.a, d.r, d.g, d.b end, function(info, r, g, b) local v = tonumber(info[#info]); local t = E.db.databars.colors.factionColors[v]; t.r, t.g, t.b = r, g, b end, nil, function() return not E.db.databars.colors.useCustomFactionColors end) +E.Options.args.databars.args.colorGroup.args.factionColors.inline = true + +for i = 1, 8 do + E.Options.args.databars.args.colorGroup.args.factionColors.args[""..i] = ACH:Color(L["FACTION_STANDING_LABEL"..i], nil, i, true) +end + +E.Options.args.databars.args.experience = ACH:Group(L["Experience"], nil, 1, nil, function(info) return DB.db.experience[info[#info]] end, function(info, value) DB.db.experience[info[#info]] = value DB:ExperienceBar_Update() DB:ExperienceBar_QuestXP() DB:UpdateAll() end) +E.Options.args.databars.args.experience.args = CopyTable(SharedOptions) +E.Options.args.databars.args.experience.args.showLevel = ACH:Toggle(L["Level"], nil, 6) +E.Options.args.databars.args.experience.args.enable.set = function(info, value) DB.db.experience[info[#info]] = value DB:ExperienceBar_Toggle() DB:UpdateAll() end +E.Options.args.databars.args.experience.args.textFormat.set = function(info, value) DB.db.experience[info[#info]] = value DB:ExperienceBar_Update() end +E.Options.args.databars.args.experience.args.conditionGroup.get = function(_, key) return DB.db.experience[key] end +E.Options.args.databars.args.experience.args.conditionGroup.set = function(_, key, value) DB.db.experience[key] = value DB:ExperienceBar_Update() DB:ExperienceBar_QuestXP() DB:UpdateAll() end +E.Options.args.databars.args.experience.args.conditionGroup.values = { + questCurrentZoneOnly = L["Quests in Current Zone Only"], + questCompletedOnly = L["Completed Quests Only"], + hideAtMaxLevel = L["Hide At Max Level"], + hideInVehicle = L["Hide In Vehicle"], + hideInCombat = L["Hide In Combat"], +} + +E.Options.args.databars.args.reputation = ACH:Group(L["Reputation"], nil, 2, nil, function(info) return DB.db.reputation[info[#info]] end, function(info, value) DB.db.reputation[info[#info]] = value DB:ReputationBar_Update() DB:UpdateAll() end) +E.Options.args.databars.args.reputation.args = CopyTable(SharedOptions) +E.Options.args.databars.args.reputation.args.enable.set = function(info, value) DB.db.reputation[info[#info]] = value DB:ReputationBar_Toggle() DB:UpdateAll() end +E.Options.args.databars.args.reputation.args.textFormat.set = function(info, value) DB.db.reputation[info[#info]] = value DB:ReputationBar_Update() end +E.Options.args.databars.args.reputation.args.conditionGroup.get = function(_, key) return DB.db.reputation[key] end +E.Options.args.databars.args.reputation.args.conditionGroup.set = function(_, key, value) DB.db.reputation[key] = value DB:ReputationBar_Update() DB:UpdateAll() end +E.Options.args.databars.args.reputation.args.conditionGroup.values = { + hideInVehicle = L["Hide In Vehicle"], + hideInCombat = L["Hide In Combat"], +} + +E.Options.args.databars.args.honor = ACH:Group(L["Honor"], nil, 3, nil, function(info) return DB.db.honor[info[#info]] end, function(info, value) DB.db.honor[info[#info]] = value DB:HonorBar_Update() DB:UpdateAll() end) +E.Options.args.databars.args.honor.args = CopyTable(SharedOptions) +E.Options.args.databars.args.honor.args.enable.set = function(info, value) DB.db.honor[info[#info]] = value DB:HonorBar_Toggle() DB:UpdateAll() end +E.Options.args.databars.args.honor.args.textFormat.set = function(info, value) DB.db.honor[info[#info]] = value DB:HonorBar_Update() end +E.Options.args.databars.args.honor.args.conditionGroup.get = function(_, key) return DB.db.honor[key] end +E.Options.args.databars.args.honor.args.conditionGroup.set = function(_, key, value) DB.db.honor[key] = value DB:HonorBar_Update() DB:UpdateAll() end +E.Options.args.databars.args.honor.args.conditionGroup.values = { + hideInVehicle = L["Hide In Vehicle"], + hideInCombat = L["Hide In Combat"], + hideOutsidePvP = L["Hide Outside PvP"], + hideBelowMaxLevel = L["Hide Below Max Level"], +} + +E.Options.args.databars.args.threat = ACH:Group(L["Threat"], nil, 4, nil, function(info) return DB.db.threat[info[#info]] end, function(info, value) DB.db.threat[info[#info]] = value DB:ThreatBar_Update() DB:UpdateAll() end) +E.Options.args.databars.args.threat.args = CopyTable(SharedOptions) +E.Options.args.databars.args.threat.args.enable.set = function(info, value) DB.db.threat[info[#info]] = value DB:ThreatBar_Toggle() DB:UpdateAll() end +E.Options.args.databars.args.threat.args.textFormat = nil +E.Options.args.databars.args.threat.args.conditionGroup = nil +E.Options.args.databars.args.threat.args.showBubbles = nil + +E.Options.args.databars.args.azerite = ACH:Group(L["Azerite"], nil, 5, nil, function(info) return DB.db.azerite[info[#info]] end, function(info, value) DB.db.azerite[info[#info]] = value DB:AzeriteBar_Update() DB:UpdateAll() end) +E.Options.args.databars.args.azerite.args = CopyTable(SharedOptions) +E.Options.args.databars.args.azerite.args.enable.set = function(info, value) DB.db.azerite[info[#info]] = value DB:AzeriteBar_Toggle() DB:UpdateAll() end +E.Options.args.databars.args.azerite.args.textFormat.set = function(info, value) DB.db.azerite[info[#info]] = value DB:AzeriteBar_Update() end +E.Options.args.databars.args.azerite.args.conditionGroup.get = function(_, key) return DB.db.azerite[key] end +E.Options.args.databars.args.azerite.args.conditionGroup.set = function(_, key, value) DB.db.azerite[key] = value DB:AzeriteBar_Update() DB:UpdateAll() end +E.Options.args.databars.args.azerite.args.conditionGroup.values = { + hideInVehicle = L["Hide In Vehicle"], + hideInCombat = L["Hide In Combat"], + hideAtMaxLevel = L["Hide At Max Level"], +} diff --git a/DataTexts.lua b/DataTexts.lua new file mode 100644 index 0000000..ef6fe7a --- /dev/null +++ b/DataTexts.lua @@ -0,0 +1,923 @@ +local E, _, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB +local C, L = unpack(select(2, ...)) +local DT = E:GetModule('DataTexts') +local Layout = E:GetModule('Layout') +local Chat = E:GetModule('Chat') +local Minimap = E:GetModule('Minimap') +local ACH = E.Libs.ACH + +local _G = _G +local type, pairs, ipairs = type, pairs, ipairs +local gsub, next, wipe = gsub, next, wipe +local tonumber = tonumber +local tostring = tostring +local format = format + +-- GLOBALS: AceGUIWidgetLSMlists +local currencyList = {} +local DTPanelOptions = { + numPoints = { + order = 2, + type = 'range', + name = L["Number of DataTexts"], + min = 1, max = 20, step = 1, + }, + growth = { + order = 3, + type = 'select', + name = L["Growth"], + values = { + HORIZONTAL = 'HORIZONTAL', + VERTICAL = 'VERTICAL' + }, + }, + width = { + order = 4, + type = 'range', + name = L["Width"], + min = 24, max = E.screenwidth, step = 1, + }, + height = { + order = 5, + type = 'range', + name = L["Height"], + min = 12, max = E.screenheight, step = 1, + }, + textJustify = { + order = 6, + type = 'select', + name = L["Text Justify"], + desc = L["Sets the font instance's horizontal text alignment style."], + values = { + CENTER = L["Center"], + LEFT = L["Left"], + RIGHT = L["Right"], + }, + }, + templateGroup = { + order = 10, + type = 'multiselect', + name = L["Template"], + sortByValue = true, + values = { + backdrop = L["Backdrop"], + panelTransparency = L["Backdrop Transparency"], + mouseover = L["Mouse Over"], + border = L["Show Border"], + }, + }, + strataAndLevel = { + order = 15, + type = 'group', + name = L["Strata and Level"], + inline = true, + args = { + frameStrata = { + order = 2, + type = 'select', + name = L["Frame Strata"], + values = C.Values.Strata, + }, + frameLevel = { + order = 5, + type = 'range', + name = L["Frame Level"], + min = 1, max = 128, step = 1, + }, + }, + }, + tooltip = { + order = 20, + type = 'group', + name = L["Tooltip"], + inline = true, + args = { + tooltipXOffset = { + order = 1, + type = 'range', + name = L["X-Offset"], + min = -30, max = 30, step = 1, + }, + tooltipYOffset = { + order = 2, + type = 'range', + name = L["Y-Offset"], + min = -30, max = 30, step = 1, + }, + tooltipAnchor = { + order = 3, + type = 'select', + name = L["Anchor"], + values = { + ANCHOR_TOP = L["TOP"], + ANCHOR_RIGHT = L["RIGHT"], + ANCHOR_BOTTOM = L["BOTTOM"], + ANCHOR_LEFT = L["LEFT"], + ANCHOR_TOPRIGHT = L["TOPRIGHT"], + ANCHOR_BOTTOMRIGHT = L["BOTTOMRIGHT"], + ANCHOR_TOPLEFT = L["TOPLEFT"], + ANCHOR_BOTTOMLEFT = L["BOTTOMLEFT"], + ANCHOR_CURSOR = L["CURSOR"], + ANCHOR_CURSOR_LEFT = L["CURSOR_LEFT"], + ANCHOR_CURSOR_RIGHT = L["CURSOR_RIGHT"], + }, + }, + }, + }, + visibility = { + type = 'input', + order = 25, + name = L["Visibility State"], + desc = L["This works like a macro, you can run different situations to get the actionbar to show/hide differently.\n Example: '[combat] show;hide'"], + width = 'full', + }, +} + +local function ColorizeName(name, color) + return format('|cFF%s%s|r', color or 'ffd100', name) +end + +local function PanelGroup_Delete(panel) + E.Options.args.datatexts.args.panels.args[panel] = nil +end + +local function PanelGroup_Create(panel) + local opts = { + type = 'group', + name = ColorizeName(panel), + get = function(info) return E.db.datatexts.panels[panel][info[#info]] end, + set = function(info, value) + E.db.datatexts.panels[panel][info[#info]] = value + DT:UpdatePanelAttributes(panel, E.global.datatexts.customPanels[panel]) + end, + args = { + enable = { + order = 0, + type = 'toggle', + name = L["Enable"], + }, + panelOptions = { + order = -1, + name = L["Panel Options"], + type = 'group', + inline = true, + get = function(info) return E.global.datatexts.customPanels[panel][info[#info]] end, + set = function(info, value) + E.global.datatexts.customPanels[panel][info[#info]] = value + DT:UpdatePanelAttributes(panel, E.global.datatexts.customPanels[panel]) + DT:PanelLayoutOptions() + end, + args = { + delete = { + order = -1, + type = 'execute', + name = L["Delete"], + width = 'full', + confirm = true, + func = function(info) + E.db.datatexts.panels[panel] = nil + E.global.datatexts.customPanels[panel] = nil + DT:ReleasePanel(panel) + PanelGroup_Delete(panel) + DT:PanelLayoutOptions() + E.Libs.AceConfigDialog:SelectGroup('ElvUI', 'datatexts', 'panels', 'newPanel') + end, + }, + fonts = { + order = 10, + type = 'group', + name = L["Fonts"], + inline = true, + get = function(info) + local settings = E.global.datatexts.customPanels[panel] + if not settings.fonts then settings.fonts = E:CopyTable({}, G.datatexts.newPanelInfo.fonts) end + return settings.fonts[info[#info]] + end, + set = function(info, value) + E.global.datatexts.customPanels[panel].fonts[info[#info]] = value + DT:UpdatePanelAttributes(panel, E.global.datatexts.customPanels[panel]) + end, + args = { + enable = { + type = 'toggle', + order = 1, + name = L["Enable"], + desc = L["This will override the global cooldown settings."], + disabled = E.noop, + }, + fontSize = { + order = 3, + type = 'range', + name = L["Text Font Size"], + min = 10, max = 50, step = 1, + }, + font = { + order = 4, + type = 'select', + name = L["Font"], + dialogControl = 'LSM30_Font', + values = AceGUIWidgetLSMlists.font, + }, + fontOutline = { + order = 5, + type = 'select', + name = L["Font Outline"], + values = C.Values.FontFlags, + }, + } + }, + }, + } + }, + } + + local panelOpts = E:CopyTable(opts.args.panelOptions.args, DTPanelOptions) + panelOpts.tooltip.args.tooltipYOffset.disabled = function() return E.global.datatexts.customPanels[panel].tooltipAnchor == 'ANCHOR_CURSOR' end + panelOpts.tooltip.args.tooltipXOffset.disabled = function() return E.global.datatexts.customPanels[panel].tooltipAnchor == 'ANCHOR_CURSOR' end + panelOpts.templateGroup.get = function(_, key) return E.global.datatexts.customPanels[panel][key] end + panelOpts.templateGroup.set = function(_, key, value) E.global.datatexts.customPanels[panel][key] = value; DT:UpdatePanelAttributes(panel, E.global.datatexts.customPanels[panel]) end + + E.Options.args.datatexts.args.panels.args[panel] = opts +end + +local dts = {[''] = L["NONE"]} +function DT:PanelLayoutOptions() + for name, data in pairs(DT.RegisteredDataTexts) do + dts[name] = data.localizedName or L[name] + end + + local options = E.Options.args.datatexts.args.panels.args + + -- Custom Panels + for panel in pairs(E.global.datatexts.customPanels) do + PanelGroup_Create(panel) + end + + -- This will mixin the options for the Custom Panels. + for name, tab in pairs(DT.db.panels) do + if type(tab) == 'table' then + if not options[name] then + options[name] = { + type = 'group', + name = ColorizeName(name, 'ffffff'), + args = {}, + get = function(info) return E.db.datatexts.panels[name][info[#info]] end, + set = function(info, value) + E.db.datatexts.panels[name][info[#info]] = value + DT:UpdatePanelInfo(name) + end, + } + end + + if not P.datatexts.panels[name] and not E.global.datatexts.customPanels[name] then + options[name].args.delete = { + order = -1, + type = 'execute', + name = L["Delete"], + func = function() + E.db.datatexts.panels[name] = nil + options[name] = nil + DT:PanelLayoutOptions() + end, + } + end + + for option in pairs(tab) do + if type(option) == 'number' then + if E.global.datatexts.customPanels[name] and option > E.global.datatexts.customPanels[name].numPoints then + tab[option] = nil + else + options[name].args[tostring(option)] = { + type = 'select', + order = option, + name = L[format('Position %d', option)], + values = dts, + get = function(info) return E.db.datatexts.panels[name][tonumber(info[#info])] end, + set = function(info, value) + E.db.datatexts.panels[name][tonumber(info[#info])] = value + DT:UpdatePanelInfo(name) + end, + } + end + end + end + end + end +end + +local function CreateCustomCurrencyOptions(currencyID) + local currency = E.global.datatexts.customCurrencies[currencyID] + if currency then + E.Options.args.datatexts.args.customCurrency.args[currency.NAME] = { + order = 1, + type = 'group', + name = currency.NAME, + inline = false, + args = { + displayStyle = { + order = 1, + type = 'select', + name = L["Display Style"], + get = function(info) return E.global.datatexts.customCurrencies[currencyID].DISPLAY_STYLE end, + set = function(info, value) + E.global.datatexts.customCurrencies[currencyID].DISPLAY_STYLE = value + DT:UpdateCustomCurrencySettings(currency.NAME, 'DISPLAY_STYLE', value) + DT:LoadDataTexts() + end, + values = { + ICON = L["Icons Only"], + ICON_TEXT = L["Icons and Text"], + ICON_TEXT_ABBR = L["Icons and Text (Short)"], + }, + }, + showMax = { + order = 2, + type = 'toggle', + name = L["Current / Max"], + get = function(info) return E.global.datatexts.customCurrencies[currencyID].SHOW_MAX end, + set = function(info, value) + E.global.datatexts.customCurrencies[currencyID].SHOW_MAX = value + DT:UpdateCustomCurrencySettings(currency.NAME, 'SHOW_MAX', value) + DT:LoadDataTexts() + end, + }, + useTooltip = { + order = 3, + type = 'toggle', + name = L["Use Tooltip"], + get = function(info) return E.global.datatexts.customCurrencies[currencyID].USE_TOOLTIP end, + set = function(info, value) + E.global.datatexts.customCurrencies[currencyID].USE_TOOLTIP = value + DT:UpdateCustomCurrencySettings(currency.NAME, 'USE_TOOLTIP', value) + end, + }, + }, + } + end +end + +local function SetupCustomCurrencies() + for currencyID in pairs(E.global.datatexts.customCurrencies) do + CreateCustomCurrencyOptions(currencyID) + end +end + +local function CreateDTOptions(name, data) + local settings = E.global.datatexts.settings[name] + if not settings then return end + + local optionTable = { + order = 1, + type = "group", + name = data.localizedName or name, + inline = false, + get = function(info) return settings[info[#info]] end, + set = function(info, value) settings[info[#info]] = value DT:ForceUpdate_DataText(name) end, + args = {}, + } + + E.Options.args.datatexts.args.settings.args[name] = optionTable + + for key in pairs(settings) do + if key == 'decimalLength' then + optionTable.args.decimalLength = { + type = 'range', + name = L["Decimal Length"], + min = 0, max = 5, step = 1, + } + elseif key == 'goldFormat' then + optionTable.args.goldFormat = { + type = 'select', + name = L["Gold Format"], + desc = L["The display format of the money text that is shown in the gold datatext and its tooltip."], + values = { SMART = L["Smart"], FULL = L["Full"], SHORT = L["SHORT"], SHORTINT = L["Short (Whole Numbers)"], CONDENSED = L["Condensed"], BLIZZARD = L["Blizzard Style"], BLIZZARD2 = L["Blizzard Style"].." 2" }, + } + elseif key == 'goldCoins' then + optionTable.args.goldCoins = { + type = 'toggle', + name = L["Show Coins"], + desc = L["Use coin icons instead of colored text."], + } + elseif key == 'Label' then + optionTable.args.Label = { + order = 0, + type = 'input', + name = L["Label"], + get = function(info) return settings[info[#info]] and gsub(settings[info[#info]], '\124', '\124\124') end, + set = function(info, value) settings[info[#info]] = gsub(value, '\124\124+', '\124') DT:ForceUpdate_DataText(name) end, + } + elseif key == 'NoLabel' then + optionTable.args.NoLabel = { + type = 'toggle', + name = L["No Label"], + } + elseif key == 'ShowOthers' then + optionTable.args.ShowOthers = { + type = 'toggle', + name = L["Other AddOns"], + } + elseif key == 'textFormat' then + optionTable.args.textFormat = { + type = 'select', + name = L["Text Format"], + width = "double", + get = function(info) return settings[info[#info]] end, + set = function(info, value) settings[info[#info]] = value; DT:ForceUpdate_DataText(name) end, + values = {}, + } + end + end + + if name == 'Combat' then + optionTable.args.TimeFull = ACH:Toggle('Full Time') + elseif name == 'Currencies' then + optionTable.args.displayedCurrency = { + type = "select", + name = L["Displayed Currency"], + values = function() return DT.CurrencyList end, + sortByValue = true, + } + optionTable.args.displayStyle = { + type = "select", + name = L["Currency Format"], + hidden = function() return (settings.displayedCurrency == "GOLD") or (settings.displayedCurrency == "BACKPACK") end, + values = { + ICON = L["Icons Only"], + ICON_TEXT = L["Icons and Text"], + ICON_TEXT_ABBR = L["Icons and Text (Short)"], + }, + } + optionTable.args.goldFormat.hidden = function() return (settings.displayedCurrency ~= "GOLD") end + optionTable.args.goldCoins.hidden = function() return (settings.displayedCurrency ~= "GOLD") end + optionTable.args.tooltipLines = { + order = -1, + type = 'group', + inline = true, + name = L["Tooltip Lines"], + args = {} + } + for i, info in ipairs(G.datatexts.settings.Currencies.tooltipData) do + if not info[2] then + optionTable.args.tooltipLines.args[tostring(i)] = { + order = i, + type = 'group', + inline = true, + name = info[1], + args = { + header = { + order = i, + type = 'toggle', + name = "Header", + get = function() return settings.tooltipData[i][4] end, + set = function(_, value) settings.tooltipData[i][4] = value end, + }, + }, + } + elseif info[3] then + optionTable.args.tooltipLines.args[tostring(info[3])].args[tostring(i)] = { + order = i, + type = 'toggle', + name = info[1], + get = function() return settings.tooltipData[i][4] end, + set = function(_, value) settings.tooltipData[i][4] = value end, + } + end + end + elseif name == 'Time' then + optionTable.args.time24 = { + type = 'toggle', + name = L["24-Hour Time"], + desc = L["Toggle 24-hour mode for the time datatext."], + } + optionTable.args.localTime = { + type = 'toggle', + name = L["Local Time"], + desc = L["If not set to true then the server time will be displayed instead."], + } + elseif name == 'Durability' then + optionTable.args.percThreshold = { + type = "range", + name = L["Flash Threshold"], + desc = L["The durability percent that the datatext will start flashing. Set to -1 to disable"], + min = -1, max = 99, step = 1, + get = function(info) return settings[info[#info]] end, + set = function(info, value) settings[info[#info]] = value; DT:ForceUpdate_DataText(name) end, + } + elseif name == 'Friends' then + optionTable.args.description = { + order = 1, + type = "description", + name = L["Hide specific sections in the datatext tooltip."], + } + optionTable.args.hideGroup1 = { + order = 2, + type = "multiselect", + name = L["Hide by Status"], + get = function(_, key) return settings[key] end, + set = function(_, key, value) settings[key] = value; DT:ForceUpdate_DataText(name) end, + values = { + hideAFK = L["AFK"], + hideDND = L["DND"], + }, + } + optionTable.args.hideGroup2 = { + order = 2, + type = "multiselect", + name = L["Hide by Application"], + get = function(_, key) return settings['hide'..key] end, + set = function(_, key, value) settings['hide'..key] = value; DT:ForceUpdate_DataText(name) end, + sortByValue = true, + values = { + WoW = "World of Warcraft", + App = "App", + BSAp = L["Mobile"], + D3 = "Diablo 3", + WTCG = "Hearthstone", + Hero = "Heroes of the Storm", + Pro = "Overwatch", + S1 = "Starcraft", + S2 = "Starcraft 2", + VIPR = "COD: Black Ops 4", + ODIN = "COD: Modern Warfare", + LAZR = "COD: Modern Warfare 2", + ZEUS = "COD: Cold War" + }, + } + elseif name == 'Reputation' or name == 'Experience' then + optionTable.args.textFormat.values = { + PERCENT = L["Percent"], + CUR = L["Current"], + REM = L["Remaining"], + CURMAX = L["Current - Max"], + CURPERC = L["Current - Percent"], + CURREM = L["Current - Remaining"], + CURPERCREM = L["Current - Percent (Remaining)"], + } + elseif name == 'Bags' then + optionTable.args.textFormat.values = { + ["FREE"] = L["Only Free Slots"], + ["USED"] = L["Only Used Slots"], + ["FREE_TOTAL"] = L["Free/Total"], + ["USED_TOTAL"] = L["Used/Total"], + } + end +end + +local function SetupDTCustomization() + local currencyTable = {} + for name, data in pairs(DT.RegisteredDataTexts) do + currencyTable[name] = data + end + + for _, info in pairs(E.global.datatexts.customCurrencies) do + local name = info.NAME + if currencyTable[name] then + currencyTable[name] = nil + end + end + + for name, data in pairs(currencyTable) do + if not data.isLibDataBroker then + CreateDTOptions(name, data) + end + end +end + +E.Options.args.datatexts = { + type = 'group', + name = L["DataTexts"], + childGroups = 'tab', + order = 2, + get = function(info) return E.db.datatexts[info[#info]] end, + set = function(info, value) E.db.datatexts[info[#info]] = value; DT:LoadDataTexts() end, + args = { + intro = ACH:Description(L["DATATEXT_DESC"], 1), + spacer = ACH:Spacer(2), + general = { + order = 3, + type = 'group', + name = L["General"], + args = { + generalGroup = { + order = 2, + type = 'group', + inline = true, + name = L["General"], + args = { + battleground = { + order = 3, + type = 'toggle', + name = L["Battleground Texts"], + desc = L["When inside a battleground display personal scoreboard information on the main datatext bars."], + }, + noCombatClick = { + order = 6, + type = 'toggle', + name = L["Block Combat Click"], + desc = L["Blocks all click events while in combat."], + }, + noCombatHover = { + order = 7, + type = 'toggle', + name = L["Block Combat Hover"], + desc = L["Blocks datatext tooltip from showing in combat."], + }, + }, + }, + fontGroup = { + order = 3, + type = 'group', + inline = true, + name = L["Fonts"], + args = { + font = { + type = 'select', dialogControl = 'LSM30_Font', + order = 1, + name = L["Font"], + values = AceGUIWidgetLSMlists.font, + }, + fontSize = { + order = 2, + name = L["FONT_SIZE"], + type = 'range', + min = 6, max = 64, step = 1, + }, + fontOutline = { + order = 3, + name = L["Font Outline"], + desc = L["Set the font outline."], + type = 'select', + values = C.Values.FontFlags, + }, + wordWrap = { + order = 4, + type = 'toggle', + name = L["Word Wrap"], + }, + }, + }, + }, + }, + panels = { + type = 'group', + name = L["Panels"], + order = 4, + args = { + newPanel = { + order = 0, + type = 'group', + name = ColorizeName(L["New Panel"], '33ff33'), + get = function(info) return E.global.datatexts.newPanelInfo[info[#info]] end, + set = function(info, value) E.global.datatexts.newPanelInfo[info[#info]] = value end, + args = { + name = { + order = 0, + type = 'input', + width = 'full', + name = L["Name"], + validate = function(_, value) + return E.global.datatexts.customPanels[value] and L["Name Taken"] or true + end, + }, + add = { + order = 1, + type = 'execute', + name = L["Add"], + width = 'full', + hidden = function() + local name = E.global.datatexts.newPanelInfo.name + return not name or name == '' + end, + func = function() + local name = E.global.datatexts.newPanelInfo.name + E.global.datatexts.customPanels[name] = E:CopyTable({}, E.global.datatexts.newPanelInfo) + E.db.datatexts.panels[name] = { enable = true } + + for i = 1, E.global.datatexts.newPanelInfo.numPoints do + E.db.datatexts.panels[name][i] = '' + end + + PanelGroup_Create(name) + DT:BuildPanelFrame(name, E.global.datatexts.customPanels[name]) + DT:PanelLayoutOptions() + + E.Libs.AceConfigDialog:SelectGroup('ElvUI', 'datatexts', 'panels', name) + E.global.datatexts.newPanelInfo = E:CopyTable({}, G.datatexts.newPanelInfo) + end, + }, + }, + }, + LeftChatDataPanel = { + type = 'group', + name = ColorizeName(L["Datatext Panel (Left)"], 'cccccc'), + desc = L["Display data panels below the chat, used for datatexts."], + order = 2, + get = function(info) return E.db.datatexts.panels.LeftChatDataPanel[info[#info]] end, + set = function(info, value) E.db.datatexts.panels.LeftChatDataPanel[info[#info]] = value DT:UpdatePanelInfo('LeftChatDataPanel') Layout:SetDataPanelStyle() end, + args = { + enable = { + order = 0, + name = L["Enable"], + type = 'toggle', + set = function(info, value) + E.db.datatexts.panels[info[#info - 1]][info[#info]] = value + if E.db.LeftChatPanelFaded then + E.db.LeftChatPanelFaded = true; + _G.HideLeftChat() + end + + if E.private.chat.enable then + Chat:UpdateEditboxAnchors() + end + + Layout:ToggleChatPanels() + Layout:SetDataPanelStyle() + DT:UpdatePanelInfo('LeftChatDataPanel') + end, + }, + backdrop = { + order = 5, + name = L["Backdrop"], + type = 'toggle', + }, + border = { + order = 6, + name = L["Border"], + type = 'toggle', + disabled = function() return not E.db.datatexts.panels.LeftChatDataPanel.backdrop end, + }, + panelTransparency = { + order = 7, + type = 'toggle', + name = L["Panel Transparency"], + disabled = function() return not E.db.datatexts.panels.LeftChatDataPanel.backdrop end, + }, + }, + }, + RightChatDataPanel = { + type = 'group', + name = ColorizeName(L["Datatext Panel (Right)"], 'cccccc'), + desc = L["Display data panels below the chat, used for datatexts."], + order = 3, + get = function(info) return E.db.datatexts.panels.RightChatDataPanel[info[#info]] end, + set = function(info, value) E.db.datatexts.panels.RightChatDataPanel[info[#info]] = value DT:UpdatePanelInfo('RightChatDataPanel') Layout:SetDataPanelStyle() end, + args = { + enable = { + order = 0, + name = L["Enable"], + type = 'toggle', + set = function(info, value) + E.db.datatexts.panels[info[#info - 1]][info[#info]] = value + if E.db.RightChatPanelFaded then + E.db.RightChatPanelFaded = true; + _G.HideRightChat() + end + + if E.private.chat.enable then + Chat:UpdateEditboxAnchors() + end + + Layout:ToggleChatPanels() + Layout:SetDataPanelStyle() + DT:UpdatePanelInfo('RightChatDataPanel') + end, + }, + backdrop = { + order = 5, + name = L["Backdrop"], + type = 'toggle', + }, + border = { + order = 6, + name = L["Border"], + type = 'toggle', + disabled = function() return not E.db.datatexts.panels.RightChatDataPanel.backdrop end, + }, + panelTransparency = { + order = 7, + type = 'toggle', + name = L["Panel Transparency"], + disabled = function() return not E.db.datatexts.panels.RightChatDataPanel.backdrop end, + }, + }, + }, + MinimapPanel = { + type = 'group', + name = ColorizeName(L["Minimap Panels"], 'cccccc'), + desc = L["Display minimap panels below the minimap, used for datatexts."], + get = function(info) return E.db.datatexts.panels.MinimapPanel[info[#info]] end, + set = function(info, value) E.db.datatexts.panels.MinimapPanel[info[#info]] = value DT:UpdatePanelInfo('MinimapPanel') end, + hidden = function() return not E.private.general.minimap.enable end, + order = 4, + args = { + enable = { + order = 0, + name = L["Enable"], + type = 'toggle', + set = function(info, value) + E.db.datatexts.panels[info[#info - 1]][info[#info]] = value + DT:UpdatePanelInfo('MinimapPanel') + + if E.private.general.minimap.enable then + Minimap:UpdateSettings() + end + end, + }, + numPoints = { + order = 5, + type = 'range', + name = L["Number of DataTexts"], + min = 1, max = 2, step = 1, + }, + backdrop = { + order = 6, + name = L["Backdrop"], + type = 'toggle', + }, + border = { + order = 7, + name = L["Border"], + type = 'toggle', + disabled = function() return not E.db.datatexts.panels.MinimapPanel.backdrop end, + }, + panelTransparency = { + order = 8, + type = 'toggle', + name = L["Panel Transparency"], + disabled = function() return not E.db.datatexts.panels.MinimapPanel.backdrop end, + }, + }, + }, + }, + }, + customCurrency = { + order = 6, + type = 'group', + name = L["Custom Currency"], + args = { + description = ACH:Description(L["This allows you to create a new datatext which will track the currency with the supplied currency ID. The datatext can be added to a panel immediately after creation."], 0), + add = { + order = 1, + type = 'select', + name = L["Add Currency"], + width = 'double', + set = function(info, value) + local currencyID = tonumber(value) + if not currencyID then return; end + DT:RegisterCustomCurrencyDT(currencyID) + CreateCustomCurrencyOptions(currencyID) + DT:PanelLayoutOptions() + DT:LoadDataTexts() + end, + values = function() + local list = E:CopyTable({}, DT.CurrencyList) + list.GOLD = nil + list.BACKPACK = nil + + return list + end, + }, + delete = { + order = 2, + type = 'select', + width = 'double', + name = L["DELETE"], + set = function(info, value) + local currencyName = E.global.datatexts.customCurrencies[value].NAME + DT:RemoveCustomCurrency(currencyName) + E.Options.args.datatexts.args.customCurrency.args[currencyName] = nil + DT.RegisteredDataTexts[currencyName] = nil + E.global.datatexts.customCurrencies[value] = nil + dts[currencyName] = nil + DT:PanelLayoutOptions() + DT:LoadDataTexts() + end, + disabled = function() return not next(E.global.datatexts.customCurrencies) end, + values = function() + wipe(currencyList) + + for currencyID, table in pairs(E.global.datatexts.customCurrencies) do + currencyList[currencyID] = table.NAME + end + + return currencyList + end + }, + }, + }, + settings = { + order = 7, + type = "group", + name = L["DataText Customization"], + args = {}, + } + }, +} + +E:CopyTable(E.Options.args.datatexts.args.panels.args.newPanel.args, DTPanelOptions) +E.Options.args.datatexts.args.panels.args.newPanel.args.templateGroup.get = function(_, key) return E.global.datatexts.newPanelInfo[key] end +E.Options.args.datatexts.args.panels.args.newPanel.args.templateGroup.set = function(_, key, value) E.global.datatexts.newPanelInfo[key] = value end + +DT:PanelLayoutOptions() +SetupCustomCurrencies() +SetupDTCustomization() diff --git a/ElvUI_OptionsUI.toc b/ElvUI_OptionsUI.toc new file mode 100644 index 0000000..bf1b146 --- /dev/null +++ b/ElvUI_OptionsUI.toc @@ -0,0 +1,27 @@ +## Interface: 90001 +## Author: Elv +## Version: 1.07 +## Title: |cff1784d1ElvUI|r |cfd9b9b9bOptionsUI|r +## Notes: Options for ElvUI. +## RequiredDeps: ElvUI +## LoadOnDemand: 1 + +Libraries\Load_Libraries.xml +Locales\Load_Locales.xml +Core.lua +General.lua +ActionBars.lua +Auras.lua +Bags.lua +Chat.lua +Cooldown.lua +DataTexts.lua +DataBars.lua +Filters.lua +Skins.lua +Tooltip.lua +UnitFrames.lua +Nameplates.lua +Maps.lua +ModuleControl.lua +Tags.lua diff --git a/Filters.lua b/Filters.lua new file mode 100644 index 0000000..22f9d6c --- /dev/null +++ b/Filters.lua @@ -0,0 +1,745 @@ +local E, _, V, P, G = unpack(ElvUI) --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB +local _, L = unpack(select(2, ...)) +local UF = E:GetModule('UnitFrames') +local ACH = E.Libs.ACH + +local gsub = gsub +local wipe = wipe +local next = next +local pairs = pairs +local format = format +local strmatch = strmatch +local tonumber = tonumber +local tostring = tostring +local GetSpellInfo = GetSpellInfo + +-- GLOBALS: MAX_PLAYER_LEVEL + +local quickSearchText, selectedSpell, selectedFilter, filterList, spellList = '', nil, nil, {}, {} +local defaultFilterList = { ['Aura Indicator (Global)'] = 'Aura Indicator (Global)', ['Aura Indicator (Class)'] = 'Aura Indicator (Class)', ['Aura Indicator (Pet)'] = 'Aura Indicator (Pet)', ['Aura Indicator (Profile)'] = 'Aura Indicator (Profile)', ['AuraBar Colors'] = 'AuraBar Colors', ['Aura Highlight'] = 'Aura Highlight' } +local auraBarDefaults = { enable = true, color = { r = 1, g = 1, b = 1 } } + +local function GetSelectedFilters() + local class = selectedFilter == 'Aura Indicator (Class)' + local pet = selectedFilter == 'Aura Indicator (Pet)' + local profile = selectedFilter == 'Aura Indicator (Profile)' + local selected = (profile and E.db.unitframe.filters.aurawatch) or (pet and (E.global.unitframe.aurawatch.PET or {})) or class and (E.global.unitframe.aurawatch[E.myclass] or {}) or E.global.unitframe.aurawatch.GLOBAL + local default = (profile and P.unitframe.filters.aurawatch) or (pet and G.unitframe.aurawatch.PET) or class and G.unitframe.aurawatch[E.myclass] or G.unitframe.aurawatch.GLOBAL + return selected, default +end + +local function GetSelectedSpell() + if selectedSpell and selectedSpell ~= '' then + local spell = strmatch(selectedSpell, ' %((%d+)%)$') or selectedSpell + if spell then + return tonumber(spell) or spell + end + end +end + +local function filterMatch(s,v) + local m1, m2, m3, m4 = '^'..v..'$', '^'..v..',', ','..v..'$', ','..v..',' + return (strmatch(s, m1) and m1) or (strmatch(s, m2) and m2) or (strmatch(s, m3) and m3) or (strmatch(s, m4) and v..',') +end + +local function removePriority(value) + if not value then return end + local x,y,z=E.db.unitframe.units,E.db.nameplates.units; + for n, t in pairs(x) do + if t and t.buffs and t.buffs.priority and t.buffs.priority ~= '' then + z = filterMatch(t.buffs.priority, E:EscapeString(value)) + if z then E.db.unitframe.units[n].buffs.priority = gsub(t.buffs.priority, z, '') end + end + if t and t.debuffs and t.debuffs.priority and t.debuffs.priority ~= '' then + z = filterMatch(t.debuffs.priority, E:EscapeString(value)) + if z then E.db.unitframe.units[n].debuffs.priority = gsub(t.debuffs.priority, z, '') end + end + if t and t.aurabar and t.aurabar.priority and t.aurabar.priority ~= '' then + z = filterMatch(t.aurabar.priority, E:EscapeString(value)) + if z then E.db.unitframe.units[n].aurabar.priority = gsub(t.aurabar.priority, z, '') end + end + end + for n, t in pairs(y) do + if t and t.buffs and t.buffs.priority and t.buffs.priority ~= '' then + z = filterMatch(t.buffs.priority, E:EscapeString(value)) + if z then E.db.nameplates.units[n].buffs.priority = gsub(t.buffs.priority, z, '') end + end + if t and t.debuffs and t.debuffs.priority and t.debuffs.priority ~= '' then + z = filterMatch(t.debuffs.priority, E:EscapeString(value)) + if z then E.db.nameplates.units[n].debuffs.priority = gsub(t.debuffs.priority, z, '') end + end + end +end + +local function SetFilterList() + wipe(filterList) + E:CopyTable(filterList, defaultFilterList) + + local list = E.global.unitframe.aurafilters + if list then + for filter in pairs(list) do + filterList[filter] = filter + end + end + + return filterList +end + +local function ResetFilterList() + wipe(filterList) + + E:CopyTable(filterList, defaultFilterList) + + local list = G.unitframe.aurafilters + if list then + for filter in pairs(list) do + filterList[filter] = filter + end + end + + return filterList +end + +local function DeleteFilterList() + wipe(filterList) + + local list = E.global.unitframe.aurafilters + local defaultList = G.unitframe.aurafilters + if list then + for filter in pairs(list) do + if not defaultList[filter] then + filterList[filter] = filter + end + end + end + + return filterList +end + +local function DeleteFilterListDisable() + wipe(filterList) + + local list = E.global.unitframe.aurafilters + local defaultList = G.unitframe.aurafilters + if list then + for filter in pairs(list) do + if not defaultList[filter] then + return false + end + end + end + + return true +end + +local function SetSpellList() + local list + if selectedFilter == 'Aura Highlight' then + list = E.global.unitframe.AuraHighlightColors + elseif selectedFilter == 'AuraBar Colors' then + list = E.global.unitframe.AuraBarColors + elseif selectedFilter == 'Aura Indicator (Pet)' or selectedFilter == 'Aura Indicator (Profile)' or selectedFilter == 'Aura Indicator (Class)' or selectedFilter == 'Aura Indicator (Global)' then + list = GetSelectedFilters() + else + list = E.global.unitframe.aurafilters[selectedFilter].spells + end + + if not list then return end + wipe(spellList) + + local searchText = quickSearchText:lower() + for filter, spell in pairs(list) do + if spell.id and (selectedFilter == 'Aura Indicator (Pet)' or selectedFilter == 'Aura Indicator (Profile)' or selectedFilter == 'Aura Indicator (Class)' or selectedFilter == 'Aura Indicator (Global)') then + filter = spell.id + end + + local spellName = tonumber(filter) and GetSpellInfo(filter) + local name = (spellName and format('%s |cFF888888(%s)|r', spellName, filter)) or tostring(filter) + + if name:lower():find(searchText) then + spellList[filter] = name + end + end + + if not next(spellList) then + spellList[''] = L["NONE"] + end + + return spellList +end + +E.Options.args.filters = { + type = 'group', + name = L["FILTERS"], + order = 3, + childGroups = 'tab', + args = { + mainOptions = { + type = 'group', + name = 'Main Options', + order = 1, + args = { + createFilter = { + order = 1, + name = L["Create Filter"], + desc = L["Create a filter, once created a filter can be set inside the buffs/debuffs section of each unit."], + type = 'input', + get = function(info) return '' end, + set = function(info, value) + if strmatch(value, '^[%s%p]-$') then + return + end + if strmatch(value, ',') then + E:Print(L["Filters are not allowed to have commas in their name. Stripping commas from filter name."]) + value = gsub(value, ',', '') + end + if strmatch(value, '^Friendly:') or strmatch(value, '^Enemy:') then + return --dont allow people to create Friendly: or Enemy: filters + end + if G.unitframe.specialFilters[value] or E.global.unitframe.aurafilters[value] then + E:Print(L["Filter already exists!"]) + return + end + E.global.unitframe.aurafilters[value] = { spells = {} } + selectedFilter = value + end, + }, + selectFilter = { + order = 2, + type = 'select', + name = L["Select Filter"], + get = function(info) return selectedFilter end, + set = function(info, value) + selectedFilter, selectedSpell, quickSearchText = nil, nil, '' + if value ~= '' then + selectedFilter = value + end + end, + values = SetFilterList, + }, + deleteFilter = { + type = 'select', + order = 3, + name = L["Delete Filter"], + desc = L["Delete a created filter, you cannot delete pre-existing filters, only custom ones."], + confirm = function(info, value) + return 'Remove Filter - '..value + end, + set = function(info, value) + E.global.unitframe.aurafilters[value] = nil + selectedFilter, selectedSpell, quickSearchText = nil, nil, '' + + removePriority(value) --This will wipe a filter from the new aura system profile settings. + end, + disabled = DeleteFilterListDisable, + values = DeleteFilterList, + }, + resetGroup = { + type = 'select', + name = L["Reset Filter"], + order = 4, + desc = L["This will reset the contents of this filter back to default. Any spell you have added to this filter will be removed."], + confirm = function(info, value) + return 'Reset Filter - '..value + end, + set = function(info, value) + if value == 'Aura Highlight' then + E.global.unitframe.AuraHighlightColors = E:CopyTable({}, G.unitframe.DebuffHighlightColors) + elseif value == 'AuraBar Colors' then + E.global.unitframe.AuraBarColors = E:CopyTable({}, G.unitframe.AuraBarColors) + elseif value == 'Aura Indicator (Pet)' or value == 'Aura Indicator (Profile)' or value == 'Aura Indicator (Class)' or value == 'Aura Indicator (Global)' then + local selectedTable, defaultTable = GetSelectedFilters() + wipe(selectedTable) + E:CopyTable(selectedTable, defaultTable) + else + E.global.unitframe.aurafilters[value].spells = E:CopyTable({}, G.unitframe.aurafilters[value].spells) + end + + selectedFilter, selectedSpell, quickSearchText = nil, nil, '' + + UF:Update_AllFrames() + end, + values = ResetFilterList, + }, + filterGroup = { + type = 'group', + name = function() return selectedFilter end, + hidden = function() return not selectedFilter end, + inline = true, + order = 10, + args = { + selectSpellheader = ACH:Description(L["|cffFF0000Warning:|r Click the arrow on the dropdown box to see a list of spells."], 0, 'medium'), + selectSpell = { + name = L["Select Spell"], + type = 'select', + order = 1, + customWidth = 350, + get = function(info) return selectedSpell or '' end, + set = function(info, value) + selectedSpell = (value ~= '' and value) or nil + end, + values = SetSpellList, + }, + quickSearch = { + order = 2, + name = L["Filter Search"], + desc = L["Search for a spell name inside of a filter."], + type = 'input', + customWidth = 200, + get = function() return quickSearchText end, + set = function(info,value) quickSearchText = value end, + }, + filterType = { + order = 3, + name = L["Filter Type"], + desc = L["Set the filter type. Blacklist will hide any auras in the list and show all others. Whitelist will show any auras in the filter and hide all others."], + type = 'select', + values = { + Whitelist = L["Whitelist"], + Blacklist = L["Blacklist"], + }, + get = function() return E.global.unitframe.aurafilters[selectedFilter].type end, + set = function(info, value) E.global.unitframe.aurafilters[selectedFilter].type = value; UF:Update_AllFrames(); end, + hidden = function() return (selectedFilter == 'Aura Highlight' or selectedFilter == 'AuraBar Colors' or selectedFilter == 'Aura Indicator (Pet)' or selectedFilter == 'Aura Indicator (Profile)' or selectedFilter == 'Aura Indicator (Class)' or selectedFilter == 'Aura Indicator (Global)' or selectedFilter == 'Whitelist' or selectedFilter == 'Blacklist') end, + }, + removeSpell = { + order = 4, + name = L["Remove Spell"], + desc = L["Remove a spell from the filter. Use the spell ID if you see the ID as part of the spell name in the filter."], + type = 'select', + confirm = function(info, value) + local spellName = tonumber(value) and GetSpellInfo(value) + local name = (spellName and format('%s |cFF888888(%s)|r', spellName, value)) or tostring(value) + return 'Remove Spell - '..name + end, + customWidth = 350, + get = function(info) return '' end, + set = function(info, value) + if not value then return end + selectedSpell = nil + + if selectedFilter == 'Aura Highlight' then + E.global.unitframe.AuraHighlightColors[value] = nil; + elseif selectedFilter == 'AuraBar Colors' then + if G.unitframe.AuraBarColors[value] then + E.global.unitframe.AuraBarColors[value].enable = false; + else + E.global.unitframe.AuraBarColors[value] = nil; + end + elseif selectedFilter == 'Aura Indicator (Pet)' or selectedFilter == 'Aura Indicator (Profile)' or selectedFilter == 'Aura Indicator (Class)' or selectedFilter == 'Aura Indicator (Global)' then + local selectedTable, defaultTable = GetSelectedFilters() + + if defaultTable[value] then + selectedTable[value].enabled = false + else + selectedTable[value] = nil + end + elseif G.unitframe.aurafilters[selectedFilter] and G.unitframe.aurafilters[selectedFilter].spells[value] then + E.global.unitframe.aurafilters[selectedFilter].spells[value].enable = false; + else + E.global.unitframe.aurafilters[selectedFilter].spells[value] = nil; + end + + UF:Update_AllFrames(); + end, + values = SetSpellList, + }, + addSpell = { + order = 5, + name = L["Add SpellID"], + desc = L["Add a spell to the filter."], + type = 'input', + customWidth = 200, + get = function(info) return '' end, + set = function(info, value) + value = tonumber(value) + if not value then return end + + local spellName = GetSpellInfo(value) + selectedSpell = (spellName and value) or nil + if not selectedSpell then return end + + if selectedFilter == 'Aura Highlight' then + if not E.global.unitframe.AuraHighlightColors[value] then + E.global.unitframe.AuraHighlightColors[value] = { enable = true, style = 'GLOW', color = {r = 0.8, g = 0, b = 0, a = 0.85} } + end + elseif selectedFilter == 'AuraBar Colors' then + if not E.global.unitframe.AuraBarColors[value] then + E.global.unitframe.AuraBarColors[value] = E:CopyTable({}, auraBarDefaults) + end + elseif selectedFilter == 'Aura Indicator (Pet)' or selectedFilter == 'Aura Indicator (Profile)' or selectedFilter == 'Aura Indicator (Class)' or selectedFilter == 'Aura Indicator (Global)' then + local selectedTable = GetSelectedFilters() + if not selectedTable[value] then + selectedTable[value] = UF:AuraWatch_AddSpell(value, 'TOPRIGHT') + end + elseif not E.global.unitframe.aurafilters[selectedFilter].spells[value] then + E.global.unitframe.aurafilters[selectedFilter].spells[value] = { enable = true, priority = 0, stackThreshold = 0 } + end + + UF:Update_AllFrames() + end, + }, + }, + }, + buffIndicator = { + type = 'group', + name = function() + local spell = GetSelectedSpell() + local spellName = spell and GetSpellInfo(spell) + return (spellName and spellName..' |cFF888888('..spell..')|r') or spell or ' ' + end, + hidden = function() return not selectedSpell or (selectedFilter ~= 'Aura Indicator (Pet)' and selectedFilter ~= 'Aura Indicator (Profile)' and selectedFilter ~= 'Aura Indicator (Class)' and selectedFilter ~= 'Aura Indicator (Global)') end, + get = function(info) + local spell = GetSelectedSpell() + if not spell then return end + + local selectedTable = GetSelectedFilters() + return selectedTable[spell][info[#info]] + end, + set = function(info, value) + local spell = GetSelectedSpell() + if not spell then return end + + local selectedTable = GetSelectedFilters() + selectedTable[spell][info[#info]] = value; + UF:Update_AllFrames() + end, + order = -10, + inline = true, + args = { + enabled = { + name = L["Enable"], + order = 1, + type = 'toggle', + }, + point = { + name = L["Anchor Point"], + order = 2, + type = 'select', + values = { + TOPLEFT = 'TOPLEFT', + LEFT = 'LEFT', + BOTTOMLEFT = 'BOTTOMLEFT', + RIGHT = 'RIGHT', + TOPRIGHT = 'TOPRIGHT', + BOTTOMRIGHT = 'BOTTOMRIGHT', + CENTER = 'CENTER', + TOP = 'TOP', + BOTTOM = 'BOTTOM', + } + }, + style = { + name = L["Style"], + order = 3, + type = 'select', + values = { + timerOnly = L["Timer Only"], + coloredIcon = L["Colored Icon"], + texturedIcon = L["Textured Icon"], + }, + }, + color = { + name = L["COLOR"], + type = 'color', + order = 4, + get = function(info) + local spell = GetSelectedSpell() + if not spell then return end + local selectedTable = GetSelectedFilters() + local t = selectedTable[spell][info[#info]] + return t.r, t.g, t.b, t.a + end, + set = function(info, r, g, b) + local spell = GetSelectedSpell() + if not spell then return end + local selectedTable = GetSelectedFilters() + local t = selectedTable[spell][info[#info]] + t.r, t.g, t.b = r, g, b + + UF:Update_AllFrames() + end, + disabled = function() + local spell = GetSelectedSpell() + if not spell then return end + local selectedTable = GetSelectedFilters() + return selectedTable[spell].style == 'texturedIcon' + end, + }, + sizeOffset = { + order = 5, + type = 'range', + name = L["Size Offset"], + desc = L["This changes the size of the Aura Icon by this value."], + min = -25, max = 25, step = 1, + }, + xOffset = { + order = 6, + type = 'range', + name = L["X-Offset"], + min = -75, max = 75, step = 1, + }, + yOffset = { + order = 7, + type = 'range', + name = L["Y-Offset"], + min = -75, max = 75, step = 1, + }, + textThreshold = { + name = L["Text Threshold"], + desc = L["At what point should the text be displayed. Set to -1 to disable."], + type = 'range', + order = 8, + min = -1, max = 60, step = 1, + }, + anyUnit = { + name = L["Show Aura From Other Players"], + order = 9, + customWidth = 205, + type = 'toggle', + }, + onlyShowMissing = { + name = L["Show When Not Active"], + order = 10, + type = 'toggle', + }, + displayText = { + name = L["Display Text"], + type = 'toggle', + order = 11, + get = function(info) + local spell = GetSelectedSpell() + if not spell then return end + + local selectedTable = GetSelectedFilters() + return (selectedTable[spell].style == 'timerOnly') or selectedTable[spell][info[#info]] + end, + disabled = function() + local spell = GetSelectedSpell() + if not spell then return end + local selectedTable = GetSelectedFilters() + return selectedTable[spell].style == 'timerOnly' + end + }, + }, + }, + spellGroup = { + type = 'group', + name = function() + local spell = GetSelectedSpell() + local spellName = spell and GetSpellInfo(spell) + return (spellName and spellName..' |cFF888888('..spell..')|r') or spell or ' ' + end, + hidden = function() return not selectedSpell or (selectedFilter == 'Aura Indicator (Pet)' or selectedFilter == 'Aura Indicator (Profile)' or selectedFilter == 'Aura Indicator (Class)' or selectedFilter == 'Aura Indicator (Global)') end, + order = -15, + inline = true, + args = { + enabled = { + name = L["Enable"], + order = 0, + type = 'toggle', + hidden = function() return (selectedFilter == 'Aura Indicator (Pet)' or selectedFilter == 'Aura Indicator (Profile)' or selectedFilter == 'Aura Indicator (Class)' or selectedFilter == 'Aura Indicator (Global)') end, + get = function(info) + local spell = GetSelectedSpell() + if not spell then return end + + if selectedFilter == 'Aura Highlight' then + return E.global.unitframe.AuraHighlightColors[spell].enable + elseif selectedFilter == 'AuraBar Colors' then + return E.global.unitframe.AuraBarColors[spell].enable + else + return E.global.unitframe.aurafilters[selectedFilter].spells[spell].enable + end + end, + set = function(info, value) + local spell = GetSelectedSpell() + if not spell then return end + + if selectedFilter == 'Aura Highlight' then + E.global.unitframe.AuraHighlightColors[spell].enable = value + elseif selectedFilter == 'AuraBar Colors' then + E.global.unitframe.AuraBarColors[spell].enable = value + else + E.global.unitframe.aurafilters[selectedFilter].spells[spell].enable = value + end + + UF:Update_AllFrames(); + end, + }, + style = { + name = L["Style"], + type = 'select', + order = 1, + values = { GLOW = L["Glow"], FILL = L["Fill"] }, + hidden = function() return selectedFilter ~= 'Aura Highlight' end, + get = function(info) + local spell = GetSelectedSpell() + if not spell then return end + + return E.global.unitframe.AuraHighlightColors[spell].style + end, + set = function(info, value) + local spell = GetSelectedSpell() + if not spell then return end + + E.global.unitframe.AuraHighlightColors[spell].style = value + UF:Update_AllFrames() + end, + }, + color = { + name = L["COLOR"], + type = 'color', + order = 2, + hasAlpha = function() return selectedFilter ~= 'AuraBar Colors' end, + hidden = function() return (selectedFilter ~= 'Aura Highlight' and selectedFilter ~= 'AuraBar Colors' and selectedFilter ~= 'Aura Indicator (Pet)' and selectedFilter ~= 'Aura Indicator (Profile)' and selectedFilter ~= 'Aura Indicator (Class)' and selectedFilter ~= 'Aura Indicator (Global)') end, + get = function(info) + local spell = GetSelectedSpell() + if not spell then return end + + local t + if selectedFilter == 'Aura Highlight' then + t = E.global.unitframe.AuraHighlightColors[spell].color + elseif selectedFilter == 'AuraBar Colors' then + t = E.global.unitframe.AuraBarColors[spell].color + end + + if t then + return t.r, t.g, t.b, t.a + end + end, + set = function(info, r, g, b, a) + local spell = GetSelectedSpell() + if not spell then return end + + local t + if selectedFilter == 'Aura Highlight' then + t = E.global.unitframe.AuraHighlightColors[spell].color + elseif selectedFilter == 'AuraBar Colors' then + t = E.global.unitframe.AuraBarColors[spell].color + end + + if t then + t.r, t.g, t.b, t.a = r, g, b, a + UF:Update_AllFrames() + end + end, + }, + removeColor = { + type = 'execute', + order = 3, + name = L["Restore Defaults"], + hidden = function() return selectedFilter ~= 'AuraBar Colors' end, + func = function(info) + local spell = GetSelectedSpell() + if not spell then return end + + if G.unitframe.AuraBarColors[spell] then + E.global.unitframe.AuraBarColors[spell] = E:CopyTable({}, G.unitframe.AuraBarColors[spell]) + else + E.global.unitframe.AuraBarColors[spell] = E:CopyTable({}, auraBarDefaults) + end + + UF:Update_AllFrames(); + end, + }, + forDebuffIndicator = { + order = 4, + type = 'group', + name = L["Used as RaidDebuff Indicator"], + inline = true, + hidden = function() return (selectedFilter == 'Aura Highlight' or selectedFilter == 'AuraBar Colors' or selectedFilter == 'Aura Indicator (Pet)' or selectedFilter == 'Aura Indicator (Profile)' or selectedFilter == 'Aura Indicator (Class)' or selectedFilter == 'Aura Indicator (Global)') end, + args = { + priority = { + order = 1, + type = 'range', + name = L["Priority"], + desc = L["Set the priority order of the spell, please note that prioritys are only used for the raid debuff module, not the standard buff/debuff module. If you want to disable set to zero."], + min = 0, max = 99, step = 1, + get = function() + local spell = GetSelectedSpell() + if not spell then + return 0 + else + return E.global.unitframe.aurafilters[selectedFilter].spells[spell].priority + end + end, + set = function(info, value) + local spell = GetSelectedSpell() + if not spell then return end + + E.global.unitframe.aurafilters[selectedFilter].spells[spell].priority = value; + UF:Update_AllFrames(); + end, + }, + stackThreshold = { + order = 2, + type = 'range', + name = L["Stack Threshold"], + desc = L["The debuff needs to reach this amount of stacks before it is shown. Set to 0 to always show the debuff."], + min = 0, max = 99, step = 1, + get = function() + local spell = GetSelectedSpell() + if not spell then + return 0 + else + return E.global.unitframe.aurafilters[selectedFilter].spells[spell].stackThreshold + end + end, + set = function(info, value) + local spell = GetSelectedSpell() + if not spell then return end + + E.global.unitframe.aurafilters[selectedFilter].spells[spell].stackThreshold = value + UF:Update_AllFrames() + end, + }, + }, + }, + }, + } + }, + }, + } +} + +E.Options.args.filters.args.help = ACH:Group('Help', nil, 2) + +local COLOR = E:ClassColor(E.myclass, true) +local COLOR1 = format('|c%s', COLOR.colorStr) +local COLOR2 = '|cFFFFFFFF' + +local FilterHelp = { + '*Whitelists:|r ^Personal, nonPersonal, Boss, CastByUnit, notCastByUnit, Dispellable (includes steal-able), CastByNPC, CastByPlayers|r', + '*Blacklists:|r ^blockNonPersonal, blockNoDuration, blockCastByPlayers | A blacklist filter is only effective against filters that come after it in the priority list. It will not block anything from the filters before it.|r', + '^A blacklist filter is only effective against filters that come after it in the priority list. It will not block anything from the filters before it.', + ' ', + '*Boss:|r ^Auras (debuffs only?) cast by a boss unit.|r', + '*Personal:|r ^Auras cast by yourself.|r', + '*nonPersonal:|r ^Auras cast by anyone other than yourself.|r', + '*CastByUnit:|r ^Auras cast by the unit of the unitframe or nameplate (so on target frame it only shows auras cast by the target unit).|r', + '*notCastByUnit:|r ^Auras cast by anyone other than the unit of the unitframe or nameplate.|r', + '*Dispellable:|r ^Auras you can either dispel or spellsteal.|r', + '*CastByNPC:|r ^Auras cast by any NPC.|r', + '*CastByPlayers:|r ^Auras cast by any player-controlled unit (so no NPCs).|r', + '*blockCastByPlayers:|r ^Blocks any aura that is cast by player-controlled units (so will only show auras cast by NPCs).|r', + '*blockNoDuration:|r ^Blocks any aura without a duration.|r', + '*blockNonPersonal:|r ^Blocks any aura that is not cast by yourself.|r', + ' ', + '*Show Everything:|r ^Set "Max Duration" to 0 & Leave Priority List Empty or (1) Personal | (2) nonPersonal', + '*Block Blacklisted Auras, Show Everything Else:|r ^(1) Blacklist| (2) Personal | (3) nonPersonal', + '*Block Auras Without Duration, Show Everything Else:|r ^(1) blockNoDuration | (2) Personal | (3) nonPersonal', + '*Block Auras Without Duration, Block Blacklisted Auras, Show Everything Else:|r ^(1) blockNoDuration | (2) Blacklist | (3) Personal | (4) nonPersonal', + '*Block Everything, Except Your Own Auras:|r ^(1) Personal', + '*Block Everything, Except Whitelisted Auras:|r ^(1) Whitelist', + '*Block Everything, Except Whitelisted Auras That Are Cast By Yourself:|r ^(1) blockNonPersonal | (2) Whitelist' +} + +for i, text in ipairs(FilterHelp) do + E.Options.args.filters.args.help.args['help'..i] = ACH:Description(text:gsub('*', COLOR1):gsub('%^', COLOR2), i, 'medium') +end + +function E:SetToFilterConfig(filter) + selectedSpell = nil + quickSearchText = '' + selectedFilter = filter or '' + E.Libs.AceConfigDialog:SelectGroup('ElvUI', 'filters') +end diff --git a/General.lua b/General.lua new file mode 100644 index 0000000..4a9fd96 --- /dev/null +++ b/General.lua @@ -0,0 +1,971 @@ +local E, _, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB +local C, L = unpack(select(2, ...)) +local Misc = E:GetModule('Misc') +local Layout = E:GetModule('Layout') +local Totems = E:GetModule('Totems') +local Blizzard = E:GetModule('Blizzard') +local NP = E:GetModule('NamePlates') +local UF = E:GetModule('UnitFrames') +local AFK = E:GetModule('AFK') +local ACH = E.Libs.ACH + +local _G = _G +local IsAddOnLoaded = IsAddOnLoaded +local IsMouseButtonDown = IsMouseButtonDown +local FCF_GetNumActiveChatFrames = FCF_GetNumActiveChatFrames + +local function GetChatWindowInfo() + local ChatTabInfo = {} + for i = 1, FCF_GetNumActiveChatFrames() do + ChatTabInfo['ChatFrame'..i] = _G['ChatFrame'..i..'Tab']:GetText() + end + return ChatTabInfo +end + +E.Options.args.general = { + type = 'group', + name = L["General"], + order = 1, + childGroups = 'tab', + get = function(info) return E.db.general[info[#info]] end, + set = function(info, value) E.db.general[info[#info]] = value end, + args = { + general = { + order = 5, + type = 'group', + name = L["General"], + args = { + loginmessage = { + order = 4, + type = 'toggle', + name = L["Login Message"], + }, + taintLog = { + order = 5, + type = 'toggle', + name = L["Log Taints"], + desc = L["Send ADDON_ACTION_BLOCKED errors to the Lua Error frame. These errors are less important in most cases and will not effect your game performance. Also a lot of these errors cannot be fixed. Please only report these errors if you notice a Defect in gameplay."], + }, + bottomPanel = { + order = 6, + type = 'toggle', + name = L["Bottom Panel"], + desc = L["Display a panel across the bottom of the screen. This is for cosmetic only."], + set = function(info, value) E.db.general.bottomPanel = value; Layout:BottomPanelVisibility() end + }, + topPanel = { + order = 7, + type = 'toggle', + name = L["Top Panel"], + desc = L["Display a panel across the top of the screen. This is for cosmetic only."], + set = function(info, value) E.db.general.topPanel = value; Layout:TopPanelVisibility() end + }, + afk = { + order = 8, + type = 'toggle', + name = L["AFK Mode"], + desc = L["When you go AFK display the AFK screen."], + set = function(info, value) E.db.general.afk = value; AFK:Toggle() end + }, + eyefinity = { + order = 9, + name = L["Multi-Monitor Support"], + desc = L["Attempt to support eyefinity/nvidia surround."], + type = 'toggle', + get = function(info) return E.global.general.eyefinity end, + set = function(info, value) E.global.general.eyefinity = value; E:StaticPopup_Show('GLOBAL_RL') end, + }, + ultrawide = { + order = 10, + name = L["Ultrawide Support"], + desc = L["Attempts to center UI elements in a 16:9 format for ultrawide monitors"], + type = 'toggle', + get = function(info) return E.global.general.ultrawide end, + set = function(info, value) E.global.general.ultrawide = value; E:StaticPopup_Show('GLOBAL_RL') end, + }, + autoAcceptInvite = { + order = 11, + name = L["Accept Invites"], + desc = L["Automatically accept invites from guild/friends."], + type = 'toggle', + }, + autoRoll = { + order = 12, + name = L["Auto Greed/DE"], + desc = L["Automatically select greed or disenchant (when available) on green quality items. This will only work if you are the max level."], + type = 'toggle', + disabled = function() return not E.private.general.lootRoll end + }, + autoTrackReputation = { + order = 13, + name = L["Auto Track Reputation"], + type = 'toggle', + }, + spacer1 = ACH:Spacer(15, 'full'), + locale = { + order = 16, + type = 'select', + name = L["LANGUAGE"], + get = function(info) return E.global.general.locale end, + set = function(info, value) + E.global.general.locale = value + E:StaticPopup_Show('CONFIG_RL') + end, + values = { + deDE = 'Deutsch', + enUS = 'English', + esMX = 'Español', + frFR = 'Français', + ptBR = 'Português', + ruRU = 'Русский', + zhCN = '简体中文', + zhTW = '正體中文', + koKR = '한국어', + itIT = 'Italiano', + }, + }, + messageRedirect = { + order = 17, + name = L["Chat Output"], + desc = L["This selects the Chat Frame to use as the output of ElvUI messages."], + type = 'select', + values = GetChatWindowInfo() + }, + numberPrefixStyle = { + order = 18, + type = 'select', + name = L["Unit Prefix Style"], + desc = L["The unit prefixes you want to use when values are shortened in ElvUI. This is mostly used on UnitFrames."], + set = function(info, value) + E.db.general.numberPrefixStyle = value + E:BuildPrefixValues() + E:StaticPopup_Show('CONFIG_RL') + end, + values = { + TCHINESE = '萬, 億', + CHINESE = '万, 亿', + ENGLISH = 'K, M, B', + GERMAN = 'Tsd, Mio, Mrd', + KOREAN = '천, 만, 억', + METRIC = 'k, M, G' + }, + }, + interruptAnnounce = { + order = 19, + name = L["Announce Interrupts"], + desc = L["Announce when you interrupt a spell to the specified chat channel."], + type = 'select', + values = { + NONE = L["NONE"], + SAY = L["SAY"], + YELL = L["YELL"], + PARTY = L["Party Only"], + RAID = L["Party / Raid"], + RAID_ONLY = L["Raid Only"], + EMOTE = L["CHAT_MSG_EMOTE"], + }, + set = function(info, value) + E.db.general[info[#info]] = value + if value == 'NONE' then + Misc:UnregisterEvent('COMBAT_LOG_EVENT_UNFILTERED') + else + Misc:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED') + end + end, + }, + autoRepair = { + order = 20, + name = L["Auto Repair"], + desc = L["Automatically repair using the following method when visiting a merchant."], + type = 'select', + values = { + NONE = L["NONE"], + GUILD = L["GUILD"], + PLAYER = L["PLAYER"], + }, + }, + spacer2 = ACH:Spacer(25, 'full'), + decimalLength = { + order = 26, + type = 'range', + name = L["Decimal Length"], + desc = L["Controls the amount of decimals used in values displayed on elements like NamePlates and UnitFrames."], + min = 0, max = 4, step = 1, + set = function(info, value) + E.db.general.decimalLength = value + E:BuildPrefixValues() + E:StaticPopup_Show('CONFIG_RL') + end, + }, + smoothingAmount = { + order = 27, + type = 'range', + isPercent = true, + name = L["Smoothing Amount"], + desc = L["Controls the speed at which smoothed bars will be updated."], + min = 0.2, max = 0.8, softMax = 0.75, softMin = 0.25, step = 0.01, + set = function(info, value) + E.db.general.smoothingAmount = value + E:SetSmoothingAmount(value) + end, + }, + UIScale = { + order = 28, + type = 'range', + name = L["UI_SCALE"], + min = 0.1, max = 1.25, step = 0.000000000000001, + softMin = 0.40, softMax = 1.15, bigStep = 0.01, + get = function(info) return E.global.general.UIScale end, + set = function(info, value) + E.global.general.UIScale = value + if not IsMouseButtonDown() then + E:PixelScaleChanged() + end + end + }, + AutoScale = { + order = 29, + type = 'execute', + name = L["Auto Scale"], + func = function() + E.global.general.UIScale = E:PixelBestSize() + E:PixelScaleChanged() + end, + }, + totems = { + order = 55, + type = 'group', + inline = true, + name = L["Class Totems"], + get = function(info) return E.db.general.totems[info[#info]] end, + set = function(info, value) E.db.general.totems[info[#info]] = value; Totems:PositionAndSize() end, + args = { + enable = { + order = 2, + type = 'toggle', + name = L["Enable"], + get = function() return E.private.general.totemBar end, + set = function(_, value) E.private.general.totemBar = value; E:StaticPopup_Show('PRIVATE_RL') end, + }, + size = { + order = 3, + type = 'range', + name = L["Button Size"], + min = 24, max = 60, step = 1, + disabled = function() return not E.private.general.totemBar end, + }, + spacing = { + order = 4, + type = 'range', + name = L["Button Spacing"], + min = 1, max = 10, step = 1, + disabled = function() return not E.private.general.totemBar end, + }, + sortDirection = { + order = 5, + type = 'select', + name = L["Sort Direction"], + disabled = function() return not E.private.general.totemBar end, + values = { + ASCENDING = L["Ascending"], + DESCENDING = L["Descending"], + }, + }, + growthDirection = { + order = 6, + type = 'select', + name = L["Bar Direction"], + disabled = function() return not E.private.general.totemBar end, + values = { + VERTICAL = L["Vertical"], + HORIZONTAL = L["Horizontal"], + }, + }, + }, + }, + }, + }, + media = { + order = 10, + type = 'group', + name = L["Media"], + get = function(info) return E.db.general[info[#info]] end, + set = function(info, value) E.db.general[info[#info]] = value end, + args = { + fontGroup = { + order = 50, + name = L["Font"], + type = 'group', + inline = true, + args = { + main = { + order = 1, + type = 'group', + name = ' ', + args = { + font = { + type = 'select', dialogControl = 'LSM30_Font', + order = 1, + name = L["Default Font"], + desc = L["The font that the core of the UI will use."], + values = AceGUIWidgetLSMlists.font, + set = function(info, value) E.db.general[info[#info]] = value; E:UpdateMedia(); E:UpdateFontTemplates(); end, + }, + fontSize = { + order = 2, + name = L["FONT_SIZE"], + desc = L["Set the font size for everything in UI. Note: This doesn't effect somethings that have their own seperate options (UnitFrame Font, Datatext Font, ect..)"], + type = 'range', + min = 6, max = 64, step = 1, + softMin = 8, softMax = 32, + set = function(info, value) E.db.general[info[#info]] = value; E:UpdateMedia(); E:UpdateFontTemplates(); end, + }, + fontStyle = { + type = 'select', + order = 3, + name = L["Font Outline"], + values = C.Values.FontFlags, + set = function(info, value) E.db.general[info[#info]] = value; E:UpdateMedia(); E:UpdateFontTemplates(); end, + }, + applyFontToAll = { + order = 4, + type = 'execute', + name = L["Apply Font To All"], + desc = L["Applies the font and font size settings throughout the entire user interface. Note: Some font size settings will be skipped due to them having a smaller font size by default."], + func = function() E:StaticPopup_Show('APPLY_FONT_WARNING'); end, + }, + replaceBlizzFonts = { + order = 5, + type = 'toggle', + name = L["Replace Blizzard Fonts"], + desc = L["Replaces the default Blizzard fonts on various panels and frames with the fonts chosen in the Media section of the ElvUI Options. NOTE: Any font that inherits from the fonts ElvUI usually replaces will be affected as well if you disable this. Enabled by default."], + get = function(info) return E.private.general[info[#info]] end, + set = function(info, value) E.private.general[info[#info]] = value; E:StaticPopup_Show('PRIVATE_RL'); end, + }, + unifiedBlizzFonts = { + order = 6, + type = 'toggle', + name = L["Unified Font Sizes"], + desc = L["This setting mimics the older style of Replace Blizzard Fonts, with a more static unified font sizing."], + get = function(info) return E.private.general[info[#info]] end, + set = function(info, value) E.private.general[info[#info]] = value; E:UpdateBlizzardFonts() end, + }, + }, + }, + replaceCombatFont = { + order = 6, + type = 'toggle', + name = L["Replace Combat Font"], + get = function(info) return E.private.general[info[#info]] end, + set = function(info, value) E.private.general[info[#info]] = value; E:StaticPopup_Show('PRIVATE_RL'); end, + }, + dmgfont = { + type = 'select', dialogControl = 'LSM30_Font', + order = 7, + name = L["CombatText Font"], + desc = L["The font that combat text will use. |cffFF0000WARNING: This requires a game restart or re-log for this change to take effect.|r"], + disabled = function() return not E.private.general.replaceCombatFont end, + values = AceGUIWidgetLSMlists.font, + get = function(info) return E.private.general[info[#info]] end, + set = function(info, value) E.private.general[info[#info]] = value; E:UpdateMedia(); E:UpdateFontTemplates(); E:StaticPopup_Show('PRIVATE_RL'); end, + }, + replaceNameFont = { + order = 8, + type = 'toggle', + name = L["Replace Name Font"], + get = function(info) return E.private.general[info[#info]] end, + set = function(info, value) E.private.general[info[#info]] = value; E:StaticPopup_Show('PRIVATE_RL'); end, + }, + namefont = { + type = 'select', dialogControl = 'LSM30_Font', + order = 9, + name = L["Name Font"], + desc = L["The font that appears on the text above players heads. |cffFF0000WARNING: This requires a game restart or re-log for this change to take effect.|r"], + disabled = function() return not E.private.general.replaceNameFont end, + values = AceGUIWidgetLSMlists.font, + get = function(info) return E.private.general[info[#info]] end, + set = function(info, value) E.private.general[info[#info]] = value; E:UpdateMedia(); E:UpdateFontTemplates(); E:StaticPopup_Show('PRIVATE_RL'); end, + }, + }, + }, + textureGroup = { + order = 51, + name = L["Textures"], + type = 'group', + inline = true, + get = function(info) return E.private.general[info[#info]] end, + args = { + normTex = { + type = 'select', dialogControl = 'LSM30_Statusbar', + order = 1, + name = L["Primary Texture"], + desc = L["The texture that will be used mainly for statusbars."], + values = AceGUIWidgetLSMlists.statusbar, + set = function(info, value) + E.private.general[info[#info]] = value; + E:UpdateMedia() + E:UpdateStatusBars() + end + }, + glossTex = { + type = 'select', dialogControl = 'LSM30_Statusbar', + order = 2, + name = L["Secondary Texture"], + desc = L["This texture will get used on objects like chat windows and dropdown menus."], + values = AceGUIWidgetLSMlists.statusbar, + set = function(info, value) + E.private.general[info[#info]] = value; + E:UpdateMedia() + E:UpdateFrameTemplates() + end + }, + applyTextureToAll = { + order = 3, + type = 'execute', + name = L["Copy Primary Texture"], + desc = L["Replaces the StatusBar texture setting on Unitframes and Nameplates with the primary texture."], + func = function() + E.db.unitframe.statusbar = E.private.general.normTex + UF:Update_StatusBars() + + E.db.nameplates.statusbar = E.private.general.normTex + NP:ConfigureAll() + end, + }, + }, + }, + bordersGroup = { + order = 52, + name = L["Borders"], + type = 'group', + inline = true, + args = { + uiThinBorders = { + order = 1, + name = L["Thin Borders"], + desc = L["The Thin Border Theme option will change the overall apperance of your UI. Using Thin Border Theme is a slight performance increase over the traditional layout."], + type = 'toggle', + get = function(info) return E.private.general.pixelPerfect end, + set = function(info, value) + E.private.general.pixelPerfect = value + E:StaticPopup_Show('PRIVATE_RL') + end + }, + ufThinBorders = { + order = 2, + name = L["Unitframe Thin Borders"], + desc = L["Use thin borders on certain unitframe elements."], + type = 'toggle', + get = function(info) return E.db.unitframe.thinBorders end, + set = function(info, value) + E.db.unitframe.thinBorders = value + E:StaticPopup_Show('CONFIG_RL') + end, + }, + npThinBorders = { + order = 2, + name = L["Nameplate Thin Borders"], + desc = L["Use thin borders on certain nameplate elements."], + type = 'toggle', + get = function(info) return E.db.nameplates.thinBorders end, + set = function(info, value) + E.db.nameplates.thinBorders = value + E:StaticPopup_Show('CONFIG_RL') + end, + }, + cropIcon = { + order = 3, + type = 'toggle', + tristate = true, + name = L["Crop Icons"], + desc = L["This is for Customized Icons in your Interface/Icons folder."], + get = function(info) + local value = E.db.general[info[#info]] + if value == 2 then return true + elseif value == 1 then return nil + else return false end + end, + set = function(info, value) + E.db.general[info[#info]] = (value and 2) or (value == nil and 1) or 0 + E:StaticPopup_Show('PRIVATE_RL') + end, + }, + } + }, + colorsGroup = { + order = 52, + name = L["Colors"], + type = 'group', + inline = true, + get = function(info) + local t = E.db.general[info[#info]] + local d = P.general[info[#info]] + return t.r, t.g, t.b, t.a, d.r, d.g, d.b, d.a + end, + set = function(info, r, g, b, a) + local setting = info[#info] + local t = E.db.general[setting] + t.r, t.g, t.b, t.a = r, g, b, a + E:UpdateMedia() + if setting == 'bordercolor' then + E:UpdateBorderColors() + elseif setting == 'backdropcolor' or setting == 'backdropfadecolor' then + E:UpdateBackdropColors() + end + end, + args = { + backdropcolor = { + type = 'color', + order = 1, + name = L["Backdrop Color"], + desc = L["Main backdrop color of the UI."], + hasAlpha = false, + }, + backdropfadecolor = { + type = 'color', + order = 2, + name = L["Backdrop Faded Color"], + desc = L["Backdrop color of transparent frames"], + hasAlpha = true, + }, + valuecolor = { + type = 'color', + order = 3, + name = L["Value Color"], + desc = L["Color some texts use."], + hasAlpha = false, + }, + spacer1 = ACH:Spacer(9, 'full'), + uiBorderColors = { + type = 'color', + order = 10, + name = L["Border Color"], + desc = L["Main border color of the UI."], + get = function(info) + local t = E.db.general.bordercolor + local d = P.general.bordercolor + return t.r, t.g, t.b, t.a, d.r, d.g, d.b, d.a + end, + set = function(info, r, g, b, a) + local t = E.db.general.bordercolor + t.r, t.g, t.b, t.a = r, g, b, a + E:UpdateMedia() + E:UpdateBorderColors() + end, + }, + ufBorderColors = { + order = 11, + type = 'color', + name = L["Unitframes Border Color"], + get = function(info) + local t = E.db.unitframe.colors.borderColor + local d = P.unitframe.colors.borderColor + return t.r, t.g, t.b, t.a, d.r, d.g, d.b, d.a + end, + set = function(info, r, g, b, a) + local t = E.db.unitframe.colors.borderColor + t.r, t.g, t.b, t.a = r, g, b, a + E:UpdateMedia() + E:UpdateBorderColors() + end, + }, + }, + }, + } + }, + alternativePowerGroup = { + order = 15, + type = 'group', + name = L["Alternative Power"], + get = function(info) return E.db.general.altPowerBar[info[#info]] end, + set = function(info, value) + E.db.general.altPowerBar[info[#info]] = value; + Blizzard:UpdateAltPowerBarSettings(); + end, + args = { + enable = { + order = 2, + type = 'toggle', + name = L["Enable"], + desc = L["Replace Blizzard's Alternative Power Bar"], + width = 'full', + set = function(info, value) + E.db.general.altPowerBar[info[#info]] = value; + E:StaticPopup_Show('PRIVATE_RL'); + end, + }, + width = { + order = 3, + type = 'range', + name = L["Width"], + min = 50, max = 1000, step = 1, + }, + height = { + order = 4, + type = 'range', + name = L["Height"], + min = 5, max = 100, step = 1, + }, + statusBarGroup = { + order = 5, + name = L["Status Bar"], + type = 'group', + inline = true, + set = function(info, value) + E.db.general.altPowerBar[info[#info]] = value; + Blizzard:UpdateAltPowerBarColors(); + end, + get = function(info) + return E.db.general.altPowerBar[info[#info]] + end, + args = { + smoothbars = { + type = 'toggle', + order = 1, + name = L["Smooth Bars"], + desc = L["Bars will transition smoothly."], + }, + statusBar = { + order = 2, + type = 'select', dialogControl = 'LSM30_Statusbar', + name = L["StatusBar Texture"], + values = AceGUIWidgetLSMlists.statusbar, + }, + statusBarColorGradient = { + order = 3, + name = L["Color Gradient"], + type = 'toggle', + }, + statusBarColor = { + type = 'color', + order = 4, + name = L["COLOR"], + disabled = function() + return E.db.general.altPowerBar.statusBarColorGradient + end, + get = function(info) + local t = E.db.general.altPowerBar[info[#info]] + local d = P.general.altPowerBar[info[#info]] + return t.r, t.g, t.b, t.a, d.r, d.g, d.b + end, + set = function(info, r, g, b) + local t = E.db.general.altPowerBar[info[#info]] + t.r, t.g, t.b = r, g, b + Blizzard:UpdateAltPowerBarColors() + end, + }, + }, + }, + textGroup = { + order = 6, + name = L["Text"], + type = 'group', + inline = true, + set = function(info, value) + E.db.general.altPowerBar[info[#info]] = value; + Blizzard:UpdateAltPowerBarSettings() + end, + get = function(info) + return E.db.general.altPowerBar[info[#info]] + end, + args = { + font = { + type = 'select', dialogControl = 'LSM30_Font', + order = 1, + name = L["Font"], + values = AceGUIWidgetLSMlists.font, + }, + fontSize = { + order = 2, + name = L["FONT_SIZE"], + type = 'range', + min = 6, max = 24, step = 1, + }, + fontOutline = { + order = 3, + type = 'select', + name = L["Font Outline"], + values = C.Values.FontFlags, + }, + textFormat = { + order = 4, + type = 'select', + name = L["Text Format"], + sortByValue = true, + values = { + NONE = L["NONE"], + NAME = L["NAME"], + NAMEPERC = L["Name: Percent"], + NAMECURMAX = L["Name: Current / Max"], + NAMECURMAXPERC = L["Name: Current / Max - Percent"], + PERCENT = L["Percent"], + CURMAX = L["Current / Max"], + CURMAXPERC = L["Current / Max - Percent"], + }, + }, + }, + }, + }, + }, + blizzUIImprovements = { + order = 20, + type = 'group', + name = L["BlizzUI Improvements"], + args = { + loot = { + order = 1, + type = 'toggle', + name = L["Loot"], + desc = L["Enable/Disable the loot frame."], + get = function(info) return E.private.general.loot end, + set = function(info, value) E.private.general.loot = value; E:StaticPopup_Show('PRIVATE_RL') end + }, + lootRoll = { + order = 2, + type = 'toggle', + name = L["Loot Roll"], + desc = L["Enable/Disable the loot roll frame."], + get = function(info) return E.private.general.lootRoll end, + set = function(info, value) E.private.general.lootRoll = value; E:StaticPopup_Show('PRIVATE_RL') end + }, + hideErrorFrame = { + order = 3, + name = L["Hide Error Text"], + desc = L["Hides the red error text at the top of the screen while in combat."], + type = 'toggle' + }, + enhancedPvpMessages = { + order = 4, + type = 'toggle', + name = L["Enhanced PVP Messages"], + desc = L["Display battleground messages in the middle of the screen."], + }, + showMissingTalentAlert = { + order = 5, + type = 'toggle', + name = L["Missing Talent Alert"], + desc = L["Show an alert frame if you have unspend talent points."], + get = function(info) return E.global.general.showMissingTalentAlert end, + set = function(info, value) E.global.general.showMissingTalentAlert = value; E:StaticPopup_Show('GLOBAL_RL') end, + }, + raidUtility = { + order = 6, + type = 'toggle', + name = L["RAID_CONTROL"], + desc = L["Enables the ElvUI Raid Control panel."], + get = function(info) return E.private.general.raidUtility end, + set = function(info, value) E.private.general.raidUtility = value; E:StaticPopup_Show('PRIVATE_RL') end + }, + voiceOverlay = { + order = 7, + type = 'toggle', + name = L["Voice Overlay"], + desc = L["Replace Blizzard's Voice Overlay."], + get = function(info) return E.private.general.voiceOverlay end, + set = function(info, value) E.private.general.voiceOverlay = value; E:StaticPopup_Show('PRIVATE_RL') end + }, + disableTutorialButtons = { + order = 8, + type = 'toggle', + name = L["Disable Tutorial Buttons"], + desc = L["Disables the tutorial button found on some frames."], + get = function(info) return E.global.general.disableTutorialButtons end, + set = function(info, value) E.global.general.disableTutorialButtons = value; E:StaticPopup_Show('GLOBAL_RL') end, + }, + resurrectSound = { + order = 9, + type = 'toggle', + name = L["Resurrect Sound"], + desc = L["Enable to hear sound if you receive a resurrect."], + }, + vehicleSeatIndicatorSize = { + order = 10, + type = 'range', + name = L["Vehicle Seat Indicator Size"], + min = 64, max = 128, step = 4, + get = function(info) return E.db.general.vehicleSeatIndicatorSize end, + set = function(info, value) E.db.general.vehicleSeatIndicatorSize = value; Blizzard:UpdateVehicleFrame() end, + }, + durabilityScale = { + order = 11, + type = 'range', + name = L["Durability Scale"], + min = 0.5, max = 8, step = 0.5, + get = function(info) return E.db.general.durabilityScale end, + set = function(info, value) E.db.general.durabilityScale = value; Blizzard:UpdateDurabilityScale() end, + }, + commandBarSetting = { + order = 12, + type = 'select', + name = L["Order Hall Command Bar"], + get = function(info) return E.global.general.commandBarSetting end, + set = function(info, value) E.global.general.commandBarSetting = value; E:StaticPopup_Show('GLOBAL_RL') end, + width = 'normal', + values = { + DISABLED = L["Disable"], + ENABLED = L["Enable"], + ENABLED_RESIZEPARENT = L["Enable + Adjust Movers"], + }, + }, + questRewardMostValueIcon = { + order = 13, + type = 'toggle', + name = L["Mark Quest Reward"], + desc = L["Marks the most valuable quest reward with a gold coin."], + }, + itemLevelInfo = { + order = 14, + name = L["Item Level"], + type = 'group', + inline = true, + get = function(info) return E.db.general.itemLevel[info[#info]] end, + args = { + displayCharacterInfo = { + order = 1, + type = 'toggle', + name = L["Display Character Info"], + desc = L["Shows item level of each item, enchants, and gems on the character page."], + set = function(info, value) + E.db.general.itemLevel.displayCharacterInfo = value; + Misc:ToggleItemLevelInfo() + end + }, + displayInspectInfo = { + order = 2, + type = 'toggle', + name = L["Display Inspect Info"], + desc = L["Shows item level of each item, enchants, and gems when inspecting another player."], + set = function(info, value) + E.db.general.itemLevel.displayInspectInfo = value; + Misc:ToggleItemLevelInfo() + end + }, + fontGroup = { + order = 3, + type = 'group', + name = L["Fonts"], + disabled = function() return not E.db.general.itemLevel.displayCharacterInfo and not E.db.general.itemLevel.displayInspectInfo end, + get = function(info) return E.db.general.itemLevel[info[#info]] end, + set = function(info, value) + E.db.general.itemLevel[info[#info]] = value + Misc:UpdateInspectPageFonts('Character') + Misc:UpdateInspectPageFonts('Inspect') + end, + args = { + itemLevelFont = { + order = 1, + type = 'select', + name = L["Font"], + dialogControl = 'LSM30_Font', + values = AceGUIWidgetLSMlists.font, + }, + itemLevelFontSize = { + order = 2, + type = 'range', + name = L["FONT_SIZE"], + min = 4, max = 42, step = 1, + }, + itemLevelFontOutline = { + order = 3, + type = 'select', + name = L["Font Outline"], + values = C.Values.FontFlags, + }, + }, + }, + }, + }, + objectiveFrameGroup = { + order = 15, + type = 'group', + inline = true, + name = L["Objective Frame"], + get = function(info) return E.db.general[info[#info]] end, + args = { + objectiveFrameAutoHide = { + order = 31, + type = 'toggle', + name = L["Auto Hide"], + desc = L["Automatically hide the objective frame during boss or arena fights."], + disabled = function() return IsAddOnLoaded('!KalielsTracker') end, + set = function(info, value) E.db.general.objectiveFrameAutoHide = value; Blizzard:SetObjectiveFrameAutoHide(); end, + }, + objectiveFrameAutoHideInKeystone = { + order = 32, + type = 'toggle', + name = L["Hide In Keystone"], + hidden = function() return not E.db.general.objectiveFrameAutoHide end, + set = function(info, value) E.db.general.objectiveFrameAutoHideInKeystone = value end, + }, + objectiveFrameHeight = { + order = 33, + type = 'range', + name = L["Objective Frame Height"], + desc = L["Height of the objective tracker. Increase size to be able to see more objectives."], + min = 400, max = E.screenheight, step = 1, + set = function(info, value) E.db.general.objectiveFrameHeight = value; Blizzard:SetObjectiveFrameHeight(); end, + }, + bonusObjectivePosition = { + order = 34, + type = 'select', + name = L["Bonus Reward Position"], + desc = L["Position of bonus quest reward frame relative to the objective tracker."], + values = { + RIGHT = L["Right"], + LEFT = L["Left"], + AUTO = L["Automatic"], + }, + }, + }, + }, + chatBubblesGroup = { + order = 16, + type = 'group', + inline = true, + name = L["Chat Bubbles"], + get = function(info) return E.private.general[info[#info]] end, + set = function(info, value) E.private.general[info[#info]] = value; E:StaticPopup_Show('PRIVATE_RL') end, + args = { + chatBubbles = { + order = 2, + type = 'select', + name = L["Chat Bubbles Style"], + desc = L["Skin the blizzard chat bubbles."], + values = { + backdrop = L["Skin Backdrop"], + nobackdrop = L["Remove Backdrop"], + backdrop_noborder = L["Skin Backdrop (No Borders)"], + disabled = L["DISABLE"], + } + }, + chatBubbleFont = { + order = 3, + type = 'select', + name = L["Font"], + dialogControl = 'LSM30_Font', + values = AceGUIWidgetLSMlists.font, + }, + chatBubbleFontSize = { + order = 4, + type = 'range', + name = L["FONT_SIZE"], + min = 6, max = 64, step = 1, + }, + chatBubbleFontOutline = { + order = 5, + type = 'select', + name = L["Font Outline"], + values = C.Values.FontFlags, + }, + chatBubbleName = { + order = 6, + type = 'toggle', + name = L["Chat Bubble Names"], + desc = L["Display the name of the unit on the chat bubble. This will not work if backdrop is disabled or when you are in an instance."], + }, + }, + }, + }, + }, + }, +} diff --git a/Libraries/Ace3/AceConfig-3.0/AceConfig-3.0.lua b/Libraries/Ace3/AceConfig-3.0/AceConfig-3.0.lua new file mode 100644 index 0000000..c5fcfd2 --- /dev/null +++ b/Libraries/Ace3/AceConfig-3.0/AceConfig-3.0.lua @@ -0,0 +1,58 @@ +--- AceConfig-3.0 wrapper library. +-- Provides an API to register an options table with the config registry, +-- as well as associate it with a slash command. +-- @class file +-- @name AceConfig-3.0 +-- @release $Id$ + +--[[ +AceConfig-3.0 + +Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole. + +]] + +local cfgreg = LibStub("AceConfigRegistry-3.0-ElvUI") +local cfgcmd = LibStub("AceConfigCmd-3.0-ElvUI") + +local MAJOR, MINOR = "AceConfig-3.0-ElvUI", 3 +local AceConfig = LibStub:NewLibrary(MAJOR, MINOR) + +if not AceConfig then return end + +--TODO: local cfgdlg = LibStub("AceConfigDialog-3.0", true) +--TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0", true) + +-- Lua APIs +local pcall, error, type, pairs = pcall, error, type, pairs + +-- ------------------------------------------------------------------- +-- :RegisterOptionsTable(appName, options, slashcmd, persist) +-- +-- - appName - (string) application name +-- - options - table or function ref, see AceConfigRegistry +-- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command + +--- Register a option table with the AceConfig registry. +-- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly. +-- @paramsig appName, options [, slashcmd] +-- @param appName The application name for the config table. +-- @param options The option table (or a function to generate one on demand). http://www.wowace.com/addons/ace3/pages/ace-config-3-0-options-tables/ +-- @param slashcmd A slash command to register for the option table, or a table of slash commands. +-- @usage +-- local AceConfig = LibStub("AceConfig-3.0") +-- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"}) +function AceConfig:RegisterOptionsTable(appName, options, slashcmd) + local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options) + if not ok then error(msg, 2) end + + if slashcmd then + if type(slashcmd) == "table" then + for _,cmd in pairs(slashcmd) do + cfgcmd:CreateChatCommand(cmd, appName) + end + else + cfgcmd:CreateChatCommand(slashcmd, appName) + end + end +end diff --git a/Libraries/Ace3/AceConfig-3.0/AceConfig-3.0.xml b/Libraries/Ace3/AceConfig-3.0/AceConfig-3.0.xml new file mode 100644 index 0000000..87972ad --- /dev/null +++ b/Libraries/Ace3/AceConfig-3.0/AceConfig-3.0.xml @@ -0,0 +1,8 @@ + + + + + +