[Bf-blender-cvs] [2aca08fc1cb] master: UI: Support tooltips for superimposed icons

Julian Eisel noreply at git.blender.org
Fri Oct 8 14:18:17 CEST 2021


Commit: 2aca08fc1cb6448b593afde7b00ba34ce590551b
Author: Julian Eisel
Date:   Fri Oct 8 14:17:03 2021 +0200
Branches: master
https://developer.blender.org/rB2aca08fc1cb6448b593afde7b00ba34ce590551b

UI: Support tooltips for superimposed icons

In a couple of places in the UI, we show superimposed icons on buttons
to execute an operation (called "Extra Icons" internally). Hovering them
would show the tooltip of the underlying button, which is misleading and
confusing.
There are cases where it's not obvious what an icon does, so a tooltip
would be quite useful here. It's likely we are going to use superimposed
icons in more places in the future, e.g. see D11890.

The extra icon basically acts as an override for the button in the
tooltip code.

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

Reviewed by: Campbell Barton

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

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_region_tooltip.c

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

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index e8b71a41439..c536eff771d 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -82,6 +82,7 @@ struct wmWindow;
 
 typedef struct uiBlock uiBlock;
 typedef struct uiBut uiBut;
+typedef struct uiButExtraOpIcon uiButExtraOpIcon;
 typedef struct uiLayout uiLayout;
 typedef struct uiPopupBlockHandle uiPopupBlockHandle;
 /* C handle for C++ #ui::AbstractTreeView type. */
