Skip to content

Commit

Permalink
TextEditor: add "Search API" side panel (#5170)
Browse files Browse the repository at this point in the history
* TextEditor: add "Search API" side panel
  • Loading branch information
mrbuds authored Jun 20, 2024
1 parent 5784e0e commit 81e4086
Show file tree
Hide file tree
Showing 2 changed files with 224 additions and 13 deletions.
2 changes: 2 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ globals = {
"WeakAurasProfilingReportMixin",
"WeakAurasProfilingLineMixin",
-- Third Party Addons/Libs
"APIDocumentation",
"APIDocumentation_LoadUI",
"BigWigs",
"BigWigsLoader",
"CUSTOM_CLASS_COLORS",
Expand Down
235 changes: 222 additions & 13 deletions WeakAurasOptions/OptionsFrames/TextEditor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -424,25 +424,20 @@ local function ConstructTextEditor(frame)
end
end

local apiSearchFrame

-- Make sidebar for snippets
local snippetsFrame = CreateFrame("Frame", "WeakAurasSnippets", group.frame, "PortraitFrameTemplate")
ButtonFrameTemplate_HidePortrait(snippetsFrame)
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)
]]
if snippetsFrame.Bg then
local color = CreateColorFromHexString("ff1f1e21") -- PANEL_BACKGROUND_COLOR
local r, g, b = color:GetRGB()
snippetsFrame.Bg:SetColorTexture(r, g, b, 0.8)
end

-- Add button to save new snippet
local AddSnippetButton = CreateFrame("Button", nil, snippetsFrame, "UIPanelButtonTemplate")
AddSnippetButton:SetPoint("TOPLEFT", snippetsFrame, "TOPLEFT", 13, -25)
Expand Down Expand Up @@ -479,6 +474,9 @@ local function ConstructTextEditor(frame)
function(self, button, down)
if not snippetsFrame:IsShown() then
snippetsFrame:Show()
if apiSearchFrame and apiSearchFrame:IsShown() then
apiSearchFrame:Hide()
end
UpdateSnippets(snippetsScroll)
else
snippetsFrame:Hide()
Expand Down Expand Up @@ -509,6 +507,217 @@ local function ConstructTextEditor(frame)
end
)

-- Make ApiSearch button
local apiSearchButton = CreateFrame("Button", "WAAPISearchButton", group.frame, "UIPanelButtonTemplate")
apiSearchButton:SetPoint("BOTTOMRIGHT", editor.frame, "TOPRIGHT", -20, 15)
apiSearchButton:SetFrameLevel(group.frame:GetFrameLevel() + 2)
apiSearchButton:SetHeight(20)
apiSearchButton:SetWidth(100)
apiSearchButton:SetText(L["Search API"])
apiSearchButton:RegisterForClicks("LeftButtonUp")

-- Make sidebar for apiSearch
apiSearchFrame = CreateFrame("Frame", "WeakAurasAPISearchFrame", group.frame, "PortraitFrameTemplate")
ButtonFrameTemplate_HidePortrait(apiSearchFrame)
apiSearchFrame:SetWidth(350)
if apiSearchFrame.Bg then
local color = CreateColorFromHexString("ff1f1e21") -- PANEL_BACKGROUND_COLOR
local r, g, b = color:GetRGB()
apiSearchFrame.Bg:SetColorTexture(r, g, b, 0.8)
end

local makeAPISearch
local APISearchTextChangeDelay = 0.3
local APISearchCTimer

-- filter line
local filterInput = CreateFrame("EditBox", "WeakAurasAPISearchFilterInput", apiSearchFrame, "SearchBoxTemplate")
filterInput:SetScript("OnTextChanged", function(self)
SearchBoxTemplate_OnTextChanged(self)
if APISearchCTimer then
APISearchCTimer:Cancel()
end
APISearchCTimer = C_Timer.NewTimer(
APISearchTextChangeDelay,
function()
makeAPISearch(filterInput:GetText())
end
)
end)
filterInput:SetHeight(15)
filterInput:SetPoint("TOPLEFT", apiSearchFrame, "TOPLEFT", 17, -30)
filterInput:SetPoint("TOPRIGHT", apiSearchFrame, "TOPRIGHT", -10, -30)
filterInput:SetFont(STANDARD_TEXT_FONT, 10, "")

local apiSearchScrollContainer = AceGUI:Create("SimpleGroup")
apiSearchScrollContainer:SetFullWidth(true)
apiSearchScrollContainer:SetFullHeight(true)
apiSearchScrollContainer:SetLayout("Fill")
apiSearchScrollContainer.frame:SetParent(apiSearchFrame)
apiSearchScrollContainer.frame:SetPoint("TOPLEFT", apiSearchFrame, "TOPLEFT", 17, -50)
apiSearchScrollContainer.frame:SetPoint("BOTTOMRIGHT", apiSearchFrame, "BOTTOMRIGHT", -10, 10)

