diff --git a/WeakAuras/BuffTrigger2.lua b/WeakAuras/BuffTrigger2.lua index 2675297..1f4448e 100644 --- a/WeakAuras/BuffTrigger2.lua +++ b/WeakAuras/BuffTrigger2.lua @@ -2622,52 +2622,53 @@ end -- @return string of additional properties function BuffTrigger.GetAdditionalProperties(data, triggernum) local trigger = data.triggers[triggernum].trigger + local props = {} + props["spellId"] = L["Spell ID"] + props["debuffClass"] = L["Debuff Class"] + props["debuffClassIcon"] = L["Debuff Class Icon"] + props["unitCaster"] = L["Caster Unit"] + props["casterName"] = L["Caster Name"] - local ret = {"|cFFFFCC00%".. triggernum .. ".spellId|r - " .. L["Spell ID"] .. "\n"} - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".debuffClass|r - " .. L["Debuff Class"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".debuffClassIcon|r - " .. L["Debuff Class Icon"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".unitCaster|r - " .. L["Caster Unit"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".casterName|r - " .. L["Caster Name"] .. "\n") if trigger.unit ~= "multi" then - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".unit|r - " .. L["Unit"] .. "\n") + props["unit"] = L["Unit"] end - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".unitName|r - " .. L["Unit Name"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".matchCount|r - " .. L["Match Count"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".matchCountPerUnit|r - " .. L["Match Count per Unit"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".unitCount|r - " .. L["Units Affected"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".totalStacks|r - " .. L["Total stacks over all matches"] .. "\n") + props["unitName"] = L["Unit Name"] + props["matchCount"] = L["Match Count"] + props["matchCountPerUnit"] = L["Match Count per Unit"] + props["unitCount"] = L["Units Affected"] + props["totalStacks"] = L["Total stacks over all matches"] if trigger.unit ~= "multi" then - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".maxUnitCount|r - " .. L["Total Units"] .. "\n") + props["maxUnitCount"] = L["Total Units"] end if not IsSingleMissing(trigger) and trigger.unit ~= "multi" and trigger.fetchTooltip then - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".tooltip|r - " .. L["Tooltip"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".tooltip1|r - " .. L["First Value of Tooltip Text"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".tooltip2|r - " .. L["Second Value of Tooltip Text"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".tooltip3|r - " .. L["Third Value of Tooltip Text"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".tooltip4|r - " .. L["Fourth Value of Tooltip Text"] .. "\n") + props["tooltip"] = L["Tooltip"] + props["tooltip1"] = L["First Value of Tooltip Text"] + props["tooltip2"] = L["Second Value of Tooltip Text"] + props["tooltip3"] = L["Third Value of Tooltip Text"] + props["tooltip4"] = L["Fourth Value of Tooltip Text"] end if trigger.unit ~= "multi" then - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".stackGainTime|r - " .. L["Since Stack Gain"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".stackLostTime|r - " .. L["Since Stack Lost"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".initialTime|r - " .. L["Since Apply"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".refreshTime|r - " .. L["Since Apply/Refresh"] .. "\n") + props["stackGainTime"] = L["Since Stack Gain"] + props["stackLostTime"] = L["Since Stack Lost"] + props["initialTime"] = L["Since Apply"] + props["refreshTime"] = L["Since Apply/Refresh"] end if trigger.unit ~= "multi" and trigger.fetchRaidMark then - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".raidMark|r - " .. L["Raid Mark"] .. "\n") + props["raidMark"] = L["Raid Mark"] end if (trigger.unit == "group" or trigger.unit == "raid" or trigger.unit == "party") and trigger.useAffected then - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".affected|r - " .. L["Names of affected Players"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".unaffected|r - " .. L["Names of unaffected Players"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".affectedUnits|r - " .. L["Units of affected Players in a table format"] .. "\n") - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".unaffectedUnits|r - " .. L["Units of unaffected Players in a table format"] .. "\n") + props["affected"] = L["Names of affected Players"] + props["unaffected"] = L["Names of unaffected Players"] + props["affectedUnits"] = L["Units of affected Players in a table format"] + props["unaffectedUnits"] = L["Units of unaffected Players in a table format"] end - return table.concat(ret) + return props end function BuffTrigger.GetProgressSources(data, triggernum, values) diff --git a/WeakAuras/Compatibility.lua b/WeakAuras/Compatibility.lua index f6f24d7..00cdea8 100644 --- a/WeakAuras/Compatibility.lua +++ b/WeakAuras/Compatibility.lua @@ -53,6 +53,12 @@ function TableHasAnyEntries(tbl) return false end +function tAppendAll(table, addedArray) + for i, element in ipairs(addedArray) do + tinsert(table, element); + end +end + function IsInGroup() return GetNumPartyMembers() > 0 or GetNumRaidMembers() > 0 end diff --git a/WeakAuras/GenericTrigger.lua b/WeakAuras/GenericTrigger.lua index c34d7e3..9a153bc 100644 --- a/WeakAuras/GenericTrigger.lua +++ b/WeakAuras/GenericTrigger.lua @@ -3826,7 +3826,7 @@ end function GenericTrigger.GetAdditionalProperties(data, triggernum) local trigger = data.triggers[triggernum].trigger - local ret = {""}; + local props = {} local prototype = GenericTrigger.GetPrototype(trigger) if prototype then for _, v in pairs(prototype.args) do @@ -3838,28 +3838,26 @@ function GenericTrigger.GetAdditionalProperties(data, triggernum) end if (enable and v.store and v.name and v.display and v.conditionType ~= "bool") then - table.insert(ret, "|cFFFFCC00%".. triggernum .. "." .. v.name .. "|r - " .. v.display .. "\n") + props[v.name] = v.display end end if prototype.countEvents then - table.insert(ret, "|cFFFFCC00%".. triggernum .. ".count|r - " .. L["Count"] .. "\n") + props.count = L["Count"] end else if (trigger.custom_type == "stateupdate") then local variables = GenericTrigger.GetTsuConditionVariables(data.id, triggernum) if (type(variables) == "table") then for var, varData in pairs(variables) do - if (type(varData) == "table") then - if varData.display then - table.insert(ret, "|cFFFFCC00%".. triggernum .. "." .. var .. "|r - " .. varData.display .. "\n") - end + if (type(varData) == "table") and varData.display then + props[var] = varData.display end end end end end - return table.concat(ret); + return props; end function GenericTrigger.GetProgressSources(data, triggernum, values) diff --git a/WeakAuras/Media/Textures/Options.blp b/WeakAuras/Media/Textures/Options.blp new file mode 100644 index 0000000..5cb5011 Binary files /dev/null and b/WeakAuras/Media/Textures/Options.blp differ diff --git a/WeakAuras/Media/Textures/sidebar.tga b/WeakAuras/Media/Textures/sidebar.tga new file mode 100644 index 0000000..d21af2d Binary files /dev/null and b/WeakAuras/Media/Textures/sidebar.tga differ diff --git a/WeakAuras/WeakAuras.lua b/WeakAuras/WeakAuras.lua index 7b60518..03c2366 100644 --- a/WeakAuras/WeakAuras.lua +++ b/WeakAuras/WeakAuras.lua @@ -3390,27 +3390,17 @@ Private.GetTriggerDescription = wrapTriggerSystemFunction("GetTriggerDescription local wrappedGetOverlayInfo = wrapTriggerSystemFunction("GetOverlayInfo", "table"); Private.GetAdditionalProperties = function(data) - local additionalProperties = "" + local props = {} for i = 1, #data.triggers do local triggerSystem = GetTriggerSystem(data, i); if (triggerSystem) then - local add = triggerSystem.GetAdditionalProperties(data, i) - if (add and add ~= "") then - if additionalProperties ~= "" then - additionalProperties = additionalProperties .. "\n" - end - additionalProperties = additionalProperties .. add; + local triggerProps = triggerSystem.GetAdditionalProperties(data, i) + if triggerProps then + props[i] = triggerProps end end end - - if additionalProperties ~= "" then - additionalProperties = "\n\n" - .. L["Additional Trigger Replacements"] .. "\n" - .. additionalProperties .. "\n\n" - .. L["The trigger number is optional, and uses the trigger providing dynamic information if not specified."] - end - return additionalProperties + return props end Private.GetProgressSources = function(data) diff --git a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasInput.lua b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasInput.lua new file mode 100644 index 0000000..585e3ed --- /dev/null +++ b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasInput.lua @@ -0,0 +1,31 @@ +if not WeakAuras.IsLibsOK() then return end + +local Type, Version = "WeakAurasInput", 1 +local AceGUI = LibStub and LibStub("AceGUI-3.0", true) +if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end + +local OnEditFocusGained = function(frame) + local self = frame.obj + local option = self.userdata.option + if option and option.callbacks and option.callbacks.OnEditFocusGained then + option.callbacks.OnEditFocusGained(self) + end +end + +local OnShow = function(frame) + local self = frame.obj + local option = self.userdata.option + if option and option.callbacks and option.callbacks.OnShow then + option.callbacks.OnShow(self) + end +end + +local function Constructor() + local widget = AceGUI:Create("EditBox") + widget.type = Type + widget.editbox:HookScript("OnEditFocusGained", OnEditFocusGained) + widget.editbox:HookScript("OnShow", OnShow) + return widget +end + +AceGUI:RegisterWidgetType(Type, Constructor, Version) diff --git a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasMultiLineEditBox.lua b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasMultiLineEditBox.lua index 73b68df..d8a4b94 100644 --- a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasMultiLineEditBox.lua +++ b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasMultiLineEditBox.lua @@ -1,6 +1,6 @@ if not WeakAuras.IsLibsOK() then return end -local Type, Version = "WeakAurasMultiLineEditBox", 36 +local Type, Version = "WeakAurasMultiLineEditBox", 38 local AceGUI = LibStub and LibStub("AceGUI-3.0", true) if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end @@ -169,6 +169,10 @@ local function OnFrameShow(frame) end end + if option and option.callbacks and option.callbacks.OnShow then + option.callbacks.OnShow(self) + end + for i = numExtraButtons + 1, #self.extraButtons do self.extraButtons[i]:Hide(); end @@ -178,6 +182,11 @@ local function OnEditFocusGained(frame) AceGUI:SetFocus(frame.obj) frame.obj:Fire("OnEditFocusGained") frame.obj.scrollFrame:EnableMouseWheel(true); + + local option = frame.obj.userdata.option + if option and option.callbacks and option.callbacks.OnEditFocusGained then + option.callbacks.OnEditFocusGained(frame.obj) + end end --[[----------------------------------------------------------------------------- @@ -369,6 +378,7 @@ local function Constructor() button = button, extraButtons = extraButtons, editBox = editBox, + editbox = editBox, frame = frame, label = label, labelHeight = 10, diff --git a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasSnippetButton.lua b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasSnippetButton.lua index c4ddda5..45ee972 100644 --- a/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasSnippetButton.lua +++ b/WeakAurasOptions/AceGUI-Widgets/AceGUIWidget-WeakAurasSnippetButton.lua @@ -4,7 +4,7 @@ Graphical Button. -------------------------------------------------------------------------------]] if not WeakAuras.IsLibsOK() then return end -local Type, Version = "WeakAurasSnippetButton", 2 +local Type, Version = "WeakAurasSnippetButton", 3 local AceGUI = LibStub and LibStub("AceGUI-3.0", true) if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return @@ -71,6 +71,12 @@ local methods = { self:SetDisabled(false) self:SetTitle() self:SetEditable(false) + + self.ntex:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight2.blp") + self.ntex:SetVertexColor(0.8, 0.8, 0.8, 0.25) + self.htex:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight2.blp") + self.htex:SetVertexColor(0.3, 0.5, 1, 0.5) + self.ptex:SetTexture(1, 1, 1, 0.2) end, -- ["OnRelease"] = nil, @@ -115,6 +121,14 @@ local methods = { self.renameEditBox:HighlightText() self.renameEditBox:SetFocus() end + end, + ["SetDynamicTextStyle"] = function(self) + self.ntex:SetTexture(nil) + self.htex:SetTexture("Interface\\AddOns\\WeakAuras\\Media\\Textures\\Options") + self.htex:SetTexCoord(0.774414, 0.957031, 0.000976562, 0.0214844) + self.htex:SetVertexColor(1, 1, 1, 1) + self.ptex:SetTexture("Interface\\AddOns\\WeakAuras\\Media\\Textures\\Options") + self.ptex:SetTexCoord(0.589844, 0.772461, 0.000976562, 0.0214844) end } @@ -154,25 +168,20 @@ local function Constructor() button.title = title local ntex = button:CreateTexture() - ntex:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight2.blp") - ntex:SetVertexColor(0.8, 0.8, 0.8, 0.25) ntex:SetPoint("TOPLEFT", 0, -1) ntex:SetPoint("BOTTOMRIGHT", 0, 1) button:SetNormalTexture(ntex) local htex = button:CreateTexture() - htex:SetTexture("Interface\\BUTTONS\\UI-Listbox-Highlight2.blp") - htex:SetVertexColor(0.3, 0.5, 1, 0.5) htex:SetBlendMode("ADD") htex:SetAllPoints(ntex) button:SetHighlightTexture(htex) button.htex = htex local ptex = button:CreateTexture() - ptex:SetTexture(1, 1, 1, 0.2) - htex:SetAllPoints(ntex) + ptex:SetAllPoints(ntex) button:SetPushedTexture(ptex) - button.ptext = ptex + button.ptex = ptex local delHighlight = deleteButton:CreateTexture() delHighlight:SetTexture([[Interface\Buttons\CancelButton-Highlight]]) @@ -214,6 +223,7 @@ local function Constructor() title = title, frame = button, type = Type, + ntex = ntex, htex = htex, ptex = ptex, deleteButton = deleteButton, diff --git a/WeakAurasOptions/ActionOptions.lua b/WeakAurasOptions/ActionOptions.lua index 5b7c137..7d99e92 100644 --- a/WeakAurasOptions/ActionOptions.lua +++ b/WeakAurasOptions/ActionOptions.lua @@ -11,6 +11,7 @@ local disabledAll = OptionsPrivate.commonOptions.CreateDisabledAll("action") local hiddenAll = OptionsPrivate.commonOptions.CreateHiddenAll("action") local getAll = OptionsPrivate.commonOptions.CreateGetAll("action") local setAll = OptionsPrivate.commonOptions.CreateSetAll("action", getAll) +local dynamicTextInputs = {} local RestrictedChannelCheck = function(data) return data.message_type == "SAY" or data.message_type == "YELL" or data.message_type == "SMARTRAID" @@ -146,14 +147,38 @@ function OptionsPrivate.GetActionOptions(data) }, start_message_dest = { type = "input", - width = WeakAuras.normalWidth, + width = WeakAuras.normalWidth - 0.15, name = L["Send To"], order = 3.1, disabled = function() return not data.actions.start.do_message end, hidden = function() return data.actions.start.message_type ~= "WHISPER" end, - desc = function() - return L["Dynamic text tooltip"] .. OptionsPrivate.Private.GetAdditionalProperties(data) + control = "WeakAurasInput", + callbacks = { + OnEditFocusGained = function(self) + local widget = dynamicTextInputs["start_message_dest"] + OptionsPrivate.ToggleTextReplacements(data, true, widget) + end, + OnShow = function(self) + dynamicTextInputs["start_message_dest"] = self + end, + } + }, + start_message_dest_text_replacements_button = { + type = "execute", + width = 0.15, + name = L["Dynamic Text Replacements"], + desc = L["There are several special codes available to make this text dynamic. Click to view a list with all dynamic text codes."], + order = 3.11, + disabled = function() return not data.actions.start.do_message end, + hidden = function() return data.actions.start.message_type ~= "WHISPER" end, + func = function() + local widget = dynamicTextInputs["start_message_dest"] + OptionsPrivate.ToggleTextReplacements(data, nil, widget) end, + imageWidth = 24, + imageHeight = 24, + control = "WeakAurasIcon", + image = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\sidebar", }, start_message_dest_isunit = { type = "toggle", @@ -166,13 +191,36 @@ function OptionsPrivate.GetActionOptions(data) }, start_message = { type = "input", - width = WeakAuras.doubleWidth, + width = WeakAuras.doubleWidth - 0.15, name = L["Message"], order = 4, disabled = function() return not data.actions.start.do_message end, - desc = function() - return L["Dynamic text tooltip"] .. OptionsPrivate.Private.GetAdditionalProperties(data) + control = "WeakAurasInput", + callbacks = { + OnEditFocusGained = function(self) + local widget = dynamicTextInputs["start_message"] + OptionsPrivate.ToggleTextReplacements(data, true, widget) + end, + OnShow = function(self) + dynamicTextInputs["start_message"] = self + end, + } + }, + start_message_text_replacements_button = { + type = "execute", + width = 0.15, + name = L["Dynamic Text Replacements"], + desc = L["There are several special codes available to make this text dynamic. Click to view a list with all dynamic text codes."], + order = 4.1, + disabled = function() return not data.actions.start.do_message end, + func = function() + local widget = dynamicTextInputs["start_message"] + OptionsPrivate.ToggleTextReplacements(data, nil, widget) end, + imageWidth = 24, + imageHeight = 24, + control = "WeakAurasIcon", + image = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\sidebar", }, -- texteditor added later start_do_sound = { @@ -537,7 +585,7 @@ function OptionsPrivate.GetActionOptions(data) }, finish_message_color = { type = "color", - width = WeakAuras.normalWidth, + width = WeakAuras.normalWidth - 0.15, name = L["Color"], order = 23, hasAlpha = false, @@ -556,11 +604,38 @@ function OptionsPrivate.GetActionOptions(data) }, finish_message_dest = { type = "input", - width = WeakAuras.normalWidth, + width = WeakAuras.normalWidth - 0.15, name = L["Send To"], order = 23.1, disabled = function() return not data.actions.finish.do_message end, - hidden = function() return data.actions.finish.message_type ~= "WHISPER" end + hidden = function() return data.actions.finish.message_type ~= "WHISPER" end, + control = "WeakAurasInput", + callbacks = { + OnEditFocusGained = function(self) + local widget = dynamicTextInputs["finish_message_dest"] + OptionsPrivate.ToggleTextReplacements(data, true, widget) + end, + OnShow = function(self) + dynamicTextInputs["finish_message_dest"] = self + end, + } + }, + finish_message_dest_text_replacements_button = { + type = "execute", + width = 0.15, + name = L["Dynamic Text Replacements"], + desc = L["There are several special codes available to make this text dynamic. Click to view a list with all dynamic text codes."], + order = 23.11, + disabled = function() return not data.actions.finish.do_message end, + hidden = function() return data.actions.finish.message_type ~= "WHISPER" end, + func = function() + local widget = dynamicTextInputs["finish_message_dest"] + OptionsPrivate.ToggleTextReplacements(data, nil, widget) + end, + imageWidth = 24, + imageHeight = 24, + control = "WeakAurasIcon", + image = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\sidebar", }, finish_message_dest_isunit = { type = "toggle", @@ -573,13 +648,36 @@ function OptionsPrivate.GetActionOptions(data) }, finish_message = { type = "input", - width = WeakAuras.doubleWidth, + width = WeakAuras.doubleWidth - 0.15, name = L["Message"], order = 24, disabled = function() return not data.actions.finish.do_message end, - desc = function() - return L["Dynamic text tooltip"] .. OptionsPrivate.Private.GetAdditionalProperties(data) + control = "WeakAurasInput", + callbacks = { + OnEditFocusGained = function(self) + local widget = dynamicTextInputs["finish_message"] + OptionsPrivate.ToggleTextReplacements(data, true, widget) + end, + OnShow = function(self) + dynamicTextInputs["finish_message"] = self + end, + } + }, + finish_message_text_replacements_button = { + type = "execute", + width = 0.15, + name = L["Dynamic Text Replacements"], + desc = L["There are several special codes available to make this text dynamic. Click to view a list with all dynamic text codes."], + order = 24.1, + disabled = function() return not data.actions.finish.do_message end, + func = function() + local widget = dynamicTextInputs["finish_message"] + OptionsPrivate.ToggleTextReplacements(data, nil, widget) end, + imageWidth = 24, + imageHeight = 24, + control = "WeakAurasIcon", + image = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\sidebar", }, -- texteditor added below finish_do_sound = { diff --git a/WeakAurasOptions/CommonOptions.lua b/WeakAurasOptions/CommonOptions.lua index 6997445..012a29e 100644 --- a/WeakAurasOptions/CommonOptions.lua +++ b/WeakAurasOptions/CommonOptions.lua @@ -98,6 +98,7 @@ local function addCollapsibleHeader(options, key, input, order, isGroupTab) local hasDown = input.__down local hasDuplicate = input.__duplicate local hasApplyTemplate = input.__applyTemplate + local hasDynamicTextCodes = input.__dynamicTextCodes local defaultCollapsed = input.__collapsed local hiddenFunc = input.__hidden local notcollapsable = input.__notcollapsable @@ -122,7 +123,7 @@ local function addCollapsibleHeader(options, key, input, order, isGroupTab) end local titleWidth = WeakAuras.doubleWidth - (hasAdd and 0.15 or 0) - (hasDelete and 0.15 or 0) - (hasUp and 0.15 or 0) - - (hasDown and 0.15 or 0) - (hasDuplicate and 0.15 or 0) - (hasApplyTemplate and 0.15 or 0) + - (hasDown and 0.15 or 0) - (hasDuplicate and 0.15 or 0) - (hasApplyTemplate and 0.15 or 0) - (hasDynamicTextCodes and 0.15 or 0) options[key .. "collapseSpacer"] = { type = marginTop and "header" or "description", @@ -241,6 +242,22 @@ local function addCollapsibleHeader(options, key, input, order, isGroupTab) } setFuncs(options[key .. "applyTemplate"], input.__applyTemplate) end + + if hasDynamicTextCodes then + options[key .. "dynamicTextCodesButton"] = { + type = "execute", + name = L["Dynamic Text Replacements"], + desc = L["There are several special codes available to make this text dynamic. Click to view a list with all dynamic text codes."], + order = order + 0.8, + width = 0.15, + hidden = hiddenFunc, + imageWidth = 24, + imageHeight = 24, + control = "WeakAurasIcon", + image = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\sidebar", + } + setFuncs(options[key .. "dynamicTextCodesButton"], input.__dynamicTextCodes) + end end if hiddenFunc then diff --git a/WeakAurasOptions/ConditionOptions.lua b/WeakAurasOptions/ConditionOptions.lua index 0b10f7d..f0506e2 100644 --- a/WeakAurasOptions/ConditionOptions.lua +++ b/WeakAurasOptions/ConditionOptions.lua @@ -241,6 +241,8 @@ local function wrapWithPlaySound(func, kit) end end +local dynamicTextInputs = {} + local function addControlsForChange(args, order, data, conditionVariable, totalAuraCount, conditions, i, j, allProperties, usedProperties) local thenText = (j == 1) and L["Then "] or L["And "]; local display = isSubset(data, conditions[i].changes[j], totalAuraCount) and allProperties.displayWithCopy or allProperties.display; @@ -917,16 +919,10 @@ local function addControlsForChange(args, order, data, conditionVariable, totalA } order = order + 1; - local descMessage = descIfNoValue2(data, conditions[i].changes[j], "value", "message", propertyType); - if (not descMessage and data ~= OptionsPrivate.tempGroup) then - descMessage = L["Dynamic text tooltip"] .. OptionsPrivate.Private.GetAdditionalProperties(data) - end - args["condition" .. i .. "value" .. j .. "message dest"] = { type = "input", - width = WeakAuras.normalWidth, + width = WeakAuras.normalWidth - 0.15, name = blueIfNoValue2(data, conditions[i].changes[j], "value", "message_dest", L["Send To"], L["Send To"]), - desc = descMessage, order = order, get = function() return type(conditions[i].changes[j].value) == "table" and conditions[i].changes[j].value.message_dest; @@ -934,7 +930,37 @@ local function addControlsForChange(args, order, data, conditionVariable, totalA set = setValueComplex("message_dest"), hidden = function() return not anyMessageType("WHISPER"); - end + end, + control = "WeakAurasInput", + callbacks = { + OnEditFocusGained = function(self) + local widget = dynamicTextInputs["condition" .. i .. "value" .. j .. "message dest"] + OptionsPrivate.ToggleTextReplacements(data, true, widget) + end, + OnShow = function(self) + dynamicTextInputs["condition" .. i .. "value" .. j .. "message dest"] = self + end, + } + } + order = order + 1; + + args["condition" .. i .. "value" .. j .. "message dest_text_replacements_button"] = { + type = "execute", + width = 0.15, + name = L["Dynamic Text Replacements"], + desc = L["There are several special codes available to make this text dynamic. Click to view a list with all dynamic text codes."], + order = order, + hidden = function() + return not anyMessageType("WHISPER"); + end, + func = function() + local widget = dynamicTextInputs["condition" .. i .. "value" .. j .. "message dest"] + OptionsPrivate.ToggleTextReplacements(data, nil, widget) + end, + imageWidth = 24, + imageHeight = 24, + control = "WeakAurasIcon", + image = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\sidebar", } order = order + 1; @@ -960,12 +986,38 @@ local function addControlsForChange(args, order, data, conditionVariable, totalA args["condition" .. i .. "value" .. j .. "message"] = { type = "input", - width = WeakAuras.doubleWidth, + width = WeakAuras.doubleWidth - 0.15, name = blueIfNoValue2(data, conditions[i].changes[j], "value", "message", L["Message"], L["Message"]), - desc = descMessage, order = order, get = message_getter, - set = setValueComplex("message") + set = setValueComplex("message"), + control = "WeakAurasInput", + callbacks = { + OnEditFocusGained = function(self) + local widget = dynamicTextInputs["condition" .. i .. "value" .. j .. "message"] + OptionsPrivate.ToggleTextReplacements(data, true, widget) + end, + OnShow = function(self) + dynamicTextInputs["condition" .. i .. "value" .. j .. "message"] = self + end, + } + } + order = order + 1; + + args["condition" .. i .. "value" .. j .. "message_text_replacements_button"] = { + type = "execute", + width = 0.15, + name = L["Dynamic Text Replacements"], + desc = L["There are several special codes available to make this text dynamic. Click to view a list with all dynamic text codes."], + order = order, + func = function() + local widget = dynamicTextInputs["condition" .. i .. "value" .. j .. "message"] + OptionsPrivate.ToggleTextReplacements(data, nil, widget) + end, + imageWidth = 24, + imageHeight = 24, + control = "WeakAurasIcon", + image = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\sidebar", } order = order + 1; diff --git a/WeakAurasOptions/OptionsFrames/OptionsFrame.lua b/WeakAurasOptions/OptionsFrames/OptionsFrame.lua index fe2fd51..1bfae9f 100644 --- a/WeakAurasOptions/OptionsFrames/OptionsFrame.lua +++ b/WeakAurasOptions/OptionsFrames/OptionsFrame.lua @@ -136,7 +136,6 @@ function OptionsPrivate.CreateFrame() OptionsPrivate.Private.ClearFakeStates() - for id, data in pairs(OptionsPrivate.Private.regions) do if data.region then data.region:Collapse() @@ -160,6 +159,10 @@ function OptionsPrivate.CreateFrame() if OptionsPrivate.Private.personalRessourceDisplayFrame then OptionsPrivate.Private.personalRessourceDisplayFrame:OptionsClosed() end + + if frame.dynamicTextCodesFrame then + frame.dynamicTextCodesFrame:Hide() + end end) local width, height @@ -225,6 +228,7 @@ function OptionsPrivate.CreateFrame() self.tipFrame:Hide() self:HideTip() self.bottomRightResizer:Hide() + self.dynamicTextCodesFrame:Hide() else WeakAurasOptionsTitleText:Show() self.bottomRightResizer:Show() @@ -236,6 +240,7 @@ function OptionsPrivate.CreateFrame() else self.buttonsContainer.frame:Hide() self.container.frame:Hide() + self.dynamicTextCodesFrame:Hide() self:HideTip() end @@ -887,6 +892,93 @@ function OptionsPrivate.CreateFrame() unloadedButton.childButtons = {} frame.unloadedButton = unloadedButton + -- Sidebar used for Dynamic Text Replacements + local sidegroup = AceGUI:Create("WeakAurasInlineGroup") + sidegroup.frame:SetParent(frame) + sidegroup.frame:SetPoint("TOPLEFT", frame, "TOPLEFT", 17, -63); + sidegroup.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -17, 46); + sidegroup.frame:Show() + sidegroup:SetLayout("flow") + + local dynamicTextCodesFrame = CreateFrame("Frame", "WeakAurasTextReplacements", sidegroup.frame, "WA_PortraitFrameTemplate") + dynamicTextCodesFrame:HidePortrait() + dynamicTextCodesFrame:SetPoint("TOPLEFT", sidegroup.frame, "TOPRIGHT", 20, 0) + dynamicTextCodesFrame:SetPoint("BOTTOMLEFT", sidegroup.frame, "BOTTOMRIGHT", 20, 0) + dynamicTextCodesFrame:SetWidth(250) + dynamicTextCodesFrame:SetScript("OnHide", function() + OptionsPrivate.currentDynamicTextInput = nil + end) + frame.dynamicTextCodesFrame = dynamicTextCodesFrame + + local dynamicTextCodesFrameTitle + if dynamicTextCodesFrame.TitleContainer and dynamicTextCodesFrame.TitleContainer.TitleText then + dynamicTextCodesFrameTitle = dynamicTextCodesFrame.TitleContainer.TitleText + elseif dynamicTextCodesFrame.TitleText then + dynamicTextCodesFrameTitle = dynamicTextCodesFrame.TitleText + end + if dynamicTextCodesFrameTitle then + dynamicTextCodesFrameTitle:SetText("Dynamic Text Replacements") + dynamicTextCodesFrameTitle:SetJustifyH("CENTER") + dynamicTextCodesFrameTitle:SetPoint("LEFT", dynamicTextCodesFrame, "TOPLEFT") + dynamicTextCodesFrameTitle:SetPoint("RIGHT", dynamicTextCodesFrame, "TOPRIGHT", -10, 0) + end + + local dynamicTextCodesLabel = AceGUI:Create("Label") + dynamicTextCodesLabel:SetText(L["Insert text replacement codes to make text dynamic."]) + dynamicTextCodesLabel:SetFontObject(GameFontNormal) + dynamicTextCodesLabel:SetPoint("TOP", dynamicTextCodesFrame, "TOP", 0, -35) + dynamicTextCodesLabel:SetFontObject(GameFontNormalSmall) + dynamicTextCodesLabel.frame:SetParent(dynamicTextCodesFrame) + dynamicTextCodesLabel.frame:Show() + + local dynamicTextCodesScrollContainer = AceGUI:Create("SimpleGroup") + dynamicTextCodesScrollContainer.frame:SetParent(dynamicTextCodesFrame) + dynamicTextCodesScrollContainer.frame:SetPoint("TOP", dynamicTextCodesLabel.frame, "BOTTOM", 0, -15) + dynamicTextCodesScrollContainer.frame:SetPoint("LEFT", dynamicTextCodesFrame, "LEFT", 15, 0) + dynamicTextCodesScrollContainer.frame:SetPoint("BOTTOMRIGHT", dynamicTextCodesFrame, "BOTTOMRIGHT", -15, 5) + dynamicTextCodesScrollContainer:SetFullWidth(true) + dynamicTextCodesScrollContainer:SetFullHeight(true) + dynamicTextCodesScrollContainer:SetLayout("Fill") + + + local dynamicTextCodesScrollList = AceGUI:Create("ScrollFrame") + dynamicTextCodesScrollList:SetLayout("List") + dynamicTextCodesScrollList:SetPoint("TOPLEFT", dynamicTextCodesScrollContainer.frame, "TOPLEFT") + dynamicTextCodesScrollList:SetPoint("BOTTOMRIGHT", dynamicTextCodesScrollContainer.frame, "BOTTOMRIGHT") + dynamicTextCodesScrollList.frame:SetParent(dynamicTextCodesFrame) + dynamicTextCodesScrollList:FixScroll() + dynamicTextCodesScrollList.scrollframe:SetScript( + "OnScrollRangeChanged", + function(frame) + frame.obj:DoLayout() + end + ) + + dynamicTextCodesScrollList.scrollframe:SetScript( + "OnSizeChanged", + function(frame) + if frame.obj.scrollBarShown then + frame.obj.content.width = frame.obj.content.original_width - 10 + frame.obj.scrollframe:SetPoint("BOTTOMRIGHT", -10, 0) + end + end + ) + + dynamicTextCodesFrame.scrollList = dynamicTextCodesScrollList + dynamicTextCodesFrame.label = dynamicTextCodesLabel + dynamicTextCodesFrame:Hide() + + function OptionsPrivate.ToggleTextReplacements(data, show, widget) + if show or not dynamicTextCodesFrame:IsShown() then + dynamicTextCodesFrame:Show() + if OptionsPrivate.currentDynamicTextInput ~= widget then + OptionsPrivate.UpdateTextReplacements(dynamicTextCodesFrame, data) + end + OptionsPrivate.currentDynamicTextInput = widget + else + dynamicTextCodesFrame:Hide() + end + end frame.ClearOptions = function(self, id) aceOptions[id] = nil @@ -1037,6 +1129,10 @@ function OptionsPrivate.CreateFrame() if data.controlledChildren and #data.controlledChildren == 0 then WeakAurasOptions:NewAura() end + + if frame.dynamicTextCodesFrame then + frame.dynamicTextCodesFrame:Hide() + end end frame.ClearPick = function(self, id) @@ -1136,6 +1232,7 @@ function OptionsPrivate.CreateFrame() targetIsDynamicGroup = parentData and parentData.regionType == "dynamicgroup" end end + self.dynamicTextCodesFrame:Hide() self.moversizer:Hide() self.pickedOption = "New" diff --git a/WeakAurasOptions/RegionOptions/Text.lua b/WeakAurasOptions/RegionOptions/Text.lua index 9f17306..3851e68 100644 --- a/WeakAurasOptions/RegionOptions/Text.lua +++ b/WeakAurasOptions/RegionOptions/Text.lua @@ -11,6 +11,8 @@ local hiddenFontExtra = function() return OptionsPrivate.IsCollapsed("text", "text", "fontflags", true) end +local dynamicTextInputs = {} + local function createOptions(id, data) local function hideCustomTextOption() if OptionsPrivate.Private.ContainsCustomPlaceHolder(data.displayText) then @@ -39,12 +41,13 @@ local function createOptions(id, data) local options = { __title = L["Text Settings"], __order = 1, + __dynamicTextCodes = function() + local widget = dynamicTextInputs["displayText"] + OptionsPrivate.ToggleTextReplacements(data, nil, widget) + end, displayText = { type = "input", width = WeakAuras.doubleWidth, - desc = function() - return L["Dynamic text tooltip"] .. OptionsPrivate.Private.GetAdditionalProperties(data) - end, multiline = true, name = L["Display Text"], order = 10, @@ -58,6 +61,16 @@ local function createOptions(id, data) WeakAuras.UpdateThumbnail(data); OptionsPrivate.ResetMoverSizer(); end, + control = "WeakAurasMultiLineEditBox", + callbacks = { + OnEditFocusGained = function(self) + local widget = dynamicTextInputs["displayText"] + OptionsPrivate.ToggleTextReplacements(data, true, widget) + end, + OnShow = function(self) + dynamicTextInputs["displayText"] = self + end, + } }, customTextUpdate = { type = "select", diff --git a/WeakAurasOptions/SubRegionOptions/SubText.lua b/WeakAurasOptions/SubRegionOptions/SubText.lua index 613ff2e..42cf1ae 100644 --- a/WeakAurasOptions/SubRegionOptions/SubText.lua +++ b/WeakAurasOptions/SubRegionOptions/SubText.lua @@ -18,6 +18,8 @@ local self_point_types = { AUTO = L["Automatic"] } +local dynamicTextInputs = {} + local function createOptions(parentData, data, index, subIndex) -- The toggles for font flags is intentionally not keyed on the id -- So that all auras share the state of that toggle @@ -45,17 +47,39 @@ local function createOptions(parentData, data, index, subIndex) }, text_text = { type = "input", - width = WeakAuras.normalWidth, - desc = function() - return L["Dynamic text tooltip"] .. OptionsPrivate.Private.GetAdditionalProperties(parentData) - end, + width = WeakAuras.normalWidth - 0.15, name = L["Display Text"], order = 11, set = function(info, v) data.text_text = OptionsPrivate.Private.ReplaceLocalizedRaidMarkers(v) WeakAuras.Add(parentData) WeakAuras.ClearAndUpdateOptions(parentData.id) - end + end, + control = "WeakAurasInput", + callbacks = { + OnEditFocusGained = function(self) + local widget = dynamicTextInputs[subIndex] + OptionsPrivate.ToggleTextReplacements(parentData, true, widget) + end, + OnShow = function(self) + dynamicTextInputs[subIndex] = self + end, + } + }, + text_replacements_button = { + type = "execute", + width = 0.15, + name = L["Dynamic Text Replacements"], + desc = L["There are several special codes available to make this text dynamic. Click to view a list with all dynamic text codes."], + order = 11.1, + func = function() + local widget = dynamicTextInputs[subIndex] + OptionsPrivate.ToggleTextReplacements(parentData, nil, widget) + end, + imageWidth = 24, + imageHeight = 24, + control = "WeakAurasIcon", + image = "Interface\\AddOns\\WeakAuras\\Media\\Textures\\sidebar", }, text_font = { type = "select", diff --git a/WeakAurasOptions/WeakAurasOptions.lua b/WeakAurasOptions/WeakAurasOptions.lua index 8f16cce..a8bccd7 100644 --- a/WeakAurasOptions/WeakAurasOptions.lua +++ b/WeakAurasOptions/WeakAurasOptions.lua @@ -1715,6 +1715,171 @@ function OptionsPrivate.OpenTriggerTemplate(data, targetId) end end +OptionsPrivate.currentDynamicTextInput = false; + +local BaseDynamicTextCodes = { + trigger = { + {type = "mini", name = "p", desc = L["Progress - The remaining time of a timer, or a non-timer value"]}, + {type = "mini", name = "t", desc = L["Total - The maximum duration of a timer, or a maximum non-timer value"]}, + {type = "mini", name = "n", desc = L["Name - The name of the display (usually an aura name), or the display's ID if there is no dynamic name"]}, + {type = "mini", name = "i", desc = L["Icon - The icon associated with the display"]}, + {type = "mini", name = "s", desc = L["Stacks - The number of stacks of an aura (usually)"]}, + }, + global = { + {type = "mini", name = "c", desc = L["Custom - Allows you to define a custom Lua function that returns a list of string values. %c1 will be replaced by the first value returned, %c2 by the second, etc."]}, + {type = "mini", name = "%", desc = L["% - To show a percent sign"]}, + } +} + +function OptionsPrivate.UpdateTextReplacements(frame, data) + frame.scrollList:ReleaseChildren() + + local props = OptionsPrivate.Private.GetAdditionalProperties(data) + local sortedProps = {} + + -- Add global header and markers + table.insert(sortedProps, {type = "header", triggerNum = 0, name = "Global Properties"}) + for index, icon in ipairs(ICON_LIST) do + table.insert(sortedProps, {type = "marker", triggerNum = 0, name = "{rt"..index.."}", desc = icon..":0|t", widthFraction = #ICON_LIST}) + end + + -- Add base dynamic text codes + local globalProps = {} + tAppendAll(globalProps, CopyTable(BaseDynamicTextCodes.trigger)) + tAppendAll(globalProps, CopyTable(BaseDynamicTextCodes.global)) + for _, prop in ipairs(globalProps) do + prop.widthFraction = #globalProps + prop.triggerNum = 0 + table.insert(sortedProps, prop) + end + + -- Process each trigger's properties + for triggerNum, triggerProps in pairs(props) do + if next(triggerProps) then + -- Create a temporary table for this trigger's properties + local tempProps = {} + + -- Add the properties to the temporary table + for name, desc in pairs(triggerProps) do + table.insert(tempProps, {triggerNum = triggerNum, name = name, desc = desc}) + end + + -- Sort the temporary table by name + table.sort(tempProps, function(a, b) + return a.name < b.name + end) + + -- Add a header for the trigger + table.insert(sortedProps, {type = "header", triggerNum = triggerNum, name = OptionsPrivate.GetTriggerTitle(data, triggerNum)}) + + -- Add the base properties for the trigger + for _, v in ipairs(BaseDynamicTextCodes.trigger) do + local prop = CopyTable(v) + prop.widthFraction = #BaseDynamicTextCodes.trigger + prop.triggerNum = triggerNum + table.insert(sortedProps, prop) + end + + -- Add the sorted properties to the sortedProps table + for _, prop in ipairs(tempProps) do + table.insert(sortedProps, prop) + end + end + end + + -- Create a modified WeakAurasSnippetButton for each property and add it to ScrollList + local lastType, miniGroup + for i, prop in ipairs(sortedProps) do + if prop.type == "header" then + local heading = AceGUI:Create("Heading") + heading:SetText(prop.name) + heading:SetRelativeWidth(1) + heading.label:SetFontObject(GameFontNormalSmall) + frame.scrollList:AddChild(heading) + else + if ((prop.type == "mini" or prop.type == "marker") and prop.type ~= lastType) + then + miniGroup = AceGUI:Create("SimpleGroup") + miniGroup:SetLayout("Flow") + miniGroup:SetAutoAdjustHeight(true) + miniGroup:SetRelativeWidth(1) + frame.scrollList:AddChild(miniGroup) + end + local button = AceGUI:Create("WeakAurasSnippetButton") + local propIndex = prop.triggerNum > 0 and ("%s"):format(prop.triggerNum) or "" + local propPrefix = prop.triggerNum > 0 and ("%%%s."):format(propIndex) or "%" + if prop.type == "marker" then + button:SetTitle(prop.desc) + else + button:SetTitle(string.format("|cFFFFCC00%s|r%s", propPrefix, prop.name)) + end + if prop.type == "mini" or prop.type == "marker" then + button:SetRelativeWidth((1/prop.widthFraction) - 1e-10) + else + button:SetRelativeWidth(1) + end + button.title:SetFontObject(GameFontNormal) + button.frame:SetHeight(28) + button:SetDynamicTextStyle() + + -- Set Tooltip + if prop.type ~= "marker" then + button.frame:SetScript("OnEnter", function(frame) + local tooltip = GameTooltip + tooltip:SetWidth(300) + tooltip:SetOwner(frame, "ANCHOR_RIGHT") + tooltip:ClearLines() + tooltip:AddLine(("%s%s"):format(propPrefix, prop.name)) + tooltip:AddLine(prop.desc, 1, 1, 1, true) + if prop.name ~= "c" and prop.name ~= "%" then + tooltip:AddLine("\n") + tooltip:AddLine( + prop.triggerNum > 0 + and L["The trigger number is optional. When no trigger number is specified, the trigger selected via dynamic information will be used."] + or L["By default this shows the information from the trigger selected via dynamic information. The information from a specific trigger can be shown via e.g. %2.p."], + 0.8, 0.8, 0.8, + true) + end + tooltip:Show() + frame.obj:Fire("OnEnter") + end) + else + button.frame:SetScript("OnEnter", nil) + end + + -- Insert dynamic text property on click + button:SetCallback("OnClick", function() + local insertProp + if prop.type == "marker" then + insertProp = prop.name + else + if IsShiftKeyDown() then + insertProp = prop.name == "%" and "%%" or ("%%{%s}"):format(prop.name) + if prop.triggerNum > 0 then + insertProp = string.format("%%{%d.%s}", propIndex, prop.name) + end + else + insertProp = prop.name == "%" and "%%" or ("%%%s"):format(prop.name) + if prop.triggerNum > 0 then + insertProp = string.format("%%%d.%s", propIndex, prop.name) + end + end + end + + OptionsPrivate.currentDynamicTextInput.editbox:Insert(insertProp) + OptionsPrivate.currentDynamicTextInput.editbox:SetFocus() + end) + + if prop.type == "mini" or prop.type == "marker" then + miniGroup:AddChild(button) + else + frame.scrollList:AddChild(button) + end + end + lastType = prop.type + end +end + function OptionsPrivate.ResetMoverSizer() if(frame and frame.mover and frame.moversizer and frame.mover.moving.region and frame.mover.moving.data) then frame.moversizer:SetToRegion(frame.mover.moving.region, frame.mover.moving.data); diff --git a/WeakAurasOptions/WeakAurasOptions.toc b/WeakAurasOptions/WeakAurasOptions.toc index 98e917e..5a42662 100644 --- a/WeakAurasOptions/WeakAurasOptions.toc +++ b/WeakAurasOptions/WeakAurasOptions.toc @@ -95,6 +95,7 @@ AceGUI-Widgets\AceGUIWidget-WeakAurasExpandAnchor.lua AceGUI-Widgets\AceGUIWidget-WeakAurasSpacer.lua AceGUI-Widgets\AceGuiWidget-WeakAurasProgressBar.lua AceGUI-Widgets\AceGUIWidget-WeakAurasSpinBox.lua +AceGUI-Widgets\AceGUIWidget-WeakAurasInput.lua AceGUI-Widgets\AceGUIWidget-WeakAurasInputFocus.lua AceGUI-Widgets\AceGUIWidget-WeakAurasMediaSound.lua AceGUI-Widgets\WeakAurasStatusbarAtlasWidget.lua