Hi guys, I have created a custom speech gui using label to display string
here is my screenshot :
(http://d.imagehost.org/t/0574/Untitled-1.jpg) (http://d.imagehost.org/view/0574/Untitled-1)
any idea how can i justify the text in this gui, just like in microsoft word ?
here is my code so far :
function ccPlayerSpeak(String speech)
{
ggspeech.SetPosition(10, 10);
int gameloops = ((speech.Length / game.text_speed) + 1) * GetGameSpeed();
Labelspeech.Text=speech;
ggspeech.Visible= true;
WaitMouseKey(gameloops);
ggspeech.Visible= false;
}
really appreciate for any of your help. thanks
You can't. Due to the way AGS renders text in labels, there's no Justify setting in the properties of GUI Labels and consequently no way to do it manually.
You'd have to write your own function, calculating the width of every word and drawing them one by one.
I haven't tested this code, but I worked it up using three functions from my StringPlus module (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=20950.0) (String.SplitByWidth, String.SplitByString, and StringMergeArray):
String JustifyText(String text, int width, FontType font) {
if ((String.IsNullOrEmpty(text)) || (width <= 0) || (font < 0) || (font >= Game.FontCount)) return null;
String lines[] = text.SplitByWidth(width, font, " .,:;!?'""); // you can supply your own delimiter set here if you want; this defines what characters should be used to determine where a line ends at
if ((lines == null) || (String.IsNullOrEmpty(lines[0])) || (!lines[0].AsInt)) return null;
int lineCount = lines[0].AsInt;
int line = 1;
while (line <= lineCount) { // change this to (line < lineCount) to skip justifying last line
String words[] = lines[line].SplitByString(" "); // since we're using whitespace to justify the text, use it to find the words in the line
if ((words != null) && (!String.IsNullOrEmpty(words[0])) && (words[0].AsInt)) {
// if there's at least two words, we can justify it here
int wordCount = words[0].AsInt;
String lineBuffer = lines[line]; // buffer to see how much justification is needed (if any)
if (lineBuffer == null) lineBuffer = ""; // prevent null pointer errors
int lineLength = lineBuffer.Length; // store the length before justification
while (GetTextWidth(lineBuffer.AppendChar(' '), font) <= width) lineBuffer = lineBuffer.AppendChar(' '); // calculate justification needed
int lineJustification = (lineBuffer.Length - lineLength); // get difference in previous and current length
int word = wordCount - 1; // justification starts on the right at the second to last word
while (lineJustification) { // while justification is needed
words[word] = words[word].AppendChar(' '); // add an extra space to the end of this word
lineJustification--; // update counter
word--; // update which word to add justification to
if (word <= 0) word = wordCount - 1; // if we've reached the first word, go back to the second to last
}
if (lineBuffer != lines[line]) lines[line] = StringMergeArray(words, " "); // if the line has been justified, update it
}
line++;
}
return StringMergeArray(lines, "["); // merge it back together using AGS line-breaks to keep our justification in place
}
Presuming it actually works (I don't have AGS on this computer), you should be able to now do:
Labelspeech.Text = JustifyText(speech, Labelspeech.Width, Labelspeech.Font);
As per your prior example code.
P.S. If you want to use the code without the other 40 or so functions in the StringPlus module, I could PM you modified versions of the module functions (modified to remove references to other module functions).
Edit: I forgot one thing that might have caused some issues with the StringPlus functions. Seeing as I'm using index 0 as the array size the word index shouldn't ever be set to 0 in the above example. It should be iterating through words[1] to words[wordCount - 1] to provide justification of the text.
I use Monkey_05_06 StringPlus Module and here is my implementation :
String JustifyText(String text, int width, FontType font) {
if ((String.IsNullOrEmpty(text)) || (width <= 0) || (font < 0) || (font >= Game.FontCount)) return null;
String lines[] = text.SplitByWidth(width, font, " "); // you can supply your own delimiter set here if you want; this defines what characters should be used to determine where a line ends at
if ((lines == null) || (String.IsNullOrEmpty(lines[0])) || (!lines[0].AsInt)) return null;
int lineCount = lines[0].AsInt;
int line = 1;
while (line < lineCount) { // change this to (line < lineCount) to skip justifying last line
String words[] = lines[line].SplitByString(" "); // since we're using whitespace to justify the text, use it to find the words in the line
if ((words != null) && (!String.IsNullOrEmpty(words[0])) && (words[0].AsInt)) {
// if there's at least two words, we can justify it here
int wordCount = words[0].AsInt;
String lineBuffer = lines[line]; // buffer to see how much justification is needed (if any)
if (lineBuffer == null) lineBuffer = ""; // prevent null pointer errors
int lineLength = lineBuffer.Length; // store the length before justification
while (GetTextWidth(lineBuffer.AppendChar(' '), font) <= width) lineBuffer = lineBuffer.AppendChar(' '); // calculate justification needed
int lineJustification = (lineBuffer.Length - lineLength); // get difference in previous and current length
int word = wordCount - 1; // justification starts on the right at the second to last word
while (lineJustification) { // while justification is needed
words[word] = words[word].AppendChar(' '); // add an extra space to the end of this word
lineJustification--; // update counter
word--; // update which word to add justification to
if (word < 0) word = wordCount - 1; // if we've reached the first word, go back to the second to last
}
if (lineBuffer != lines[line]) lines[line] = StringMergeArray(words, " "); // if the line has been justified, update it
}
line++;
}
return StringMergeArray(lines, "["); // merge it back together using AGS line-breaks to keep our justification in place
}
and for my custom speech GUI
function ccPemainSpeak(String Kalimat)
{
ggspeech.SetPosition(10, 10);
int gameloops = ((Kalimat.Length / game.text_speed) + 1) * GetGameSpeed();
Labelspeech.Text=JustifyText(Kalimat, Labelspeech.Width - GetTextWidth("[", Labelspeech.Font),Labelspeech.Font);
ggspeech.Visible= true;
WaitMouseKey(gameloops);
ggspeech.Visible= false;
}
here is the result :
(http://d.imagehost.org/t/0866/Untitled-1_10.jpg) (http://d.imagehost.org/view/0866/Untitled-1_10)
The first two line seems justified correctly, the remaining are still repeating the last word at end of the line twice.