WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Legion Beta archived threads (https://www.wowinterface.com/forums/forumdisplay.php?f=177)
-   -   EditBox and long strings (https://www.wowinterface.com/forums/showthread.php?t=53494)

Ketho 05-26-16 06:44 AM

EditBox and long strings
 
I have problems using EditBoxes containing large amounts of text.
For example 3,500 lines of text comprising 270,000 characters.

Calling :SetText() and :Insert() with very long strings;
or scrolling, resizing and typing in the editbox can freeze up the game.

It's not really a Legion bug, since it's the same on Live and has always been like that as far as I can remember.
Are there maybe any previous discussions about this?



WeakAuras also has problems dealing with it
http://eu.battle.net/wow/en/forum/topic/17611871083

Edit: I guess the EditBox was not meant for big amounts of text then. If I just wanted to see an in-game plain text list of the amount of character GUIDs I met on the Beta it's already too much to show.

zork 05-26-16 07:39 AM

The game freeze means that the call blocks all other actions until the function is done.

Only way around this would be to make the function non-blocking using some kind of worker with a callback.

Chunking can help too.

Not sure if WoW can do such a thing. I doubt it.

Gethe 05-26-16 05:28 PM

I've been tinkering with a modified version of LibTextDump in RealUI for good while. It utilizes a faux scroll frame where the text is a specific chunk of the current buffer based on the scroll position. The chunk is created from using two optional args for table.concat where you can specify the start and end indices for the function.

There are still some lingering scroll issues, but for the most part it works pretty well.

Ketho 05-28-16 05:37 AM

Quote:

Originally Posted by Gethe (Post 315249)
I've been tinkering with a modified version of LibTextDump in RealUI for good while.

Your modified version of LibTextDump really works nicely! :)
I obviously can't copy the full amount of text to clipboard, but it's fine for just viewing I guess

(Instead of the original LibTextDump version, which had problems with massive amounts of text)


Gethe 05-28-16 10:31 PM

Not being able to select the entire text is the main drawback to the design, but I added some bits that allow you to dump the buffer into a savedvar (passed to :New via the added 4th arg) when you click the page icon. You can then browse it at your leisure in your favorite text editor.

Probably could have documented that better, but w/e ...

Ivaria 06-07-16 02:14 AM

Yes this is making doing any sort of large profile import/export freeze the WoW client for several seconds in VuhDo as well. Super annoying and I haven't found a way around it that allows easy copy & paste. :(

semlar 06-07-16 09:56 AM

Sorry I missed this topic, I solved this for weak auras a long time ago but they didn't get around to implementing it until recently.

The lag is caused by having word wrap enabled on a font string, and since this is generally only an issue for copying and pasting large amounts of text into and out of the game you can get around it by grabbing the editbox's font string and disabling "NonSpaceWrap", which is enabled by default and has no method on the edit box to turn it off.

Assuming you haven't called SetMultiLine or SetIndentedWordWrap on the edit box, all you need to do is run something like editbox:GetRegions():SetNonSpaceWrap(false) to disable it on the fontstring.

This will get rid of the lag but reduce you to a single line of text. If you'd like to still be able to view what's in the edit box you can create your own font string which truncates the text to whatever should be visible in the window.

Also, this problem should be somewhat mitigated in legion since I talked to a dev about it and he implemented a bandaid fix (eg. 3 seconds of lag instead of 60).

Ketho 06-07-16 06:31 PM

Quote:

Originally Posted by semlar (Post 315496)
Assuming you haven't called SetMultiLine or SetIndentedWordWrap on the edit box, all you need to do is run something like editbox:GetRegions():SetNonSpaceWrap(false) to disable it on the fontstring.


If I don't call SetMultiLine it already seems to almost completely reduce the lag, if I just wanted to copy/paste stuff.
Also tried :GetRegions():SetNonSpaceWrap(false) but not sure if it had any effect. I honestly don't have much experience with the EditBox.



The used editbox for reference:
https://gist.github.com/anonymous/70...ad5bbaa5cb04f2

Quote:

Originally Posted by semlar (Post 315496)
Also, this problem should be somewhat mitigated in legion since I talked to a dev about it and he implemented a bandaid fix (eg. 3 seconds of lag instead of 60).


Is this already implemented? I didn't benchmark how long it took, otherwise will have to test it on Live as Infus did


Quote:

Originally Posted by Gethe (Post 315310)
Not being able to select the entire text is the main drawback to the design, but I added some bits that allow you to dump the buffer into a savedvar (passed to :New via the added 4th arg) when you click the page icon. You can then browse it at your leisure in your favorite text editor.

Probably could have documented that better, but w/e ...


Ow, didn't know about that yet. I'm a bit used that with most WoW libraries the documentation is in the library itself x)

