[Bf-blender-cvs] [3c6b5b7] master: Add a new "shortening process" for UI string drawing, which keeps both right and left parts of the drawstr and replaces the middle by '...'

Bastien Montagne noreply at git.blender.org
Wed Jan 1 11:59:04 CET 2014


Commit: 3c6b5b72a497dd5cdb05e3c35c4117a4e8f5daf2
Author: Bastien Montagne
Date:   Wed Jan 1 11:18:27 2014 +0100
https://developer.blender.org/rB3c6b5b72a497dd5cdb05e3c35c4117a4e8f5daf2

Add a new "shortening process" for UI string drawing, which keeps both right and left parts
of the drawstr and replaces the middle by '...'

Rationnal:
It's usually easier to figure out what a troncated string means if you have both its start and end parts.

Details:
It currently affects all UI items (text fields, buttons, labels...).
Only exceptions are buttons inside menus, text fields & co being edited, and numbuttons/sliders.
Note that some static texts (like panels' titles or items in outliner) do not use usual UI items,
and just draw the whole text, using OpenGL to clip it. Will make another patch to fix this.

Reviewers: campbellbarton, brecht, carter2422, #user_interface

Reviewed by: brecht, carter2422

CC: billrey

Differential Revision: https://developer.blender.org/D114

===================================================================

M	source/blender/editors/interface/interface_widgets.c

===================================================================

diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 477b7c4..bffb1b6 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -33,6 +33,7 @@
 #include <string.h>
 #include <assert.h>
 
+#include "MEM_guardedalloc.h"
 
 #include "DNA_screen_types.h"
 #include "DNA_userdef_types.h"
@@ -968,6 +969,69 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
 }
 
 /**
+ * Cut off the middle of the text to fit into the width of \a rect
+ */
+static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
+{
+	const int border = UI_TEXT_CLIP_MARGIN + 1;
+	const int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0);
+	float strwidth;
+
+	/* need to set this first */
+	uiStyleFontSet(fstyle);
+
+	if (fstyle->kerning == 1) /* for BLF_width */
+		BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+
+	but->ofs = 0;
+	strwidth = BLF_width(fstyle->uifont_id, but->drawstr, sizeof(but->drawstr));
+
+	if (strwidth > okwidth) {
+		const char *sep = "...";
+		const int sep_len = strlen(sep);
+
+		const size_t max_len = sizeof(but->drawstr);
+		size_t l_end;
+
+		const float sep_strwidth = BLF_width(fstyle->uifont_id, sep, sizeof(sep));
+		const float parts_strwidth = ((float)okwidth - sep_strwidth) / 2.0f;
+
+		if (parts_strwidth < (float)UI_DPI_ICON_SIZE) {
+			/* If we really have no place, only show start of string. */
+			l_end = BLF_width_to_strlen(fstyle->uifont_id, but->drawstr, max_len, okwidth, &strwidth);
+			but->drawstr[l_end] = '\0';
+		}
+		else {
+			size_t r_offset, r_len;
+
+			l_end = BLF_width_to_strlen(fstyle->uifont_id, but->drawstr, max_len, parts_strwidth, &strwidth);
+			r_offset = BLF_width_to_rstrlen(fstyle->uifont_id, but->drawstr, max_len, parts_strwidth, &strwidth);
+			r_len = strlen(but->drawstr + r_offset) + 1;  /* +1 for the trailing '\0'... */
+
+			if (l_end + sep_len + r_len > max_len) {
+				/* Corner case, the str already takes all available mem, and the ellipsis chars would actually
+				 * add more chars...
+				 * Better to just trim one or two letters to the right in this case...
+				 */
+				l_end = BLF_width_to_strlen(fstyle->uifont_id, but->drawstr, max_len, okwidth, &strwidth);
+				but->drawstr[l_end] = '\0';
+			}
+			else {
+				memmove(but->drawstr + l_end + sep_len, but->drawstr + r_offset, r_len);
+				memcpy(but->drawstr + l_end, sep, sep_len);
+				strwidth = BLF_width(fstyle->uifont_id, but->drawstr, max_len);
+			}
+		}
+	}
+
+	but->strwidth = strwidth;
+
+	if (fstyle->kerning == 1) {
+		BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
+	}
+}
+
+/**
  * Cut off the text, taking into account the cursor location (text display while editing).
  */
 static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
@@ -1295,18 +1359,17 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
 	else if (ELEM(but->type, NUM, NUMSLI)) {
 		ui_text_clip_right_label(fstyle, but, rect);
 	}
+#if 0
 	/* Special hack for non-embossed TEX buttons in uiList (we want them to behave as much as possible as labels). */
 	else if ((but->type == TEX) && (but->flag & UI_BUT_LIST_ITEM) && (but->dt & UI_EMBOSSN)) {
 		but->ofs = 0;
 	}
-	else if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
-		ui_text_clip_left(fstyle, but, rect);
-	}
+#endif
 	else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) {
 		ui_text_clip_left(fstyle, but, rect);
 	}
 	else {
-		but->ofs = 0;
+		ui_text_clip_middle(fstyle, but, rect);
 	}
 
 	/* always draw text for textbutton cursor */




More information about the Bf-blender-cvs mailing list