@@ -1432,6 +1433,8 @@ typedef struct uiStringInfo {
  *       Will fill them with translated strings, when possible.
  *       Strings in uiStringInfo must be MEM_freeN'ed by caller. */
 void UI_but_string_info_get(struct bContext *C, uiBut *but, ...) ATTR_SENTINEL(0);
+void UI_but_extra_icon_string_info_get(struct bContext *C, uiButExtraOpIcon *extra_icon, ...)
+    ATTR_SENTINEL(0);
 
 /* Edit i18n stuff. */
 /* Name of the main py op from i18n addon. */
@@ -1724,6 +1727,8 @@ struct PointerRNA *UI_but_extra_operator_icon_add(uiBut *but,
                                                   const char *opname,
                                                   short opcontext,
                                                   int icon);
+struct wmOperatorType *UI_but_extra_operator_icon_optype_get(struct uiButExtraOpIcon *extra_icon);
+struct PointerRNA *UI_but_extra_operator_icon_opptr_get(struct uiButExtraOpIcon *extra_icon);
 
 /* Autocomplete
  *
@@ -2713,6 +2718,11 @@ struct ARegion *UI_tooltip_create_from_button(struct bContext *C,
                                               struct ARegion *butregion,
                                               uiBut *but,
                                               bool is_label);
+struct ARegion *UI_tooltip_create_from_button_or_extra_icon(struct bContext *C,
+                                                            struct ARegion *butregion,
+                                                            uiBut *but,
+                                                            uiButExtraOpIcon *extra_icon,
+                                                            bool is_label);
 struct ARegion *UI_tooltip_create_from_gizmo(struct bContext *C, struct wmGizmo *gz);
 void UI_tooltip_free(struct bContext *C, struct bScreen *screen, struct ARegion *region);
 
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 92391a703ef..68595e49871 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1224,16 +1224,21 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str
  * \{ */
 
 static bool ui_but_event_operator_string_from_operator(const bContext *C,
-                                                       uiBut *but,
+                                                       wmOperatorCallParams *op_call_params,
                                                        char *buf,
                                                        const size_t buf_len)
 {
-  BLI_assert(but->optype != NULL);
+  BLI_assert(op_call_params->optype != NULL);
   bool found = false;
-  IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
-
-  if (WM_key_event_operator_string(
-          C, but->optype->idname, but->opcontext, prop, true, buf, buf_len)) {
+  IDProperty *prop = (op_call_params->opptr) ? op_call_params->opptr->data : NULL;
+
+  if (WM_key_event_operator_string(C,
+                                   op_call_params->optype->idname,
+                                   op_call_params->opcontext,
+                                   prop,
+                                   true,
+                                   buf,
+                                   buf_len)) {
     found = true;
   }
   return found;
@@ -1318,7 +1323,12 @@ static bool ui_but_event_operator_string(const bContext *C,
   bool found = false;
 
   if (but->optype != NULL) {
-    found = ui_but_event_operator_string_from_operator(C, but, buf, buf_len);
+    found = ui_but_event_operator_string_from_operator(
+        C,
+        &(wmOperatorCallParams){
+            .optype = but->optype, .opptr = but->opptr, .opcontext = but->opcontext},
+        buf,
+        buf_len);
   }
   else if (UI_but_menutype_get(but) != NULL) {
     found = ui_but_event_operator_string_from_menu(C, but, buf, buf_len);
@@ -1330,6 +1340,20 @@ static bool ui_but_event_operator_string(const bContext *C,
   return found;
 }
 
+static bool ui_but_extra_icon_event_operator_string(const bContext *C,
+                                                    uiButExtraOpIcon *extra_icon,
+                                                    char *buf,
+                                                    const size_t buf_len)
+{
+  wmOperatorType *extra_icon_optype = UI_but_extra_operator_icon_optype_get(extra_icon);
+
+  if (extra_icon_optype) {
+    return ui_but_event_operator_string_from_operator(C, extra_icon->optype_params, buf, buf_len);
+  }
+
+  return false;
+}
+
 static bool ui_but_event_property_operator_string(const bContext *C,
                                                   uiBut *but,
                                                   char *buf,
@@ -1713,6 +1737,16 @@ PointerRNA *UI_but_extra_operator_icon_add(uiBut *but,
   return NULL;
 }
 
+wmOperatorType *UI_but_extra_operator_icon_optype_get(uiButExtraOpIcon *extra_icon)
+{
+  return extra_icon ? extra_icon->optype_params->optype : NULL;
+}
+
+PointerRNA *UI_but_extra_operator_icon_opptr_get(uiButExtraOpIcon *extra_icon)
+{
+  return extra_icon->optype_params->opptr;
+}
+
 static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but)
 {
   BLI_assert(but->type == UI_BTYPE_TEXT);
@@ -7262,6 +7296,42 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
   }
 }
 
+void UI_but_extra_icon_string_info_get(struct bContext *C, uiButExtraOpIcon *extra_icon, ...)
+{
+  va_list args;
+  uiStringInfo *si;
+
+  wmOperatorType *optype = UI_but_extra_operator_icon_optype_get(extra_icon);
+  PointerRNA *opptr = UI_but_extra_operator_icon_opptr_get(extra_icon);
+
+  va_start(args, extra_icon);
+  while ((si = (uiStringInfo *)va_arg(args, void *))) {
+    char *tmp = NULL;
+
+    switch (si->type) {
+      case BUT_GET_LABEL:
+        tmp = BLI_strdup(WM_operatortype_name(optype, opptr));
+        break;
+      case BUT_GET_TIP:
+        tmp = WM_operatortype_description(C, optype, opptr);
+        break;
+      case BUT_GET_OP_KEYMAP: {
+        char buf[128];
+        if (ui_but_extra_icon_event_operator_string(C, extra_icon, buf, sizeof(buf))) {
+          tmp = BLI_strdup(buf);
+        }
+      }
+        /* Other types not supported. The caller should expect that outcome, no need to message or
+         * assert here. */
+      default:
+        break;
+    }
+
+    si->strinfo = tmp;
+  }
+  va_end(args);
+}
+
 /* Program Init/Exit */
 
 void UI_init(void)
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index c508cf2f36c..bf9b37c00fa 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -8235,7 +8235,11 @@ static ARegion *ui_but_tooltip_init(
   uiBut *but = UI_region_active_but_get(region);
   *r_exit_on_event = false;
   if (but) {
-    return UI_tooltip_create_from_button(C, region, but, is_label);
+    const wmWindow *win = CTX_wm_window(C);
+    uiButExtraOpIcon *extra_icon = ui_but_extra_operator_icon_mouse_over_get(
+        but, but->active, win->eventstate);
+
+    return UI_tooltip_create_from_button_or_extra_icon(C, region, but, extra_icon, is_label);
   }
   return NULL;
 }
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index a8f289702f8..6071e14d153 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -761,7 +761,9 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
   return data;
 }
 
-static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
+static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
+                                                                uiBut *but,
+                                                                uiButExtraOpIcon *extra_icon)
 {
   uiStringInfo but_label = {BUT_GET_LABEL, NULL};
   uiStringInfo but_tip = {BUT_GET_TIP, NULL};
@@ -774,20 +776,29 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
 
   char buf[512];
 
+  wmOperatorType *optype = extra_icon ? UI_but_extra_operator_icon_optype_get(extra_icon) :
+                                        but->optype;
+  PropertyRNA *rnaprop = extra_icon ? NULL : but->rnaprop;
+
   /* create tooltip data */
   uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
 
-  UI_but_string_info_get(C,
-                         but,
-                         &but_label,
-                         &but_tip,
-                         &enum_label,
-                         &enum_tip,
-                         &op_keymap,
-                         &prop_keymap,
-                         &rna_struct,
-                         &rna_prop,
-                         NULL);
+  if (extra_icon) {
+    UI_but_extra_icon_string_info_get(C, extra_icon, &but_label, &but_tip, &op_keymap, NULL);
+  }
+  else {
+    UI_but_string_info_get(C,
+                           but,
+                           &but_label,
+                           &but_tip,
+                           &enum_label,
+                           &enum_tip,
+                           &op_keymap,
+                           &prop_keymap,
+                           &rna_struct,
+                           &rna_prop,
+                           NULL);
+  }
 
   /* Tip Label (only for buttons not already showing the label).
    * Check prefix instead of comparing because the button may include the shortcut. */
@@ -818,8 +829,7 @@ static uiTooltipData *ui_t

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list