33import com .cleanroommc .modularui .drawable .text .Spacer ;
44import com .cleanroommc .modularui .utils .Alignment ;
55
6+ import java .util .function .UnaryOperator ;
7+ import java .util .regex .Pattern ;
8+
69public 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 ();
0 commit comments