local apiSearchScroll = AceGUI:Create("ScrollFrame")
apiSearchScroll:SetLayout("List")
apiSearchScrollContainer:AddChild(apiSearchScroll)
apiSearchScroll:FixScroll(true)
apiSearchScroll.scrollframe:SetScript(
"OnScrollRangeChanged",
function(frame)
frame.obj:DoLayout()
end
)

local snippetOnClickCallback = function(self)
if self.isSystem then
filterInput:SetText(self.name)
else
self.editor.editBox:Insert(self.name)
self.editor:SetFocus()
end
end

local function loadBlizzardAPIDocumentation()
local apiAddonName = "Blizzard_APIDocumentation"
local _, loaded = C_AddOns.IsAddOnLoaded(apiAddonName)
if not loaded then
C_AddOns.LoadAddOn(apiAddonName)
end
if #APIDocumentation.systems == 0 then
APIDocumentation_LoadUI()
end
end

local function addLine(results, apiInfo)
local name
if apiInfo.Type == "System" then
name = apiInfo.Namespace
elseif apiInfo.Type == "Function" then
name = apiInfo:GetFullName()
elseif apiInfo.Type == "Event" then
name = apiInfo.LiteralName
end
table.insert(results, { name = name, apiInfo = apiInfo })
end

local function APIListSystems()
local results = {}
for i, systemInfo in ipairs(APIDocumentation.systems) do
if systemInfo.Namespace and #systemInfo.Functions > 0 then
addLine(results, systemInfo)
end
end
table.sort(results, function(a, b)
return a.name < b.name
end)
return results
end

local function APISearch(word)
local lowerWord = word:lower()
local results = {}

-- if search match name of namespace, show all functions & events for the namespace, and also show all other functions & events matching the search
-- if search is composed with name of a namespace and a word separated by a dot, show matching function for matching namespace

local nsName, rest = lowerWord:match("^([%w%_]+)(.*)")
local funcName = rest and rest:match("^%.([%w%_]+)")

for _, systemInfo in ipairs(APIDocumentation.systems) do
-- search for namespaceName or namespaceName.functionName
local systemMatch = nsName and #nsName >= 4
and systemInfo.Namespace and systemInfo.Namespace:lower():match(nsName)

for _, apiInfo in ipairs(systemInfo.Functions) do
if systemMatch then
if funcName then
if apiInfo:MatchesSearchString(funcName) then
addLine(results, apiInfo)
end
else
addLine(results, apiInfo)
end
else
if apiInfo:MatchesSearchString(lowerWord) then
addLine(results, apiInfo)
end
end
end

if systemMatch and rest == "" then
for _, apiInfo in ipairs(systemInfo.Events) do
addLine(results, apiInfo)
end
else
for _, apiInfo in ipairs(systemInfo.Events) do
if apiInfo:MatchesSearchString(lowerWord) then
addLine(results, apiInfo)
end
end
end
end

return results
end

local lastSearch = nil
makeAPISearch = function(apiToSearchFor)
loadBlizzardAPIDocumentation()
local results
if not apiToSearchFor or #apiToSearchFor < 4 then
if lastSearch == "" then return end
results = APIListSystems()
lastSearch = ""
else
if lastSearch == apiToSearchFor then return end
results = APISearch(apiToSearchFor)
lastSearch = apiToSearchFor
end
apiSearchScroll:ReleaseChildren()
for _, element in ipairs(results) do
local apiInfo = element.apiInfo
if apiInfo then
local button = AceGUI:Create("WeakAurasSnippetButton")
button:SetTitle(element.name)
button:SetEditable(false)
button:SetHeight(20)
button:SetRelativeWidth(1)
if apiInfo.Type ~= "System" and apiInfo.GetDetailedOutputLines then
local desc = table.concat(apiInfo:GetDetailedOutputLines(), "\n")
button:SetDescription(desc)
else
button:SetDescription()
end
button.name = element.name
button.editor = editor
button.isSystem = apiInfo.Type == "System"
button:SetCallback("OnClick", snippetOnClickCallback)
apiSearchScroll:AddChild(button)
end
end
end

apiSearchFrame:Hide()

-- Toggle the side bar on click
apiSearchButton:SetScript(
"OnClick",
function()
if apiSearchFrame:IsShown() then
apiSearchFrame:Hide()
else
apiSearchFrame:Show()
apiSearchFrame:ClearAllPoints()
apiSearchFrame:SetPoint("TOPLEFT", group.frame, "TOPRIGHT", 20, 0)
apiSearchFrame:SetPoint("BOTTOMLEFT", group.frame, "BOTTOMRIGHT", 20, 0)
filterInput:SetFocus()
if snippetsFrame and snippetsFrame:IsShown() then
snippetsFrame:Hide()
end
end
end
)

-- CTRL + S saves and closes
editor.editBox:HookScript(
"OnKeyDown",
Expand Down

0 comments on commit 81e4086

Please sign in to comment.