[Bf-blender-cvs] [7f36db35cee] master: UI: show tool cycling shortcuts in the toolbar

Campbell Barton noreply at git.blender.org
Wed Dec 11 08:09:58 CET 2019


Commit: 7f36db35cee4a0c5c6eebd5d7baeacd3dd529983
Author: Campbell Barton
Date:   Wed Dec 11 18:05:02 2019 +1100
Branches: master
https://developer.blender.org/rB7f36db35cee4a0c5c6eebd5d7baeacd3dd529983

UI: show tool cycling shortcuts in the toolbar

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

M	release/scripts/startup/bl_ui/space_toolsystem_common.py
M	source/blender/editors/interface/interface_region_tooltip.c

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

diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py
index 01bd6dc3068..4413dee4189 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_common.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -322,6 +322,25 @@ class ToolSelectPanelHelper:
                         return (item, -1, None)
         return None, -1, None
 
+    @classmethod
+    def _tool_get_group_by_id(cls, context, idname, *, coerce=False):
+        """
+        Return the group which contains idname, or None.
+        """
+        for item in cls.tools_from_context(context):
+            if item is not None:
+                if type(item) is tuple:
+                    for subitem in item:
+                        if subitem.idname == idname:
+                            return item
+                else:
+                    if item.idname == idname:
+                        if coerce:
+                            return (item,)
+                        else:
+                            return None
+        return None
+
     @classmethod
     def _tool_get_by_flat_index(cls, context, tool_index):
         """
@@ -1038,6 +1057,13 @@ def item_from_id_active_with_group(context, space_type, idname):
     return item
 
 
+def item_group_from_id(context, space_type, idname, *, coerce=False):
+    cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type)
+    if cls is None:
+        return None
+    return cls._tool_get_group_by_id(context, idname, coerce=coerce)
+
+
 def item_from_flat_index(context, space_type, index):
     cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type)
     if cls is None:
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index d81e0c46297..f4407d59d7f 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -503,7 +503,10 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
   }
 
   /* Shortcut. */
-  if (is_label == false && ((but->block->flag & UI_BLOCK_SHOW_SHORTCUT_ALWAYS) == 0)) {
+  const bool show_shortcut = is_label == false &&
+                             ((but->block->flag & UI_BLOCK_SHOW_SHORTCUT_ALWAYS) == 0);
+
+  if (show_shortcut) {
     /* There are different kinds of shortcuts:
      *
      * - Direct access to the tool (as if the toolbar button is pressed).
@@ -610,6 +613,80 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
     }
   }
 
+  if (show_shortcut) {
+    /* Shortcut for Cycling
+     *
+     * As a second option, we may have a shortcut to cycle this tool group.
+     *
+     * Since some keymaps may use this for the primary means of binding keys,
+     * it's useful to show these too.
+     * Without this there is no way to know how to use a key to set the tool.
+     *
+     * This is a little involved since the shortcut may be bound to another tool in this group,
+     * instead of the current tool on display. */
+
+    char *expr_result = NULL;
+    size_t expr_result_len;
+
+    {
+      const char *expr_imports[] = {"bpy", "bl_ui", NULL};
+      char expr[256];
+      SNPRINTF(expr,
+               "'\\x00'.join("
+               "item.idname for item in bl_ui.space_toolsystem_common.item_group_from_id("
+               "bpy.context, "
+               "bpy.context.space_data.type, '%s', coerce=True) "
+               "if item is not None)",
+               tool_id);
+
+      if (has_valid_context == false) {
+        /* pass */
+      }
+      else if (BPY_execute_string_as_string_and_size(
+                   C, expr_imports, expr, true, &expr_result, &expr_result_len)) {
+        /* pass. */
+      }
+    }
+
+    if (expr_result != NULL) {
+      PointerRNA op_props;
+      WM_operator_properties_create_ptr(&op_props, but->optype);
+      RNA_boolean_set(&op_props, "cycle", true);
+
+      char shortcut[128] = "";
+
+      const char *item_end = expr_result + expr_result_len;
+      const char *item_step = expr_result;
+
+      while (item_step < item_end) {
+        RNA_string_set(&op_props, "name", item_step);
+        if (WM_key_event_operator_string(C,
+                                         but->optype->idname,
+                                         WM_OP_INVOKE_REGION_WIN,
+                                         op_props.data,
+                                         true,
+                                         shortcut,
+                                         ARRAY_SIZE(shortcut))) {
+          break;
+        }
+        item_step += strlen(item_step) + 1;
+      }
+
+      WM_operator_properties_free(&op_props);
+      MEM_freeN(expr_result);
+
+      if (shortcut[0] != '\0') {
+        uiTooltipField *field = text_field_add(data,
+                                               &(uiTooltipFormat){
+                                                   .style = UI_TIP_STYLE_NORMAL,
+                                                   .color_id = UI_TIP_LC_VALUE,
+                                                   .is_pad = true,
+                                               });
+        field->text = BLI_sprintfN(TIP_("Shortcut Cycle: %s"), shortcut);
+      }
+    }
+  }
+
   /* Keymap */
 
   /* This is too handy not to expose somehow, let's be sneaky for now. */



More information about the Bf-blender-cvs mailing list