You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
824 lines
26 KiB
824 lines
26 KiB
if not WeakAuras.IsLibsOK() then return end
|
|
local AddonName, OptionsPrivate = ...
|
|
|
|
-- Lua APIs
|
|
local pairs, type, ipairs = pairs, type, ipairs
|
|
local loadstring = loadstring
|
|
local gsub = gsub
|
|
|
|
-- WoW APIs
|
|
local CreateFrame = CreateFrame
|
|
|
|
local AceGUI = LibStub("AceGUI-3.0")
|
|
local SharedMedia = LibStub("LibSharedMedia-3.0")
|
|
local IndentationLib = IndentationLib
|
|
|
|
local WeakAuras = WeakAuras
|
|
local L = WeakAuras.L
|
|
|
|
local textEditor
|
|
|
|
local editor_themes = {
|
|
["Standard"] = {
|
|
["Table"] = "|c00ff3333",
|
|
["Arithmetic"] = "|c00ff3333",
|
|
["Relational"] = "|c00ff3333",
|
|
["Logical"] = "|c004444ff",
|
|
["Special"] = "|c00ff3333",
|
|
["Keyword"] = "|c004444ff",
|
|
["Comment"] = "|c0000aa00",
|
|
["Number"] = "|c00ff9900",
|
|
["String"] = "|c00999999"
|
|
},
|
|
["Monokai"] = {
|
|
["Table"] = "|c00ffffff",
|
|
["Arithmetic"] = "|c00f92672",
|
|
["Relational"] = "|c00ff3333",
|
|
["Logical"] = "|c00f92672",
|
|
["Special"] = "|c0066d9ef",
|
|
["Keyword"] = "|c00f92672",
|
|
["Comment"] = "|c0075715e",
|
|
["Number"] = "|c00ae81ff",
|
|
["String"] = "|c00e6db74"
|
|
},
|
|
["Obsidian"] = {
|
|
["Table"] = "|c00AFC0E5",
|
|
["Arithmetic"] = "|c00E0E2E4",
|
|
["Relational"] = "|c00B3B689",
|
|
["Logical"] = "|c0093C763",
|
|
["Special"] = "|c00AFC0E5",
|
|
["Keyword"] = "|c0093C763",
|
|
["Comment"] = "|c0066747B",
|
|
["Number"] = "|c00FFCD22",
|
|
["String"] = "|c00EC7600"
|
|
}
|
|
}
|
|
|
|
if not WeakAurasSaved.editor_tab_spaces then WeakAurasSaved.editor_tab_spaces = 4 end
|
|
if not WeakAurasSaved.editor_font_size then WeakAurasSaved.editor_font_size = 12 end -- set default font size if missing
|
|
local color_scheme = {[0] = "|r"}
|
|
local function set_scheme()
|
|
if not WeakAurasSaved.editor_theme then
|
|
WeakAurasSaved.editor_theme = "Monokai"
|
|
end
|
|
local theme = editor_themes[WeakAurasSaved.editor_theme]
|
|
color_scheme[IndentationLib.tokens.TOKEN_SPECIAL] = theme["Special"]
|
|
color_scheme[IndentationLib.tokens.TOKEN_KEYWORD] = theme["Keyword"]
|
|
color_scheme[IndentationLib.tokens.TOKEN_COMMENT_SHORT] = theme["Comment"]
|
|
color_scheme[IndentationLib.tokens.TOKEN_COMMENT_LONG] = theme["Comment"]
|
|
color_scheme[IndentationLib.tokens.TOKEN_NUMBER] = theme["Number"]
|
|
color_scheme[IndentationLib.tokens.TOKEN_STRING] = theme["String"]
|
|
|
|
color_scheme["..."] = theme["Table"]
|
|
color_scheme["{"] = theme["Table"]
|
|
color_scheme["}"] = theme["Table"]
|
|
color_scheme["["] = theme["Table"]
|
|
color_scheme["]"] = theme["Table"]
|
|
|
|
color_scheme["+"] = theme["Arithmetic"]
|
|
color_scheme["-"] = theme["Arithmetic"]
|
|
color_scheme["/"] = theme["Arithmetic"]
|
|
color_scheme["*"] = theme["Arithmetic"]
|
|
color_scheme[".."] = theme["Arithmetic"]
|
|
|
|
color_scheme["=="] = theme["Relational"]
|
|
color_scheme["<"] = theme["Relational"]
|
|
color_scheme["<="] = theme["Relational"]
|
|
color_scheme[">"] = theme["Relational"]
|
|
color_scheme[">="] = theme["Relational"]
|
|
color_scheme["~="] = theme["Relational"]
|
|
|
|
color_scheme["and"] = theme["Logical"]
|
|
color_scheme["or"] = theme["Logical"]
|
|
color_scheme["not"] = theme["Logical"]
|
|
end
|
|
|
|
-- Define the premade snippets
|
|
local premadeSnippets = {
|
|
{
|
|
name = "Basic function",
|
|
snippet = [=[
|
|
function()
|
|
|
|
return
|
|
end]=]
|
|
},
|
|
{
|
|
name = "Custom Activation",
|
|
snippet = [=[
|
|
function(trigger)
|
|
return trigger[1] and (trigger[2] or trigger[3])
|
|
end]=]
|
|
},
|
|
{
|
|
name = "Trigger: CLEU",
|
|
snippet = [=[
|
|
function(event, timestamp, subEvent, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, ...)
|
|
|
|
return
|
|
end]=]
|
|
},
|
|
{
|
|
name = "Simple throttle",
|
|
snippet = [=[
|
|
if not aura_env.last or aura_env.last < GetTime() - 1 then
|
|
aura_env.last = GetTime()
|
|
|
|
end]=]
|
|
},
|
|
{
|
|
name = "Trigger State Updater",
|
|
snippet = [=[
|
|
function(allstates, event, ...)
|
|
allstates[""] = {
|
|
show = true,
|
|
changed = true,
|
|
progressType = "static"||"timed",
|
|
value = ,
|
|
total = ,
|
|
duration = ,
|
|
expirationTime = ,
|
|
autoHide = true,
|
|
name = ,
|
|
icon = ,
|
|
stacks = ,
|
|
index = ,
|
|
}
|
|
return true
|
|
end]=]
|
|
},
|
|
}
|
|
|
|
local function ConstructTextEditor(frame)
|
|
local group = AceGUI:Create("WeakAurasInlineGroup")
|
|
group.frame:SetParent(frame)
|
|
group.frame:SetPoint("TOPLEFT", frame, "TOPLEFT", 16, -16);
|
|
group.frame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -16, 46);
|
|
group.frame:Hide()
|
|
group:SetLayout("flow")
|
|
|
|
local title = AceGUI:Create("Label")
|
|
title:SetFontObject(GameFontNormalHuge)
|
|
title:SetFullWidth(true)
|
|
title:SetText(L["Code Editor"])
|
|
group:AddChild(title)
|
|
|
|
local editor = AceGUI:Create("MultiLineEditBox")
|
|
editor:SetFullWidth(true)
|
|
editor:SetFullHeight(true)
|
|
editor:DisableButton(true)
|
|
local fontPath = SharedMedia:Fetch("font", "Fira Mono Medium")
|
|
if (fontPath) then
|
|
editor.editBox:SetFont(fontPath, WeakAurasSaved.editor_font_size, "")
|
|
end
|
|
group:AddChild(editor)
|
|
editor.frame:SetClipsChildren(true)
|
|
|
|
local originalOnCursorChanged = editor.editBox:GetScript("OnCursorChanged")
|
|
editor.editBox:SetScript("OnCursorChanged", function(self, ...)
|
|
-- WORKAROUND the editbox sends spurious OnCursorChanged events if its resized
|
|
-- That makes AceGUI scroll the editbox to make the cursor visible, leading to unintended
|
|
-- movements. Prevent all of that by checking if the edit box has focus, as otherwise the cursor
|
|
-- is invisible, and we don't care about making it visible
|
|
if not self:HasFocus() then
|
|
return
|
|
end
|
|
originalOnCursorChanged(self, ...)
|
|
end)
|
|
|
|
-- The indention lib overrides GetText, but for the line number
|
|
-- display we ned the original, so save it here.
|
|
local originalGetText = editor.editBox.GetText
|
|
set_scheme()
|
|
IndentationLib.enable(editor.editBox, color_scheme, WeakAurasSaved.editor_tab_spaces)
|
|
|
|
local cancel = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate")
|
|
cancel:SetScript(
|
|
"OnClick",
|
|
function()
|
|
group:CancelClose()
|
|
end
|
|
)
|
|
cancel:SetPoint("BOTTOMRIGHT", -20, -24)
|
|
cancel:SetFrameLevel(cancel:GetFrameLevel() + 1)
|
|
cancel:SetHeight(20)
|
|
cancel:SetWidth(100)
|
|
cancel:SetText(L["Cancel"])
|
|
|
|
local close = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate")
|
|
close:SetScript(
|
|
"OnClick",
|
|
function()
|
|
group:Close()
|
|
end
|
|
)
|
|
close:SetPoint("RIGHT", cancel, "LEFT", -10, 0)
|
|
close:SetFrameLevel(close:GetFrameLevel() + 1)
|
|
close:SetHeight(20)
|
|
close:SetWidth(100)
|
|
close:SetText(L["Done"])
|
|
|
|
local settings_frame = CreateFrame("Button", "WASettingsButton", close, "UIPanelButtonTemplate")
|
|
settings_frame:SetPoint("RIGHT", close, "LEFT", -10, 0)
|
|
settings_frame:SetHeight(20)
|
|
settings_frame:SetWidth(100)
|
|
settings_frame:SetText(L["Settings"])
|
|
settings_frame:RegisterForClicks("LeftButtonUp")
|
|
|
|
local helpButton = CreateFrame("Button", nil, group.frame, "UIPanelButtonTemplate")
|
|
helpButton:SetPoint("BOTTOMLEFT", 12, -24)
|
|
helpButton:SetFrameLevel(cancel:GetFrameLevel() + 1)
|
|
helpButton:SetHeight(20)
|
|
helpButton:SetWidth(100)
|
|
helpButton:SetText(L["Help"])
|
|
|
|
local urlText = CreateFrame("EditBox", nil, group.frame)
|
|
urlText:SetFrameLevel(cancel:GetFrameLevel() + 1)
|
|
urlText:SetFont(STANDARD_TEXT_FONT, 12, "")
|
|
urlText:EnableMouse(true)
|
|
urlText:SetAutoFocus(false)
|
|
urlText:SetCountInvisibleLetters(false)
|
|
urlText:Hide()
|
|
|
|
local urlCopyLabel = urlText:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
|
|
urlCopyLabel:SetPoint("BOTTOMLEFT", group.frame, "BOTTOMLEFT", 12, -20)
|
|
urlCopyLabel:SetText(L["Press Ctrl+C to copy"])
|
|
urlCopyLabel:Hide()
|
|
|
|
urlText:SetPoint("TOPLEFT", urlCopyLabel, "TOPRIGHT", 12, 0)
|
|
urlText:SetPoint("RIGHT", settings_frame, "LEFT")
|
|
|
|
local dropdown = CreateFrame("Frame", "SettingsMenuFrame", settings_frame, "UIDropDownMenuTemplate")
|
|
|
|
local function settings_dropdown_initialize(frame, level, menu)
|
|
if level == 1 then
|
|
for k, v in pairs(editor_themes) do
|
|
local item = {
|
|
text = k,
|
|
isNotRadio = false,
|
|
checked = function()
|
|
return WeakAurasSaved.editor_theme == k
|
|
end,
|
|
func = function()
|
|
WeakAurasSaved.editor_theme = k
|
|
set_scheme()
|
|
editor.editBox:SetText(editor.editBox:GetText())
|
|
end
|
|
}
|
|
UIDropDownMenu_AddButton(item, level)
|
|
end
|
|
UIDropDownMenu_AddButton(
|
|
{
|
|
text = L["Bracket Matching"],
|
|
isNotRadio = true,
|
|
checked = function()
|
|
return WeakAurasSaved.editor_bracket_matching
|
|
end,
|
|
func = function()
|
|
WeakAurasSaved.editor_bracket_matching = not WeakAurasSaved.editor_bracket_matching
|
|
end
|
|
},
|
|
level)
|
|
UIDropDownMenu_AddButton(
|
|
{
|
|
text = L["Indent Size"],
|
|
hasArrow = true,
|
|
notCheckable = true,
|
|
menuList = "spaces"
|
|
},
|
|
level)
|
|
UIDropDownMenu_AddButton(
|
|
{
|
|
text = WeakAuras.newFeatureString .. L["Font Size"],
|
|
hasArrow = true,
|
|
notCheckable = true,
|
|
menuList = "sizes"
|
|
},
|
|
level)
|
|
elseif menu == "spaces" then
|
|
local spaces = {2,4}
|
|
for _, i in pairs(spaces) do
|
|
UIDropDownMenu_AddButton(
|
|
{
|
|
text = i,
|
|
isNotRadio = false,
|
|
checked = function()
|
|
return WeakAurasSaved.editor_tab_spaces == i
|
|
end,
|
|
func = function()
|
|
WeakAurasSaved.editor_tab_spaces = i
|
|
IndentationLib.enable(editor.editBox, color_scheme, WeakAurasSaved.editor_tab_spaces)
|
|
editor.editBox:SetText(editor.editBox:GetText().."\n")
|
|
IndentationLib.indentEditbox(editor.editBox)
|
|
end
|
|
},
|
|
level)
|
|
end
|
|
elseif menu == "sizes" then
|
|
local sizes = {10, 12, 14, 16}
|
|
for _, i in pairs(sizes) do
|
|
UIDropDownMenu_AddButton(
|
|
{
|
|
text = i,
|
|
isNotRadio = false,
|
|
checked = function()
|
|
return WeakAurasSaved.editor_font_size == i
|
|
end,
|
|
func = function()
|
|
WeakAurasSaved.editor_font_size = i
|
|
editor.editBox:SetFont(fontPath, WeakAurasSaved.editor_font_size, "")
|
|
end
|
|
},
|
|
level)
|
|
end
|
|
end
|
|
end
|
|
UIDropDownMenu_Initialize(dropdown, settings_dropdown_initialize, "MENU")
|
|
|
|
settings_frame:SetScript(
|
|
"OnClick",
|
|
function(self, button, down)
|
|
ToggleDropDownMenu(1, nil, dropdown, settings_frame, 0, 0)
|
|
end
|
|
)
|
|
|
|
-- Make Snippets button (top right, near the line number)
|
|
local snippetsButton = CreateFrame("Button", "WASnippetsButton", group.frame, "UIPanelButtonTemplate")
|
|
snippetsButton:SetPoint("BOTTOMRIGHT", editor.frame, "TOPRIGHT", 0, -15)
|
|
snippetsButton:SetFrameLevel(group.frame:GetFrameLevel() + 2)
|
|
snippetsButton:SetHeight(20)
|
|
snippetsButton:SetWidth(100)
|
|
snippetsButton:SetText(L["Snippets"])
|
|
snippetsButton:RegisterForClicks("LeftButtonUp")
|
|
|
|
-- Get the saved snippets from SavedVars
|
|
WeakAurasOptionsSaved.savedSnippets = WeakAurasOptionsSaved.savedSnippets or {}
|
|
local savedSnippets = WeakAurasOptionsSaved.savedSnippets
|
|
|
|
-- function to build snippet selection list
|
|
local function UpdateSnippets(frame)
|
|
-- release first before rebuilding
|
|
frame:ReleaseChildren()
|
|
table.sort(
|
|
savedSnippets,
|
|
function(a, b)
|
|
return a.name < b.name
|
|
end
|
|
)
|
|
|
|
local heading1 = AceGUI:Create("Heading")
|
|
heading1:SetText(L["Premade Snippets"])
|
|
heading1:SetRelativeWidth(0.7)
|
|
frame:AddChild(heading1)
|
|
|
|
-- Iterate premade snippets and make buttons for them
|
|
for order, snippet in ipairs(premadeSnippets) do
|
|
local button = AceGUI:Create("WeakAurasSnippetButton")
|
|
button:SetTitle(snippet.name)
|
|
button:SetDescription(snippet.snippet)
|
|
button:SetCallback(
|
|
"OnClick",
|
|
function()
|
|
editor.editBox:Insert(snippet.snippet)
|
|
editor:SetFocus()
|
|
end
|
|
)
|
|
button:SetRelativeWidth(1)
|
|
frame:AddChild(button)
|
|
end
|
|
|
|
local heading2 = AceGUI:Create("Heading")
|
|
heading2:SetText(L["Your Saved Snippets"])
|
|
heading2:SetRelativeWidth(1)
|
|
frame:AddChild(heading2)
|
|
|
|
-- iterate saved snippets and make buttons
|
|
for order, snippet in ipairs(savedSnippets) do
|
|
local button = AceGUI:Create("WeakAurasSnippetButton")
|
|
local snippetInsert = gsub(snippet.snippet, "|", "||")
|
|
button:SetTitle(snippet.name)
|
|
button:SetDescription(snippetInsert)
|
|
button:SetEditable(true)
|
|
button:SetRelativeWidth(1)
|
|
button:SetNew(snippet.new)
|
|
snippet.new = false
|
|
button:SetCallback(
|
|
"OnClick",
|
|
function()
|
|
editor.editBox:Insert(snippetInsert)
|
|
editor:SetFocus()
|
|
end
|
|
)
|
|
button.deleteButton:SetScript(
|
|
"OnClick",
|
|
function()
|
|
table.remove(savedSnippets, order)
|
|
UpdateSnippets(frame)
|
|
end
|
|
)
|
|
button:SetCallback(
|
|
"OnEnterPressed",
|
|
function()
|
|
local newName = button.renameEditBox:GetText()
|
|
if newName and #newName > 0 then
|
|
local found = false
|
|
for _, snippet in ipairs(savedSnippets) do
|
|
if snippet.name == newName then
|
|
found = true
|
|
break
|
|
end
|
|
end
|
|
if not found then
|
|
savedSnippets[order].name = newName
|
|
UpdateSnippets(frame)
|
|
end
|
|
end
|
|
end
|
|
)
|
|
frame:AddChild(button)
|
|
end
|
|
end
|
|
|
|
-- Make sidebar for snippets
|
|
local snippetsFrame = CreateFrame("Frame", "WeakAurasSnippets", group.frame, "BackdropTemplate")
|
|
snippetsFrame:SetPoint("TOPLEFT", group.frame, "TOPRIGHT", 20, 0)
|
|
snippetsFrame:SetPoint("BOTTOMLEFT", group.frame, "BOTTOMRIGHT", 20, 0)
|
|
snippetsFrame:SetWidth(250)
|
|
snippetsFrame:SetBackdrop(
|
|
{
|
|
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
|
|
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
|
|
tile = true,
|
|
tileSize = 32,
|
|
edgeSize = 32,
|
|
insets = {left = 8, right = 8, top = 8, bottom = 8}
|
|
}
|
|
)
|
|
snippetsFrame:SetBackdropColor(0, 0, 0, 1)
|
|
|
|
-- Add button to save new snippet
|
|
local AddSnippetButton = CreateFrame("Button", nil, snippetsFrame, "UIPanelButtonTemplate")
|
|
AddSnippetButton:SetPoint("TOPLEFT", snippetsFrame, "TOPLEFT", 13, -10)
|
|
AddSnippetButton:SetPoint("TOPRIGHT", snippetsFrame, "TOPRIGHT", -13, -10)
|
|
AddSnippetButton:SetHeight(20)
|
|
AddSnippetButton:SetText(L["Add Snippet"])
|
|
AddSnippetButton:RegisterForClicks("LeftButtonUp")
|
|
|
|
-- house the buttons in a scroll frame
|
|
-- All AceGUI from this point, so that buttons can be released and reused
|
|
local snippetsScrollContainer = AceGUI:Create("SimpleGroup")
|
|
snippetsScrollContainer:SetFullWidth(true)
|
|
snippetsScrollContainer:SetFullHeight(true)
|
|
snippetsScrollContainer:SetLayout("Fill")
|
|
snippetsScrollContainer.frame:SetParent(snippetsFrame)
|
|
snippetsScrollContainer.frame:SetPoint("TOPLEFT", snippetsFrame, "TOPLEFT", 17, -35)
|
|
snippetsScrollContainer.frame:SetPoint("BOTTOMRIGHT", snippetsFrame, "BOTTOMRIGHT", -10, 10)
|
|
local snippetsScroll = AceGUI:Create("ScrollFrame")
|
|
snippetsScroll:SetLayout("List")
|
|
snippetsScrollContainer:AddChild(snippetsScroll)
|
|
snippetsScroll:FixScroll(true)
|
|
snippetsScroll.scrollframe:SetScript(
|
|
"OnScrollRangeChanged",
|
|
function(frame)
|
|
frame.obj:DoLayout()
|
|
end
|
|
)
|
|
|
|
snippetsFrame:Hide()
|
|
|
|
-- Toggle the side bar on click
|
|
snippetsButton:SetScript(
|
|
"OnClick",
|
|
function(self, button, down)
|
|
if not snippetsFrame:IsShown() then
|
|
snippetsFrame:Show()
|
|
UpdateSnippets(snippetsScroll)
|
|
else
|
|
snippetsFrame:Hide()
|
|
end
|
|
end
|
|
)
|
|
|
|
AddSnippetButton:SetScript(
|
|
"OnClick",
|
|
function(self)
|
|
local snippet = editor.editBox:GetText()
|
|
if snippet and #snippet > 0 then
|
|
local baseName, name, index = "New Snippet", "New Snippet", 0
|
|
local snippetExists = function(name)
|
|
for _, snippet in ipairs(savedSnippets) do
|
|
if snippet.name == name then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
while snippetExists(name) do
|
|
index = index + 1
|
|
name = format("%s %d", baseName, index)
|
|
end
|
|
table.insert(savedSnippets, {name = name, snippet = snippet, new = true})
|
|
UpdateSnippets(snippetsScroll)
|
|
end
|
|
end
|
|
)
|
|
|
|
-- CTRL + S saves and closes
|
|
editor.editBox:HookScript(
|
|
"OnKeyDown",
|
|
function(_, key)
|
|
if IsControlKeyDown() and key == "S" then
|
|
group:Close()
|
|
end
|
|
end
|
|
)
|
|
|
|
-- bracket matching
|
|
editor.editBox:HookScript(
|
|
"OnChar",
|
|
function(_, char)
|
|
if not IsControlKeyDown() and WeakAurasSaved.editor_bracket_matching then
|
|
if char == "(" then
|
|
editor.editBox:Insert(")")
|
|
editor.editBox:SetCursorPosition(editor.editBox:GetCursorPosition() - 1)
|
|
elseif char == "{" then
|
|
editor.editBox:Insert("}")
|
|
editor.editBox:SetCursorPosition(editor.editBox:GetCursorPosition() - 1)
|
|
elseif char == "[" then
|
|
editor.editBox:Insert("]")
|
|
editor.editBox:SetCursorPosition(editor.editBox:GetCursorPosition() - 1)
|
|
end
|
|
end
|
|
end
|
|
)
|
|
|
|
local editorError = group.frame:CreateFontString(nil, "OVERLAY")
|
|
editorError:SetFont(STANDARD_TEXT_FONT, 12, "")
|
|
editorError:SetJustifyH("LEFT")
|
|
editorError:SetJustifyV("TOP")
|
|
editorError:SetTextColor(1, 0, 0)
|
|
editorError:SetPoint("LEFT", helpButton, "RIGHT", 0, 4)
|
|
editorError:SetPoint("RIGHT", settings_frame, "LEFT")
|
|
|
|
local editorLine = CreateFrame("EditBox", nil, group.frame)
|
|
-- Set script on enter pressed..
|
|
editorLine:SetPoint("BOTTOMRIGHT", editor.frame, "TOPRIGHT", -100, -15)
|
|
editorLine:SetFont(STANDARD_TEXT_FONT, 10, "")
|
|
editorLine:SetJustifyH("RIGHT")
|
|
editorLine:SetWidth(80)
|
|
editorLine:SetHeight(20)
|
|
editorLine:SetNumeric(true)
|
|
editorLine:SetTextInsets(10, 10, 0, 0)
|
|
editorLine:SetAutoFocus(false)
|
|
|
|
urlText:SetScript(
|
|
"OnChar",
|
|
function(self)
|
|
self:SetText(group.url)
|
|
self:HighlightText()
|
|
end
|
|
)
|
|
urlText:SetScript(
|
|
"OnEscapePressed",
|
|
function()
|
|
urlText:ClearFocus()
|
|
urlText:Hide()
|
|
urlCopyLabel:Hide()
|
|
helpButton:Show()
|
|
editor:SetFocus()
|
|
end
|
|
)
|
|
|
|
helpButton:SetScript(
|
|
"OnClick",
|
|
function()
|
|
urlText:Show()
|
|
urlText:SetFocus()
|
|
urlText:HighlightText()
|
|
urlCopyLabel:Show()
|
|
helpButton:Hide()
|
|
editorError:Hide()
|
|
end
|
|
)
|
|
|
|
local oldOnCursorChanged = editor.editBox:GetScript("OnCursorChanged")
|
|
editor.editBox:SetScript(
|
|
"OnCursorChanged",
|
|
function(...)
|
|
oldOnCursorChanged(...)
|
|
local cursorPosition = editor.editBox:GetCursorPosition()
|
|
local next = -1
|
|
local line = 0
|
|
while (next and cursorPosition >= next) do
|
|
next = originalGetText(editor.editBox):find("[\n]", next + 1)
|
|
line = line + 1
|
|
end
|
|
editorLine:SetNumber(line)
|
|
end
|
|
)
|
|
|
|
editorLine:SetScript(
|
|
"OnEnterPressed",
|
|
function()
|
|
local newLine = editorLine:GetNumber()
|
|
local newPosition = 0
|
|
while (newLine > 1 and newPosition) do
|
|
newPosition = originalGetText(editor.editBox):find("[\n]", newPosition + 1)
|
|
newLine = newLine - 1
|
|
end
|
|
|
|
if (newPosition) then
|
|
editor.editBox:SetCursorPosition(newPosition)
|
|
editor.editBox:SetFocus()
|
|
end
|
|
end
|
|
)
|
|
|
|
function group.Open(self, data, path, enclose, multipath, reloadOptions, setOnParent, url, validator)
|
|
self.data = data
|
|
self.path = path
|
|
self.multipath = multipath
|
|
self.reloadOptions = reloadOptions
|
|
self.setOnParent = setOnParent
|
|
self.url = url
|
|
urlText:SetText(url or "")
|
|
urlText:Hide()
|
|
urlCopyLabel:Hide()
|
|
if url then
|
|
helpButton:Show()
|
|
else
|
|
helpButton:Hide()
|
|
end
|
|
if (frame.window == "texture") then
|
|
frame.texturePicker:CancelClose()
|
|
elseif (frame.window == "icon") then
|
|
frame.iconPicker:CancelClose()
|
|
end
|
|
frame.window = "texteditor"
|
|
frame:UpdateFrameVisible()
|
|
local title = (type(data.id) == "string" and data.id or L["Temporary Group"]) .. " -"
|
|
if (not multipath) then
|
|
for index, field in pairs(path) do
|
|
if (type(field) == "number") then
|
|
field = "Trigger " .. field
|
|
end
|
|
title = title .. " " .. field:sub(1, 1):upper() .. field:sub(2)
|
|
end
|
|
end
|
|
editor:SetLabel(title)
|
|
editor.editBox:SetScript(
|
|
"OnEscapePressed",
|
|
function()
|
|
-- catch it so that escape doesn't default to losing focus (after which another escape would close config)
|
|
end
|
|
)
|
|
self.oldOnTextChanged = editor.editBox:GetScript("OnTextChanged")
|
|
editor.editBox:SetScript(
|
|
"OnTextChanged",
|
|
function(...)
|
|
local str = editor.editBox:GetText()
|
|
if not str or str:trim() == "" or editor.combinedText == true then
|
|
editorError:SetText("")
|
|
else
|
|
local func, errorString
|
|
if (enclose) then
|
|
func, errorString = loadstring("return function() " .. str .. "\n end")
|
|
else
|
|
func, errorString = loadstring("return " .. str)
|
|
end
|
|
if not errorString and validator then
|
|
local ok, validate = xpcall(func, function(err) errorString = err end)
|
|
if ok then
|
|
errorString = validator(validate)
|
|
end
|
|
end
|
|
if errorString then
|
|
urlText:Hide()
|
|
urlCopyLabel:Hide()
|
|
if self.url then
|
|
helpButton:Show()
|
|
end
|
|
editorError:Show()
|
|
editorError:SetText(errorString)
|
|
else
|
|
editorError:SetText("")
|
|
end
|
|
end
|
|
self.oldOnTextChanged(...)
|
|
end
|
|
)
|
|
|
|
if setOnParent then
|
|
editor:SetText(OptionsPrivate.Private.ValueFromPath(data, path) or "")
|
|
else
|
|
local singleText
|
|
local sameTexts = true
|
|
local combinedText = ""
|
|
for child in OptionsPrivate.Private.TraverseLeafsOrAura(data) do
|
|
local text
|
|
if multipath then
|
|
text = path[child.id] and OptionsPrivate.Private.ValueFromPath(child, path[child.id])
|
|
else
|
|
text = OptionsPrivate.Private.ValueFromPath(child, path)
|
|
end
|
|
if text then
|
|
if not (singleText) then
|
|
singleText = text
|
|
else
|
|
if singleText ~= text then
|
|
sameTexts = false
|
|
end
|
|
end
|
|
if combinedText ~= "" then
|
|
combinedText = combinedText .. "\n\n"
|
|
end
|
|
|
|
combinedText =
|
|
combinedText .. L["-- Do not remove this comment, it is part of this aura: "] .. child.id .. "\n"
|
|
combinedText = combinedText .. (text or "")
|
|
end
|
|
end
|
|
if (sameTexts) then
|
|
editor:SetText(singleText or "")
|
|
editor.combinedText = false
|
|
else
|
|
editor:SetText(combinedText)
|
|
editor.combinedText = true
|
|
end
|
|
end
|
|
editor:SetFocus()
|
|
end
|
|
|
|
function group.CancelClose(self)
|
|
editor.editBox:SetScript("OnTextChanged", self.oldOnTextChanged)
|
|
editor:ClearFocus()
|
|
frame.window = "default"
|
|
frame:UpdateFrameVisible()
|
|
end
|
|
|
|
local function extractTexts(input)
|
|
local texts = {}
|
|
|
|
local currentPos, id, startIdLine, startId, endId, endIdLine
|
|
while (true) do
|
|
startIdLine, startId =
|
|
string.find(input, L["-- Do not remove this comment, it is part of this aura: "], currentPos, true)
|
|
if (not startId) then
|
|
break
|
|
end
|
|
|
|
endId, endIdLine = string.find(input, "\n", startId, true)
|
|
if (not endId) then
|
|
break
|
|
end
|
|
|
|
if (currentPos) then
|
|
local trimmedPosition = startIdLine - 1
|
|
while (string.sub(input, trimmedPosition, trimmedPosition) == "\n") do
|
|
trimmedPosition = trimmedPosition - 1
|
|
end
|
|
|
|
texts[id] = string.sub(input, currentPos, trimmedPosition)
|
|
end
|
|
|
|
id = string.sub(input, startId + 1, endId - 1)
|
|
|
|
currentPos = endIdLine + 1
|
|
end
|
|
|
|
if (id) then
|
|
texts[id] = string.sub(input, currentPos, string.len(input))
|
|
end
|
|
|
|
return texts
|
|
end
|
|
|
|
function group.Close(self)
|
|
if self.setOnParent then
|
|
OptionsPrivate.Private.ValueToPath(self.data, self.path, editor:GetText())
|
|
WeakAuras.Add(self.data)
|
|
else
|
|
local textById = editor.combinedText and extractTexts(editor:GetText())
|
|
for child in OptionsPrivate.Private.TraverseLeafsOrAura(self.data) do
|
|
local text = editor.combinedText and (textById[child.id] or "") or editor:GetText()
|
|
OptionsPrivate.Private.ValueToPath(child, self.multipath and self.path[child.id] or self.path, text)
|
|
WeakAuras.Add(child)
|
|
OptionsPrivate.ClearOptions(child.id)
|
|
end
|
|
end
|
|
|
|
WeakAuras.ClearAndUpdateOptions(self.data.id)
|
|
|
|
editor.editBox:SetScript("OnTextChanged", self.oldOnTextChanged)
|
|
editor:ClearFocus()
|
|
frame.window = "default"
|
|
frame:UpdateFrameVisible()
|
|
WeakAuras.FillOptions()
|
|
end
|
|
|
|
return group
|
|
end
|
|
|
|
function OptionsPrivate.TextEditor(frame)
|
|
textEditor = textEditor or ConstructTextEditor(frame)
|
|
return textEditor
|
|
end
|
|
|