No more line1, line2, ..., line5 bull shit.
What you will get
"Be able to display normal text \\n" +
"without manually having to make \\n" +
"line breaks in the client. Also \\n" +
"includes dynamic text interface type \\n" +
"which automatically wraps to fit \\n" +
"the given width."
Part 1
Core method is this. Add it to RSInterface.java or any suitable place.
Code:
/**
* Adds newlines to a text for a certain TextDrawingArea so each line is never longer than width.
* Param tda The textDrawing Area for the text, basically the font
* Param text The text to convert to wrapped text
* Param width The width above which wrapping is applied
* Return The wrapped text
*/
public static String getWrappedText(TextDrawingArea tda, String text, int width) {
if (text.contains("\\n") || tda.getTextWidth(text) <= width) {
return text;
}
int spaceWidth = tda.getTextWidth(" ");
StringBuilder result = new StringBuilder(text.length());
StringBuilder line = new StringBuilder();
int lineLength = 0;
int curIndex = 0;
while (true) {
int spaceIndex = text.indexOf(' ', curIndex);
int newLength = lineLength;
boolean last = false;
String curWord;
if (spaceIndex < 0) {
last = true;
curWord = text.substring(curIndex);
} else {
curWord = text.substring(curIndex, spaceIndex);
newLength += spaceWidth;
}
curIndex = spaceIndex + 1;
int w = tda.getTextWidth(curWord);
newLength += w;
if (newLength > width) {
result.append(line);
result.append("\\n");
line = new StringBuilder(curWord);
line.append(' ');
lineLength = w;
} else {
line.append(curWord);
line.append(' ');
lineLength = newLength;
}
if (last) {
break;
}
}
result.append(line);
return result.toString();
}
Somebody might get this cleaner but eh it works perfectly atm.
This goes over the text for a given font and adds line breaks in spaces to prevent any line exceeding the specified width.
Precondition is the text doesn't contain the client's custom new line string, \\n, since it uses that to check if wrapping has already been applied.
You can call this method now to get wrapped text for a specified width which is useful as is, but we can also apply it dynamically.
Part 2
New wrappable text interface type. Copy an existing addText method and change the type to 17 instead of 4 (can use constants, surprised I didn't). For the message call the method from the first part to getWrappedText. Make an apropriate method name for the new method.
Code:
/**
* Adds text with the specified properties. Automatically wraps text so it doesn't exceed width.
* Only use for dynamic interfaces as there is some computation to check if wrapping is required.
* If static text, use another addText method and pass the text into RSInterface.getWrappedText() firstly.
* Param id The child id for the text
* Param text The text message
* Param tda The tdas available
* Param idx The index of the tda to use
* Param color The text color
* Param center Whether the text is centered
* Param shadow Whether the text has shadow
* Param width The maximum width of each line before wrapping applies
* Return
*/
public static RSInterface addWrappingText(int id, String text, TextDrawingArea tda[],
int idx, int color, boolean center, boolean shadow, int width) {
RSInterface tab = addTabInterface(id);
tab.parentID = id;
tab.id = id;
tab.type = 17;
tab.atActionType = 0;
tab.width = width;
tab.height = 11;
tab.contentType = 0;
tab.opacity = 0;
tab.hoverType = -1;
tab.centerText = center;
tab.shadowed = shadow;
tab.textDrawingAreas = tda[idx];
tab.message = getWrappedText(tab.textDrawingAreas, text, tab.width);
tab.enabledMessage = "";
tab.disabledColor = color;
tab.enabledColor = 0;
tab.disabledMouseOverColor = 0;
tab.enabledMouseOverColor = 0;
return tab;
}
Will post proper code later, this is from memory now.
Go to Client.java. For all uses of interface type == 4 add || interface type == 17.
For the part that loads the string from the interface replace
Code:
String s = rsi.message
with
Code:
String s;
if (rsi.type == 17) {
s = RSInterface.getWrappedText(rsi.tda, rsi.message, rsi.width);
} else {
s = rsi.message;
}
You should be done! Double check you have checked all the type 4 cases and added the wrappable text type in as well otherwise you might have nothing displaying or errors. I'll post some media later or you can test it on LoyaltyScape with ::t to open the beta teleport interface and check the minigames category which has nice autowrapping descriptions with a width of 126 pixels.
Edit: Media
I asked if I should release this and Displee said I should so here you go. This is for 317s bit could easily be adapted to any client. I was making a teleport interface and had a tight space to fit any text information and other interfaces in the client done by other people would do separate lines and then have to manually decide which text goes on which line which is ridiculous. E.g.
Code:
private BossData(String name, int npcId, int npcZoom, int[][] bossItems, String line1, String line2, String line3, String line4, String line5) {
this.name = name;
this.npcId = npcId;
this.npcZoom = npcZoom;
this.bossItems = bossItems;
this.line1 = line1;
this.line2 = line2;
this.line3 = line3;
this.line4 = line4;
this.line5 = line5;
}
This also has advantage of having the text in a single child id. Additionally there is no cap for a line limit.
Note I didn't support color modifiers such as @red@. Not a fan of them and you can add that yourself.