[Bf-blender-cvs] [77f73a92843] blender-v2.92-release: Fix library name clipping most of the data-block name in data-block menus

Julian Eisel noreply at git.blender.org
Mon Jan 25 23:10:38 CET 2021


Commit: 77f73a92843965906189dd56dcc4d18eae2371cc
Author: Julian Eisel
Date:   Mon Jan 25 22:54:00 2021 +0100
Branches: blender-v2.92-release
https://developer.blender.org/rB77f73a92843965906189dd56dcc4d18eae2371cc

Fix library name clipping most of the data-block name in data-block menus

Issue is visible here https://developer.blender.org/F8626313.

If there is enough space for both the item name and the library hint, display
both. Otherwise, clip either the item name, the library hint, or both so that
not more than 60% and 40% of the available width are used repectively.
There are further improvements we could do, as noted in T84188, this just fixes
the regression for the release.

Part of T84188. There were multiple reports about this, see merged in and
mentioned reports in T84188 and T78012.

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

M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_region_search.c
M	source/blender/editors/interface/interface_widgets.c

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

diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 991e8aaf89a..f4e68ca3909 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -991,12 +991,26 @@ extern void ui_draw_but(const struct bContext *C,
                         uiBut *but,
                         rcti *rect);
 
+/**
+ * Info about what the separator character separates, used to decide between different drawing
+ * styles. E.g. we never want a shortcut string to be clipped, but other hint strings can be
+ * clipped.
+ */
+typedef enum {
+  UI_MENU_ITEM_SEPARATOR_NONE,
+  /** Separator is used to indicate shortcut string of this item. Shortcut string will not get
+   * clipped. */
+  UI_MENU_ITEM_SEPARATOR_SHORTCUT,
+  /** Separator is used to indicate some additional hint to display for this item. Hint string will
+   * get clipped before the normal text. */
+  UI_MENU_ITEM_SEPARATOR_HINT,
+} uiMenuItemSeparatorType;
 void ui_draw_menu_item(const struct uiFontStyle *fstyle,
                        rcti *rect,
                        const char *name,
                        int iconid,
                        int state,
-                       bool use_sep,
+                       uiMenuItemSeparatorType separator_type,
                        int *r_xmax);
 void ui_draw_preview_item(
     const struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state);
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 7a665909c76..816162e9aa2 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -610,7 +610,15 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
         char *name = data->items.names[a];
         int icon = data->items.icons[a];
         char *name_sep_test = NULL;
-        const bool use_sep_char = data->use_sep || (state & UI_BUT_HAS_SEP_CHAR);
+
+        uiMenuItemSeparatorType separator_type = UI_MENU_ITEM_SEPARATOR_NONE;
+        if (data->use_sep) {
+          separator_type = UI_MENU_ITEM_SEPARATOR_SHORTCUT;
+        }
+        /* Only set for displaying additional hint (e.g. library name of a linked data-block). */
+        else if (state & UI_BUT_HAS_SEP_CHAR) {
+          separator_type = UI_MENU_ITEM_SEPARATOR_HINT;
+        }
 
         ui_searchbox_butrect(&rect, data, a);
 
@@ -623,7 +631,7 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
           }
 
           /* Simple menu item. */
-          ui_draw_menu_item(&data->fstyle, &rect, name, icon, state, use_sep_char, NULL);
+          ui_draw_menu_item(&data->fstyle, &rect, name, icon, state, separator_type, NULL);
         }
         else {
           /* Split menu item, faded text before the separator. */
@@ -637,8 +645,13 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
           const char name_sep_prev = *name_sep;
           *name_sep = '\0';
           int name_width = 0;
-          ui_draw_menu_item(
-              &data->fstyle, &rect, name, 0, state | UI_BUT_INACTIVE, false, &name_width);
+          ui_draw_menu_item(&data->fstyle,
+                            &rect,
+                            name,
+                            0,
+                            state | UI_BUT_INACTIVE,
+                            UI_MENU_ITEM_SEPARATOR_NONE,
+                            &name_width);
           *name_sep = name_sep_prev;
           rect.xmin += name_width;
           rect.xmin += UI_UNIT_X / 4;
@@ -650,7 +663,7 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
 
           /* The previous menu item draws the active selection. */
           ui_draw_menu_item(
-              &data->fstyle, &rect, name_sep, icon, state & ~UI_ACTIVE, use_sep_char, NULL);
+              &data->fstyle, &rect, name_sep, icon, state & ~UI_ACTIVE, separator_type, NULL);
         }
       }
       /* indicate more */
@@ -943,10 +956,16 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
                           CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, text_pre),
                           data->items.icons[a],
                           state,
