[Bf-blender-cvs] [256a069] master: Middle-clip tweaks: * Now only middle-clip when both left and right parts of remaining strings are at least two times icon-width (thus most short labels will never be middle-clipped). * Add a trailing ellipsis to right-clipped strings (unless it would take more than 20% of whole available width, in this case just clip chars, to keep as much data visible as possible!).

Bastien Montagne noreply at git.blender.org
Tue Jan 7 14:53:10 CET 2014


Commit: 256a069987e2c0b931b267561b8ba00e017cf472
Author: Bastien Montagne
Date:   Mon Jan 6 15:02:35 2014 +0100
https://developer.blender.org/rB256a069987e2c0b931b267561b8ba00e017cf472

Middle-clip tweaks:
* Now only middle-clip when both left and right parts of remaining strings are at least two times icon-width (thus most short labels will never be middle-clipped).
* Add a trailing ellipsis to right-clipped strings (unless it would take more than 20% of whole available width, in this case just clip chars, to keep as much data visible as possible!).

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

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 c6aabbc..a83f5b4 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -967,8 +967,32 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
 	}
 }
 
+/* Helper.
+ * This func assumes things like kerning handling have already been handled!
+ * Return the length of modified (right-clipped + ellipsis) string.
+ */
+static void ui_text_clip_right_ex(uiFontStyle *fstyle, uiBut *but, const size_t max_len, const float okwidth,
+                                  const char *sep, const int sep_len, const float sep_strwidth)
+{
+	float tmp;
+	int l_end;
+
+	/* If the trailing ellipsis takes more than 20% of all available width, just cut the string
+	 * (as using the ellipsis would remove even more useful chars, and we cannot show much already!).
+	 */
+	if (sep_strwidth / okwidth > 0.2f) {
+		l_end = BLF_width_to_strlen(fstyle->uifont_id, but->drawstr, max_len, okwidth, &tmp);
+		but->drawstr[l_end] = '\0';
+	}
+	else {
+		l_end = BLF_width_to_strlen(fstyle->uifont_id, but->drawstr, max_len, okwidth - sep_strwidth, &tmp);
+		memcpy(but->drawstr + l_end, sep, sep_len + 1);  /* +1 for trailing '\0'. */
+	}
+}
+
 /**
- * Cut off the middle of the text to fit into the width of \a rect
+ * Cut off the middle of the text to fit into the width of \a rect.
+ * Note in case this middle clipping would just remove a few chars, it rather clips right, which is more readable.
  */
 static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
 {
@@ -976,6 +1000,7 @@ static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rec
 	const int border = ELEM(but->type, LABEL, MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
 	const int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0);
 	float strwidth;
+	const size_t max_len = sizeof(but->drawstr);
 
 	/* need to set this first */
 	uiStyleFontSet(fstyle);
@@ -984,24 +1009,21 @@ static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rec
 		BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
 
 	but->ofs = 0;
-	strwidth = BLF_width(fstyle->uifont_id, but->drawstr, sizeof(but->drawstr));
+	strwidth = BLF_width(fstyle->uifont_id, but->drawstr, max_len);
 
 	if (strwidth > okwidth) {
-		const char sep[] = "...";
+		const char sep[] = "…";
 		const int sep_len = sizeof(sep) - 1;
-
-		const size_t max_len = sizeof(but->drawstr);
 		size_t l_end;
 
 		const float sep_strwidth = BLF_width(fstyle->uifont_id, sep, sep_len + 1);
 		const float parts_strwidth = ((float)okwidth - sep_strwidth) / 2.0f;
 
-		if (min_ff(parts_strwidth, strwidth - okwidth) < (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 1.5) {
+		if (min_ff(parts_strwidth, strwidth - okwidth) < (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f) {
 			/* If we really have no place, or we would clip a very small piece of string in the middle,
 			 * 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';
+			ui_text_clip_right_ex(fstyle, but, max_len, (float)okwidth, sep, sep_len, sep_strwidth);
 		}
 		else {
 			size_t r_offset, r_len;
@@ -1014,16 +1036,16 @@ static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rec
 				/* 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...
+				 * Note: with a single-char ellipsis, this should never happen! But better be safe here...
 				 */
-				l_end = BLF_width_to_strlen(fstyle->uifont_id, but->drawstr, max_len, okwidth, &strwidth);
-				but->drawstr[l_end] = '\0';
+				ui_text_clip_right_ex(fstyle, but, max_len, (float)okwidth, sep, sep_len, sep_strwidth);
 			}
 			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);
 			}
 		}
+		strwidth = BLF_width(fstyle->uifont_id, but->drawstr, max_len);
 	}
 
 	but->strwidth = strwidth;




More information about the Bf-blender-cvs mailing list