From 5ee13d8cee52505056a14c3ba3793d0e56afa202 Mon Sep 17 00:00:00 2001 From: salmonik Date: Tue, 27 Oct 2026 20:30:15 +0100 Subject: GUI: wrap all text instead of truncating - Remove ellipsis truncation from text_in; text is never cut to fit. - Add a wrapping helper that breaks at spaces and, for long words such as paths, at character boundaries. Card titles, control labels, info rows, sections, tooltips and toasts now wrap and their rows/panels grow. - Use ISurface::GetTextSize (slot 75) for real glyph widths, with the old estimate only as a fallback before the surface/fonts exist. - Dynamic card header height for wrapped titles; Active/Bind controls stay vertically centered. Slider controls are vertically centered in taller wrapped rows. - Auto-size System buttons to their labels. - Tooltips wrap to a panel sized by the widest line. - Drop the duplicate config path from the footer; the System page shows it wrapped, so the footer hint fits without clipping. --- src/gui.cpp | 419 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 245 insertions(+), 174 deletions(-) (limited to 'src/gui.cpp') diff --git a/src/gui.cpp b/src/gui.cpp index fc95d1f..f4ba009 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -30,7 +30,8 @@ enum { GS_DrawPrintText = 22, GS_GetScreenSize = 38, GS_CreateFont = 66, - GS_AddGlyphSet = 67 + GS_AddGlyphSet = 67, + GS_GetTextSize = 75 }; static unsigned long g_font_body = 0; @@ -87,6 +88,11 @@ static void s_screen(int &w, int &h) { using Fn = void (*)(void *, int &, int &); vfunc(g_surface, GS_GetScreenSize)(g_surface, w, h); } +static void s_text_size(unsigned long font, const wchar_t *text, int &w, + int &h) { + using Fn = void (*)(void *, unsigned long, const wchar_t *, int &, int &); + vfunc(g_surface, GS_GetTextSize)(g_surface, font, text, w, h); +} // --------------------------------------------------------------------------- // SDL polling @@ -511,17 +517,98 @@ static void ensure_fonts() { } static int text_w(const char *s, int tall) { - if (!s) return 0; + if (!s) + return 0; + unsigned long font = + (g_font_title && tall == g_title_h) ? g_font_title : g_font_body; + if (g_surface && font) { + wchar_t wbuf[1024]; + size_t n = mbstowcs(wbuf, s, 1023); + if (n != (size_t)-1) { + wbuf[n] = 0; + int w = 0, h = 0; + s_text_size(font, wbuf, w, h); + if (w > 0) + return w; + } + } + // Fallback when the surface/font is not ready yet. return (int)(strlen(s) * tall * 0.52f + 0.5f); } +static void draw_text_raw(int x, int y, const char *s, unsigned long font, + int tall); + +// Break text into lines that fit max_w. Words that are too wide (paths, long +// identifiers) are split by character so nothing is ever truncated. +static void wrap_text(const char *text, int max_w, int tall, + std::vector &out) { + out.clear(); + if (!text || !*text || max_w <= 0) + return; + const char *p = text; + std::string line; + while (*p) { + while (*p == ' ') + p++; + if (!*p) + break; + const char *start = p; + while (*p && *p != ' ') + p++; + std::string word(start, (size_t)(p - start)); + if (!line.empty()) { + std::string cand = line + " " + word; + if (text_w(cand.c_str(), tall) <= max_w) { + line = cand; + continue; + } + out.push_back(line); + line.clear(); + } + while (text_w(word.c_str(), tall) > max_w && word.size() > 1) { + size_t n = word.size(); + while (n > 1 && text_w(word.substr(0, n).c_str(), tall) > max_w) + n--; + out.push_back(word.substr(0, n)); + word = word.substr(n); + } + line = word; + } + if (!line.empty()) + out.push_back(line); +} + +static int wrap_count(const char *text, int max_w, int tall) { + std::vector lines; + wrap_text(text, max_w, tall, lines); + return (int)lines.size(); +} + +static void draw_wrapped(const Rect &clip, int x, int y, const char *text, + unsigned long font, int tall, int max_w, + const Col &c, int line_gap = 2) { + if (!text || !font) + return; + std::vector lines; + wrap_text(text, max_w, tall, lines); + s_text_color(c.r, c.g, c.b, c.a); + int lh = tall + line_gap; + for (size_t i = 0; i < lines.size(); i++) { + int ly = y + (int)i * lh; + if (ly < clip.y || ly + tall > clip.y + clip.h) + continue; + draw_text_raw(x, ly, lines[i].c_str(), font, tall); + } +} + static void draw_text_raw(int x, int y, const char *s, unsigned long font, int tall) { (void)tall; if (!s || !font) return; - wchar_t w[256]; - size_t n = mbstowcs(w, s, 255); + wchar_t w[1024]; + size_t n = mbstowcs(w, s, 1023); if (n == (size_t)-1) return; w[n] = 0; @@ -532,46 +619,20 @@ static void draw_text_raw(int x, int y, const char *s, unsigned long font, static void text_in(const Rect &clip, int x, int y, const char *s, unsigned long font, int tall, int max_w, const Col &c) { + (void)max_w; // callers must size the layout; text is never truncated if (!s || !font) return; if (y < clip.y || y + tall > clip.y + clip.h) return; if (x >= clip.x + clip.w) return; - - // Available space from x to the clip edge, optionally capped by max_w. - // Truncate first, then clamp: shifting before truncating used to draw the - // text outside the tooltip/button box. - int avail = clip.x + clip.w - x; - if (max_w > 0 && max_w < avail) - avail = max_w; - if (avail <= 0) - return; - - char buf[256]; - const char *draw = s; int w = text_w(s, tall); - if (w > avail) { - snprintf(buf, sizeof(buf), "%s", s); - int n = (int)strlen(buf); - int dots = text_w("...", tall); - while (n > 0 && text_w(buf, tall) + dots > avail) - buf[--n] = 0; - if (n > 0 && n + 3 < (int)sizeof(buf)) { - buf[n++] = '.'; - buf[n++] = '.'; - buf[n++] = '.'; - buf[n] = 0; - } - draw = buf; - w = text_w(draw, tall); - } if (x + w > clip.x + clip.w) x = clip.x + clip.w - w; if (x < clip.x) x = clip.x; s_text_color(c.r, c.g, c.b, c.a); - draw_text_raw(x, y, draw, font, tall); + draw_text_raw(x, y, s, font, tall); } static Rect clip_rect(const Rect &r, const Rect &clip) { @@ -640,13 +701,48 @@ static void layout() { if (g_win_y + g_win_h > h) g_win_y = h - g_win_h; } +static int card_content_w() { return g_win_w - S(190.0f) - S(28.0f); } + +static int title_max_w() { return card_content_w() - S(210.0f); } + +static int header_h(const Card &c) { + int n = wrap_count(c.title, title_max_w(), g_title_h); + if (n < 1) + n = 1; + int h = n * (g_title_h + S(2.0f)) + S(12.0f); + return h < S(36.0f) ? S(36.0f) : h; +} + +static int label_max_w(const Ctrl &c) { + if (c.kind == CK_SLIDER) + return S(214.0f); + return card_content_w() - S(16.0f) - S(110.0f); +} + +static int button_w(const char *label) { + int bw = text_w(label, g_body_h) + S(20.0f); + if (bw < S(160.0f)) + bw = S(160.0f); + int maxw = card_content_w() - S(24.0f); + if (bw > maxw) + bw = maxw; + return bw; +} + static int row_h(const Ctrl &c) { - switch (c.kind) { - case CK_SECTION: return S(24.0f); - case CK_INFO: return S(20.0f); - case CK_BUTTON: return S(32.0f); - default: return S(27.0f); - } + if (c.kind == CK_BUTTON) + return S(32.0f); + int maxw = (c.kind == CK_INFO || c.kind == CK_SECTION) + ? card_content_w() - S(24.0f) + : label_max_w(c); + int n = wrap_count(c.label, maxw, g_body_h); + if (n < 1) + n = 1; + int h = n * (g_body_h + S(2.0f)) + S(8.0f); + int minh = (c.kind == CK_INFO) ? S(20.0f) + : (c.kind == CK_SECTION) ? S(24.0f) + : S(27.0f); + return h < minh ? minh : h; } static int body_h(const Card &c) { @@ -658,7 +754,7 @@ static int body_h(const Card &c) { return h + S(6.0f); } -static int card_h(const Card &c) { return S(36.0f) + body_h(c) + S(8.0f); } +static int card_h(const Card &c) { return header_h(c) + body_h(c) + S(8.0f); } static Rect card_rect(int index, int y) { Card &c = g_cards[index]; @@ -866,14 +962,15 @@ static void handle_mouse_click() { Card &c = g_cards[i]; Rect cr = card_rect(i, y); int ch = card_h(c); + int hh = header_h(c); if (my >= cr.y && my < cr.y + ch) { // header - if (my < cr.y + S(36.0f)) { + if (my < cr.y + hh) { if (c.feat) { - Rect active{cr.x + cr.w - S(170.0f), cr.y + S(9.0f), S(18.0f), - S(18.0f)}; - Rect bind{cr.x + cr.w - S(112.0f), cr.y + S(7.0f), S(100.0f), - S(22.0f)}; + Rect active{cr.x + cr.w - S(170.0f), + cr.y + (hh - S(18.0f)) / 2, S(18.0f), S(18.0f)}; + Rect bind{cr.x + cr.w - S(112.0f), + cr.y + (hh - S(22.0f)) / 2, S(100.0f), S(22.0f)}; if (active.has(mx, my)) { c.feat->active = !c.feat->active; config_save(); @@ -895,7 +992,7 @@ static void handle_mouse_click() { return; } // body - int by = cr.y + S(36.0f) + S(6.0f); + int by = cr.y + hh + S(6.0f); for (int j = 0; j < c.n; j++) { Ctrl &ct = g_ctrls[c.c0 + j]; int rh = row_h(ct); @@ -908,7 +1005,8 @@ static void handle_mouse_click() { return; } if (ct.kind == CK_SLIDER) { - Rect track{cr.x + S(16.0f) + S(230.0f), by + S(9.0f), + Rect track{cr.x + S(16.0f) + S(230.0f), + by + (rh - S(8.0f)) / 2, cr.w - S(16.0f) - S(230.0f) - S(64.0f), S(8.0f)}; if (mx >= track.x && mx < track.x + track.w) { float t = (float)(mx - track.x) / (float)track.w; @@ -921,8 +1019,9 @@ static void handle_mouse_click() { return; } if (ct.kind == CK_BUTTON) { - Rect b{cr.x + cr.w - S(176.0f), by + S(3.0f), S(160.0f), - S(26.0f)}; + int bw = button_w(ct.label); + Rect b{cr.x + cr.w - S(16.0f) - bw, + by + (rh - S(26.0f)) / 2, bw, S(26.0f)}; if (b.has(mx, my)) { if (ct.action == ACT_RELOAD) { config_reload(); @@ -964,13 +1063,14 @@ static void handle_hover() { Card &c = g_cards[i]; Rect cr = card_rect(i, y); int ch = card_h(c); + int hh = header_h(c); if (my >= cr.y && my < cr.y + ch) { - if (my < cr.y + S(36.0f)) { + if (my < cr.y + hh) { if (c.feat) { - Rect active{cr.x + cr.w - S(170.0f), cr.y + S(9.0f), S(18.0f), - S(18.0f)}; - Rect bind{cr.x + cr.w - S(112.0f), cr.y + S(7.0f), S(100.0f), - S(22.0f)}; + Rect active{cr.x + cr.w - S(170.0f), + cr.y + (hh - S(18.0f)) / 2, S(18.0f), S(18.0f)}; + Rect bind{cr.x + cr.w - S(112.0f), + cr.y + (hh - S(22.0f)) / 2, S(100.0f), S(22.0f)}; if (active.has(mx, my)) g_hover_desc = "Enable this feature. A bind, when set, must be " "held for it to run."; @@ -987,7 +1087,7 @@ static void handle_hover() { } return; } - int by = cr.y + S(36.0f) + S(6.0f); + int by = cr.y + hh + S(6.0f); for (int j = 0; j < c.n; j++) { Ctrl &ct = g_ctrls[c.c0 + j]; int rh = row_h(ct); @@ -1165,11 +1265,13 @@ static void draw_checkbox(int x, int y, bool on) { } } -static void draw_slider(const Rect &clip, const Rect &cr, int y, const Ctrl &ct) { +static void draw_slider(const Rect &clip, const Rect &cr, int y, int rh, + const Ctrl &ct) { int track_x = cr.x + S(16.0f) + S(230.0f); int track_w = cr.w - S(16.0f) - S(230.0f) - S(64.0f); if (track_w < S(30.0f)) track_w = S(30.0f); - Rect track{track_x, y + S(9.0f), track_w, S(8.0f)}; + int track_y = y + (rh - S(8.0f)) / 2; + Rect track{track_x, track_y, track_w, S(8.0f)}; fill(track, Col{38, 42, 50, 255}, &clip); int value = ctrl_val(ct); float t = (ct.max > ct.min) @@ -1181,8 +1283,8 @@ static void draw_slider(const Rect &clip, const Rect &cr, int y, const Ctrl &ct) fill(Rect{kx, track.y - S(4.0f), S(8.0f), S(16.0f)}, C_ACCENT, &clip); char val[32]; snprintf(val, sizeof(val), "%d", value); - text_in(clip, cr.x + cr.w - S(52.0f), y + S(4.0f), val, g_font_body, g_body_h, - S(44.0f), C_TEXT); + text_in(clip, cr.x + cr.w - S(52.0f), y + (rh - g_body_h) / 2, val, + g_font_body, g_body_h, 0, C_TEXT); } static void draw_card(const Rect &clip, int index, int y) { @@ -1193,10 +1295,12 @@ static void draw_card(const Rect &clip, int index, int y) { return; fill(cr, C_PANEL, &clip); outline(cr, Col{52, 57, 67, 255}, &clip); - Rect head{cr.x, cr.y, cr.w, S(36.0f)}; + int hh = header_h(c); + Rect head{cr.x, cr.y, cr.w, hh}; fill(head, C_HEADER, &clip); + // expand arrow - int ax = cr.x + S(10.0f), ay = cr.y + S(13.0f); + int ax = cr.x + S(10.0f), ay = cr.y + (hh - S(8.0f)) / 2; if (c.expanded) { line(ax, ay, ax + S(4.0f), ay + S(5.0f), C_DIM); line(ax + S(4.0f), ay + S(5.0f), ax + S(8.0f), ay, C_DIM); @@ -1204,40 +1308,53 @@ static void draw_card(const Rect &clip, int index, int y) { line(ax, ay, ax + S(5.0f), ay + S(4.0f), C_DIM); line(ax + S(5.0f), ay + S(4.0f), ax, ay + S(8.0f), C_DIM); } - text_in(clip, cr.x + S(24.0f), cr.y + S(8.0f), c.title, g_font_title, - g_title_h, cr.w - S(180.0f), C_TEXT); + + // title (wraps instead of truncating) + std::vector title_lines; + wrap_text(c.title, title_max_w(), g_title_h, title_lines); + int tlh = g_title_h + S(2.0f); + int title_h = (int)title_lines.size() * tlh - S(2.0f); + int ty = cr.y + (hh - title_h) / 2; + draw_wrapped(clip, cr.x + S(24.0f), ty, c.title, g_font_title, g_title_h, + title_max_w(), C_TEXT, S(2.0f)); + if (c.feat) { bool active = c.feat->active; - draw_checkbox(cr.x + cr.w - S(170.0f), cr.y + S(10.0f), active); - text_in(clip, cr.x + cr.w - S(148.0f), cr.y + S(9.0f), - active ? "On" : "Off", g_font_body, g_body_h, S(32.0f), - active ? C_GOOD : C_DIM); - Rect bind{cr.x + cr.w - S(112.0f), cr.y + S(7.0f), S(100.0f), S(22.0f)}; + int active_y = cr.y + (hh - S(18.0f)) / 2; + draw_checkbox(cr.x + cr.w - S(170.0f), active_y, active); + text_in(clip, cr.x + cr.w - S(148.0f), + active_y + (S(18.0f) - g_body_h) / 2, active ? "On" : "Off", + g_font_body, g_body_h, 0, active ? C_GOOD : C_DIM); + Rect bind{cr.x + cr.w - S(112.0f), cr.y + (hh - S(22.0f)) / 2, S(100.0f), + S(22.0f)}; fill(bind, Col{45, 50, 60, 255}, &clip); outline(bind, C_BORDER, &clip); const char *bl = (g_capture_card == index) ? "Press..." : scancode_name(c.feat->bind); - text_in(clip, bind.x + S(7.0f), bind.y + S(3.0f), bl, g_font_body, g_body_h, - bind.w - S(22.0f), C_TEXT); - text_in(clip, bind.x + bind.w - S(16.0f), bind.y + S(3.0f), "x", - g_font_body, g_body_h, S(10.0f), C_DIM); + text_in(clip, bind.x + S(7.0f), bind.y + (bind.h - g_body_h) / 2, bl, + g_font_body, g_body_h, 0, C_TEXT); + text_in(clip, bind.x + bind.w - S(16.0f), + bind.y + (bind.h - g_body_h) / 2, "x", g_font_body, g_body_h, 0, + C_DIM); } if (!c.expanded) return; - int by = cr.y + S(36.0f) + S(6.0f); + int by = cr.y + hh + S(6.0f); for (int j = 0; j < c.n; j++) { Ctrl &ct = g_ctrls[c.c0 + j]; int rh = row_h(ct); if (ct.kind == CK_SECTION) { - text_in(clip, cr.x + S(16.0f), by + S(3.0f), ct.label, g_font_body, - g_body_h, cr.w - S(24.0f), C_ACCENT); + draw_wrapped(clip, cr.x + S(16.0f), by + S(3.0f), ct.label, g_font_body, + g_body_h, card_content_w() - S(24.0f), C_ACCENT, S(2.0f)); } else if (ct.kind == CK_INFO) { - text_in(clip, cr.x + S(16.0f), by + S(1.0f), ct.label, g_font_body, - g_body_h, cr.w - S(24.0f), C_DIM); + draw_wrapped(clip, cr.x + S(16.0f), by + S(3.0f), ct.label, g_font_body, + g_body_h, card_content_w() - S(24.0f), C_DIM, S(2.0f)); } else if (ct.kind == CK_BUTTON) { - Rect b{cr.x + cr.w - S(176.0f), by + S(3.0f), S(160.0f), S(26.0f)}; + int bw = button_w(ct.label); + Rect b{cr.x + cr.w - S(16.0f) - bw, by + (rh - S(26.0f)) / 2, bw, + S(26.0f)}; fill(b, Col{45, 50, 60, 255}, &clip); outline(b, C_BORDER, &clip); const char *label = ct.label; @@ -1247,19 +1364,25 @@ static void draw_card(const Rect &clip, int index, int y) { else label = "Confirm reset"; } - text_in(clip, b.x + S(10.0f), b.y + S(4.0f), label, g_font_body, - g_body_h, b.w - S(16.0f), C_TEXT); + text_in(clip, b.x + S(10.0f), b.y + (b.h - g_body_h) / 2, label, + g_font_body, g_body_h, 0, C_TEXT); } else { - text_in(clip, cr.x + S(16.0f), by + S(4.0f), ct.label, g_font_body, - g_body_h, S(220.0f), C_TEXT); + int maxw = label_max_w(ct); + std::vector lines; + wrap_text(ct.label, maxw, g_body_h, lines); + int lh = g_body_h + S(2.0f); + int text_h = (int)lines.size() * lh - S(2.0f); + int ly = by + (rh - text_h) / 2; + draw_wrapped(clip, cr.x + S(16.0f), ly, ct.label, g_font_body, g_body_h, + maxw, C_TEXT, S(2.0f)); if (ct.kind == CK_TOGGLE) { bool on = ctrl_val(ct) != 0; - draw_checkbox(cr.x + cr.w - S(31.0f), by + S(5.0f), on); - text_in(clip, cr.x + cr.w - S(58.0f), by + S(3.0f), - on ? "On" : "Off", g_font_body, g_body_h, S(26.0f), + draw_checkbox(cr.x + cr.w - S(31.0f), by + (rh - S(15.0f)) / 2, on); + text_in(clip, cr.x + cr.w - S(58.0f), by + (rh - g_body_h) / 2, + on ? "On" : "Off", g_font_body, g_body_h, 0, on ? C_GOOD : C_DIM); } else if (ct.kind == CK_SLIDER) { - draw_slider(clip, cr, by, ct); + draw_slider(clip, cr, by, rh, ct); } } by += rh; @@ -1272,94 +1395,46 @@ static void draw_tooltip() { float d = now_sec() - (float)g_hover_since; if (d < 0.4f) return; - int tw = text_w(g_hover_desc, g_body_h) + S(16.0f); int maxw = S(380.0f); - if (tw > maxw) tw = maxw; - int th = g_body_h + S(14.0f); + if (maxw > g_scr_w - S(32.0f)) + maxw = g_scr_w - S(32.0f); + std::vector lines; + wrap_text(g_hover_desc, maxw, g_body_h, lines); + if (lines.empty()) + return; + int line_w = 0; + for (auto &line : lines) { + int w = text_w(line.c_str(), g_body_h); + if (w > line_w) + line_w = w; + } + int line_h = g_body_h + S(3.0f); + int tw = line_w + S(16.0f); + int th = (int)lines.size() * line_h + S(12.0f) - S(3.0f); int x = g_hover_x + S(14.0f); int y = g_hover_y + S(16.0f); - if (x + tw > g_scr_w - S(4.0f)) x = g_hover_x - tw - S(10.0f); - if (y + th > g_scr_h - S(4.0f)) y = g_hover_y - th - S(10.0f); + if (x + tw > g_scr_w - S(4.0f)) + x = g_hover_x - tw - S(10.0f); + if (y + th > g_scr_h - S(4.0f)) + y = g_hover_y - th - S(10.0f); + if (x < S(4.0f)) + x = S(4.0f); + if (y < S(4.0f)) + y = S(4.0f); Rect r{x, y, tw, th}; fill(r, Col{12, 14, 18, 248}); outline(r, C_ACCENT_DIM); - Rect inner{x + S(7.0f), y + S(6.0f), tw - S(14.0f), g_body_h}; - text_in(inner, inner.x, inner.y, g_hover_desc, g_font_body, g_body_h, - inner.w, C_TEXT); + s_text_font(g_font_body); + s_text_color(C_TEXT.r, C_TEXT.g, C_TEXT.b, C_TEXT.a); + for (size_t i = 0; i < lines.size(); i++) + draw_text_raw(x + S(7.0f), y + S(6.0f) + (int)i * line_h, + lines[i].c_str(), g_font_body, g_body_h); } // --------------------------------------------------------------------------- // Toast drawing // --------------------------------------------------------------------------- -static int wrap_toast(const char *text, int max_w, int tall, - char lines[][256], int max_lines) { - int n = 0; - char cur[256] = {}; - bool truncated = false; - const char *p = text; - while (*p) { - while (*p == ' ') - p++; - if (!*p) - break; - const char *start = p; - while (*p && *p != ' ') - p++; - size_t wl = (size_t)(p - start); - if (wl > 120) - wl = 120; - char word[128]; - memcpy(word, start, wl); - word[wl] = 0; - - char cand[256]; - if (cur[0]) - snprintf(cand, sizeof(cand), "%s %s", cur, word); - else - snprintf(cand, sizeof(cand), "%s", word); - - if (text_w(cand, tall) <= max_w || !cur[0]) { - snprintf(cur, sizeof(cur), "%s", cand); - if (text_w(cur, tall) > max_w) { - // A single word longer than the panel: hard-truncate it. - int len = (int)strlen(cur); - while (len > 3 && text_w(cur, tall) > max_w) - cur[--len] = 0; - if (len > 3) { - cur[len - 3] = '.'; - cur[len - 2] = '.'; - cur[len - 1] = '.'; - } - truncated = true; - } - } else { - if (n < max_lines) - snprintf(lines[n++], 256, "%s", cur); - else - truncated = true; - snprintf(cur, sizeof(cur), "%s", word); - } - } - if (cur[0]) { - if (n < max_lines) - snprintf(lines[n++], 256, "%s", cur); - else - truncated = true; - } - if (truncated && n > 0) { - char *last = lines[n - 1]; - int len = (int)strlen(last); - if (len + 3 < 256) { - last[len++] = '.'; - last[len++] = '.'; - last[len++] = '.'; - last[len] = 0; - } - } - return n; -} - void gui_draw_toasts() { if (!g_surface) return; @@ -1401,13 +1476,14 @@ void gui_draw_toasts() { if (a > 1.0f) a = 1.0f; int alpha = (int)(a * 255.0f); - char lines[4][256]; - int nl = wrap_toast(t.text, max_w, g_body_h, lines, 4); + std::vector lines; + wrap_text(t.text, max_w, g_body_h, lines); + int nl = (int)lines.size(); if (nl == 0) continue; int line_w = 0; for (int j = 0; j < nl; j++) { - int w = text_w(lines[j], g_body_h); + int w = text_w(lines[j].c_str(), g_body_h); if (w > line_w) line_w = w; } @@ -1432,7 +1508,7 @@ void gui_draw_toasts() { for (int j = 0; j < nl; j++) { s_text_pos(x + pad + S(6.0f), y + pad + j * line_h); wchar_t w[256]; - size_t wn = mbstowcs(w, lines[j], 255); + size_t wn = mbstowcs(w, lines[j].c_str(), 255); if (wn == (size_t)-1) continue; w[wn] = 0; @@ -1515,15 +1591,10 @@ void gui_draw() { g_capture_card >= 0 ? "press a key / Esc" : "INS close"; int hint_w = text_w(hint, g_body_h); int hint_x = foot.x + foot.w - hint_w - S(12.0f); - int left_x = foot.x + S(12.0f); - if (hint_x < left_x) - hint_x = left_x; - int left_max = hint_x - left_x - S(12.0f); - if (left_max > 0) - text_in(foot, left_x, foot.y + S(6.0f), g_config_label, g_font_body, - g_body_h, left_max, C_DIM); - text_in(foot, hint_x, foot.y + S(6.0f), hint, g_font_body, g_body_h, - hint_w + S(4.0f), C_DIM); + if (hint_x < foot.x + S(12.0f)) + hint_x = foot.x + S(12.0f); + text_in(foot, hint_x, foot.y + S(6.0f), hint, g_font_body, g_body_h, 0, + C_DIM); draw_tooltip(); } -- cgit v1.2.3