semlar 06-07-16 08:05 PM

Quote:

Originally Posted by Ketho (Post 315499)
If I don't call SetMultiLine it already seems to almost completely reduce the lag, if I just wanted to copy/paste stuff.

SetText doesn't behave the same way as actually typing characters into the edit box, so pasting large amounts of text will still lag your game while calling SetText does not.

Unfortunately, I just tried this and disabling word wrap doesn't appear to solve this problem any more. It was working about a week ago, but things change.

If you need to paste large amounts of text into the game, you can call editbox:SetMaxBytes(1) to limit the length of the string, and hook the edit box's OnChar function which will fire for every character in the paste regardless of whether it's being displayed.

Just insert the characters into a table OnChar and use OnUpdate to call table.concat on it on the next frame after the paste is finished to get your string.

Here's a relatively long example which accepts pastes and displays a truncated portion of it, something similar is being used in weak auras for importing strings.
Lua Code:
  1. local f = CreateFrame('frame')
  2. f:SetBackdrop({
  3.     bgFile = 'Interface/Tooltips/UI-Tooltip-Background',
  4.     edgeFile = 'Interface/Tooltips/UI-Tooltip-Border', edgeSize = 16,
  5.     insets = {left = 4, right = 4, top = 4, bottom = 4}
  6. })
  7. f:SetBackdropColor(0.2, 0.2, 0.2)
  8. f:SetBackdropBorderColor(0.2, 0.2, 0.2)
  9. f:SetPoint('CENTER')
  10. f:SetSize(400, 300)
  11.  
  12. local cursor = f:CreateTexture() -- make a fake blinking cursor, not really necessary
  13. cursor:SetTexture(1, 1, 1)
  14. cursor:SetSize(4, 8)
  15. cursor:SetPoint('TOPLEFT', 8, -8)
  16. cursor:Hide()
  17.  
  18. local editbox = CreateFrame('editbox', nil, f)
  19. editbox:SetMaxBytes(1) -- limit the max length of anything entered into the box, this is what prevents the lag
  20. editbox:SetAutoFocus(false)
  21.  
  22. local timeSince = 0
  23. local function UpdateCursor(self, elapsed)
  24.     timeSince = timeSince + elapsed
  25.     if timeSince >= 0.5 then
  26.         timeSince = 0
  27.         cursor:SetShown(not cursor:IsShown())
  28.     end
  29. end
  30.  
  31. local fontstring = f:CreateFontString(nil, nil, 'GameFontHighlightSmall')
  32. fontstring:SetPoint('TOPLEFT', 8, -8)
  33. fontstring:SetPoint('BOTTOMRIGHT', -8, 8)
  34. fontstring:SetJustifyH('LEFT')
  35. fontstring:SetJustifyV('TOP')
  36. fontstring:SetWordWrap(true)
  37. fontstring:SetNonSpaceWrap(true)
  38. fontstring:SetText('Click me!')
  39. fontstring:SetTextColor(0.6, 0.6, 0.6)
  40.  
  41. local textBuffer, i, lastPaste = {}, 0, 0
  42.  
  43. local function clearBuffer(self)
  44.     self:SetScript('OnUpdate', nil)
  45.     if i > 10 then -- ignore shorter strings
  46.         print(i, 'characters pasted')
  47.         local paste = strtrim(table.concat(textBuffer))
  48.         -- the longer this font string, the more it will lag trying to draw it
  49.         fontstring:SetText(strsub(paste, 1, 2500))
  50.         editbox:ClearFocus()
  51.     end
  52. end
  53.  
  54. editbox:SetScript('OnChar', function(self, c) -- runs for every character being pasted
  55.     if lastPaste ~= GetTime() then -- a timestamp can be used to track how many characters have been added within the same frame
  56.         textBuffer, i, lastPaste = {}, 0, GetTime()
  57.         self:SetScript('OnUpdate', clearBuffer)
  58.     end
  59.    
  60.     i = i + 1
  61.     textBuffer[i] = c -- store entered characters in a table to concat into a string later
  62. end)
  63.  
  64. editbox:SetScript('OnEditFocusGained', function(self)
  65.     fontstring:SetText('')
  66.     timeSince = 0
  67.     cursor:Show()
  68.     f:SetScript('OnUpdate', UpdateCursor)
  69. end)
  70.  
  71. editbox:SetScript('OnEditFocusLost', function(self)
  72.     f:SetScript('OnUpdate', nil)
  73.     cursor:Hide()
  74. end)
  75.  
  76. editbox:SetScript('OnEscapePressed', editbox.ClearFocus)
  77.  
  78. f:EnableMouse()
  79. f:SetScript('OnMouseDown', function()
  80.     editbox:SetFocus()
  81. end)


All times are GMT -6. The time now is 04:47 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI