nuklear
nuklear copied to clipboard
Multiline text in labels
In nk_label or nk_label_wrap, when i displaying some text with symbols '\n' or '\r', all text showing in one line with symbols '?' instead of line wraping. What i'm doing wrong?
P.S. Sorry for my English, by the way.
Same problem here with tooltips. Single line tooltips are not of much use for a game.
Sorry for bumping old issue, i stumbled across it when looking for duplicate issues. I also need to display multiline text. Here is my take on this: i saw #661 but i'm not sure if new API functions are really needed to display such text. IMO it could be separated into two problems:
-
nk_label()
andnk_label_wrap()
don't handle\r
or\n
-
\r
and\n
are displayed as?
on screen
So below is a patch that solves both problems, it's like 10 lines of code or so. Sadly i had to change indentation of some lines too, but it's basically 3 ifs. I'm aware that nuklear now has dedicated files for different parts of library, but this is patch is for amalgamated nuklear.h
, it's easier to present it this way. It should apply cleanly to adc52d71.
diff --git a/nuklear.h b/nuklear.h
index e847d5e..f24da9e 100644
--- a/nuklear.h
+++ b/nuklear.h
@@ -3720,6 +3720,14 @@ NK_API struct nk_rect nk_rectv(const float *xywh);
NK_API struct nk_rect nk_rectiv(const int *xywh);
NK_API struct nk_vec2 nk_rect_pos(struct nk_rect);
NK_API struct nk_vec2 nk_rect_size(struct nk_rect);
+/* =============================================================================
+ *
+ * UTIL
+ *
+ * ============================================================================= */
+NK_API int nk_text_clamp(const struct nk_user_font *font, const char *text,
+ int text_len, float space, int *glyphs, float *text_width,
+ nk_rune *sep_list, int sep_count);
/* =============================================================================
*
* STRING
@@ -5822,7 +5830,7 @@ NK_LIB void nk_zero(void *ptr, nk_size size);
NK_LIB char *nk_itoa(char *s, long n);
NK_LIB int nk_string_float_limit(char *string, int prec);
NK_LIB char *nk_dtoa(char *s, double n);
-NK_LIB int nk_text_clamp(const struct nk_user_font *font, const char *text, int text_len, float space, int *glyphs, float *text_width, nk_rune *sep_list, int sep_count);
+NK_API int nk_text_clamp(const struct nk_user_font *font, const char *text, int text_len, float space, int *glyphs, float *text_width, nk_rune *sep_list, int sep_count);
NK_LIB struct nk_vec2 nk_text_calculate_text_bounds(const struct nk_user_font *font, const char *begin, int byte_len, float row_height, const char **remaining, struct nk_vec2 *out_offset, int *glyphs, int op);
#ifdef NK_INCLUDE_STANDARD_VARARGS
NK_LIB int nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args);
@@ -7328,7 +7336,7 @@ nk_file_load(const char* path, nk_size* siz, struct nk_allocator *alloc)
return buf;
}
#endif
-NK_LIB int
+NK_API int
nk_text_clamp(const struct nk_user_font *font, const char *text,
int text_len, float space, int *glyphs, float *text_width,
nk_rune *sep_list, int sep_count)
@@ -7350,6 +7358,12 @@ nk_text_clamp(const struct nk_user_font *font, const char *text,
glyph_len = nk_utf_decode(text, &unicode, text_len);
while (glyph_len && (width < space) && (len < text_len)) {
len += glyph_len;
+ if (unicode == '\n' || unicode == '\r') {
+ sep_width = last_width = width;
+ sep_g = g+1;
+ sep_len = len;
+ break;
+ }
s = font->width(font->userdata, font->height, text, len);
for (i = 0; i < sep_count; ++i) {
if (unicode != sep_list[i]) continue;
@@ -10366,23 +10380,25 @@ nk_draw_list_add_text(struct nk_draw_list *list, const struct nk_user_font *font
float gx, gy, gh, gw;
float char_width = 0;
if (unicode == NK_UTF_INVALID) break;
-
- /* query currently drawn glyph information */
- next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
- font->query(font->userdata, font_height, &g, unicode,
- (next == NK_UTF_INVALID) ? '\0' : next);
-
- /* calculate and draw glyph drawing rectangle and image */
- gx = x + g.offset.x;
- gy = rect.y + g.offset.y;
- gw = g.width; gh = g.height;
- char_width = g.xadvance;
- nk_draw_list_push_rect_uv(list, nk_vec2(gx,gy), nk_vec2(gx + gw, gy+ gh),
- g.uv[0], g.uv[1], fg);
+ if (unicode != '\n' && unicode != '\r') {
+ /* query currently drawn glyph information */
+ next_glyph_len = nk_utf_decode(text + text_len + glyph_len, &next, (int)len - text_len);
+ font->query(font->userdata, font_height, &g, unicode,
+ (next == NK_UTF_INVALID) ? '\0' : next);
+
+ /* calculate and draw glyph drawing rectangle and image */
+ gx = x + g.offset.x;
+ gy = rect.y + g.offset.y;
+ gw = g.width; gh = g.height;
+ char_width = g.xadvance;
+ nk_draw_list_push_rect_uv(list, nk_vec2(gx,gy), nk_vec2(gx + gw, gy+ gh),
+ g.uv[0], g.uv[1], fg);
+
+ x += char_width;
+ }
/* offset next glyph */
text_len += glyph_len;
- x += char_width;
glyph_len = next_glyph_len;
unicode = next;
}
@@ -13026,10 +13042,11 @@ nk_font_text_width(nk_handle handle, float height, const char *text, int len)
while (text_len <= (int)len && glyph_len) {
const struct nk_font_glyph *g;
if (unicode == NK_UTF_INVALID) break;
-
- /* query currently drawn glyph information */
- g = nk_font_find_glyph(font, unicode);
- text_width += g->xadvance * scale;
+ if (unicode != '\n' && unicode != '\r') {
+ /* query currently drawn glyph information */
+ g = nk_font_find_glyph(font, unicode);
+ text_width += g->xadvance * scale;
+ }
/* offset next glyph */
glyph_len = nk_utf_decode(text + text_len, &unicode, (int)len - text_len);
So basically with this patch \r
and \n
are not displayed on screen (skipped) and nk_text_clamp()
will clamp on \r
and \n
as if width limit was reached. It also would be nice to make nk_text_clamp()
into NK_API
instead of NK_LIB
so it's possible to tell beforehand how many lines text would take, but it's not a big deal, it can be excluded from patch.
How does that look, is that something that could potentially be merged?
@vurtun @dumblob
Didn't have time to think much of this, but on the first sight it seems the patch does wrap the text twice in case it CRLF
and not just either of CR
or LF
.
The API seems clear to me, but I'd like to hear what the thoughts of @AntiBlueQuirk would be about this patch instead of #661 .
No, it doesn't handle CRLF, neither other newline characters line NEL. This is a bare minimum to fit into github comment. Other newline characters are just extension of [ CR, LF ] set, CR+LF is one read-ahead with proper checks or so i think.
By the way, line terminators could be passed to nk_text_clamp()
similarly to word separators, but probably it's better to pass a function instead of array. If we all could agree on general approach, then i think this patch could be potentially extended.