diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2014-01-06 18:02:35 +0400 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2014-01-07 17:53:32 +0400 |
commit | 256a069987e2c0b931b267561b8ba00e017cf472 (patch) | |
tree | 1728579d3383e69a8a9ce6b457442648feee5bdc /source/blender/editors | |
parent | 0213a43562cd60fa6e20535c5851733f47f20da4 (diff) |
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!).
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index c6aabbc61ca..a83f5b4776a 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; |