[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