Fix T38678: Long strings on Search widget not getting shortened/no tooltip.
Note this commit only makes search menus wider and adds shortening to their strings. Adding tooltips here is not trivial, would need much bigger changes... Reviewers: brecht Reviewed By: brecht Differential Revision: https://developer.blender.org/D341
This commit is contained in:
parent
65c5be9676
commit
c35ac8f7ac
Notes:
blender-bot
2023-02-14 11:10:56 +01:00
Referenced by issue #38678, Long strings on Search widget not getting shortened/no tooltip
|
@ -665,8 +665,7 @@ int uiSearchBoxHeight(void)
|
|||
|
||||
int uiSearchBoxWidth(void)
|
||||
{
|
||||
/* was hardcoded at 150 */
|
||||
return 9 * UI_UNIT_X;
|
||||
return 12 * UI_UNIT_X;
|
||||
}
|
||||
|
||||
int uiSearchItemFindIndex(uiSearchItems *items, const char *name)
|
||||
|
|
|
@ -972,7 +972,7 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
|
|||
* 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,
|
||||
static void ui_text_clip_right_ex(uiFontStyle *fstyle, char *str, const size_t max_len, const float okwidth,
|
||||
const char *sep, const int sep_len, const float sep_strwidth)
|
||||
{
|
||||
float tmp;
|
||||
|
@ -982,35 +982,32 @@ static void ui_text_clip_right_ex(uiFontStyle *fstyle, uiBut *but, const size_t
|
|||
* (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';
|
||||
l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth, &tmp);
|
||||
str[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'. */
|
||||
l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, okwidth - sep_strwidth, &tmp);
|
||||
memcpy(str + 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 given width.
|
||||
* 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)
|
||||
static float ui_text_clip_middle_ex(uiFontStyle *fstyle, char *str, const float okwidth, const float minwidth,
|
||||
const size_t max_len)
|
||||
{
|
||||
/* No margin for labels! */
|
||||
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);
|
||||
|
||||
if (fstyle->kerning == 1) /* for BLF_width */
|
||||
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, max_len);
|
||||
strwidth = BLF_width(fstyle->uifont_id, str, max_len);
|
||||
|
||||
if (strwidth > okwidth) {
|
||||
/* utf8 ellipsis '...', some compilers complain */
|
||||
|
@ -1021,18 +1018,18 @@ static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rec
|
|||
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 * 2.0f) {
|
||||
if (min_ff(parts_strwidth, strwidth - okwidth) < minwidth) {
|
||||
/* If we really have no place, or we would clip a very small piece of string in the middle,
|
||||
* only show start of string.
|
||||
*/
|
||||
ui_text_clip_right_ex(fstyle, but, max_len, (float)okwidth, sep, sep_len, sep_strwidth);
|
||||
ui_text_clip_right_ex(fstyle, str, max_len, okwidth, sep, sep_len, sep_strwidth);
|
||||
}
|
||||
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'... */
|
||||
l_end = BLF_width_to_strlen(fstyle->uifont_id, str, max_len, parts_strwidth, &strwidth);
|
||||
r_offset = BLF_width_to_rstrlen(fstyle->uifont_id, str, max_len, parts_strwidth, &strwidth);
|
||||
r_len = strlen(str + 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
|
||||
|
@ -1040,21 +1037,33 @@ static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rec
|
|||
* 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...
|
||||
*/
|
||||
ui_text_clip_right_ex(fstyle, but, max_len, (float)okwidth, sep, sep_len, sep_strwidth);
|
||||
ui_text_clip_right_ex(fstyle, str, max_len, 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);
|
||||
memmove(str + l_end + sep_len, str + r_offset, r_len);
|
||||
memcpy(str + l_end, sep, sep_len);
|
||||
}
|
||||
}
|
||||
strwidth = BLF_width(fstyle->uifont_id, but->drawstr, max_len);
|
||||
strwidth = BLF_width(fstyle->uifont_id, str, max_len);
|
||||
}
|
||||
|
||||
but->strwidth = strwidth;
|
||||
|
||||
if (fstyle->kerning == 1) {
|
||||
BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
|
||||
}
|
||||
|
||||
return strwidth;
|
||||
}
|
||||
|
||||
static void ui_text_clip_middle(uiFontStyle *fstyle, uiBut *but, const rcti *rect)
|
||||
{
|
||||
/* No margin for labels! */
|
||||
const int border = ELEM(but->type, LABEL, MENU) ? 0 : (int)(UI_TEXT_CLIP_MARGIN + 0.5f);
|
||||
const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0);
|
||||
const size_t max_len = sizeof(but->drawstr);
|
||||
const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f;
|
||||
|
||||
but->ofs = 0;
|
||||
but->strwidth = ui_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3632,7 +3641,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
|
|||
{
|
||||
uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM);
|
||||
rcti _rect = *rect;
|
||||
char *cpoin;
|
||||
char *cpoin = NULL;
|
||||
|
||||
wt->state(wt, state);
|
||||
wt->draw(&wt->wcol, rect, 0, 0);
|
||||
|
@ -3649,13 +3658,35 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
|
|||
cpoin = strchr(name, UI_SEP_CHAR);
|
||||
if (cpoin) {
|
||||
*cpoin = 0;
|
||||
rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + 10;
|
||||
|
||||
/* need to set this first */
|
||||
uiStyleFontSet(fstyle);
|
||||
|
||||
if (fstyle->kerning == 1) { /* for BLF_width */
|
||||
BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
|
||||
}
|
||||
|
||||
rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + UI_DPI_ICON_SIZE;
|
||||
|
||||
if (fstyle->kerning == 1) {
|
||||
BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glColor4ubv((unsigned char *)wt->wcol.text);
|
||||
uiStyleFontDraw(fstyle, rect, name);
|
||||
|
||||
|
||||
{
|
||||
char drawstr[UI_MAX_DRAW_STR];
|
||||
const float okwidth = (float)BLI_rcti_size_x(rect);
|
||||
const size_t max_len = sizeof(drawstr);
|
||||
const float minwidth = (float)(UI_DPI_ICON_SIZE);
|
||||
|
||||
BLI_strncpy(drawstr, name, sizeof(drawstr));
|
||||
ui_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len);
|
||||
|
||||
glColor4ubv((unsigned char *)wt->wcol.text);
|
||||
uiStyleFontDraw(fstyle, rect, drawstr);
|
||||
}
|
||||
|
||||
/* part text right aligned */
|
||||
if (use_sep) {
|
||||
if (cpoin) {
|
||||
|
@ -3717,8 +3748,17 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int
|
|||
glEnable(GL_BLEND);
|
||||
glRecti(bg_rect.xmin, bg_rect.ymin, bg_rect.xmax, bg_rect.ymax);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glColor3ubv((unsigned char *)wt->wcol.text);
|
||||
|
||||
uiStyleFontDraw(fstyle, &trect, name);
|
||||
{
|
||||
char drawstr[UI_MAX_DRAW_STR];
|
||||
const float okwidth = (float)BLI_rcti_size_x(&trect);
|
||||
const size_t max_len = sizeof(drawstr);
|
||||
const float minwidth = (float)(UI_DPI_ICON_SIZE);
|
||||
|
||||
BLI_strncpy(drawstr, name, sizeof(drawstr));
|
||||
ui_text_clip_middle_ex(fstyle, drawstr, okwidth, minwidth, max_len);
|
||||
|
||||
glColor4ubv((unsigned char *)wt->wcol.text);
|
||||
uiStyleFontDraw(fstyle, &trect, drawstr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1078,10 +1078,10 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
|
|||
uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
|
||||
|
||||
#if 0 /* ok, this isn't so easy... */
|
||||
uiDefBut(block, LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, 180, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
||||
uiDefBut(block, LABEL, 0, RNA_struct_ui_name(op->type->srna), 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
|
||||
#endif
|
||||
but = uiDefSearchButO_ptr(block, op->type, op->ptr->data, search, 0, ICON_VIEWZOOM, sizeof(search),
|
||||
10, 10, 9 * UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
|
||||
10, 10, uiSearchBoxWidth(), UI_UNIT_Y, 0, 0, "");
|
||||
|
||||
/* fake button, it holds space for search items */
|
||||
uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxHeight(), uiSearchBoxWidth(), uiSearchBoxHeight(), NULL, 0, 0, 0, 0, NULL);
|
||||
|
@ -1929,7 +1929,7 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_
|
|||
block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
|
||||
uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_SEARCH_MENU);
|
||||
|
||||
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, 9 * UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
|
||||
but = uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, sizeof(search), 10, 10, uiSearchBoxWidth(), UI_UNIT_Y, 0, 0, "");
|
||||
uiOperatorSearch_But(but);
|
||||
|
||||
/* fake button, it holds space for search items */
|
||||
|
|
Loading…
Reference in New Issue