Automatic text flow from one GuiMLTextCtrl to another
by Jacob · in Torque Game Engine · 10/26/2005 (5:20 pm) · 18 replies
I think I need some help here...
I have some books in my game with fairly long text, that I would like to spread across several GuiMLTextCtrls - automagically. I was looking at guiMLTextCtrl.cc/.h and there is a function declared
but it's not defined anywhere. It looks like maybe it was meant to be used for getting text that was overflowing the MLTextCtrl? In any case - it's not defined.
I thought that getNumChars() would return the size of the visible text but it returns the size of the whole thing, even the text that does not fit in the control.
So, what I am hoping for is some help with figuring out how to get the text that is not fitting inside the control. Once I have that, I can have it sent to the next control and so on...until it is all displayed.
I have some books in my game with fairly long text, that I would like to spread across several GuiMLTextCtrls - automagically. I was looking at guiMLTextCtrl.cc/.h and there is a function declared
getWrappedText(char* pBuffer, const U32 bufferSize) const;
but it's not defined anywhere. It looks like maybe it was meant to be used for getting text that was overflowing the MLTextCtrl? In any case - it's not defined.
I thought that getNumChars() would return the size of the visible text but it returns the size of the whole thing, even the text that does not fit in the control.
So, what I am hoping for is some help with figuring out how to get the text that is not fitting inside the control. Once I have that, I can have it sent to the next control and so on...until it is all displayed.
About the author
#2
10/27/2005 (5:41 am)
I don't follow what you mean by "images & such"...
#3
------------
| text..... |
| text..... | <---- this upper area represents the size of my first GuiMLTextCtrl
| text..... |
|-----------|
|text...... | <---- this lower area represents text that does not fit inside my first GuiMLTextCtrl
|_______|
I would like to take the text that does not fit (from the lower area) and have it show up in the next available GuiMLTextCtrl - the next page of the book.
I would like this to happen automatically, so I don't have to divide my text variable into pieces, each one just the right size to fit in each control. I could divide it but the text will change so it will not always fit as it should.
So...is there a way to get the overflowing text that is not fitting into the control?
Thank You!
10/27/2005 (9:39 am)
In case my original post was misunderstood, here is a visual:------------
| text..... |
| text..... | <---- this upper area represents the size of my first GuiMLTextCtrl
| text..... |
|-----------|
|text...... | <---- this lower area represents text that does not fit inside my first GuiMLTextCtrl
|_______|
I would like to take the text that does not fit (from the lower area) and have it show up in the next available GuiMLTextCtrl - the next page of the book.
I would like this to happen automatically, so I don't have to divide my text variable into pieces, each one just the right size to fit in each control. I could divide it but the text will change so it will not always fit as it should.
So...is there a way to get the overflowing text that is not fitting into the control?
Thank You!
#4
10/31/2005 (1:15 pm)
I am still hoping for some help on this one.
#5
P.S. I still don't know what Ben meant in his reply...
11/25/2005 (11:58 am)
I would appreciate it if someone from GG or anyone knwledgeable could give me an idea on how easy this would be to implement so I can make a decision whethere to attempt it or find a different approach. :)P.S. I still don't know what Ben meant in his reply...
#6
I think Ben was talking about adding an image reference in your book text. Here's what a typical .HFL graphic embedding tag might look like . . .
"bitmap:" is the call, "demo/client/ui" is the path leading to the image, and "separator" is the name of the actual image (it automatically accepts .JPG or .PNG files -- in that order of preference).
I hope this helps,
Aaron E.
11/25/2005 (1:04 pm)
Jacob,I think Ben was talking about adding an image reference in your book text. Here's what a typical .HFL graphic embedding tag might look like . . .
<bitmap:demo/client/ui/separator>
"bitmap:" is the call, "demo/client/ui" is the path leading to the image, and "separator" is the name of the actual image (it automatically accepts .JPG or .PNG files -- in that order of preference).
I hope this helps,
Aaron E.
#7
I hope this clears it up...or am I just not understanding what you are saying? :)
11/25/2005 (1:13 pm)
Thanks for the reply Aaron, however, I think that there still may be some misunderstanding. This is not a book that is being typed in by the user, but a book that is already prepared/typed (by me) and is just displayed to the user. The text of the book is too large to fit into one ML Control. I want to have the text that overflows the first page to be automagically forwarded and displayed on the next page and so on, until all of it fits.I hope this clears it up...or am I just not understanding what you are saying? :)
#8
The stuff that Ben and I were referring to was for pre-typed book/text files that have been saved in .HFL format. The file names for some 'hypothetical' books could be . . .
The Real Neversaint.HFL
Biography of the Fox King.HFL
The Broom Man.HFL
Here is the text and .HFL markup tags for a short, two-page 'book' titled "The Broom Man".
Again, this is for pre-written text documents. Notice where the image link is placed and the syntax for it. A page divider image with page numbers could be embedded using this technique.
If none of that makes sense, I can do a quick gui example and post a screenshot of it.
11/26/2005 (10:59 am)
Jacob,The stuff that Ben and I were referring to was for pre-typed book/text files that have been saved in .HFL format. The file names for some 'hypothetical' books could be . . .
The Real Neversaint.HFL
Biography of the Fox King.HFL
The Broom Man.HFL
Here is the text and .HFL markup tags for a short, two-page 'book' titled "The Broom Man".
<lmargin%:3><rmargin%:97><font:Arial Bold:20>The Broom Man<font:Arial:16> Of all the members of the Lesag Gont I've spoken with, none disturbed me as much as Maxus Rentak. A quiet and reserved man who never drank, never visited a brothel or even uttered a curse, he was famous for his ability to make people disappear. I asked him once what his weapon of choice was, and was equally startled by his answer. "I only like to use brooms," he said in his typical, quiet voice. The image of this silent, dour fellow attacking anyone with a weapon as inherently common and harmless as a broom so amused and intrigued me that I questioned him about it further. Maxus did not mind the questions, though it took some time to get the full story out of him, as naturally shy and reserved as he was. Maxus had been orphaned at a very young age and sent to live with his uncle, a seawheat plantation owner along the Mad Coast in northern Wyvernlund. The man promised to show his nephew the business and eventually make him a partner when he was old enough. In the meantime, the boy was put to work as his uncle's house servant. It was a grueling life as the old man was very particular about how things should be done. The boy was required to sweep the floors, ring the tower bell and dust the library. Whenever these chores were not completed to the uncle's satisfaction, which was frequent, Maxus was thrashed and forced to begin again. <bitmap:demo/client/ui/horizontalpagebar> After several years, Maxus Rentak grew into a young man, but his job responsibilities were not increased. His uncle promised to teach him the business, once Maxus had demonstrated his mastery of his servile assignments. In his eighteenth year, Maxus was called into the cellar by his uncle. He thought that he had not done a good enough job scouring the floor down there, and expected a beating. What he found, however, was his uncle packing his goods into crates. "I'm leaving Yesterbreeze," he explained. "The business has gone sour, so I thought I'd try my luck running a caravan in Worldpeak. I understand there's good money to be made, trading fake Delven artifacts to the Northmen and Traderkin. I wish I could take you with me, but there won't be much need for scouring, bell pulling, and dusting where I'm going." "But uncle," said Maxus. "I can't read, I know nothing of the business you promised to teach me. What will I do on my own?" "I'm certain you can find a job in some domestic capacity," shrugged the uncle. "I've done my best with you." Maxus had never stood up to his uncle before, and felt no anger only a sort of coldness that gripped his heart. Among his uncle's possessions being packed away was an old sturdy wooden broom, allegedly of Delven manufacture. He picked it up in his hands and swung it into his uncle's right arm. The old man screamed with pain and rage, but for some reason, Maxus didn't feel afraid anymore. He propped the broom against his other shoulder, and swung it out again. It smashed against the old man's neck and he fell to the floor. It was well known that Maxus' uncle was planning to leave Yesterbreeze, so his disappearance provoked no suspicion. The house and all the belongings were sold to the debt collectors, but Maxus took the broom. It seemed that his uncle had given him some worthwhile business skills after all.
Again, this is for pre-written text documents. Notice where the image link is placed and the syntax for it. A page divider image with page numbers could be embedded using this technique.
If none of that makes sense, I can do a quick gui example and post a screenshot of it.
#9
I should probably have asked this earlier, but is there a game that uses something similar for me (or others) to reference your situation with? If what you want has already been done before in another game, maybe we can get a better idea of what you're going for.
For example, the previous long example I sent a few minutes ago uses only one GUIMLText control with the verticle scroll bar enabled -- which works great for Morrowind style scrolls and parchments, but not books. This approach (ML text control with a scroll bar) seems to fit your original diagram pretty well.
However, if the effect you're going for is like a Morrowind style book with two pages visible at all times, then yes, you will probably need two separate ML control objects arranged side-by-side. Getting that to work will likely involve reading the entire text into a variable, sub-stringing out the characters for each page, and then doing a settext on the page/ML control objects.
Aaron E.
11/26/2005 (11:22 am)
Hello again,I should probably have asked this earlier, but is there a game that uses something similar for me (or others) to reference your situation with? If what you want has already been done before in another game, maybe we can get a better idea of what you're going for.
For example, the previous long example I sent a few minutes ago uses only one GUIMLText control with the verticle scroll bar enabled -- which works great for Morrowind style scrolls and parchments, but not books. This approach (ML text control with a scroll bar) seems to fit your original diagram pretty well.
However, if the effect you're going for is like a Morrowind style book with two pages visible at all times, then yes, you will probably need two separate ML control objects arranged side-by-side. Getting that to work will likely involve reading the entire text into a variable, sub-stringing out the characters for each page, and then doing a settext on the page/ML control objects.
Aaron E.
#10
In order to place images in an ML control you end up playing this game where you are moving the image around in the line of text trying to get the image to go where you want it. Since the test has an effect on where the image ends up, change the text and you have to reposition the image. Translate into a different language and there goes the layout. Same with user modified text.
Ideally, you could just put the image where you want it on the screen and have the text flow around it. Which is what Jacob's flowing text control idea would allow because you could set up your images and your text controls to be positioned just right and then it would wrap fine no matter the input.
11/26/2005 (11:25 am)
If the text is user input, then using images would not be an optimal solution. In order to place images in an ML control you end up playing this game where you are moving the image around in the line of text trying to get the image to go where you want it. Since the test has an effect on where the image ends up, change the text and you have to reposition the image. Translate into a different language and there goes the layout. Same with user modified text.
Ideally, you could just put the image where you want it on the screen and have the text flow around it. Which is what Jacob's flowing text control idea would allow because you could set up your images and your text controls to be positioned just right and then it would wrap fine no matter the input.
#11
Edit: Aaron, to answer your question about a game that uses a similar technique; think of Myst and the different books that one could read in it. However, I think they used images as the pages since they were animated when you turned them.
Imagine you have a GUI that is a book - it has pages side by side, each being a separate MLTextCtrl. Threre could be as many as 50 pages, if need be - depending on the length of the text that I type up for this particular book.
On the bottom of the left page is an arrow (button) that takes you to the previous two page layout and on the right is an arrow (button) that takes you to the nex two page layout.
My text is stored in a variable (not in a file) to protect it from being edited by the user. Imagine that the text stored in this variable is way to long to fit into one MLTextCtrl. If I .setText() the first MLTextCtrl with the variable, only whatever fits in the extents of the Ctrl will show and the rest will be hidden.
I want to take that which did not fit and forward it to the next page of my book (the next MLTextCtrl) - automatically.
I sort of have a solution where I figured out the average number of characters that fits inside my MLTextCtrls space and I have a function divide the text variable into chunks of text the size of the number I figured would always fit. The thing with this method though, is that not all chunks of text with x number of characters will be the same in length, due to the fact that each character is different in size.
So, the above method is a temp solution. What I would like, is to have a way to cut and forward the text to the next Ctrl according to what is fitting inside the extents of the Ctrl, and not by how many characters it is. This way things would always look clean, as each page would be filled equally.
I hope this makes sense! :)...and thanks for all your replies!
Edit #2: I think this should be clear by now, but I am not using scroll controls, otherwise this would be very easy and I wouldn't have even started this thread :)
11/26/2005 (12:26 pm)
Thanks guys. I do understand the .HFL format and I am using many of the special ML tags in my text. I'll try to make my idea even more clear :)Edit: Aaron, to answer your question about a game that uses a similar technique; think of Myst and the different books that one could read in it. However, I think they used images as the pages since they were animated when you turned them.
Imagine you have a GUI that is a book - it has pages side by side, each being a separate MLTextCtrl. Threre could be as many as 50 pages, if need be - depending on the length of the text that I type up for this particular book.
On the bottom of the left page is an arrow (button) that takes you to the previous two page layout and on the right is an arrow (button) that takes you to the nex two page layout.
My text is stored in a variable (not in a file) to protect it from being edited by the user. Imagine that the text stored in this variable is way to long to fit into one MLTextCtrl. If I .setText() the first MLTextCtrl with the variable, only whatever fits in the extents of the Ctrl will show and the rest will be hidden.
I want to take that which did not fit and forward it to the next page of my book (the next MLTextCtrl) - automatically.
I sort of have a solution where I figured out the average number of characters that fits inside my MLTextCtrls space and I have a function divide the text variable into chunks of text the size of the number I figured would always fit. The thing with this method though, is that not all chunks of text with x number of characters will be the same in length, due to the fact that each character is different in size.
So, the above method is a temp solution. What I would like, is to have a way to cut and forward the text to the next Ctrl according to what is fitting inside the extents of the Ctrl, and not by how many characters it is. This way things would always look clean, as each page would be filled equally.
I hope this makes sense! :)...and thanks for all your replies!
Edit #2: I think this should be clear by now, but I am not using scroll controls, otherwise this would be very easy and I wouldn't have even started this thread :)
#12
11/26/2005 (12:40 pm)
Ok. Cool. Sorry about that. In that case, it sounds like substrings and settexts are the way to go with this. And, if I remember correctly, I saw something that counts the number of words in a string. A variation of that code/script/whatever could help you achieve the clean look you described. Unfortunately, I can't remember where I saw the word count stuff. If I find it again, I'll post a link to it.
#13
11/26/2005 (12:45 pm)
Thanks Aaron, what you described is how I have it set up now. Maybe I'll figure a better way at some point.
#14
Forwarding isn't a good way to solve the problem, it adds a lot of complications and not a lot of gain. I suggested images because you initially made it sound like you had a basically columnar layout that you wanted to flow around existing controls - in which case you could make things flow by placing transparent images in the right places.
Most games that have this sort of functionality often have manual page breaks set up, or even precooked images that they show like a slideshow. How hard would it be to add a [pagebreak] tag that you parse out in script and use to seperate pages?
It's actually called TorqueML, .hfl stands for help file, which is what those files happen to contain. In the feature demo, TorqueML is stored in .txt files.
11/26/2005 (12:47 pm)
So why not have two controls, and then just page them both down when the user "turns the page"?Forwarding isn't a good way to solve the problem, it adds a lot of complications and not a lot of gain. I suggested images because you initially made it sound like you had a basically columnar layout that you wanted to flow around existing controls - in which case you could make things flow by placing transparent images in the right places.
Most games that have this sort of functionality often have manual page breaks set up, or even precooked images that they show like a slideshow. How hard would it be to add a [pagebreak] tag that you parse out in script and use to seperate pages?
It's actually called TorqueML, .hfl stands for help file, which is what those files happen to contain. In the feature demo, TorqueML is stored in .txt files.
#15
11/26/2005 (1:07 pm)
Ben, thanks for the reply. I have noticed a few complications and even though they are not too big, I might take a different approach. I did think of the "slideshow" before but if I keep editing my text, it will mean that I would have to change every "slide"/picture as they will all need to be reflowed... So there is no way to extract only the text that does not fit into the constraints of the MLTextCtrl?
#16
My project is very text-heavy, so these ideas are relevant for me as well. I'm really glad you started this thread. By the way, one possible option might involve using the GameSWF resource for Flash-based content. I've used it for in-game slideshows and it works great, so maybe there's some paging/text flow potential there.
@Ben
If I'm understanding you correctly, someone could place two identical ML controls side by side, each containing the exact same document, but displaying those contents at different positions within the text for each page. That sounds like a nice solution. I've never thought about directing scroll actions from script before but I'm definitely curious now.
TorqueML sounds like a more appropriate name than what I've been calling it. :) In my project I have a variety of document types that are differentiated by file extensions. That way, journal notes, books and other reading materials can be organized separately. I don't know about anyone else, but the first time I saw the TorqueML stuff in action, I got really excited about it. :)
[Edit: forgot something]
11/28/2005 (9:11 am)
@JacobMy project is very text-heavy, so these ideas are relevant for me as well. I'm really glad you started this thread. By the way, one possible option might involve using the GameSWF resource for Flash-based content. I've used it for in-game slideshows and it works great, so maybe there's some paging/text flow potential there.
@Ben
If I'm understanding you correctly, someone could place two identical ML controls side by side, each containing the exact same document, but displaying those contents at different positions within the text for each page. That sounds like a nice solution. I've never thought about directing scroll actions from script before but I'm definitely curious now.
TorqueML sounds like a more appropriate name than what I've been calling it. :) In my project I have a variety of document types that are differentiated by file extensions. That way, journal notes, books and other reading materials can be organized separately. I don't know about anyone else, but the first time I saw the TorqueML stuff in action, I got really excited about it. :)
[Edit: forgot something]
#17
Here's the word count command info I mentioned before.
GetWordCount(%mytext);
I accidentally found it today in the Appendix of Ken Finney's book. While I haven't tried it yet, it might come in handy for you.
Aaron E.
11/29/2005 (1:26 pm)
Jacob,Here's the word count command info I mentioned before.
GetWordCount(%mytext);
I accidentally found it today in the Appendix of Ken Finney's book. While I haven't tried it yet, it might come in handy for you.
Aaron E.
#18
11/29/2005 (2:14 pm)
The thing with getWordCount(%text) is that every word is not the same length :)...but it does what is says - get the word count.
Associate Kyle Carter