Thread Tools Display Modes
10-09-11, 07:13 AM   #1
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
modify chat frame text wrapping

Hello,

Sorry for all the questions during the last few days... If you prefer me to continue a previous thread, let me know, I don't want to spam here.

I've encountered a problem with the scrolling part of the chat frame. By default, it is wrapping automatically the text, according to the chat frame width and the displayed text length.
However, the text I insert through my addon is right-to-left, and the wrapping corrupts it: the bottom line of the wrapped text should be actually the top line and so on.

How can I modify/fix this wrapping in order to display my right-to-left text properly? Is there a function I can hook?

Thanks in advance!
  Reply With Quote
10-09-11, 06:09 PM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Have you looked at addons like Prat that change the alignment of text in the chat frame? They (or at least they used to) have to do some tricky stuff to move the clickable regions over links when using a non-default text alignment, that may be relevant to what you're trying to do.

You could also take a look at the Blizzard UI code to see how they actually implement the wrapping. If they do it in Lua, you should be able to modify it fairly easily.
  Reply With Quote
10-09-11, 06:17 PM   #3
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Thank you for your reply!

I will take a look in Prat, to see what they do there.

I tried to look for the wrapping implementation in chatframe.lua before I posted this question, but I couldn't find the relevant code. Perhaps you can direct me to the right file or location?

Thanks!
  Reply With Quote
10-10-11, 12:13 AM   #4
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Well, now that I think about it, text wrapping is actually a property of font string objects, and is definitely not implemented in Lua, but if there is any Lua related to wrapping in the chat frame, it probably would be in the file that defines functions for the ScrollingMessageFrame template. Look at the files with "template" in their name.
  Reply With Quote
10-10-11, 12:50 AM   #5
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Last I checked the Chat Window had it's own special code for wrapping it's text, and is un-alterable to the end user. Blizzard made this change back in BC I think, to stop people fooling others by pretending to be another user, when it was just their message going down one line.

[Trade] [Bob]: Yo, I heard u liek mudkipz!
[Trade] [Tony]: Yeah man, I love mudkipz!
[Trade] [Tony]: What? I didn't say that!


So now it's:
[Trade] [Bob]: Yo, I heard u liek mudkipz!
.....[Trade] [Tony]: Yeah man, I love mudkipz!
[Trade] [Tony]: Hah! What an idort!



Setting justification in chat these days is as easy as ChatFrame#:SetJustifyH(val), and everything sorts itself out.
  Reply With Quote
10-10-11, 01:53 AM   #6
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
I've tried justification before, it doesn't fix the problem: the wrapping remains the same, and the lines are the same. The lines are just "pushed" to the right as they are.