-                          false,
+                          UI_MENU_ITEM_SEPARATOR_NONE,
+                          NULL);
+        ui_draw_menu_item(&data->fstyle,
+                          &rect_post,
+                          data->items.names[a],
+                          0,
+                          state,
+                          data->use_sep ? UI_MENU_ITEM_SEPARATOR_SHORTCUT :
+                                          UI_MENU_ITEM_SEPARATOR_NONE,
                           NULL);
-        ui_draw_menu_item(
-            &data->fstyle, &rect_post, data->items.names[a], 0, state, data->use_sep, NULL);
       }
     }
     /* indicate more */
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index a99f05730bb..c0c34b0a93d 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -5221,11 +5221,13 @@ void ui_draw_menu_item(const uiFontStyle *fstyle,
                        const char *name,
                        int iconid,
                        int state,
-                       bool use_sep,
+                       uiMenuItemSeparatorType separator_type,
                        int *r_xmax)
 {
   uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM);
   const rcti _rect = *rect;
+  int max_hint_width = INT_MAX;
+  int padding = 0.25f * UI_UNIT_X;
   char *cpoin = NULL;
 
   wt->state(wt, state, 0, UI_EMBOSS_UNDEFINED);
@@ -5234,13 +5236,13 @@ void ui_draw_menu_item(const uiFontStyle *fstyle,
   UI_fontstyle_set(fstyle);
 
   /* text location offset */
-  rect->xmin += 0.25f * UI_UNIT_X;
+  rect->xmin += padding;
   if (iconid) {
     rect->xmin += UI_DPI_ICON_SIZE;
   }
 
   /* cut string in 2 parts? */
-  if (use_sep) {
+  if (separator_type != UI_MENU_ITEM_SEPARATOR_NONE) {
     cpoin = strrchr(name, UI_SEP_CHAR);
     if (cpoin) {
       *cpoin = 0;
@@ -5253,7 +5255,30 @@ void ui_draw_menu_item(const uiFontStyle *fstyle,
         BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
       }
 
-      rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + UI_DPI_ICON_SIZE;
+      if (separator_type == UI_MENU_ITEM_SEPARATOR_SHORTCUT) {
+        /* Shrink rect to exclude the shortcut string. */
+        rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + UI_DPI_ICON_SIZE;
+      }
+      else if (separator_type == UI_MENU_ITEM_SEPARATOR_HINT) {
+        /* Deterimine max-width for the hint string to leave the name string un-clipped (if there's
+         * enough space to display it). */
+
+        const int available_width = BLI_rcti_size_x(rect) - padding;
+        const int name_width = BLF_width(fstyle->uifont_id, name, INT_MAX);
+        const int hint_width = BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + padding;
+
+        if ((name_width + hint_width) > available_width) {
+          /* Clipping width for hint string. */
+          max_hint_width = available_width * 0.40f;
+          /* Clipping xmax for clipping of item name. */
+          rect->xmax = (hint_width < max_hint_width) ?
+                           (rect->xmax - hint_width) :
+                           (rect->xmin + (available_width - max_hint_width));
+        }
+      }
+      else {
+        BLI_assert(!"Unknwon menu item separator type");
+      }
 
       if (fstyle->kerning == 1) {
         BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT);
@@ -5308,15 +5333,26 @@ void ui_draw_menu_item(const uiFontStyle *fstyle,
   }
 
   /* part text right aligned */
-  if (use_sep) {
+  if (separator_type != UI_MENU_ITEM_SEPARATOR_NONE) {
     if (cpoin) {
       /* Set inactive state for grayed out text. */
       wt->state(wt, state | UI_BUT_INACTIVE, 0, UI_EMBOSS_UNDEFINED);
 
+      char hint_drawstr[UI_MAX_DRAW_STR];
+      {
+        const size_t max_len = sizeof(hint_drawstr);
+        const float minwidth = (float)(UI_DPI_ICON_SIZE);
+
+        BLI_strncpy(hint_drawstr, cpoin + 1, sizeof(hint_drawstr));
+        if (hint_drawstr[0] && (max_hint_width < INT_MAX)) {
+          UI_text_clip_middle_ex(fstyle, hint_drawstr, max_hint_width, minwidth, max_len, '\0');
+        }
+      }
+
       rect->xmax = _rect.xmax - 5;
       UI_fontstyle_draw(fstyle,
                         rect,
-                        cpoin + 1,
+                        hint_drawstr,
                         wt->wcol.text,
                         &(struct uiFontStyleDraw_Params){
                             .align = UI_STYLE_TEXT_RIGHT,



More information about the Bf-blender-cvs mailing list