Skip to content

Commit 9ef7b49

Browse files
committed
helper methods to insert and replace tooltip elements and javadoc
1 parent 9ca3142 commit 9ef7b49

File tree

9 files changed

+368
-12
lines changed

9 files changed

+368
-12
lines changed

src/main/java/com/cleanroommc/modularui/api/drawable/IRichTextBuilder.java

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,34 @@
33
import com.cleanroommc.modularui.drawable.text.Spacer;
44
import com.cleanroommc.modularui.utils.Alignment;
55

6+
import java.util.function.UnaryOperator;
7+
import java.util.regex.Pattern;
8+
69
public interface IRichTextBuilder<T extends IRichTextBuilder<T>> {
710

811
T getThis();
912

1013
IRichTextBuilder<?> getRichText();
1114

15+
/**
16+
* Adds a string to the current line
17+
*
18+
* @param s string to add
19+
* @return this
20+
*/
1221
default T add(String s) {
1322
getRichText().add(s);
1423
return getThis();
1524
}
1625

26+
/**
27+
* Adds a drawable to the current line. If the drawable is not a {@link IIcon} it will convert to one with {@link IDrawable#asIcon()}.
28+
* If that icon then has no default height (<=0) then it is set to the default text height (9 pixel). If the width of the icon is not
29+
* set, then the width of the widest tooltip line is used.
30+
*
31+
* @param drawable drawable to add.
32+
* @return this
33+
*/
1734
default T add(IDrawable drawable) {
1835
getRichText().add(drawable);
1936
return getThis();
@@ -29,38 +46,90 @@ default T addLine(ITextLine line) {
2946
return getThis();
3047
}
3148

49+
/**
50+
* Adds a drawable to the current line and creates a new line.
51+
* Refer to {@link #add(IDrawable)} for additional information.
52+
*
53+
* @param line drawable to add.
54+
* @return this
55+
* @see #add(IDrawable)
56+
*/
3257
default T addLine(IDrawable line) {
3358
getRichText().add(line).newLine();
3459
return getThis();
3560
}
3661

62+
/**
63+
* Starts a new line. This is always preferred over {@code "\n"} or {@code IKey.str("\n)}, it reduces computation a lot and maybe saves
64+
* a tiny bit of memory.
65+
*
66+
* @return this
67+
*/
3768
default T newLine() {
3869
return add(IKey.LINE_FEED);
3970
}
4071

72+
/**
73+
* Adds a space character to the current line. This is rarely useful.
74+
*
75+
* @return this
76+
*/
4177
default T space() {
4278
return add(IKey.SPACE);
4379
}
4480

81+
/**
82+
* Adds a line with a given thickness in pixels. This will result in larger text line gap.
83+
*
84+
* @param pixelSpace thickness in pixel
85+
* @return this
86+
*/
4587
default T spaceLine(int pixelSpace) {
4688
return addLine(Spacer.of(pixelSpace));
4789
}
4890

91+
/**
92+
* Adds a two pixel thick empty line. This will result in larger text line gap.
93+
* This is useful for titles.
94+
*
95+
* @return this
96+
*/
4997
default T spaceLine() {
5098
return addLine(Spacer.SPACER_2PX);
5199
}
52100

101+
/**
102+
* Adds an empty line which is as tall as a normal text line.
103+
*
104+
* @return this
105+
*/
53106
default T emptyLine() {
54107
return addLine(Spacer.LINE_SPACER);
55108
}
56109

110+
/**
111+
* Adds a drawable sto the current line.
112+
* Refer to {@link #add(IDrawable)} for additional information.
113+
*
114+
* @param drawables drawables to add.
115+
* @return this
116+
* @see #add(IDrawable)
117+
*/
57118
default T addElements(Iterable<IDrawable> drawables) {
58119
for (IDrawable drawable : drawables) {
59120
getRichText().add(drawable);
60121
}
61122
return getThis();
62123
}
63124

125+
/**
126+
* Adds each drawable and creates a new line after each.
127+
* Refer to {@link #add(IDrawable)} for additional information.
128+
*
129+
* @param drawables drawables to add.
130+
* @return this
131+
* @see #add(IDrawable)
132+
*/
64133
default T addDrawableLines(Iterable<IDrawable> drawables) {
65134
for (IDrawable drawable : drawables) {
66135
getRichText().add(drawable).newLine();
@@ -75,6 +144,156 @@ default T addStringLines(Iterable<String> drawables) {
75144
return getThis();
76145
}
77146

147+
/**
148+
* Finds the next element which contains the matching regex and put the cursor after it.
149+
* If none was found the cursor is at the end.
150+
*
151+
* @param regex regex to match strings for
152+
* @return this
153+
*/
154+
default T moveCursorAfterElement(String regex) {
155+
return moveCursorAfterElement(Pattern.compile(regex));
156+
}
157+
158+
/**
159+
* Finds the next element which contains the matching regex and put the cursor after it.
160+
* If none was found the cursor is at the end.
161+
*
162+
* @param regex regex to match strings for
163+
* @return this
164+
*/
165+
default T moveCursorAfterElement(Pattern regex) {
166+
getRichText().moveCursorAfterElement(regex);
167+
return getThis();
168+
}
169+
170+
/**
171+
* Finds the next element which contains the matching regex and replaces the whole element with the result of the function.
172+
* The cursor is then placed after the new element. If the function returns {@code null}, then the element is removed.
173+
* If no element is found nothing happens and the cursor stays in place.
174+
*
175+
* @param regex regex to match strings for
176+
* @param function function to modify the found element
177+
* @return this
178+
*/
179+
default T replace(String regex, UnaryOperator<IKey> function) {
180+
return replace(Pattern.compile(regex), function);
181+
}
182+
183+
/**
184+
* Finds the next element which contains the matching regex and replaces the whole element with the result of the function.
185+
* The cursor is then placed after the new element. If the function returns {@code null}, then the element is removed.
186+
* If no element is found nothing happens and the cursor stays in place.
187+
*
188+
* @param regex regex to match strings for
189+
* @param function function to modify the found element
190+
* @return this
191+
*/
192+
default T replace(Pattern regex, UnaryOperator<IKey> function) {
193+
getRichText().replace(regex, function);
194+
return getThis();
195+
}
196+
197+
/**
198+
* Moves the cursor to the very start.
199+
*
200+
* @return this
201+
*/
202+
default T moveCursorToStart() {
203+
getRichText().moveCursorToStart();
204+
return getThis();
205+
}
206+
207+
/**
208+
* Moves the cursor to the very end (default).
209+
*
210+
* @return this
211+
*/
212+
default T moveCursorToEnd() {
213+
getRichText().moveCursorToEnd();
214+
return getThis();
215+
}
216+
217+
/**
218+
* Moves the cursor a given number of elements forward. The cursor will be clamped at the end.
219+
*
220+
* @param by amount to move cursor by
221+
* @return this
222+
*/
223+
default T moveCursorForward(int by) {
224+
getRichText().moveCursorForward(by);
225+
return getThis();
226+
}
227+
228+
/**
229+
* Moves the cursor one element forward. The cursor will be clamped at the end.
230+
*
231+
* @return this
232+
*/
233+
default T moveCursorForward() {
234+
return moveCursorForward(1);
235+
}
236+
237+
/**
238+
* Moves the cursor a given number of elements backward. The cursor will be clamped at the start.
239+
*
240+
* @param by amount to move cursor by
241+
* @return this
242+
*/
243+
default T moveCursorBackward(int by) {
244+
getRichText().moveCursorBackward(by);
245+
return getThis();
246+
}
247+
248+
/**
249+
* Moves the cursor one element backward. The cursor will be clamped at the start.
250+
*
251+
* @return this
252+
*/
253+
default T moveCursorBackward() {
254+
return moveCursorBackward(1);
255+
}
256+
257+
/**
258+
* This finds the next element ending with a line break and moves the cursor after it. Note that if the line break is somewhere in the
259+
* middle of the element, that element will be ignored.
260+
*
261+
* @return this
262+
*/
263+
default T moveCursorToNextLine() {
264+
getRichText().moveCursorToNextLine();
265+
return getThis();
266+
}
267+
268+
/**
269+
* When the cursor is locked it will no longer move automatically when elements are added, but it can still be moved manually with the
270+
* move methods from above.
271+
*
272+
* @return this
273+
* @see #unlockCursor()
274+
*/
275+
default T lockCursor() {
276+
getRichText().lockCursor();
277+
return getThis();
278+
}
279+
280+
/**
281+
* When the cursor is locked it will no longer move automatically when elements are added, but it can still be moved manually with the
282+
* move methods from above.
283+
*
284+
* @return this
285+
* @see #lockCursor() ()
286+
*/
287+
default T unlockCursor() {
288+
getRichText().unlockCursor();
289+
return getThis();
290+
}
291+
292+
/**
293+
* Removes all text.
294+
*
295+
* @return this
296+
*/
78297
default T clearText() {
79298
getRichText().clearText();
80299
return getThis();

src/main/java/com/cleanroommc/modularui/api/drawable/ITextLine.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public interface ITextLine {
1010

1111
int getHeight(FontRenderer fr);
1212

13-
void draw(GuiContext context, FontRenderer fr, float x, float y, int color, boolean shadow);
13+
void draw(GuiContext context, FontRenderer fr, float x, float y, int color, boolean shadow, int availableWidth, int availableHeight);
1414

1515
Object getHoveringElement(FontRenderer fr, int x, int y);
1616

src/main/java/com/cleanroommc/modularui/drawable/text/ComposedLine.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public int getHeight(FontRenderer fr) {
3636
}
3737

3838
@Override
39-
public void draw(GuiContext context, FontRenderer fr, float x, float y, int color, boolean shadow) {
39+
public void draw(GuiContext context, FontRenderer fr, float x, float y, int color, boolean shadow, int availableWidth, int availableHeight) {
4040
this.lastX = x;
4141
this.lastY = y;
4242
for (Object o : this.elements) {
@@ -47,11 +47,12 @@ public void draw(GuiContext context, FontRenderer fr, float x, float y, int colo
4747
x += fr.getStringWidth(s);
4848
} else if (o instanceof IIcon icon) {
4949
float drawY = getHeight(fr) / 2f - icon.getHeight() / 2f;
50-
icon.draw(context, (int) x, (int) (y + drawY), icon.getWidth(), icon.getHeight(), IThemeApi.get().getDefaultTheme().getFallback());
50+
int w = icon.getWidth() > 0 ? icon.getWidth() : availableWidth;
51+
icon.draw(context, (int) x, (int) (y + drawY), w, icon.getHeight(), IThemeApi.get().getDefaultTheme().getFallback());
5152
if (icon instanceof IHoverable hoverable) {
5253
hoverable.setRenderedAt((int) x, (int) (y + drawY));
5354
}
54-
x += icon.getWidth();
55+
x += w;
5556
}
5657
}
5758
}

0 commit comments

Comments
 (0)