Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-12-11 10:05:02 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-12-11 10:09:39 +0300
commit7f36db35cee4a0c5c6eebd5d7baeacd3dd529983 (patch)
tree4339fcbfdc80a3da99dac35cee2ba731fe072716
parent576d385ddb581190d21febfa724086797c47492a (diff)
UI: show tool cycling shortcuts in the toolbar
-rw-r--r--release/scripts/startup/bl_ui/space_toolsystem_common.py26
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c79
2 files changed, 104 insertions, 1 deletions
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
@@ -323,6 +323,25 @@ class ToolSelectPanelHelper:
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):
"""
Return the active Python tool definition and index (if in sub-group, else -1).
@@ -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. */