487 lines
17 KiB
Lua
487 lines
17 KiB
Lua
local ADDON_NAME = "HailMaryGuildTools"
|
|
local HMGT = _G[ADDON_NAME]
|
|
if not HMGT then return end
|
|
|
|
local L = HMGT.L or LibStub("AceLocale-3.0"):GetLocale(ADDON_NAME)
|
|
local AceGUI = LibStub("AceGUI-3.0", true)
|
|
|
|
local function GetOrderedDebugLevels()
|
|
return { "error", "info", "verbose" }
|
|
end
|
|
|
|
local function GetOrderedDebugScopes()
|
|
local values = HMGT:GetDebugScopeOptions() or {}
|
|
local names = { "ALL" }
|
|
for scope in pairs(values) do
|
|
if scope ~= "ALL" then
|
|
names[#names + 1] = scope
|
|
end
|
|
end
|
|
table.sort(names, function(a, b)
|
|
if a == "ALL" then return true end
|
|
if b == "ALL" then return false end
|
|
return tostring(values[a] or a) < tostring(values[b] or b)
|
|
end)
|
|
return names, values
|
|
end
|
|
|
|
local function SetFilterButtonText(buttonWidget, prefix, valueLabel)
|
|
if not buttonWidget then
|
|
return
|
|
end
|
|
buttonWidget:SetText(string.format("%s: %s", tostring(prefix or ""), tostring(valueLabel or "")))
|
|
end
|
|
|
|
local function AdvanceDebugLevel(step)
|
|
local levels = GetOrderedDebugLevels()
|
|
local current = HMGT:GetConfiguredDebugLevel()
|
|
local nextIndex = 1
|
|
for index, value in ipairs(levels) do
|
|
if value == current then
|
|
nextIndex = index + (step or 1)
|
|
break
|
|
end
|
|
end
|
|
if nextIndex < 1 then
|
|
nextIndex = #levels
|
|
elseif nextIndex > #levels then
|
|
nextIndex = 1
|
|
end
|
|
HMGT.db.profile.debugLevel = levels[nextIndex]
|
|
HMGT:RefreshDebugWindow()
|
|
end
|
|
|
|
local function AdvanceDebugScope(step)
|
|
local scopes, labels = GetOrderedDebugScopes()
|
|
local current = (HMGT.db and HMGT.db.profile and HMGT.db.profile.debugScope) or "ALL"
|
|
local nextIndex = 1
|
|
for index, value in ipairs(scopes) do
|
|
if value == current then
|
|
nextIndex = index + (step or 1)
|
|
break
|
|
end
|
|
end
|
|
if nextIndex < 1 then
|
|
nextIndex = #scopes
|
|
elseif nextIndex > #scopes then
|
|
nextIndex = 1
|
|
end
|
|
HMGT.db.profile.debugScope = scopes[nextIndex]
|
|
HMGT:RefreshDebugWindow()
|
|
end
|
|
|
|
function HMGT:SetDebugWindowMinimized(minimized)
|
|
local frame = self.debugWindow
|
|
if not frame then
|
|
return
|
|
end
|
|
|
|
minimized = minimized and true or false
|
|
self.debugWindowStatus = self.debugWindowStatus or {
|
|
width = 860,
|
|
height = 340,
|
|
}
|
|
self.debugWindowStatus.minimized = minimized
|
|
|
|
local collapsedHeight = 64
|
|
if minimized then
|
|
self.debugWindowStatus.restoreHeight = self.debugWindowStatus.height or frame:GetHeight() or 340
|
|
end
|
|
|
|
local targetHeight = minimized
|
|
and collapsedHeight
|
|
or (self.debugWindowStatus.restoreHeight or self.debugWindowStatus.height or 340)
|
|
|
|
if frame.aceWidget then
|
|
frame.aceWidget:EnableResize(not minimized)
|
|
frame.aceWidget:SetHeight(targetHeight)
|
|
else
|
|
frame:SetHeight(targetHeight)
|
|
end
|
|
|
|
if frame.minimizeButton then
|
|
frame.minimizeButton:SetText(minimized and "+" or "-")
|
|
end
|
|
if frame.clearButton then
|
|
local buttonFrame = frame.clearButton.frame or frame.clearButton
|
|
buttonFrame:SetShown(not minimized)
|
|
end
|
|
if frame.selectButton then
|
|
local buttonFrame = frame.selectButton.frame or frame.selectButton
|
|
buttonFrame:SetShown(not minimized)
|
|
end
|
|
if frame.levelFilter then
|
|
local filterFrame = frame.levelFilter.frame or frame.levelFilter
|
|
filterFrame:SetShown(not minimized)
|
|
end
|
|
if frame.scopeFilter then
|
|
local filterFrame = frame.scopeFilter.frame or frame.scopeFilter
|
|
filterFrame:SetShown(not minimized)
|
|
end
|
|
if frame.logWidget then
|
|
frame.logWidget.frame:SetShown(not minimized)
|
|
end
|
|
if frame.scrollBG then
|
|
frame.scrollBG:SetShown(not minimized)
|
|
end
|
|
|
|
if not minimized then
|
|
self:RefreshDebugWindow()
|
|
end
|
|
end
|
|
|
|
function HMGT:ToggleDebugWindowMinimized()
|
|
self:SetDebugWindowMinimized(not (self.debugWindowStatus and self.debugWindowStatus.minimized))
|
|
end
|
|
|
|
function HMGT:EnsureDebugWindow()
|
|
if self.debugWindow then
|
|
return self.debugWindow
|
|
end
|
|
|
|
local frameWidget
|
|
if AceGUI then
|
|
frameWidget = AceGUI:Create("Frame")
|
|
self.debugWindowStatus = self.debugWindowStatus or {
|
|
width = 860,
|
|
height = 340,
|
|
}
|
|
frameWidget:SetTitle(L["DEBUG_WINDOW_TITLE"] or "HMGT Debug Console")
|
|
frameWidget:SetStatusText(L["DEBUG_WINDOW_HINT"] or "Mouse wheel scrolls, Ctrl+A selects all, Ctrl+C copies selected text")
|
|
frameWidget:SetStatusTable(self.debugWindowStatus)
|
|
frameWidget:SetWidth(self.debugWindowStatus.width or 860)
|
|
frameWidget:SetHeight(self.debugWindowStatus.height or 340)
|
|
frameWidget:EnableResize(true)
|
|
frameWidget.frame:SetClampedToScreen(true)
|
|
frameWidget.frame:SetToplevel(true)
|
|
frameWidget.frame:SetFrameStrata("FULLSCREEN_DIALOG")
|
|
frameWidget:Hide()
|
|
end
|
|
|
|
local frame = frameWidget and frameWidget.frame or CreateFrame("Frame", "HMGT_DebugWindow", UIParent, "BackdropTemplate")
|
|
if not frameWidget then
|
|
frame:SetSize(860, 340)
|
|
frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
|
|
frame:SetFrameStrata("DIALOG")
|
|
frame:SetClampedToScreen(true)
|
|
frame:SetMovable(true)
|
|
frame:EnableMouse(true)
|
|
frame:RegisterForDrag("LeftButton")
|
|
frame:SetScript("OnDragStart", function(selfFrame) selfFrame:StartMoving() end)
|
|
frame:SetScript("OnDragStop", function(selfFrame) selfFrame:StopMovingOrSizing() end)
|
|
frame:SetBackdrop({
|
|
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
edgeSize = 12,
|
|
insets = { left = 3, right = 3, top = 3, bottom = 3 },
|
|
})
|
|
frame:SetBackdropColor(0.05, 0.05, 0.06, 0.95)
|
|
frame:SetBackdropBorderColor(0.35, 0.55, 0.85, 1)
|
|
frame:Hide()
|
|
|
|
local title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
|
|
title:SetPoint("TOPLEFT", frame, "TOPLEFT", 14, -12)
|
|
title:SetText(L["DEBUG_WINDOW_TITLE"] or "HMGT Debug Console")
|
|
frame.title = title
|
|
|
|
local closeButton = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
|
|
closeButton:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -5, -5)
|
|
frame.closeButton = closeButton
|
|
|
|
local minimizeButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
|
minimizeButton:SetSize(22, 20)
|
|
minimizeButton:SetPoint("TOPRIGHT", closeButton, "TOPLEFT", -2, 0)
|
|
minimizeButton:SetText((self.debugWindowStatus and self.debugWindowStatus.minimized) and "+" or "-")
|
|
minimizeButton:SetScript("OnClick", function()
|
|
HMGT:ToggleDebugWindowMinimized()
|
|
end)
|
|
frame.minimizeButton = minimizeButton
|
|
end
|
|
|
|
frame.aceWidget = frameWidget
|
|
|
|
if frameWidget and AceGUI then
|
|
local content = frameWidget.content
|
|
|
|
local minimizeButton = AceGUI:Create("Button")
|
|
minimizeButton:SetText((self.debugWindowStatus and self.debugWindowStatus.minimized) and "+" or "-")
|
|
minimizeButton:SetWidth(24)
|
|
minimizeButton:SetCallback("OnClick", function()
|
|
HMGT:ToggleDebugWindowMinimized()
|
|
end)
|
|
minimizeButton.frame:SetParent(frame)
|
|
minimizeButton.frame:ClearAllPoints()
|
|
minimizeButton.frame:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -34, -4)
|
|
minimizeButton.frame:SetHeight(20)
|
|
minimizeButton.frame:Show()
|
|
frame.minimizeButton = minimizeButton
|
|
|
|
local clearButton = AceGUI:Create("Button")
|
|
clearButton:SetText(L["OPT_DEBUG_CLEAR"] or "Clear log")
|
|
clearButton:SetWidth(120)
|
|
clearButton:SetCallback("OnClick", function()
|
|
HMGT:ClearDebugLog()
|
|
end)
|
|
clearButton.frame:SetParent(content)
|
|
clearButton.frame:ClearAllPoints()
|
|
clearButton.frame:SetPoint("TOPRIGHT", content, "TOPRIGHT", 0, -2)
|
|
clearButton.frame:Show()
|
|
frame.clearButton = clearButton
|
|
|
|
local selectButton = AceGUI:Create("Button")
|
|
selectButton:SetText(L["OPT_DEBUG_SELECT_ALL"] or "Select all")
|
|
selectButton:SetWidth(120)
|
|
selectButton:SetCallback("OnClick", function()
|
|
if frame.editBox then
|
|
frame.editBox:SetFocus()
|
|
frame.editBox:HighlightText(0)
|
|
end
|
|
end)
|
|
selectButton.frame:SetParent(content)
|
|
selectButton.frame:ClearAllPoints()
|
|
selectButton.frame:SetPoint("TOPRIGHT", clearButton.frame, "TOPLEFT", -6, 0)
|
|
selectButton.frame:Show()
|
|
frame.selectButton = selectButton
|
|
|
|
local levelFilter = AceGUI:Create("Button")
|
|
levelFilter:SetWidth(150)
|
|
levelFilter:SetCallback("OnClick", function()
|
|
AdvanceDebugLevel(1)
|
|
end)
|
|
levelFilter.frame:SetParent(content)
|
|
levelFilter.frame:ClearAllPoints()
|
|
levelFilter.frame:SetPoint("TOPLEFT", content, "TOPLEFT", 0, 0)
|
|
levelFilter.frame:Show()
|
|
frame.levelFilter = levelFilter
|
|
|
|
local scopeFilter = AceGUI:Create("Button")
|
|
scopeFilter:SetWidth(180)
|
|
scopeFilter:SetCallback("OnClick", function()
|
|
AdvanceDebugScope(1)
|
|
end)
|
|
scopeFilter.frame:SetParent(content)
|
|
scopeFilter.frame:ClearAllPoints()
|
|
scopeFilter.frame:SetPoint("TOPLEFT", levelFilter.frame, "TOPRIGHT", 8, 0)
|
|
scopeFilter.frame:Show()
|
|
frame.scopeFilter = scopeFilter
|
|
|
|
local logWidget = AceGUI:Create("MultiLineEditBox")
|
|
logWidget:SetLabel("")
|
|
logWidget:DisableButton(true)
|
|
logWidget:SetNumLines(18)
|
|
logWidget:SetText("")
|
|
logWidget.frame:SetParent(content)
|
|
logWidget.frame:ClearAllPoints()
|
|
logWidget.frame:SetPoint("TOPLEFT", content, "TOPLEFT", 0, -54)
|
|
logWidget.frame:SetPoint("BOTTOMRIGHT", content, "BOTTOMRIGHT", 0, 0)
|
|
logWidget.frame:Show()
|
|
logWidget:SetCallback("OnTextChanged", function()
|
|
HMGT:RefreshDebugWindow()
|
|
end)
|
|
logWidget.editBox:SetScript("OnKeyDown", function(selfBox, key)
|
|
if IsControlKeyDown() and (key == "A" or key == "a") then
|
|
selfBox:HighlightText(0)
|
|
end
|
|
end)
|
|
frame.logWidget = logWidget
|
|
frame.editBox = logWidget.editBox
|
|
frame.scrollFrame = logWidget.scrollFrame
|
|
|
|
self.debugWindow = frame
|
|
self:SetDebugWindowMinimized(self.debugWindowStatus and self.debugWindowStatus.minimized)
|
|
return frame
|
|
end
|
|
|
|
local clearButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
|
clearButton:SetSize(90, 22)
|
|
clearButton:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -30, -6)
|
|
clearButton:SetText(L["OPT_DEBUG_CLEAR"] or "Clear log")
|
|
clearButton:SetScript("OnClick", function()
|
|
HMGT:ClearDebugLog()
|
|
end)
|
|
frame.clearButton = clearButton
|
|
|
|
local selectButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
|
selectButton:SetSize(90, 22)
|
|
selectButton:SetPoint("TOPRIGHT", clearButton, "TOPLEFT", -6, 0)
|
|
selectButton:SetText(L["OPT_DEBUG_SELECT_ALL"] or "Select all")
|
|
selectButton:SetScript("OnClick", function()
|
|
if frame.editBox then
|
|
frame.editBox:SetFocus()
|
|
frame.editBox:HighlightText(0)
|
|
end
|
|
end)
|
|
frame.selectButton = selectButton
|
|
|
|
local scopeFilter = CreateFrame("Frame", nil, frame)
|
|
scopeFilter:SetSize(170, 22)
|
|
scopeFilter:SetPoint("TOPLEFT", frame, "TOPLEFT", 16, -8)
|
|
frame.scopeFilter = scopeFilter
|
|
|
|
local scrollBG = CreateFrame("Frame", nil, frame, "BackdropTemplate")
|
|
scrollBG:SetBackdrop({
|
|
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
edgeSize = 16,
|
|
insets = { left = 4, right = 3, top = 4, bottom = 3 },
|
|
})
|
|
scrollBG:SetBackdropColor(0, 0, 0, 0.95)
|
|
scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
|
|
scrollBG:SetPoint("TOPLEFT", frame, "TOPLEFT", 14, -36)
|
|
scrollBG:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -30, 14)
|
|
frame.scrollBG = scrollBG
|
|
|
|
local scrollFrame = CreateFrame("ScrollFrame", nil, scrollBG, "UIPanelScrollFrameTemplate")
|
|
scrollFrame:SetPoint("TOPLEFT", scrollBG, "TOPLEFT", 6, -6)
|
|
scrollFrame:SetPoint("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -27, 4)
|
|
scrollFrame:EnableMouseWheel(true)
|
|
scrollFrame:SetScript("OnMouseWheel", function(selfMsg, delta)
|
|
if delta > 0 then
|
|
selfMsg:SetVerticalScroll(math.max(0, selfMsg:GetVerticalScroll() - 42))
|
|
else
|
|
selfMsg:SetVerticalScroll(selfMsg:GetVerticalScroll() + 42)
|
|
end
|
|
end)
|
|
frame.scrollFrame = scrollFrame
|
|
|
|
local editBox = CreateFrame("EditBox", nil, scrollFrame)
|
|
editBox:SetMultiLine(true)
|
|
editBox:SetAutoFocus(false)
|
|
editBox:SetFontObject(ChatFontNormal)
|
|
editBox:SetWidth(780)
|
|
editBox:SetTextInsets(6, 6, 6, 6)
|
|
editBox:EnableMouse(true)
|
|
editBox:SetScript("OnEscapePressed", function(selfBox)
|
|
selfBox:ClearFocus()
|
|
end)
|
|
editBox:SetScript("OnKeyDown", function(selfBox, key)
|
|
if IsControlKeyDown() and (key == "A" or key == "a") then
|
|
selfBox:HighlightText(0)
|
|
end
|
|
end)
|
|
editBox:SetScript("OnTextChanged", function(selfBox, userInput)
|
|
if userInput then
|
|
HMGT:RefreshDebugWindow()
|
|
else
|
|
selfBox:SetCursorPosition(selfBox:GetNumLetters())
|
|
selfBox:SetHeight(math.max(scrollFrame:GetHeight(), HMGT:GetDebugWindowTextHeight(frame, selfBox:GetText()) + 16))
|
|
scrollFrame:UpdateScrollChildRect()
|
|
end
|
|
end)
|
|
editBox:SetScript("OnMouseUp", function(selfBox)
|
|
selfBox:SetFocus()
|
|
end)
|
|
scrollFrame:SetScrollChild(editBox)
|
|
frame.editBox = editBox
|
|
|
|
local measureText = frame:CreateFontString(nil, "ARTWORK", "ChatFontNormal")
|
|
measureText:SetJustifyH("LEFT")
|
|
measureText:SetJustifyV("TOP")
|
|
if measureText.SetSpacing then
|
|
measureText:SetSpacing(2)
|
|
end
|
|
measureText:SetWidth(768)
|
|
frame.measureText = measureText
|
|
|
|
self.debugWindow = frame
|
|
self:SetDebugWindowMinimized(self.debugWindowStatus and self.debugWindowStatus.minimized)
|
|
return frame
|
|
end
|
|
|
|
function HMGT:GetDebugWindowTextHeight(frame, text)
|
|
if not frame or not frame.measureText then
|
|
return 0
|
|
end
|
|
|
|
local width = 768
|
|
if frame.editBox then
|
|
width = math.max(1, (frame.editBox:GetWidth() or width) - 12)
|
|
end
|
|
frame.measureText:SetWidth(width)
|
|
frame.measureText:SetText(text or "")
|
|
return frame.measureText:GetStringHeight()
|
|
end
|
|
|
|
function HMGT:RefreshDebugWindow()
|
|
local frame = self:EnsureDebugWindow()
|
|
if not frame then
|
|
return
|
|
end
|
|
|
|
local filtered = self:GetFilteredDebugBuffer() or self.debugBuffer or {}
|
|
local text = table.concat(filtered, "\n")
|
|
if frame.logWidget and frame.editBox then
|
|
if frame.levelFilter then
|
|
local levelOptions = self:GetDebugLevelOptions()
|
|
SetFilterButtonText(frame.levelFilter, L["OPT_DEBUG_LEVEL"] or "Level", levelOptions[self:GetConfiguredDebugLevel()])
|
|
end
|
|
if frame.scopeFilter then
|
|
local scopeOptions = self:GetDebugScopeOptions()
|
|
local currentScope = (self.db and self.db.profile and self.db.profile.debugScope) or "ALL"
|
|
SetFilterButtonText(frame.scopeFilter, L["OPT_DEBUG_SCOPE"] or "Module", scopeOptions[currentScope] or currentScope)
|
|
end
|
|
frame.logWidget:SetText(text)
|
|
frame.editBox:SetCursorPosition(frame.editBox:GetNumLetters())
|
|
return
|
|
end
|
|
|
|
if not frame.editBox then
|
|
return
|
|
end
|
|
|
|
frame.editBox:SetText(text)
|
|
frame.editBox:SetCursorPosition(#text)
|
|
frame.editBox:SetHeight(math.max(frame.scrollFrame:GetHeight(), self:GetDebugWindowTextHeight(frame, text) + 16))
|
|
frame.scrollFrame:SetVerticalScroll(math.max(0, frame.editBox:GetHeight() - frame.scrollFrame:GetHeight()))
|
|
end
|
|
|
|
function HMGT:UpdateDebugWindowVisibility()
|
|
if self.db and self.db.profile then
|
|
self.db.profile.debug = false
|
|
end
|
|
local frame = self.debugWindow
|
|
if not frame then
|
|
return
|
|
end
|
|
local widget = frame.aceWidget
|
|
if widget then
|
|
widget:Hide()
|
|
else
|
|
frame:Hide()
|
|
end
|
|
end
|
|
|
|
function HMGT:ClearDebugLog()
|
|
wipe(self.debugBuffer)
|
|
if self.debugWindow and self.debugWindow.logWidget then
|
|
self.debugWindow.logWidget:SetText("")
|
|
self.debugWindow.editBox:SetCursorPosition(0)
|
|
self.debugWindow.scrollFrame:SetVerticalScroll(0)
|
|
return
|
|
end
|
|
if self.debugWindow and self.debugWindow.editBox then
|
|
self.debugWindow.editBox:SetText("")
|
|
self.debugWindow.scrollFrame:SetVerticalScroll(0)
|
|
end
|
|
end
|
|
|
|
function HMGT:ToggleDebugWindowShortcut()
|
|
if self.db and self.db.profile then
|
|
self.db.profile.debug = false
|
|
end
|
|
local frame = self.debugWindow
|
|
if not frame then
|
|
return
|
|
end
|
|
local widget = frame.aceWidget
|
|
if widget then
|
|
widget:Hide()
|
|
else
|
|
frame:Hide()
|
|
end
|
|
end
|
|
|
|
function HMGT:DumpDebugLog(maxLines)
|
|
return
|
|
end
|