Edit: Sorry if this is in the wrong section, just noticed there's a Lua/XML Help section.
Hi.
I'm a few months into learning Lua and addon development.
My first addon allows players to customize each chat frame.
One of the features allows players to copy messages from a chat frame by duplicating them to an AceGUI multi line edit box when you hold control and left click on a chat tab.
I noticed that if I AFK for about 10 minutes and come back, sometimes no messages show up when I try to open the frame.
Lua Code:
local AceGUI = LibStub("AceGUI-3.0")
--- @class Private
local Private = select(2, ...)
--- @class CopyModule: AceModule
local CopyModule = Private.Addon:NewModule("Copy")
--- @class CopyConstants
local CopyConstants = Private.CopyConstants
--- @class ChatFrameUtils
local ChatFrameUtils = Private.ChatFrameUtils
--- @class DatabaseUtils
local DatabaseUtils = Private.DatabaseUtils
--- @class CopyState
--- @field copyFrame table?
--- @field multiLineEditBox table?
--- @field text string?
local state = {
copyFrame = nil,
multiLineEditBox = nil,
text = "",
}
--- Configures the copy frame.
local function configureCopyFrame(copyFrame)
copyFrame:SetTitle(CopyConstants.FRAME_TITLE)
copyFrame:SetWidth(CopyConstants.FRAME_WIDTH)
copyFrame:SetHeight(CopyConstants.FRAME_HEIGHT)
copyFrame:SetLayout(CopyConstants.FRAME_LAYOUT)
copyFrame.frame:EnableKeyboard(true)
copyFrame.frame:SetClampedToScreen(true)
copyFrame.frame:SetFrameStrata(CopyConstants.FRAME_STRATA)
copyFrame.frame:SetPropagateKeyboardInput(true)
end
--- Creates the copy frame.
local function createCopyFrame()
local copyFrame = AceGUI:Create("Frame")
configureCopyFrame(copyFrame)
return copyFrame
end
--- Handles the text changing in the multi line edit box.
local function onTextChangedCallback(widget)
local currentText = state.text
local cursorPosition = widget:GetCursorPosition()
widget:SetText(currentText)
widget:SetCursorPosition(cursorPosition)
end
--- Configures the multi line edit box.
local function configureMultiLineEditBox(multiLineEditBox)
multiLineEditBox:DisableButton(true)
multiLineEditBox:SetLabel("")
multiLineEditBox:SetCallback("OnTextChanged", onTextChangedCallback)
end
--- Creates the multi line edit box.
local function createMultiLineEditBox()
local multiLineEditBox = AceGUI:Create("MultiLineEditBox")
configureMultiLineEditBox(multiLineEditBox)
return multiLineEditBox
end
--- Updates the copy frame with the chat frame messages.
--- @param chatFrame table
local function updateCopyFrame(chatFrame)
state.text = table.concat(ChatFrameUtils:GetChatFrameMessages(chatFrame), "\n")
state.multiLineEditBox:SetText(state.text)
-- To scroll to the bottom of the multi line edit box, we need to wait.
C_Timer.After(0, function()
state.multiLineEditBox:SetCursorPosition(#state.text)
end)
end
--- Closes the copy frame.
local function closeCopyFrame()
state.copyFrame:Hide()
AceGUI:Release(state.copyFrame)
state.copyFrame = nil
end
--- Sets the escape key handler for a frame.
local function setEscapeKeyHandler(frame, editBox)
frame:SetScript("OnKeyDown", function(self, key)
if key ~= "ESCAPE" then
self:SetPropagateKeyboardInput(true)
return
end
closeCopyFrame()
self:SetPropagateKeyboardInput(false)
end)
end
--- Initializes the copy frame.
local function initializeCopyFrame()
local copyFrame = createCopyFrame()
local multiLineEditBox = createMultiLineEditBox()
copyFrame:AddChild(multiLineEditBox)
setEscapeKeyHandler(copyFrame.frame, multiLineEditBox.editBox)
state.copyFrame = copyFrame
state.multiLineEditBox = multiLineEditBox
state.text = ""
end
--- Shows the copy frame.
--- @param chatFrame table
function CopyModule:ShowCopyFrame(chatFrame)
if not state.copyFrame then
initializeCopyFrame()
end
updateCopyFrame(chatFrame)
state.copyFrame:Show()
state.copyFrame.frame:SetPropagateKeyboardInput(true)
end
I have tried to debug the problem as shown below. I was able to reproduce the issue of the messages not showing up in the multi line edit box, but they would appear in ChatFrame4 and ChatFrame5.
Lua Code:
--- Updates the copy frame with the chat frame messages.
--- @param chatFrame table
local function updateCopyFrame(chatFrame)
state.text = table.concat(ChatFrameUtils:GetChatFrameMessages(chatFrame), "\n")
ChatFrame5:AddMessage(state.text)
state.multiLineEditBox:SetText(state.text)
for _, msg in ipairs(ChatFrameUtils:GetChatFrameMessages(chatFrame)) do
ChatFrame4:AddMessage(msg)
end
C_Timer.After(2, function()
state.multiLineEditBox:SetText(state.text)
end)
-- To scroll to the bottom of the multi line edit box, we need to wait.
C_Timer.After(4, function()
state.multiLineEditBox:SetCursorPosition(#state.text)
end)
end
My code is on GitHub as well so it might be easier to look at here:
https://github.com/drzewieckinichola...dules/Copy.lua
The files we're probably interested in are Modules/Copy.lua, Hooks/ChatFrame.lua, and I guess Utils/ChatFrame.lua, but I'm assuming the problem is in Modules/Copy.lua.
Does anybody have any idea what I'm doing wrong?
Here are some images as well:
https://imgur.com/a/M46PsRp
Thanks in advance!