[Bf-blender-cvs] [b1ccb6ad25b] blender2.8: Tool System: support tool description for tips

Campbell Barton noreply at git.blender.org
Fri Aug 31 06:31:30 CEST 2018


Commit: b1ccb6ad25b82acf424e9c6130a6e83568a5d37e
Author: Campbell Barton
Date:   Fri Aug 31 14:37:10 2018 +1000
Branches: blender2.8
https://developer.blender.org/rBb1ccb6ad25b82acf424e9c6130a6e83568a5d37e

Tool System: support tool description for tips

When the description isn't set, the operators is used instead.

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

M	release/scripts/startup/bl_ui/space_toolsystem_common.py
M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.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 b8e3d81c1d4..1be86ea7c1c 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_common.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py
@@ -23,8 +23,13 @@ from bpy.types import (
 )
 
 __all__ = (
-    "ToolSelectPanelHelper",
     "ToolDef",
+    "ToolSelectPanelHelper",
+    "activate_by_name",
+    "activate_by_name_or_cycle",
+    "description_from_name",
+    "keymap_from_name",
+    "keymap_from_context",
 )
 
 # Support reloading icons.
@@ -70,6 +75,8 @@ ToolDef = namedtuple(
     (
         # The name to display in the interface.
         "text",
+        # Description (for tooltip), when not set, use the description of 'operator'.
+        "description",
         # The name of the icon to use (found in ``release/datafiles/icons``) or None for no icon.
         "icon",
         # An optional cursor to use when this tool is active.
@@ -104,6 +111,7 @@ def from_dict(kw_args):
     (since keymap is a callback).
     """
     kw = {
+        "description": None,
         "icon": None,
         "cursor": None,
         "widget": None,
@@ -631,6 +639,44 @@ def activate_by_name_or_cycle(context, space_type, text, offset=1):
     return True
 
 
+def description_from_name(context, space_type, text, *, use_operator=True):
+    # Used directly for tooltips.
+    cls, item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text)
+    if item is None:
+        return False
+
+    # Custom description.
+    description = item.description
+    if description is not None:
+        return description
+
+    # Extract from the operator.
+    if use_operator:
+        operator = item.operator
+
+        if operator is None:
+            if item.keymap is not None:
+                operator = item.keymap[0].keymap_items[0].idname
+
+        if operator is not None:
+            import _bpy
+            return _bpy.ops.get_rna(operator).bl_rna.description
+    return ""
+
+
+def keymap_from_name(context, space_type, text):
+    # Used directly for tooltips.
+    cls, item, index = ToolSelectPanelHelper._tool_get_by_name(context, space_type, text)
+    if item is None:
+        return False
+
+    keymap = item.keymap
+    # List container of one.
+    if keymap:
+        return keymap[0]
+    return ""
+
+
 def keymap_from_context(context, space_type):
     """
     Keymap for popup toolbar, currently generated each time.
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index ae8c7d82f9a..003f1fa4a7a 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -163,6 +163,9 @@ class _defs_view3d_generic:
 
         return dict(
             text="Cursor",
+            description=(
+                "Set the 3D cursor location, drag to transform"
+            ),
             icon="ops.generic.cursor",
             keymap=(
                 ("view3d.cursor3d", dict(), dict(type='ACTIONMOUSE', value='PRESS')),
@@ -369,6 +372,9 @@ class _defs_transform:
 
         return dict(
             text="Transform",
+            description=(
+                "Supports any combination of grab, rotate & scale at once"
+            ),
             icon="ops.transform.transform",
             widget="TRANSFORM_GGT_gizmo",
             # No keymap default action, only for gizmo!
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 97f501b7448..ae6ab09a62a 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -67,6 +67,10 @@
 #include "BLF_api.h"
 #include "BLT_translation.h"
 
+#ifdef WITH_PYTHON
+#  include "BPY_extern.h"
+#endif
+
 #include "ED_screen.h"
 
 #include "interface_intern.h"
@@ -306,13 +310,13 @@ static void ui_tooltip_region_free_cb(ARegion *ar)
 /** \name ToolTip Creation
  * \{ */
 
-static uiTooltipData *ui_tooltip_data_from_keymap(bContext *C, wmKeyMap *keymap)
+static bool ui_tooltip_data_append_from_keymap(
+        bContext *C, uiTooltipData *data,
+        wmKeyMap *keymap)
 {
+	const int fields_len_init = data->fields_len;
 	char buf[512];
 
-	/* create tooltip data */
-	uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
-
 	for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
 		wmOperatorType *ot = WM_operatortype_find(kmi->idname, true);
 		if (ot != NULL) {
@@ -341,7 +345,7 @@ static uiTooltipData *ui_tooltip_data_from_keymap(bContext *C, wmKeyMap *keymap)
 			}
 
 			/* Python */
-			{
+			if (U.flag & USER_TOOLTIPS_PYTHON) {
 				uiTooltipField *field = text_field_add(
 				        data, &(uiTooltipFormat){
 				            .style = UI_TIP_STYLE_NORMAL,
@@ -354,6 +358,88 @@ static uiTooltipData *ui_tooltip_data_from_keymap(bContext *C, wmKeyMap *keymap)
 			}
 		}
 	}
+
+	return (fields_len_init != data->fields_len);
+}
+
+
+/**
+ * Special tool-system exception.
+ */
+static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but)
+{
+	if (but->optype == NULL) {
+		return NULL;
+	}
+
+	if (!STREQ(but->optype->idname, "WM_OT_tool_set_by_name")) {
+		return NULL;
+	}
+
+	char tool_name[MAX_NAME];
+	RNA_string_get(but->opptr, "name", tool_name);
+	BLI_assert(tool_name[0] != '\0');
+
+	/* We have a tool, now extract the info. */
+	uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
+
+#ifdef WITH_PYTHON
+	/* it turns out to be most simple to do this via Python since C
+	 * doesn't have access to information about non-active tools.
+	 */
+	char expr[256];
+
+	/* Tip */
+	{
+		SNPRINTF(
+		        expr,
+		        "__import__('bl_ui').space_toolsystem_common.description_from_name("
+		        "__import__('bpy').context, "
+		        "__import__('bpy').context.space_data.type, "
+		        "'%s') + '.'",
+		        tool_name);
+
+		char *expr_result = NULL;
+		if (BPY_execute_string_as_string(C, expr, true, &expr_result)) {
+			if (!STREQ(expr_result, ".")) {
+				uiTooltipField *field = text_field_add(
+				        data, &(uiTooltipFormat){
+				            .style = UI_TIP_STYLE_NORMAL,
+				            .color_id = UI_TIP_LC_MAIN,
+				            .is_pad = true,
+				        });
+				field->text = expr_result;
+			}
+			else {
+				MEM_freeN(expr_result);
+			}
+		}
+	}
+
+	/* Keymap */
+
+	/* This is too handy not to expose somehow, let's be sneaky for now. */
+	if (CTX_wm_window(C)->eventstate->shift) {
+		SNPRINTF(
+		        expr,
+		        "getattr("
+		        "__import__('bl_ui').space_toolsystem_common.keymap_from_name("
+		        "__import__('bpy').context, "
+		        "__import__('bpy').context.space_data.type, "
+		        "'%s'), "
+		        "'as_pointer', lambda: 0)()",
+		        tool_name);
+
+		intptr_t expr_result = 0;
+		if (BPY_execute_string_as_intptr(C, expr, true, &expr_result)) {
+			if (expr_result != 0) {
+				wmKeyMap *keymap = (wmKeyMap *)expr_result;
+				ui_tooltip_data_append_from_keymap(C, data, keymap);
+			}
+		}
+	}
+#endif  /* WITH_PYTHON */
+
 	if (data->fields_len == 0) {
 		MEM_freeN(data);
 		return NULL;
@@ -894,31 +980,14 @@ ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *b
 	}
 	uiTooltipData *data = NULL;
 
-	/* custom tips for pre-defined operators */
-	if (but->optype) {
-		/* TODO(campbell): we now use 'WM_OT_tool_set_by_name', this logic will be moved into the status bar. */
-		if (false && STREQ(but->optype->idname, "WM_OT_tool_set")) {
-			char keymap[64] = "";
-			RNA_string_get(but->opptr, "keymap", keymap);
-			if (keymap[0]) {
-				ScrArea *sa = CTX_wm_area(C);
-				/* It happens in rare cases, for tooltips originated from the toolbar.
-				 * It is hard to reproduce, but it happens when the mouse is nowhere near the actual tool. */
-				if (sa == NULL) {
-					return NULL;
-				}
-				wmKeyMap *km = WM_keymap_find_all(C, keymap, sa->spacetype, RGN_TYPE_WINDOW);
-				if (km != NULL) {
-					data = ui_tooltip_data_from_keymap(C, km);
-				}
-			}
-		}
+	if (data == NULL) {
+		data = ui_tooltip_data_from_tool(C, but);
 	}
-	/* toolsystem exception */
 
 	if (data == NULL) {
 		data = ui_tooltip_data_from_button(C, but);
 	}
+
 	if (data == NULL) {
 		return NULL;
 	}



More information about the Bf-blender-cvs mailing list