The Problem with right-to-left text is that the last words of the text are at the beginning of the string. These words go to the top line upon wrapping (since it's the beginning of the string). Same for the first words of the text - they are at the end of the string and go to the lowest line upon wrapping.

First, I thought of rearranging the text when the user hits "enter" (before the wrapping), according to the chat frame size. However, I found out that the width of the characters is taken into account for wrapping. For example you can put more "iiiiiiiii..." in a wrapped line than "aaaaa....." since "a" is wider than "i". That means there is no fixed number of chars in a wrapped line. So I really don't know how to calculate it and know in advance how to rearrange the text just before the text is sent and the wrapping occur.

Will be happy for more help and ideas
  Reply With Quote
10-10-11, 03:00 AM   #7
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
You can easily calculate text width.

Code:
local MyFrame = CreateFrame("Frame", nil, UIParent)
MyFrame:Hide()
MyFrame.text = MyFrame:CreateFontString()
MyFrame.text:SetAllPoints(MyFrame)
MyFrame.text:SetFont(font, size)

function GetTextWidth(str)
	MyFrame.text:SetText(str)
	return MyFrame.text:GetWidth()
end
Make sure the font and size is the same as the Chat Frame. Incorporate some loops, and routines, and you'll be able to get subsets of strings that equal the same as where the Chat Frame wraps it's text A ChatFrame1:GetWidth() and a bit of trial and error should get you there.

Last edited by Nibelheim : 10-10-11 at 03:02 AM.
  Reply With Quote
10-10-11, 01:59 PM   #8
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Nibelheim View Post
Last I checked the Chat Window had it's own special code for wrapping it's text, and is un-alterable to the end user. Blizzard made this change back in BC I think, to stop people fooling others by pretending to be another user, when it was just their message going down one line.
I think you're confusing actual text wrapping with handling of consecutive whitespace characters. The issue your post is referring to was caused by users adding enough consecutive spaces in their message to cause it to wrap at exactly the right point to look like two separate messages for users who had not adjusted the width or font size of their chat frame. Now, the chat frame just displays any number of spaces as a single space. This also breaks those obnoxious gigantic ASCII art macros.
  Reply With Quote
10-10-11, 03:00 PM   #9
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Originally Posted by Nibelheim View Post
You can easily calculate text width.

Code:
local MyFrame = CreateFrame("Frame", nil, UIParent)
MyFrame:Hide()
MyFrame.text = MyFrame:CreateFontString()
MyFrame.text:SetAllPoints(MyFrame)
MyFrame.text:SetFont(font, size)

function GetTextWidth(str)
	MyFrame.text:SetText(str)
	return MyFrame.text:GetWidth()
end
Make sure the font and size is the same as the Chat Frame. Incorporate some loops, and routines, and you'll be able to get subsets of strings that equal the same as where the Chat Frame wraps it's text A ChatFrame1:GetWidth() and a bit of trial and error should get you there.
Thank you for your answer. I've started working on it, then I realized that if I rearrange the string according to frame width, it will only fix the display for the player who sends the text.
Another player might have different width and font size, and when he sees the text from the first player, it will look broken/corrupted to him.

So I guess I'm back at the beginning: I need a way to modify the wrapping procedure itself, when the text is displayed on the frame chat.
Any ideas how can I do it? I wasn't able to find the relevant part in the default code.

Thanks
  Reply With Quote
10-10-11, 06:52 PM   #10
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Originally Posted by Animor View Post
Any ideas how can I do it? I wasn't able to find the relevant part in the default code.

Thanks
Don't think you can, and even if you could it'd only be for your frame as well.

I think you're confusing actual text wrapping with handling of consecutive whitespace characters.
Nah, was referencing wrapping, just using an example that no longer applies
  Reply With Quote
10-16-11, 12:19 PM   #11
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Originally Posted by Nibelheim View Post
You can easily calculate text width.

Code:
local MyFrame = CreateFrame("Frame", nil, UIParent)
MyFrame:Hide()
MyFrame.text = MyFrame:CreateFontString()
MyFrame.text:SetAllPoints(MyFrame)
MyFrame.text:SetFont(font, size)

function GetTextWidth(str)
	MyFrame.text:SetText(str)
	return MyFrame.text:GetWidth()
end
Make sure the font and size is the same as the Chat Frame. Incorporate some loops, and routines, and you'll be able to get subsets of strings that equal the same as where the Chat Frame wraps it's text A ChatFrame1:GetWidth() and a bit of trial and error should get you there.
Hello
I tried again with the method you suggested, and I ran into problem getting the fontstring width. It looks like I'm getting wrong results. So I did an experiment: I sent a line of wide chars ("w") and then a line of narrow chars ("i"). On my screen, the line appeared to be more or less the same width. However, the width wasn't the same, was far from it. Here is a snapshot:

You can see that "w" line is 473.6 width and "i" line is 438.7 width. Even though the "i" line is a bit wider on the screen!

What am I missing here? How can I calculate the correct width?
  Reply With Quote
10-16-11, 12:23 PM   #12
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
First guess it the font between the Chat frame and the font string aren't exactly the same.
  Reply With Quote
10-16-11, 12:35 PM   #13
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Originally Posted by Nibelheim View Post
First guess it the font between the Chat frame and the font string aren't exactly the same.
I doubled checked it... also I can see the width changes when I change the font. For the snapshot example I just used the default font (Fonts\\ARIALN.TTF).
  Reply With Quote
10-16-11, 05:25 PM   #14
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Originally Posted by Animor View Post
Hello
I tried again with the method you suggested, and I ran into problem getting the fontstring width. <snip>
For FontStrings, you want to use FontString:GetStringWidth(); using FontString:GetWidth() returns the width of its region, which is set to zero by default. Using FontString:SetWidth() will actually truncate the FontSting should its StringWidth exceed its Width.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
10-16-11, 05:56 PM   #15
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Originally Posted by Torhal View Post
For FontStrings, you want to use FontString:GetStringWidth(); using FontString:GetWidth() returns the width of its region, which is set to zero by default. Using FontString:SetWidth() will actually truncate the FontSting should its StringWidth exceed its Width.
Only if you set the FS width to begin with. Unless this has been changed. Definitely worth checking out.

Among other things, if no width is explicitly set, GetWidth() will return the exact same result as GetStringWidth()
  Reply With Quote
10-16-11, 06:33 PM   #16
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Hrm, that is correct now that you mention it. Meh. I shouldn't hit forums after just waking up.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
10-17-11, 02:01 AM   #17
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
Thank you for your answer.
Actually, I tried both GetWidth and GetStringWidth. I got the same results from both of them.
I also tried several fonts. I displayed the fontstring itself on the screen to make sure I'm seeing the exact thing I'm measuring.

But still, the width I get is different from what I see. Did someone ever tried this kind of testing on string width?
  Reply With Quote
10-17-11, 02:10 AM   #18
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Originally Posted by Animor View Post
Thank you for your answer.
Actually, I tried both GetWidth and GetStringWidth. I got the same results from both of them.
I also tried several fonts. I displayed the fontstring itself on the screen to make sure I'm seeing the exact thing I'm measuring.

But still, the width I get is different from what I see. Did someone ever tried this kind of testing on string width?
So the Fontstring that appears on the screen is the correct, measured width, but the Chat Frame is different? Hmm, I wonder what the Chat frame would do to the font.

If you can, take a screenshot of both the Fontstring and the same text as the Fontstring displayed in the Chat frame, and let me know what the measured GetWidth was for that Fontstring

I've done a few pieces of code that measured text widths, and never had an issue with it being incorrect size. We just have to find out what's going on in this circumstance.
  Reply With Quote
10-17-11, 02:36 AM   #19
Animor
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Mar 2011
Posts: 136
mmm I think I wasn't clear enough.
I displayed the fontstring on the screen in order to make sure I'm not using one font for chatframe and one font for fontstring.

But still, I got the same strange results. I displayed two fontstrings on my screen: one with a long line of "w" and other with a long line of "i". On the screen, the lines look about the same width, and obviously there were more "i" than "w".
However, when I measured the width with either GetWidth or GetStringWidth, I got very strange results. I expected the widths of the two fontstrings to be more or less the same, but it wasn't the case.
Basically what I did is the same as in the snapshot I shown before, only this time I displayed the fontstrings directly on the screen.

When you compare few chars, you can't see the difference. But this difference grows and becomes meaningful when you have long strings, as I did.
  Reply With Quote
10-17-11, 02:44 AM   #20
Nibelheim
local roygbi-
 
Nibelheim's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 1,600
Ahh. The strange thing is neither of the strings shown in the picture above are nowhere near their reported widths (both being around 610 pixels wide). Don't know what's going on.

I've seen a similar effect to this, when two fontstrings have different OUTLINE or Shadow settings, as the fontstring will naturally add a gap between letters if they have an outline/shadow. This causes strings of thin letters (I's) to become longer due to more gaps being added. However, doesn't really sound like what's happening here.

Last edited by Nibelheim : 10-17-11 at 02:48 AM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » modify chat frame text wrapping


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off