d9824eb73e
The notice was intentionally kept for two releases to inform users about the upcoming end of Midnight support. It is now removed, as the message should have reached users. (cherry picked from commit f524ab5c840f00d45f771423c9b1b2ecb72bf08f)
1649 lines
56 KiB
Lua
1649 lines
56 KiB
Lua
if not WeakAuras.IsLibsOK() then return end
|
|
local AddonName = ...
|
|
local OptionsPrivate = select(2, ...)
|
|
|
|
-- Lua APIs
|
|
local tinsert, tremove, wipe = table.insert, table.remove, wipe
|
|
local pairs, type, error = pairs, type, error
|
|
local _G = _G
|
|
|
|
-- WoW APIs
|
|
local GetScreenWidth, GetScreenHeight, CreateFrame, GetAddOnInfo
|
|
= GetScreenWidth, GetScreenHeight, CreateFrame, GetAddOnInfo
|
|
|
|
local AceGUI = LibStub("AceGUI-3.0")
|
|
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
|
|
local AceConfigRegistry = LibStub("AceConfigRegistry-3.0")
|
|
local SharedMedia = LibStub("LibSharedMedia-3.0")
|
|
|
|
local WeakAuras = WeakAuras
|
|
local L = WeakAuras.L
|
|
|
|
local displayButtons = OptionsPrivate.displayButtons
|
|
local tempGroup = OptionsPrivate.tempGroup
|
|
local aceOptions = {}
|
|
|
|
local function CreateFrameSizer(frame, callback, position)
|
|
callback = callback or (function() end)
|
|
|
|
local left, right, top, bottom, xOffset1, yOffset1, xOffset2, yOffset2
|
|
if position == "BOTTOMLEFT" then
|
|
left, right, top, bottom = 1, 0, 0, 1
|
|
xOffset1, yOffset1 = 1, 1
|
|
xOffset2, yOffset2 = 0, 0
|
|
elseif position == "BOTTOMRIGHT" then
|
|
left, right, top, bottom = 0, 1, 0, 1
|
|
xOffset1, yOffset1 = 0, 1
|
|
xOffset2, yOffset2 = -1, 0
|
|
elseif position == "TOPLEFT" then
|
|
left, right, top, bottom = 1, 0, 1, 0
|
|
xOffset1, yOffset1 = 1, 0
|
|
xOffset2, yOffset2 = 0, -1
|
|
elseif position == "TOPRIGHT" then
|
|
left, right, top, bottom = 0, 1, 1, 0
|
|
xOffset1, yOffset1 = 0, 0
|
|
xOffset2, yOffset2 = -1, -1
|
|
end
|
|
|
|
local handle = CreateFrame("Button", nil, frame)
|
|
handle:SetPoint(position, frame)
|
|
handle:SetSize(25, 25)
|
|
handle:EnableMouse()
|
|
|
|
handle:SetScript("OnMouseDown", function()
|
|
frame:StartSizing(position)
|
|
end)
|
|
|
|
handle:SetScript("OnMouseUp", function()
|
|
frame:StopMovingOrSizing()
|
|
callback()
|
|
end)
|
|
|
|
local normal = handle:CreateTexture(nil, "OVERLAY")
|
|
normal:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
|
|
normal:SetTexCoord(left, right, top, bottom)
|
|
normal:SetPoint("BOTTOMLEFT", handle, xOffset1, yOffset1)
|
|
normal:SetPoint("TOPRIGHT", handle, xOffset2, yOffset2)
|
|
handle:SetNormalTexture(normal)
|
|
|
|
local pushed = handle:CreateTexture(nil, "OVERLAY")
|
|
pushed:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
|
|
pushed:SetTexCoord(left, right, top, bottom)
|
|
pushed:SetPoint("BOTTOMLEFT", handle, xOffset1, yOffset1)
|
|
pushed:SetPoint("TOPRIGHT", handle, xOffset2, yOffset2)
|
|
handle:SetPushedTexture(pushed)
|
|
|
|
local highlight = handle:CreateTexture(nil, "OVERLAY")
|
|
highlight:SetTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
|
|
highlight:SetTexCoord(left, right, top, bottom)
|
|
highlight:SetPoint("BOTTOMLEFT", handle, xOffset1, yOffset1)
|
|
highlight:SetPoint("TOPRIGHT", handle, xOffset2, yOffset2)
|
|
handle:SetHighlightTexture(highlight)
|
|
|
|
return handle
|
|
end
|
|
|
|
local defaultWidth = 830
|
|
local defaultHeight = 665
|
|
local minWidth = 750
|
|
local minHeight = 240
|
|
|
|
|
|
|
|
function OptionsPrivate.CreateFrame()
|
|
CreateFrame("Frame", "WeakAuras_DropDownMenu", nil, "UIDropDownMenuTemplate")
|
|
local frame
|
|
local db = OptionsPrivate.savedVars.db
|
|
local odb = OptionsPrivate.savedVars.odb
|
|
|
|
frame = CreateFrame("Frame", "WeakAurasOptions", UIParent)
|
|
WeakAuras.XMLTemplates["PortraitFrameTemplate"](frame)
|
|
|
|
function OptionsPrivate.SetTitle(title)
|
|
local text = "WeakAuras " .. WeakAuras.versionString
|
|
if title and title ~= "" then
|
|
text = ("%s - %s"):format(text, title)
|
|
end
|
|
WeakAurasOptionsTitleText:SetText(text)
|
|
end
|
|
|
|
tinsert(UISpecialFrames, frame:GetName())
|
|
frame:EnableMouse(true)
|
|
frame:SetMovable(true)
|
|
frame:SetResizable(true)
|
|
frame:SetMinResize(minWidth, minHeight)
|
|
frame:SetFrameStrata("DIALOG")
|
|
|
|
local now = time()
|
|
local y = date("*t", now).year
|
|
local inJune = now >= time{year=y, month=6, day=1, hour=0} and now < time{year=y, month=7, day=1, hour=0}
|
|
if inJune then
|
|
frame.PortraitContainer.portrait:SetTexture([[Interface\AddOns\WeakAuras\Media\Textures\logo_256_round_pride.tga]])
|
|
else
|
|
frame.PortraitContainer.portrait:SetTexture([[Interface\AddOns\WeakAuras\Media\Textures\logo_256_round.tga]])
|
|
end
|
|
|
|
frame.window = "default"
|
|
|
|
local xOffset, yOffset
|
|
|
|
if db.frame then
|
|
-- Convert from old settings to new
|
|
odb.frame = db.frame
|
|
if odb.frame.xOffset and odb.frame.yOffset then
|
|
odb.frame.xOffset = odb.frame.xOffset + GetScreenWidth() - (odb.frame.width or defaultWidth) / 2
|
|
odb.frame.yOffset = odb.frame.yOffset + GetScreenHeight()
|
|
end
|
|
db.frame = nil
|
|
end
|
|
|
|
if odb.frame then
|
|
xOffset, yOffset = odb.frame.xOffset, odb.frame.yOffset
|
|
end
|
|
|
|
if not (xOffset and yOffset) then
|
|
xOffset = GetScreenWidth() / 2
|
|
yOffset = GetScreenHeight() - defaultHeight / 2
|
|
end
|
|
|
|
frame:SetPoint("TOP", UIParent, "BOTTOMLEFT", xOffset, yOffset)
|
|
frame:Hide()
|
|
|
|
frame:SetScript("OnHide", function()
|
|
local suspended = OptionsPrivate.Private.PauseAllDynamicGroups()
|
|
|
|
OptionsPrivate.Private.ClearFakeStates()
|
|
|
|
for id, data in pairs(OptionsPrivate.Private.regions) do
|
|
if data.region then
|
|
data.region:Collapse()
|
|
data.region:OptionsClosed()
|
|
if OptionsPrivate.Private.clones[id] then
|
|
for _, cloneRegion in pairs(OptionsPrivate.Private.clones[id]) do
|
|
cloneRegion:Collapse()
|
|
cloneRegion:OptionsClosed()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
OptionsPrivate.Private.ResumeAllDynamicGroups(suspended)
|
|
OptionsPrivate.Private.Resume()
|
|
|
|
if OptionsPrivate.Private.mouseFrame then
|
|
OptionsPrivate.Private.mouseFrame:OptionsClosed()
|
|
end
|
|
|
|
if OptionsPrivate.Private.personalRessourceDisplayFrame then
|
|
OptionsPrivate.Private.personalRessourceDisplayFrame:OptionsClosed()
|
|
end
|
|
|
|
if frame.dynamicTextCodesFrame then
|
|
frame.dynamicTextCodesFrame:Hide()
|
|
end
|
|
|
|
if frame.moversizer then
|
|
frame.moversizer:OptionsClosed()
|
|
end
|
|
end)
|
|
|
|
local width, height
|
|
|
|
if odb.frame then
|
|
width, height = odb.frame.width, odb.frame.height
|
|
end
|
|
|
|
if not (width and height) then
|
|
width, height = defaultWidth, defaultHeight
|
|
end
|
|
|
|
width = max(width, minWidth)
|
|
height = max(height, minHeight)
|
|
frame:SetWidth(width)
|
|
frame:SetHeight(height)
|
|
|
|
|
|
OptionsPrivate.SetTitle()
|
|
|
|
local function commitWindowChanges()
|
|
if not frame.minimized then
|
|
local xOffset = frame:GetRight()-(frame:GetWidth()/2)
|
|
local yOffset = frame:GetTop()
|
|
odb.frame = odb.frame or {}
|
|
odb.frame.xOffset = xOffset
|
|
odb.frame.yOffset = yOffset
|
|
odb.frame.width = frame:GetWidth()
|
|
odb.frame.height = frame:GetHeight()
|
|
end
|
|
end
|
|
|
|
frame:SetScript("OnMouseDown", function()
|
|
frame:StartMoving()
|
|
end)
|
|
frame:SetScript("OnMouseUp", function()
|
|
frame:StopMovingOrSizing()
|
|
commitWindowChanges()
|
|
end)
|
|
|
|
|
|
frame.bottomRightResizer = CreateFrameSizer(frame, commitWindowChanges, "BOTTOMRIGHT")
|
|
|
|
frame.UpdateFrameVisible = function(self)
|
|
self.tipPopup:Hide()
|
|
if self.minimized then
|
|
WeakAurasOptionsTitleText:Hide()
|
|
self.buttonsContainer.frame:Hide()
|
|
for _, fn in ipairs({"TexturePicker", "IconPicker", "ModelPicker", "ImportExport", "TextEditor", "CodeReview", "UpdateFrame", "DebugLog"}) do
|
|
local obj = OptionsPrivate[fn](self, true)
|
|
if obj then
|
|
obj.frame:Hide()
|
|
end
|
|
end
|
|
if self.newView then
|
|
self.newView.frame:Hide()
|
|
end
|
|
self.container.frame:Hide()
|
|
|
|
self.loadProgress:Hide()
|
|
self.toolbarContainer:Hide()
|
|
self.filterInput:Hide();
|
|
self.tipFrame:Hide()
|
|
self:HideTip()
|
|
self.bottomRightResizer:Hide()
|
|
self.dynamicTextCodesFrame:Hide()
|
|
else
|
|
WeakAurasOptionsTitleText:Show()
|
|
self.bottomRightResizer:Show()
|
|
if self.window == "default" then
|
|
OptionsPrivate.SetTitle()
|
|
self.buttonsContainer.frame:Show()
|
|
self.container.frame:Show()
|
|
self:ShowTip()
|
|
else
|
|
self.buttonsContainer.frame:Hide()
|
|
self.container.frame:Hide()
|
|
self.dynamicTextCodesFrame:Hide()
|
|
self:HideTip()
|
|
end
|
|
local widgets = {
|
|
{ window = "texture", title = L["Texture Picker"], fn = "TexturePicker" },
|
|
{ window = "icon", title = L["Icon Picker"], fn = "IconPicker" },
|
|
{ window = "model", title = L["Model Picker"], fn = "ModelPicker" },
|
|
{ window = "importexport", title = L["Import / Export"], fn = "ImportExport" },
|
|
{ window = "texteditor", title = L["Code Editor"], fn = "TextEditor" },
|
|
{ window = "codereview", title = L["Custom Code Viewer"], fn = "CodeReview" },
|
|
{ window = "debuglog", title = L["Debug Log"], fn = "DebugLog" },
|
|
{ window = "update", title = L["Update"], fn = "UpdateFrame" },
|
|
}
|
|
|
|
for _, widget in ipairs(widgets) do
|
|
local obj = OptionsPrivate[widget.fn](self, true)
|
|
if self.window == widget.window then
|
|
OptionsPrivate.SetTitle(widget.title)
|
|
if obj then
|
|
obj.frame:Show()
|
|
end
|
|
else
|
|
if obj then
|
|
obj.frame:Hide()
|
|
end
|
|
end
|
|
end
|
|
|
|
if self.window == "newView" then
|
|
OptionsPrivate.SetTitle(L["New Template"])
|
|
self.newView.frame:Show()
|
|
else
|
|
if self.newView then
|
|
self.newView.frame:Hide()
|
|
end
|
|
end
|
|
if self.window == "default" then
|
|
if self.loadProgessVisible then
|
|
self.loadProgress:Show()
|
|
self.toolbarContainer:Hide()
|
|
self.filterInput:Hide();
|
|
else
|
|
self.loadProgress:Hide()
|
|
self.toolbarContainer:Show()
|
|
self.filterInput:Show();
|
|
--self.filterInputClear:Show();
|
|
end
|
|
else
|
|
self.loadProgress:Hide()
|
|
self.toolbarContainer:Hide()
|
|
self.filterInput:Hide();
|
|
end
|
|
end
|
|
end
|
|
|
|
local minimizebutton = CreateFrame("Button", nil, frame)
|
|
WeakAuras.XMLTemplates["MaximizeMinimizeButtonFrameTemplate"](minimizebutton)
|
|
minimizebutton:SetPoint("RIGHT", frame.CloseButton, "LEFT", 0, 0)
|
|
minimizebutton:SetOnMaximizedCallback(function()
|
|
frame.minimized = false
|
|
local right, top = frame:GetRight(), frame:GetTop()
|
|
frame:ClearAllPoints()
|
|
frame:SetPoint("TOPRIGHT", UIParent, "BOTTOMLEFT", right, top)
|
|
frame:SetHeight(odb.frame and odb.frame.height or defaultHeight)
|
|
frame:SetWidth(odb.frame and odb.frame.width or defaultWidth)
|
|
frame.buttonsScroll:DoLayout()
|
|
frame:UpdateFrameVisible()
|
|
end)
|
|
minimizebutton:SetOnMinimizedCallback(function()
|
|
commitWindowChanges()
|
|
frame.minimized = true
|
|
local right, top = frame:GetRight(), frame:GetTop()
|
|
frame:ClearAllPoints()
|
|
frame:SetPoint("TOPRIGHT", UIParent, "BOTTOMLEFT", right, top)
|
|
frame:SetHeight(75)
|
|
frame:SetWidth(160)
|
|
frame:UpdateFrameVisible()
|
|
end)
|
|
|
|
local tipFrame = CreateFrame("Frame", nil, frame)
|
|
tipFrame:SetPoint("TOPLEFT", frame, "BOTTOMLEFT", 17, 30)
|
|
tipFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -17, 10)
|
|
tipFrame:Hide()
|
|
frame.tipFrame = tipFrame
|
|
|
|
local tipPopup = CreateFrame("Frame", nil, frame)
|
|
tipPopup:SetFrameStrata("FULLSCREEN")
|
|
tipPopup:SetBackdrop({
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true,
|
|
tileSize = 16,
|
|
edgeSize = 16,
|
|
insets = { left = 4, right = 4, top = 4, bottom = 4 }
|
|
})
|
|
tipPopup:SetBackdropColor(0, 0, 0, 0.8)
|
|
--tipPopup:SetHeight(100)
|
|
tipPopup:Hide()
|
|
frame.tipPopup = tipPopup
|
|
|
|
local tipPopupTitle = tipPopup:CreateFontString(nil, "BACKGROUND", "GameFontNormalLarge")
|
|
tipPopupTitle:SetPoint("TOPLEFT", tipPopup, "TOPLEFT", 10, -10)
|
|
tipPopupTitle:SetPoint("TOPRIGHT", tipPopup, "TOPRIGHT", -10, -10)
|
|
tipPopupTitle:SetJustifyH("LEFT")
|
|
tipPopupTitle:SetJustifyV("TOP")
|
|
|
|
local tipPopupLabel = tipPopup:CreateFontString(nil, "BACKGROUND", "GameFontWhite")
|
|
local fontPath = SharedMedia:Fetch("font", "Fira Sans Medium")
|
|
if (fontPath) then
|
|
tipPopupLabel:SetFont(fontPath, 12)
|
|
end
|
|
tipPopupLabel:SetPoint("TOPLEFT", tipPopupTitle, "BOTTOMLEFT", 0, -6)
|
|
tipPopupLabel:SetPoint("TOPRIGHT", tipPopupTitle, "BOTTOMRIGHT", 0, -6)
|
|
tipPopupLabel:SetJustifyH("LEFT")
|
|
tipPopupLabel:SetJustifyV("TOP")
|
|
|
|
local tipPopupLabelCJ = tipPopup:CreateFontString(nil, "BACKGROUND", "GameFontWhite")
|
|
tipPopupLabelCJ:SetFont("Fonts\\ARKai_T.ttf", 12)
|
|
tipPopupLabelCJ:SetPoint("TOPLEFT", tipPopupLabel, "BOTTOMLEFT", 0, 0)
|
|
tipPopupLabelCJ:SetPoint("TOPRIGHT", tipPopupLabel, "BOTTOMRIGHT", 0, 0)
|
|
tipPopupLabelCJ:SetJustifyH("LEFT")
|
|
tipPopupLabelCJ:SetJustifyV("TOP")
|
|
|
|
local tipPopupLabelK = tipPopup:CreateFontString(nil, "BACKGROUND", "GameFontWhite")
|
|
tipPopupLabelK:SetFont("Fonts\\K_Pagetext.TTF", 12)
|
|
tipPopupLabelK:SetPoint("TOPLEFT", tipPopupLabelCJ, "BOTTOMLEFT", 0, 0)
|
|
tipPopupLabelK:SetPoint("TOPRIGHT", tipPopupLabelCJ, "BOTTOMRIGHT", 0, 0)
|
|
tipPopupLabelK:SetJustifyH("LEFT")
|
|
tipPopupLabelK:SetJustifyV("TOP")
|
|
|
|
local urlWidget = CreateFrame("EditBox", nil, tipPopup)
|
|
WeakAuras.XMLTemplates["InputBoxTemplate"](urlWidget)
|
|
urlWidget:SetFont(STANDARD_TEXT_FONT, 12)
|
|
urlWidget:SetPoint("TOPLEFT", tipPopupLabelK, "BOTTOMLEFT", 6, 0)
|
|
urlWidget:SetPoint("TOPRIGHT", tipPopupLabelK, "BOTTOMRIGHT", 0, 0)
|
|
urlWidget:SetScript("OnChar", function() urlWidget:SetText(urlWidget.text); urlWidget:HighlightText(); end);
|
|
urlWidget:SetScript("OnMouseUp", function() urlWidget:HighlightText(); end);
|
|
urlWidget:SetScript("OnEscapePressed", function() tipPopup:Hide() end)
|
|
urlWidget:SetHeight(34)
|
|
|
|
local tipPopupCtrlC = tipPopup:CreateFontString(nil, "BACKGROUND", "GameFontWhite")
|
|
tipPopupCtrlC:SetPoint("TOPLEFT", urlWidget, "BOTTOMLEFT", -6, 0)
|
|
tipPopupCtrlC:SetPoint("TOPRIGHT", urlWidget, "BOTTOMRIGHT", 0, 0)
|
|
tipPopupCtrlC:SetJustifyH("LEFT")
|
|
tipPopupCtrlC:SetJustifyV("TOP")
|
|
tipPopupCtrlC:SetText(L["Press Ctrl+C to copy the URL"])
|
|
|
|
local function ToggleTip(referenceWidget, url, title, description, descriptionCJ, descriptionK, rightAligned, width)
|
|
width = width or 400
|
|
if tipPopup:IsVisible() and urlWidget.text == url then
|
|
tipPopup:Hide()
|
|
return
|
|
end
|
|
urlWidget.text = url
|
|
urlWidget:SetText(url)
|
|
tipPopupTitle:SetText(title)
|
|
tipPopupLabel:SetText(description)
|
|
tipPopupLabelCJ:SetText(descriptionCJ)
|
|
tipPopupLabelK:SetText(descriptionK)
|
|
urlWidget:HighlightText()
|
|
|
|
tipPopup:ClearAllPoints();
|
|
if rightAligned then
|
|
tipPopup:SetPoint("BOTTOMRIGHT", referenceWidget, "TOPRIGHT", 6, 4)
|
|
else
|
|
tipPopup:SetPoint("BOTTOMLEFT", referenceWidget, "TOPLEFT", -6, 4)
|
|
end
|
|
|
|
tipPopup:SetWidth(width)
|
|
tipPopup:Show()
|
|
tipPopup:SetHeight(26 + tipPopupTitle:GetHeight() + tipPopupLabel:GetHeight() + tipPopupLabelCJ:GetHeight() + tipPopupLabelK:GetHeight()
|
|
+ urlWidget:GetHeight() + tipPopupCtrlC:GetHeight())
|
|
-- This does somehow fix an issue where the first popup after a game restart doesn't show up.
|
|
-- This isn't reproducable after a simple ui reload, so no idea what goes wrong, but with this line here,
|
|
-- it seems to work.
|
|
tipPopupLabel:GetRect()
|
|
tipPopupLabelCJ:GetRect()
|
|
tipPopupLabelK:GetRect()
|
|
end
|
|
|
|
OptionsPrivate.ToggleTip = ToggleTip
|
|
|
|
local addFooter = function(title, texture, url, description, descriptionCJ, descriptionK, rightAligned, width)
|
|
local button = AceGUI:Create("WeakAurasToolbarButton")
|
|
button:SetSmallFont(true)
|
|
button:SetText(title)
|
|
button:SetTexture(texture)
|
|
button:SetCallback("OnClick", function()
|
|
ToggleTip(button.frame, url, title, description, descriptionCJ, descriptionK, rightAligned, width)
|
|
end)
|
|
button.frame:Show()
|
|
return button.frame
|
|
end
|
|
|
|
local function lineWrapDiscordList(list)
|
|
local patreonLines = {}
|
|
local lineLength = 0
|
|
local currentLine = {}
|
|
for _, patreon in ipairs(list) do
|
|
if lineLength + #patreon + 2 > 130 then
|
|
tinsert(patreonLines, table.concat(currentLine, ", ") .. ", ")
|
|
currentLine = {}
|
|
tinsert(currentLine, patreon)
|
|
lineLength = #patreon + 2
|
|
else
|
|
lineLength = lineLength + #patreon + 2
|
|
tinsert(currentLine, patreon)
|
|
end
|
|
end
|
|
if #currentLine > 0 then
|
|
tinsert(patreonLines, table.concat(currentLine, ", "))
|
|
end
|
|
return table.concat(patreonLines, "\n")
|
|
end
|
|
|
|
local thanksList = L["We thank"] .. "\n"
|
|
.. L["All maintainers of the libraries we use, especially:"] .. "\n"
|
|
.. "• " .. L["Ace: Funkeh, Nevcairiel"] .. "\n"
|
|
.. "• " .. L["LibCompress: Galmok"] .. "\n"
|
|
.. "• " .. L["LibCustomGlow: Dooez"] .. "\n"
|
|
.. "• " .. L["LibDeflate: Yoursafety"] .. "\n"
|
|
.. "• " .. L["LibDispel: Simpy"] .. "\n"
|
|
.. "• " .. L["LibSerialize: Sanjo"] .. "\n"
|
|
.. "• " .. L["Our translators (too many to name)"] .. "\n"
|
|
.. "• " .. L["And our Patreons, Discord Regulars and Subscribers, and Friends of the Addon:"] .. "\n"
|
|
|
|
thanksList = thanksList .. lineWrapDiscordList(OptionsPrivate.Private.DiscordList)
|
|
|
|
local footerSpacing = 4
|
|
local thanksListCJ = lineWrapDiscordList(OptionsPrivate.Private.DiscordListCJ)
|
|
local thanksListK = lineWrapDiscordList(OptionsPrivate.Private.DiscordListK)
|
|
|
|
local discordButton = addFooter(L["Discord"], [[Interface\AddOns\WeakAuras\Media\Textures\discord.tga]], "https://discord.gg/classlesswow",
|
|
L["Chat with WeakAuras experts on our Discord server."])
|
|
discordButton:SetParent(tipFrame)
|
|
discordButton:SetPoint("LEFT", tipFrame, "LEFT")
|
|
|
|
local documentationButton = addFooter(L["Documentation"], [[Interface\AddOns\WeakAuras\Media\Textures\GitHub.tga]], "https://github.com/WeakAuras/WeakAuras2/wiki",
|
|
L["Check out our wiki for a large collection of examples and snippets."])
|
|
documentationButton:SetParent(tipFrame)
|
|
documentationButton:SetPoint("LEFT", discordButton, "RIGHT", footerSpacing, 0)
|
|
|
|
local thanksButton = addFooter(L["Thanks"], [[Interface\AddOns\WeakAuras\Media\Textures\waheart.tga]],
|
|
"https://www.patreon.com/WeakAuras", thanksList, thanksListCJ, thanksListK, nil, 800)
|
|
thanksButton:SetParent(tipFrame)
|
|
thanksButton:SetPoint("LEFT", documentationButton, "RIGHT", footerSpacing, 0)
|
|
|
|
local changelogButton
|
|
if OptionsPrivate.changelog then
|
|
local changelog
|
|
if OptionsPrivate.changelog.highlightText then
|
|
changelog = L["Highlights"] .. "\n" .. OptionsPrivate.changelog.highlightText
|
|
else
|
|
changelog = OptionsPrivate.changelog.commitText
|
|
end
|
|
|
|
changelogButton = addFooter(L["Changelog"], "", OptionsPrivate.changelog.fullChangeLogUrl,
|
|
changelog, nil, nil, false, 800)
|
|
changelogButton:SetParent(tipFrame)
|
|
changelogButton:SetPoint("LEFT", thanksButton, "RIGHT", footerSpacing, 0)
|
|
end
|
|
|
|
local reportbugButton = addFooter(L["Found a Bug?"], [[Interface\AddOns\WeakAuras\Media\Textures\bug_report.tga]], "https://github.com/Ascension-Addons/WeakAuras-Ascension/issues",
|
|
L["Report bugs on our issue tracker."], nil, nil, true)
|
|
reportbugButton:SetParent(tipFrame)
|
|
reportbugButton:SetPoint("RIGHT", tipFrame, "RIGHT")
|
|
|
|
local wagoButton = addFooter(L["Find Auras"], [[Interface\AddOns\WeakAuras\Media\Textures\wago.tga]], "https://wago.io/search/imports/wow/all?q=3.3.5",
|
|
L["Browse Wago, the largest collection of auras."], nil, nil, true)
|
|
wagoButton:SetParent(tipFrame)
|
|
wagoButton:SetPoint("RIGHT", reportbugButton, "LEFT", -footerSpacing, 0)
|
|
|
|
local companionButton
|
|
if not OptionsPrivate.Private.CompanionData.slugs then
|
|
companionButton = addFooter(L["Update Auras"], [[Interface\AddOns\WeakAuras\Media\Textures\wagoupdate_refresh.tga]], "https://weakauras.wtf",
|
|
L["Keep your Wago imports up to date with the Companion App."])
|
|
companionButton:SetParent(tipFrame)
|
|
companionButton:SetPoint("RIGHT", wagoButton, "LEFT", -footerSpacing, 0)
|
|
end
|
|
|
|
frame.ShowTip = function(self)
|
|
self.tipFrame:Show()
|
|
self.buttonsContainer.frame:SetPoint("BOTTOMLEFT", self, "BOTTOMLEFT", 17, 30)
|
|
self.container.frame:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -17, 28)
|
|
end
|
|
|
|
frame.HideTip = function(self)
|
|
self.tipFrame:Hide()
|
|
self.buttonsContainer.frame:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 17, 12)
|
|
self.container.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -17, 10)
|
|
end
|
|
|
|
-- Right Side Container
|
|
local container = AceGUI:Create("InlineGroup")
|
|
container.frame:SetParent(frame)
|
|
container.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -17, 10)
|
|
container.frame:SetPoint("TOPLEFT", frame, "TOPRIGHT", -63 - WeakAuras.normalWidth * 340, 0)
|
|
container.frame:Show()
|
|
container.titletext:Hide()
|
|
-- Hide the border
|
|
container.content:GetParent():SetBackdrop(nil)
|
|
container.content:SetPoint("TOPLEFT", 0, -28)
|
|
container.content:SetPoint("BOTTOMRIGHT", 0, 0)
|
|
frame.container = container
|
|
frame.moversizer, frame.mover = OptionsPrivate.MoverSizer(frame)
|
|
|
|
-- filter line
|
|
local filterInput = CreateFrame("EditBox", "WeakAurasFilterInput", frame)
|
|
WeakAuras.XMLTemplates["SearchBoxTemplate"](filterInput)
|
|
filterInput:SetScript("OnTextChanged", function(self)
|
|
WA_SearchBoxTemplate_OnTextChanged(self)
|
|
OptionsPrivate.SortDisplayButtons(filterInput:GetText())
|
|
end)
|
|
filterInput:SetHeight(15)
|
|
filterInput:SetPoint("TOP", frame, "TOP", 0, -65)
|
|
filterInput:SetPoint("LEFT", frame, "LEFT", 24, 0)
|
|
filterInput:SetPoint("RIGHT", container.frame, "LEFT", -2, 0)
|
|
filterInput:SetFont(STANDARD_TEXT_FONT, 10)
|
|
frame.filterInput = filterInput
|
|
filterInput:Hide()
|
|
|
|
-- Left Side Container
|
|
local buttonsContainer = AceGUI:Create("InlineGroup")
|
|
buttonsContainer:SetWidth(170)
|
|
buttonsContainer.frame:SetParent(frame)
|
|
buttonsContainer.frame:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 17, 12)
|
|
buttonsContainer.frame:SetPoint("TOP", frame, "TOP", 0, -67)
|
|
buttonsContainer.frame:SetPoint("RIGHT", container.frame, "LEFT", -17)
|
|
buttonsContainer.frame:Show()
|
|
frame.buttonsContainer = buttonsContainer
|
|
|
|
-- Toolbar
|
|
local toolbarContainer = CreateFrame("Frame", nil, buttonsContainer.frame)
|
|
toolbarContainer:SetParent(buttonsContainer.frame)
|
|
-- toolbarContainer:Hide()
|
|
toolbarContainer:SetPoint("TOPLEFT", buttonsContainer.frame, "TOPLEFT", 30, 30)
|
|
toolbarContainer:SetPoint("BOTTOMRIGHT", buttonsContainer.frame, "TOPRIGHT", 0, 0)
|
|
|
|
local undo = AceGUI:Create("WeakAurasToolbarButton")
|
|
undo:SetText(L["Undo"])
|
|
undo:SetTexture("Interface\\AddOns\\WeakAuras\\Media\\Textures\\upleft")
|
|
undo:SetCallback("OnClick", function()
|
|
OptionsPrivate.Private.TimeMachine:StepBackward()
|
|
frame:FillOptions()
|
|
end)
|
|
undo.frame:SetParent(toolbarContainer)
|
|
if OptionsPrivate.Private.Features:Enabled("undo") then
|
|
undo.frame:Show()
|
|
else
|
|
undo.frame:Hide()
|
|
end
|
|
undo:SetPoint("LEFT")
|
|
|
|
local redo = AceGUI:Create("WeakAurasToolbarButton")
|
|
redo:SetText(L["Redo"])
|
|
redo:SetTexture("Interface\\AddOns\\WeakAuras\\Media\\Textures\\upright")
|
|
redo:SetCallback("OnClick", function()
|
|
OptionsPrivate.Private.TimeMachine:StepForward()
|
|
frame:FillOptions()
|
|
end)
|
|
redo.frame:SetParent(toolbarContainer)
|
|
if OptionsPrivate.Private.Features:Enabled("undo") then
|
|
redo.frame:Show()
|
|
else
|
|
redo.frame:Hide()
|
|
end
|
|
redo:SetPoint("LEFT", undo.frame, "RIGHT", 10, 0)
|
|
if OptionsPrivate.Private.TimeMachine:DescribeNext() ~= nil then
|
|
redo.frame:Enable()
|
|
else
|
|
redo.frame:Disable()
|
|
end
|
|
OptionsPrivate.Private.Features:Subscribe("undo",
|
|
function()
|
|
undo.frame:Show()
|
|
redo.frame:Show()
|
|
end,
|
|
function()
|
|
undo.frame:Hide()
|
|
redo.frame:Hide()
|
|
end
|
|
)
|
|
|
|
local tmControls = {
|
|
undo = undo,
|
|
redo = redo,
|
|
}
|
|
|
|
function tmControls:Step()
|
|
-- slightly annoying workaround
|
|
-- Buttons behave in a strange way if they are disabled inside of the OnClick handler
|
|
-- where the pushed texture refuses to vanish until the button is enabled & user clicks it again
|
|
-- so, just disable the button after next frame draw, so it's imperceptible to the user but we're not in the OnClick handler
|
|
WeakAuras.timer:ScheduleTimer(function()
|
|
self.undo:SetDisabled(OptionsPrivate.Private.TimeMachine:DescribePrevious() == nil)
|
|
self.redo:SetDisabled(OptionsPrivate.Private.TimeMachine:DescribeNext() == nil)
|
|
end, 0)
|
|
end
|
|
tmControls:Step()
|
|
OptionsPrivate.Private.TimeMachine.sub:AddSubscriber("Step", tmControls)
|
|
|
|
|
|
local newButton = AceGUI:Create("WeakAurasToolbarButton")
|
|
newButton:SetText(L["New Aura"])
|
|
newButton:SetTexture("Interface\\AddOns\\WeakAuras\\Media\\Textures\\newaura")
|
|
newButton.frame:SetParent(toolbarContainer)
|
|
newButton.frame:Show()
|
|
newButton:SetPoint("LEFT", redo.frame, "RIGHT", 10, 0)
|
|
frame.toolbarContainer = toolbarContainer
|
|
|
|
newButton:SetCallback("OnClick", function()
|
|
frame:NewAura()
|
|
end)
|
|
|
|
local importButton = AceGUI:Create("WeakAurasToolbarButton")
|
|
importButton:SetText(L["Import"])
|
|
importButton:SetTexture("Interface\\AddOns\\WeakAuras\\Media\\Textures\\importsmall")
|
|
importButton:SetCallback("OnClick", OptionsPrivate.ImportFromString)
|
|
importButton.frame:SetParent(toolbarContainer)
|
|
importButton.frame:Show()
|
|
importButton:SetPoint("LEFT", newButton.frame, "RIGHT", 10, 0)
|
|
|
|
local lockButton = AceGUI:Create("WeakAurasToolbarButton")
|
|
lockButton:SetText(L["Lock Positions"])
|
|
lockButton:SetTexture("Interface\\AddOns\\WeakAuras\\Media\\Textures\\lockPosition")
|
|
lockButton:SetCallback("OnClick", function(self)
|
|
if WeakAurasOptionsSaved.lockPositions then
|
|
lockButton:SetStrongHighlight(false)
|
|
lockButton:UnlockHighlight()
|
|
WeakAurasOptionsSaved.lockPositions = false
|
|
else
|
|
lockButton:SetStrongHighlight(true)
|
|
lockButton:LockHighlight()
|
|
WeakAurasOptionsSaved.lockPositions = true
|
|
end
|
|
end)
|
|
if WeakAurasOptionsSaved.lockPositions then
|
|
lockButton:LockHighlight()
|
|
end
|
|
lockButton.frame:SetParent(toolbarContainer)
|
|
lockButton.frame:Show()
|
|
lockButton:SetPoint("LEFT", importButton.frame, "RIGHT", 10, 0)
|
|
|
|
local magnetButton = AceGUI:Create("WeakAurasToolbarButton")
|
|
magnetButton:SetText(L["Magnetically Align"])
|
|
magnetButton:SetTexture("Interface\\AddOns\\WeakAuras\\Media\\Textures\\magnetic")
|
|
magnetButton:SetCallback("OnClick", function(self)
|
|
if WeakAurasOptionsSaved.magnetAlign then
|
|
magnetButton:SetStrongHighlight(false)
|
|
magnetButton:UnlockHighlight()
|
|
WeakAurasOptionsSaved.magnetAlign = false
|
|
else
|
|
magnetButton:SetStrongHighlight(true)
|
|
magnetButton:LockHighlight()
|
|
WeakAurasOptionsSaved.magnetAlign = true
|
|
end
|
|
end)
|
|
|
|
if WeakAurasOptionsSaved.magnetAlign then
|
|
magnetButton:LockHighlight()
|
|
end
|
|
magnetButton.frame:SetParent(toolbarContainer)
|
|
magnetButton.frame:Show()
|
|
magnetButton:SetPoint("LEFT", lockButton.frame, "RIGHT", 10, 0)
|
|
|
|
|
|
local loadProgress = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
|
loadProgress:SetPoint("TOP", buttonsContainer.frame, "TOP", 0, -4)
|
|
loadProgress:SetText(L["Creating options: "].."0/0")
|
|
frame.loadProgress = loadProgress
|
|
|
|
frame.SetLoadProgressVisible = function(self, visible)
|
|
self.loadProgessVisible = visible
|
|
self:UpdateFrameVisible()
|
|
end
|
|
|
|
local buttonsScroll = AceGUI:Create("ScrollFrame")
|
|
buttonsScroll:SetLayout("ButtonsScrollLayout")
|
|
buttonsScroll.width = "fill"
|
|
buttonsScroll.height = "fill"
|
|
buttonsContainer:SetLayout("fill")
|
|
buttonsContainer:AddChild(buttonsScroll)
|
|
buttonsScroll.DeleteChild = function(self, delete)
|
|
for index, widget in ipairs(buttonsScroll.children) do
|
|
if widget == delete then
|
|
tremove(buttonsScroll.children, index)
|
|
end
|
|
end
|
|
delete:OnRelease()
|
|
buttonsScroll:DoLayout()
|
|
end
|
|
frame.buttonsScroll = buttonsScroll
|
|
|
|
function buttonsScroll:GetScrollPos()
|
|
local status = self.status or self.localstatus
|
|
return status.offset, status.offset + self.scrollframe:GetHeight()
|
|
end
|
|
|
|
-- override SetScroll to make children visible as needed
|
|
local oldSetScroll = buttonsScroll.SetScroll
|
|
buttonsScroll.SetScroll = function(self, value)
|
|
oldSetScroll(self, value)
|
|
self.LayoutFunc(self.content, self.children, true)
|
|
end
|
|
|
|
function buttonsScroll:SetScrollPos(top, bottom)
|
|
local status = self.status or self.localstatus
|
|
local viewheight = self.scrollframe:GetHeight()
|
|
local height = self.content:GetHeight()
|
|
local move
|
|
|
|
local viewtop = -1 * status.offset
|
|
local viewbottom = -1 * (status.offset + viewheight)
|
|
if top > viewtop then
|
|
move = top - viewtop
|
|
elseif bottom < viewbottom then
|
|
move = bottom - viewbottom
|
|
else
|
|
move = 0
|
|
end
|
|
|
|
status.offset = status.offset - move
|
|
|
|
self.content:ClearAllPoints()
|
|
self.content:SetPoint("TOPLEFT", 0, status.offset)
|
|
self.content:SetPoint("TOPRIGHT", 0, status.offset)
|
|
|
|
status.scrollvalue = status.offset / ((height - viewheight) / 1000.0)
|
|
end
|
|
|
|
-- Ready to Install section
|
|
local pendingInstallButton = AceGUI:Create("WeakAurasLoadedHeaderButton")
|
|
pendingInstallButton:SetText(L["Ready for Install"])
|
|
pendingInstallButton:Disable()
|
|
pendingInstallButton:EnableExpand()
|
|
pendingInstallButton.frame.view:Hide()
|
|
if odb.pendingImportCollapse then
|
|
pendingInstallButton:Collapse()
|
|
else
|
|
pendingInstallButton:Expand()
|
|
end
|
|
pendingInstallButton:SetOnExpandCollapse(function()
|
|
if pendingInstallButton:GetExpanded() then
|
|
odb.pendingImportCollapse = nil
|
|
else
|
|
odb.pendingImportCollapse = true
|
|
end
|
|
OptionsPrivate.SortDisplayButtons()
|
|
end)
|
|
pendingInstallButton:SetExpandDescription(L["Expand all pending Import"])
|
|
pendingInstallButton:SetCollapseDescription(L["Collapse all pending Import"])
|
|
frame.pendingInstallButton = pendingInstallButton
|
|
|
|
-- Ready for update section
|
|
local pendingUpdateButton = AceGUI:Create("WeakAurasLoadedHeaderButton")
|
|
pendingUpdateButton:SetText(L["Ready for Update"])
|
|
pendingUpdateButton:Disable()
|
|
pendingUpdateButton:EnableExpand()
|
|
pendingUpdateButton.frame.view:Hide()
|
|
if odb.pendingUpdateCollapse then
|
|
pendingUpdateButton:Collapse()
|
|
else
|
|
pendingUpdateButton:Expand()
|
|
end
|
|
pendingUpdateButton:SetOnExpandCollapse(function()
|
|
if pendingUpdateButton:GetExpanded() then
|
|
odb.pendingUpdateCollapse = nil
|
|
else
|
|
odb.pendingUpdateCollapse = true
|
|
end
|
|
OptionsPrivate.SortDisplayButtons()
|
|
end)
|
|
pendingUpdateButton:SetExpandDescription(L["Expand all pending Import"])
|
|
pendingUpdateButton:SetCollapseDescription(L["Collapse all pending Import"])
|
|
frame.pendingUpdateButton = pendingUpdateButton
|
|
|
|
-- Loaded section
|
|
local loadedButton = AceGUI:Create("WeakAurasLoadedHeaderButton")
|
|
loadedButton:SetText(L["Loaded/Standby"])
|
|
loadedButton:Disable()
|
|
loadedButton:EnableExpand()
|
|
if odb.loadedCollapse then
|
|
loadedButton:Collapse()
|
|
else
|
|
loadedButton:Expand()
|
|
end
|
|
loadedButton:SetOnExpandCollapse(function()
|
|
if loadedButton:GetExpanded() then
|
|
odb.loadedCollapse = nil
|
|
else
|
|
odb.loadedCollapse = true
|
|
end
|
|
OptionsPrivate.SortDisplayButtons()
|
|
end)
|
|
loadedButton:SetExpandDescription(L["Expand all loaded displays"])
|
|
loadedButton:SetCollapseDescription(L["Collapse all loaded displays"])
|
|
loadedButton:SetViewClick(function()
|
|
local suspended = OptionsPrivate.Private.PauseAllDynamicGroups()
|
|
|
|
if loadedButton.view.visibility == 2 then
|
|
for _, child in ipairs(loadedButton.childButtons) do
|
|
if child:IsLoaded() then
|
|
child:PriorityHide(2)
|
|
end
|
|
end
|
|
loadedButton:PriorityHide(2)
|
|
else
|
|
for _, child in ipairs(loadedButton.childButtons) do
|
|
if child:IsLoaded() then
|
|
child:PriorityShow(2)
|
|
end
|
|
end
|
|
loadedButton:PriorityShow(2)
|
|
end
|
|
OptionsPrivate.Private.ResumeAllDynamicGroups(suspended)
|
|
end)
|
|
loadedButton.RecheckVisibility = function(self)
|
|
local none, all = true, true
|
|
for _, child in ipairs(loadedButton.childButtons) do
|
|
if child:GetVisibility() ~= 2 then
|
|
all = false
|
|
end
|
|
if child:GetVisibility() ~= 0 then
|
|
none = false
|
|
end
|
|
end
|
|
local newVisibility
|
|
if all then
|
|
newVisibility = 2
|
|
elseif none then
|
|
newVisibility = 0
|
|
else
|
|
newVisibility = 1
|
|
end
|
|
if newVisibility ~= self.view.visibility then
|
|
self.view.visibility = newVisibility
|
|
self:UpdateViewTexture()
|
|
end
|
|
end
|
|
loadedButton:SetViewDescription(L["Toggle the visibility of all loaded displays"])
|
|
loadedButton.childButtons = {}
|
|
frame.loadedButton = loadedButton
|
|
|
|
-- Not Loaded section
|
|
local unloadedButton = AceGUI:Create("WeakAurasLoadedHeaderButton")
|
|
unloadedButton:SetText(L["Not Loaded"])
|
|
unloadedButton:Disable()
|
|
unloadedButton:EnableExpand()
|
|
if odb.unloadedCollapse then
|
|
unloadedButton:Collapse()
|
|
else
|
|
unloadedButton:Expand()
|
|
end
|
|
unloadedButton:SetOnExpandCollapse(function()
|
|
if unloadedButton:GetExpanded() then
|
|
odb.unloadedCollapse = nil
|
|
else
|
|
odb.unloadedCollapse = true
|
|
end
|
|
OptionsPrivate.SortDisplayButtons()
|
|
end)
|
|
unloadedButton:SetExpandDescription(L["Expand all non-loaded displays"])
|
|
unloadedButton:SetCollapseDescription(L["Collapse all non-loaded displays"])
|
|
unloadedButton:SetViewClick(function()
|
|
local suspended = OptionsPrivate.Private.PauseAllDynamicGroups()
|
|
if unloadedButton.view.visibility == 2 then
|
|
for _, child in ipairs(unloadedButton.childButtons) do
|
|
child:PriorityHide(2)
|
|
end
|
|
unloadedButton:PriorityHide(2)
|
|
else
|
|
for _, child in ipairs(unloadedButton.childButtons) do
|
|
child:PriorityShow(2)
|
|
end
|
|
unloadedButton:PriorityShow(2)
|
|
end
|
|
OptionsPrivate.Private.ResumeAllDynamicGroups(suspended)
|
|
end)
|
|
unloadedButton.RecheckVisibility = function(self)
|
|
local none, all = true, true
|
|
for _, child in ipairs(unloadedButton.childButtons) do
|
|
if child:GetVisibility() ~= 2 then
|
|
all = false
|
|
end
|
|
if child:GetVisibility() ~= 0 then
|
|
none = false
|
|
end
|
|
end
|
|
local newVisibility
|
|
if all then
|
|
newVisibility = 2
|
|
elseif none then
|
|
newVisibility = 0
|
|
else
|
|
newVisibility = 1
|
|
end
|
|
if newVisibility ~= self.view.visibility then
|
|
self.view.visibility = newVisibility
|
|
self:UpdateViewTexture()
|
|
end
|
|
end
|
|
unloadedButton:SetViewDescription(L["Toggle the visibility of all non-loaded displays"])
|
|
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)
|
|
WeakAuras.XMLTemplates["PortraitFrameTemplate"](dynamicTextCodesFrame)
|
|
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, widget, event)
|
|
-- If the text edit has focus when the user clicks on the button, we'll get two events:
|
|
-- a) The OnEditFocusLost
|
|
-- b) The ToggleButton OnClick event
|
|
-- Since we want to hide the text replacement window in that case,
|
|
-- ignore the ToggleButton if it is directly after the OnEditFocusLost
|
|
local currentTime = GetTime()
|
|
if event == "ToggleButton"
|
|
and dynamicTextCodesFrame.lastCaller
|
|
and dynamicTextCodesFrame.lastCaller.event == "OnEditFocusLost"
|
|
and currentTime - dynamicTextCodesFrame.lastCaller.time < 0.2
|
|
then
|
|
return
|
|
end
|
|
|
|
dynamicTextCodesFrame.lastCaller = {
|
|
event = event,
|
|
time = currentTime,
|
|
}
|
|
|
|
if event == "OnEnterPressed" then
|
|
dynamicTextCodesFrame:Hide()
|
|
elseif event == "OnEditFocusGained" or not dynamicTextCodesFrame:IsShown() then
|
|
dynamicTextCodesFrame:Show()
|
|
if OptionsPrivate.currentDynamicTextInput ~= widget then
|
|
OptionsPrivate.UpdateTextReplacements(dynamicTextCodesFrame, data)
|
|
end
|
|
OptionsPrivate.currentDynamicTextInput = widget
|
|
elseif not dynamicTextCodesFrame:IsMouseOver() then -- Prevents hiding when clicking inside the frame
|
|
dynamicTextCodesFrame:Hide()
|
|
end
|
|
end
|
|
|
|
frame.ClearOptions = function(self, id)
|
|
aceOptions[id] = nil
|
|
OptionsPrivate.commonOptionsCache:Clear()
|
|
if type(id) == "string" then
|
|
local data = WeakAuras.GetData(id)
|
|
if data and data.parent then
|
|
frame:ClearOptions(data.parent)
|
|
end
|
|
for child in OptionsPrivate.Private.TraverseAllChildren(tempGroup) do
|
|
if (id == child.id) then
|
|
frame:ClearOptions(tempGroup.id)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
frame.ReloadOptions = function(self)
|
|
if self.pickedDisplay then
|
|
self:ClearAndUpdateOptions(self.pickedDisplay, true)
|
|
self:FillOptions()
|
|
end
|
|
end
|
|
|
|
frame.ClearAndUpdateOptions = function(self, id, clearChildren)
|
|
frame:ClearOptions(id)
|
|
|
|
if clearChildren then
|
|
local data
|
|
if type(id) == "string" then
|
|
data = WeakAuras.GetData(id)
|
|
elseif self.pickedDisplay then
|
|
data = tempGroup
|
|
end
|
|
|
|
for child in OptionsPrivate.Private.TraverseAllChildren(data) do
|
|
frame:ClearOptions(child.id)
|
|
end
|
|
end
|
|
if (type(self.pickedDisplay) == "string" and self.pickedDisplay == id)
|
|
or (type(self.pickedDisplay) == "table" and id == tempGroup.id)
|
|
then
|
|
frame:UpdateOptions()
|
|
end
|
|
end
|
|
|
|
frame.UpdateOptions = function(self)
|
|
if not self.pickedDisplay then
|
|
return
|
|
end
|
|
OptionsPrivate.commonOptionsCache:Clear()
|
|
self.selectedTab = self.selectedTab or "region"
|
|
local data
|
|
if type(self.pickedDisplay) == "string" then
|
|
data = WeakAuras.GetData(frame.pickedDisplay)
|
|
elseif self.pickedDisplay then
|
|
data = tempGroup
|
|
end
|
|
|
|
if not data.controlledChildren or data == tempGroup then
|
|
if self.selectedTab == "group" then
|
|
self.selectedTab = "region"
|
|
end
|
|
end
|
|
|
|
local optionTable = self:EnsureOptions(data, self.selectedTab)
|
|
if optionTable then
|
|
AceConfigRegistry:RegisterOptionsTable("WeakAuras", optionTable, true)
|
|
end
|
|
end
|
|
|
|
frame.EnsureOptions = function(self, data, tab)
|
|
local id = data.id
|
|
aceOptions[id] = aceOptions[id] or {}
|
|
if not aceOptions[id][tab] then
|
|
local optionsGenerator =
|
|
{
|
|
group = OptionsPrivate.GetGroupOptions,
|
|
region = OptionsPrivate.GetDisplayOptions,
|
|
trigger = OptionsPrivate.GetTriggerOptions,
|
|
conditions = OptionsPrivate.GetConditionOptions,
|
|
load = OptionsPrivate.GetLoadOptions,
|
|
action = OptionsPrivate.GetActionOptions,
|
|
animation = OptionsPrivate.GetAnimationOptions,
|
|
authorOptions = OptionsPrivate.GetAuthorOptions,
|
|
information = OptionsPrivate.GetInformationOptions,
|
|
}
|
|
if optionsGenerator[tab] then
|
|
aceOptions[id][tab] = optionsGenerator[tab](data)
|
|
end
|
|
end
|
|
return aceOptions[id][tab]
|
|
end
|
|
|
|
-- This function refills the options pane
|
|
-- This is ONLY necessary if AceOptions doesn't know that it should do
|
|
-- that automatically. That is any change that goes through the AceOptions
|
|
-- doesn't need to call this
|
|
-- Any changes to the options that go around that, e.g. drag/drop, group,
|
|
-- texture pick, etc should call this
|
|
frame.FillOptions = function(self)
|
|
if not self.pickedDisplay then
|
|
return
|
|
end
|
|
|
|
OptionsPrivate.commonOptionsCache:Clear()
|
|
|
|
frame:UpdateOptions()
|
|
|
|
local data
|
|
if type(self.pickedDisplay) == "string" then
|
|
data = WeakAuras.GetData(frame.pickedDisplay)
|
|
elseif self.pickedDisplay then
|
|
data = tempGroup
|
|
end
|
|
|
|
local tabsWidget
|
|
|
|
container.frame:SetPoint("TOPLEFT", frame, "TOPRIGHT", -63 - WeakAuras.normalWidth * 340, -10)
|
|
container:ReleaseChildren()
|
|
container:SetLayout("Fill")
|
|
tabsWidget = AceGUI:Create("TabGroup")
|
|
|
|
local tabs = {
|
|
{ value = "region", text = L["Display"]},
|
|
{ value = "trigger", text = L["Trigger"]},
|
|
{ value = "conditions", text = L["Conditions"]},
|
|
{ value = "action", text = L["Actions"]},
|
|
{ value = "animation", text = L["Animations"]},
|
|
{ value = "load", text = L["Load"]},
|
|
{ value = "authorOptions", text = L["Custom Options"]},
|
|
{ value = "information", text = L["Information"]},
|
|
}
|
|
-- Check if group and not the temp group
|
|
if data.controlledChildren and type(data.id) == "string" then
|
|
tinsert(tabs, 1, { value = "group", text = L["Group"]})
|
|
end
|
|
|
|
tabsWidget:SetTabs(tabs)
|
|
tabsWidget:SelectTab(self.selectedTab)
|
|
tabsWidget:SetLayout("Fill")
|
|
container:AddChild(tabsWidget)
|
|
|
|
local group = AceGUI:Create("WeakAurasInlineGroup")
|
|
tabsWidget:AddChild(group)
|
|
|
|
tabsWidget:SetCallback("OnGroupSelected", function(self, event, tab)
|
|
frame.selectedTab = tab
|
|
frame:FillOptions()
|
|
end)
|
|
|
|
AceConfigDialog:Open("WeakAuras", group)
|
|
tabsWidget:SetTitle("")
|
|
|
|
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)
|
|
local index = nil
|
|
for i, childId in pairs(tempGroup.controlledChildren) do
|
|
if childId == id then
|
|
index = i
|
|
break
|
|
end
|
|
end
|
|
|
|
tremove(tempGroup.controlledChildren, index)
|
|
displayButtons[id]:ClearPick()
|
|
|
|
-- Clear trigger expand state
|
|
OptionsPrivate.ClearTriggerExpandState()
|
|
|
|
self:ClearOptions(tempGroup.id)
|
|
self:FillOptions()
|
|
end
|
|
|
|
frame.OnRename = function(self, uid, oldid, newid)
|
|
if type(frame.pickedDisplay) == "string" and frame.pickedDisplay == oldid then
|
|
frame.pickedDisplay = newid
|
|
else
|
|
for i, childId in pairs(tempGroup.controlledChildren) do
|
|
if (childId == newid) then
|
|
tempGroup.controlledChildren[i] = newid
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
frame.ClearPicks = function(self, noHide)
|
|
local suspended = OptionsPrivate.Private.PauseAllDynamicGroups()
|
|
for id, button in pairs(displayButtons) do
|
|
button:ClearPick(true)
|
|
if not noHide then
|
|
button:PriorityHide(1)
|
|
end
|
|
end
|
|
if not noHide then
|
|
for id, button in pairs(displayButtons) do
|
|
if button.data.controlledChildren then
|
|
button:RecheckVisibility()
|
|
end
|
|
end
|
|
end
|
|
|
|
frame.pickedDisplay = nil
|
|
frame.pickedOption = nil
|
|
wipe(tempGroup.controlledChildren)
|
|
loadedButton:ClearPick(noHide)
|
|
unloadedButton:ClearPick(noHide)
|
|
container:ReleaseChildren()
|
|
self.moversizer:Hide()
|
|
|
|
OptionsPrivate.Private.ResumeAllDynamicGroups(suspended)
|
|
|
|
-- Clear trigger expand state
|
|
OptionsPrivate.ClearTriggerExpandState()
|
|
end
|
|
|
|
frame.GetTargetAura = function(self)
|
|
if self.pickedDisplay then
|
|
if type(self.pickedDisplay) == "table" and tempGroup.controlledChildren and tempGroup.controlledChildren[1] then
|
|
return tempGroup.controlledChildren[1]
|
|
elseif type(self.pickedDisplay) == "string" then
|
|
return self.pickedDisplay
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
frame.NewAura = function(self)
|
|
local targetId
|
|
local targetIsDynamicGroup
|
|
|
|
if self.pickedDisplay then
|
|
if type(self.pickedDisplay) == "table" and tempGroup.controlledChildren and tempGroup.controlledChildren[1] then
|
|
targetId = tempGroup.controlledChildren[1]
|
|
WeakAuras.PickDisplay(targetId)
|
|
elseif type(self.pickedDisplay) == "string" then
|
|
targetId = self.pickedDisplay
|
|
else
|
|
self:ClearPicks()
|
|
end
|
|
end
|
|
|
|
if targetId then
|
|
local pickedButton = OptionsPrivate.GetDisplayButton(targetId)
|
|
if pickedButton.data.controlledChildren then
|
|
targetIsDynamicGroup = pickedButton.data.regionType == "dynamicgroup"
|
|
else
|
|
local parent = pickedButton.data.parent
|
|
local parentData = parent and WeakAuras.GetData(parent)
|
|
targetIsDynamicGroup = parentData and parentData.regionType == "dynamicgroup"
|
|
end
|
|
end
|
|
self.dynamicTextCodesFrame:Hide()
|
|
self.moversizer:Hide()
|
|
self.pickedOption = "New"
|
|
|
|
container:ReleaseChildren()
|
|
container.frame:SetPoint("TOPLEFT", frame, "TOPRIGHT", -63 - WeakAuras.normalWidth * 340, 0)
|
|
container:SetLayout("fill")
|
|
local border = AceGUI:Create("InlineGroup")
|
|
border:SetLayout("Fill")
|
|
container:AddChild(border)
|
|
|
|
local containerScroll = AceGUI:Create("ScrollFrame")
|
|
containerScroll:SetLayout("flow")
|
|
border:AddChild(containerScroll)
|
|
|
|
local enabled = select(4, GetAddOnInfo("WeakAurasTemplates"))
|
|
if enabled then
|
|
local simpleLabel = AceGUI:Create("Label")
|
|
simpleLabel:SetFont(STANDARD_TEXT_FONT, 24, "OUTLINE")
|
|
simpleLabel:SetColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
|
|
simpleLabel:SetText(L["Simple"])
|
|
simpleLabel:SetFullWidth(true)
|
|
containerScroll:AddChild(simpleLabel)
|
|
|
|
local button = AceGUI:Create("WeakAurasNewButton")
|
|
button:SetTitle(L["Premade Auras"])
|
|
button:SetDescription(L["Offer a guided way to create auras for your character"])
|
|
button:SetIcon("Interface\\Icons\\Inv_misc_book_09")
|
|
button:SetClick(function()
|
|
OptionsPrivate.OpenTriggerTemplate(nil, self:GetTargetAura())
|
|
end)
|
|
containerScroll:AddChild(button)
|
|
|
|
local spacer1Label = AceGUI:Create("Label")
|
|
spacer1Label:SetText("")
|
|
containerScroll:AddChild(spacer1Label)
|
|
|
|
local advancedLabel = AceGUI:Create("Label")
|
|
advancedLabel:SetFont(STANDARD_TEXT_FONT, 24, "OUTLINE")
|
|
advancedLabel:SetColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
|
|
advancedLabel:SetText(L["Advanced"])
|
|
advancedLabel:SetFullWidth(true)
|
|
containerScroll:AddChild(advancedLabel)
|
|
end
|
|
|
|
local regionTypesSorted = {}
|
|
for regionType, regionData in pairs(OptionsPrivate.Private.regionOptions) do
|
|
tinsert(regionTypesSorted, regionType)
|
|
end
|
|
|
|
-- Sort group + dynamic group first, then the others alphabetically
|
|
table.sort(regionTypesSorted, function(a, b)
|
|
if (a == "group") then
|
|
return true
|
|
end
|
|
|
|
if (b == "group") then
|
|
return false
|
|
end
|
|
|
|
if (a == "dynamicgroup") then
|
|
return true
|
|
end
|
|
if (b == "dynamicgroup") then
|
|
return false
|
|
end
|
|
|
|
return OptionsPrivate.Private.regionOptions[a].displayName < OptionsPrivate.Private.regionOptions[b].displayName
|
|
end)
|
|
|
|
for index, regionType in ipairs(regionTypesSorted) do
|
|
if (targetIsDynamicGroup and (regionType == "group" or regionType == "dynamicgroup")) then
|
|
-- Dynamic groups can't contain group/dynamic groups
|
|
else
|
|
local regionData = OptionsPrivate.Private.regionOptions[regionType]
|
|
local button = AceGUI:Create("WeakAurasNewButton")
|
|
button:SetTitle(regionData.displayName)
|
|
if(type(regionData.icon) == "string" or type(regionData.icon) == "table") then
|
|
button:SetIcon(regionData.icon)
|
|
end
|
|
button:SetDescription(regionData.description)
|
|
button:SetClick(function()
|
|
WeakAuras.NewAura(nil, regionType, self:GetTargetAura())
|
|
end)
|
|
containerScroll:AddChild(button)
|
|
end
|
|
end
|
|
|
|
local spacer2Label = AceGUI:Create("Label")
|
|
spacer2Label:SetText("")
|
|
containerScroll:AddChild(spacer2Label)
|
|
|
|
local externalLabel = AceGUI:Create("Label")
|
|
externalLabel:SetFont(STANDARD_TEXT_FONT, 24, "OUTLINE")
|
|
externalLabel:SetColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b)
|
|
externalLabel:SetText(L["External"])
|
|
externalLabel:SetFullWidth(true)
|
|
containerScroll:AddChild(externalLabel)
|
|
|
|
local spacer3Label = AceGUI:Create("Label")
|
|
spacer3Label:SetText("")
|
|
containerScroll:AddChild(spacer3Label)
|
|
|
|
-- Import
|
|
local importButton = AceGUI:Create("WeakAurasNewButton")
|
|
importButton:SetTitle(L["Import"])
|
|
|
|
local data = {
|
|
outline = false,
|
|
color = {1, 1, 1, 1},
|
|
justify = "CENTER",
|
|
font = "Friz Quadrata TT",
|
|
fontSize = 8,
|
|
displayText = [[
|
|
b4vmErLxtfM
|
|
xu5fDEn1CEn
|
|
vmUmJyZ4hyY
|
|
DtnEnvBEnfz
|
|
EnfzErLxtjx
|
|
zNL2BUrvEWv
|
|
MxtfwDYfMyH
|
|
jNxtLgzEnLt
|
|
LDNx051u25L
|
|
tXmdmY4fDE5
|
|
]]
|
|
}
|
|
|
|
if not frame.importThumbnail then
|
|
local thumbnail = OptionsPrivate.Private.regionOptions["text"].createThumbnail(UIParent)
|
|
OptionsPrivate.Private.regionOptions["text"].modifyThumbnail(UIParent, thumbnail, data)
|
|
thumbnail.mask:SetPoint("BOTTOMLEFT", thumbnail, "BOTTOMLEFT", 3, 3)
|
|
thumbnail.mask:SetPoint("TOPRIGHT", thumbnail, "TOPRIGHT", -3, -3)
|
|
frame.importThumbnail = thumbnail
|
|
end
|
|
|
|
importButton:SetIcon(frame.importThumbnail)
|
|
importButton:SetDescription(L["Import a display from an encoded string"])
|
|
importButton:SetClick(OptionsPrivate.ImportFromString)
|
|
containerScroll:AddChild(importButton)
|
|
end
|
|
|
|
local function ExpandParents(data)
|
|
if data.parent then
|
|
if not displayButtons[data.parent]:GetExpanded() then
|
|
displayButtons[data.parent]:Expand()
|
|
end
|
|
local parentData = WeakAuras.GetData(data.parent)
|
|
ExpandParents(parentData)
|
|
end
|
|
end
|
|
|
|
frame.PickDisplay = function(self, id, tab, noHide)
|
|
local data = WeakAuras.GetData(id)
|
|
|
|
-- Always expand even if already picked
|
|
ExpandParents(data)
|
|
|
|
if OptionsPrivate.Private.loaded[id] ~= nil then
|
|
-- Under loaded
|
|
if not loadedButton:GetExpanded() then
|
|
loadedButton:Expand()
|
|
end
|
|
else
|
|
-- Under Unloaded
|
|
if not unloadedButton:GetExpanded() then
|
|
unloadedButton:Expand()
|
|
end
|
|
end
|
|
|
|
if self.pickedDisplay == id and (self.pickedDisplay == tab or tab == nil) then
|
|
return
|
|
end
|
|
|
|
local suspended = OptionsPrivate.Private.PauseAllDynamicGroups()
|
|
|
|
self:ClearPicks(noHide)
|
|
|
|
displayButtons[id]:Pick()
|
|
self.pickedDisplay = id
|
|
|
|
|
|
if tab then
|
|
self.selectedTab = tab
|
|
end
|
|
self:FillOptions()
|
|
WeakAuras.SetMoverSizer(id)
|
|
|
|
local _, _, _, _, yOffset = displayButtons[id].frame:GetPoint(1)
|
|
if not yOffset then
|
|
yOffset = displayButtons[id].frame.yOffset
|
|
end
|
|
if yOffset then
|
|
self.buttonsScroll:SetScrollPos(yOffset, yOffset - 32)
|
|
end
|
|
|
|
for child in OptionsPrivate.Private.TraverseAllChildren(data) do
|
|
displayButtons[child.id]:PriorityShow(1)
|
|
end
|
|
displayButtons[data.id]:RecheckParentVisibility()
|
|
|
|
OptionsPrivate.Private.ResumeAllDynamicGroups(suspended)
|
|
end
|
|
|
|
frame.CenterOnPicked = function(self)
|
|
if self.pickedDisplay then
|
|
local centerId = type(self.pickedDisplay) == "string" and self.pickedDisplay or self.pickedDisplay.controlledChildren[1]
|
|
|
|
if displayButtons[centerId] then
|
|
local _, _, _, _, yOffset = displayButtons[centerId].frame:GetPoint(1)
|
|
if not yOffset then
|
|
yOffset = displayButtons[centerId].frame.yOffset
|
|
end
|
|
if yOffset then
|
|
self.buttonsScroll:SetScrollPos(yOffset, yOffset - 32)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
frame.PickDisplayMultiple = function(self, id)
|
|
if not self.pickedDisplay then
|
|
self:PickDisplay(id)
|
|
else
|
|
local wasGroup = false
|
|
if type(self.pickedDisplay) == "string" then
|
|
if WeakAuras.GetData(self.pickedDisplay).controlledChildren or WeakAuras.GetData(id).controlledChildren then
|
|
wasGroup = true
|
|
elseif not OptionsPrivate.IsDisplayPicked(id) then
|
|
tinsert(tempGroup.controlledChildren, self.pickedDisplay)
|
|
end
|
|
end
|
|
if wasGroup then
|
|
self:PickDisplay(id)
|
|
elseif not OptionsPrivate.IsDisplayPicked(id) then
|
|
self.pickedDisplay = tempGroup
|
|
displayButtons[id]:Pick()
|
|
tinsert(tempGroup.controlledChildren, id)
|
|
OptionsPrivate.ClearOptions(tempGroup.id)
|
|
self:FillOptions()
|
|
end
|
|
end
|
|
end
|
|
|
|
frame.PickDisplayBatch = function(self, batchSelection)
|
|
local alreadySelected = {}
|
|
for child in OptionsPrivate.Private.TraverseAllChildren(tempGroup) do
|
|
alreadySelected[child.id] = true
|
|
end
|
|
|
|
for _, id in ipairs(batchSelection) do
|
|
if not alreadySelected[id] then
|
|
displayButtons[id]:Pick()
|
|
tinsert(tempGroup.controlledChildren, id)
|
|
end
|
|
end
|
|
frame:ClearOptions(tempGroup.id)
|
|
self.pickedDisplay = tempGroup
|
|
self:FillOptions()
|
|
end
|
|
|
|
frame.GetPickedDisplay = function(self)
|
|
if type(self.pickedDisplay) == "string" then
|
|
return WeakAuras.GetData(self.pickedDisplay)
|
|
end
|
|
return self.pickedDisplay
|
|
end
|
|
|
|
frame:SetClampedToScreen(true)
|
|
local w, h = frame:GetSize()
|
|
local left, right, top, bottom = w/2,-w/2, 0, h-25
|
|
frame:SetClampRectInsets(left, right, top, bottom)
|
|
|
|
--[[ Add warning about Midnight support ending, to notify users about possible coming changes
|
|
local midnightWarning = CreateFrame("Frame", nil, frame)
|
|
midnightWarning:SetBackdrop({
|
|
bgFile = "Interface\\Addons\\WeakAuras\\Media\\Textures\\Square_FullWhite.tga",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true,
|
|
tileSize = 16,
|
|
edgeSize = 16,
|
|
insets = { left = 4, right = 4, top = 4, bottom = 4 }
|
|
})
|
|
|
|
midnightWarning:SetBackdropBorderColor(1, 0, 0, 1);
|
|
midnightWarning:SetBackdropColor(0, 0, 0, 1)
|
|
|
|
midnightWarning:SetPoint("TOPLEFT", frame, "BOTTOMLEFT")
|
|
midnightWarning:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT")
|
|
midnightWarning:SetHeight(50)
|
|
|
|
local text = midnightWarning:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
|
|
text:SetPoint("LEFT", midnightWarning, "LEFT", 10, 0)
|
|
text:SetText(L["WeakAuras will not support Midnight. On release of the prepatch, WeakAuras will be disabled.\nRead more on our Patreon page https://patreon.com/WeakAuras"])
|
|
|
|
-- Fade-out animation and hide for rest of the session
|
|
local fade = midnightWarning:CreateAnimationGroup()
|
|
local alpha = fade:CreateAnimation("Alpha")
|
|
alpha:SetChange(-1)
|
|
alpha:SetDuration(0.5)
|
|
alpha:SetStartDelay(5) -- hide after 5 second
|
|
alpha:SetSmoothing("OUT")
|
|
fade:SetScript("OnFinished", function()
|
|
midnightWarning:Hide()
|
|
end)
|
|
|
|
fade:Play()]]
|
|
|
|
return frame
|
|
end
|