diff options
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 118 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 12 |
3 files changed, 131 insertions, 2 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index b997d0ef6a0..b566fd360b6 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -534,7 +534,8 @@ enum { BUT_GET_TIP, BUT_GET_RNA_TIP, BUT_GET_RNAENUM_TIP, - BUT_GET_OP_KEYMAP + BUT_GET_OP_KEYMAP, + BUT_GET_PROP_KEYMAP }; typedef struct uiStringInfo { diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 19eb978a01e..9ac499fc94b 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -901,6 +901,114 @@ static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *bu return found; } +static bool ui_but_event_property_operator_string(const bContext *C, uiBut *but, char *buf, const size_t buf_len) +{ + /* context toggle operator names to check... */ + const char *ctx_toggle_opnames[] = { + "WM_OT_context_toggle", + "WM_OT_context_toggle_enum", + "WM_OT_context_cycle_int", + "WM_OT_context_cycle_enum", + "WM_OT_context_cycle_array", + "WM_OT_context_menu_enum", + NULL + }; + const size_t num_ops = sizeof(ctx_toggle_opnames) / sizeof(const char *); + + bool found = false; + + /* this version is only for finding hotkeys for properties (which get set via context using operators) */ + if (but->rnaprop) { + /* to avoid massive slowdowns on property panels, for now, we only check the + * hotkeys for Editor / Scene settings... + * + * TODO: userpref settings? + */ + // TODO: value (for enum stuff)? + char *data_path = NULL; + + if (but->rnapoin.id.data) { + ID *id = but->rnapoin.id.data; + + if (GS(id->name) == ID_SCR) { + /* screen/editor property + * NOTE: in most cases, there is actually no info for backwards tracing + * how to get back to ID from the editor data we may be dealing with + */ + if (RNA_struct_is_a(but->rnapoin.type, &RNA_Space)) { + /* data should be directly on here... */ + data_path = BLI_sprintfN("space_data.%s", RNA_property_identifier(but->rnaprop)); + } + else { + /* special exceptions for common nested data in editors... */ + if (RNA_struct_is_a(but->rnapoin.type, &RNA_DopeSheet)) { + /* dopesheet filtering options... */ + data_path = BLI_sprintfN("space_data.dopesheet.%s", RNA_property_identifier(but->rnaprop)); + } + } + } + else if (GS(id->name) == ID_SCE) { + if (RNA_struct_is_a(but->rnapoin.type, &RNA_ToolSettings)) { + /* toolsettings property + * NOTE: toolsettings is usually accessed directly (i.e. not through scene) + */ + data_path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop); + } + else { + /* scene property */ + char *path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop); + + if (path) { + data_path = BLI_sprintfN("scene.%s", path); + MEM_freeN(path); + } + else { + printf("ERROR in %s(): Couldn't get path for scene property - %s\n", + __func__, RNA_property_identifier(but->rnaprop)); + } + } + } + else { + //puts("other id"); + } + + //printf("prop shortcut: '%s' (%s)\n", RNA_property_identifier(but->rnaprop), data_path); + } + + /* we have a datapath! */ + if (data_path) { + size_t i; + + /* create a property to host the "datapath" property we're sending to the operators */ + IDProperty *prop_path; + IDProperty *prop_path_value; + + IDPropertyTemplate val = {0}; + prop_path = IDP_New(IDP_GROUP, &val, __func__); + prop_path_value = IDP_NewString(data_path, "data_path", strlen(data_path) + 1); /* len + 1, or else will be truncated */ + IDP_AddToGroup(prop_path, prop_path_value); + + /* check each until one works... */ + for (i = 0; (i < num_ops) && (ctx_toggle_opnames[i]); i++) { + //printf("\t%s\n", ctx_toggle_opnames[i]); + if (WM_key_event_operator_string(C, ctx_toggle_opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false, + buf, buf_len)) + { + found = true; + break; + } + } + + /* cleanup */ + IDP_FreeProperty(prop_path); + MEM_freeN(prop_path); + MEM_freeN(data_path); + } + } + + return found; +} + static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) { uiBut *but; @@ -915,6 +1023,9 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) { ui_but_add_shortcut(but, buf, FALSE); } + else if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) { + ui_but_add_shortcut(but, buf, FALSE); + } } } @@ -4011,6 +4122,13 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...) } } } + else if (type == BUT_GET_PROP_KEYMAP) { + /* for properties that are bound to one of the context cycle, etc. keys... */ + char buf[128]; + if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) { + tmp = BLI_strdup(buf); + } + } si->strinfo = tmp; } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index fbe23b1a1ed..9558baf0334 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -439,6 +439,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL}; uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL}; uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, NULL}; + uiStringInfo prop_keymap = {BUT_GET_PROP_KEYMAP, NULL}; uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL}; uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL}; @@ -448,7 +449,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* create tooltip data */ data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); - uiButGetStrInfo(C, but, &but_tip, &enum_label, &enum_tip, &op_keymap, &rna_struct, &rna_prop, NULL); + uiButGetStrInfo(C, but, &but_tip, &enum_label, &enum_tip, &op_keymap, &prop_keymap, &rna_struct, &rna_prop, NULL); /* special case, enum rna buttons only have enum item description, * use general enum description too before the specific one */ @@ -480,6 +481,13 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->color_id[data->totline] = UI_TIP_LC_NORMAL; data->totline++; } + + /* Property context-toggle shortcut */ + if (prop_keymap.strinfo) { + BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Shortcut: %s"), prop_keymap.strinfo); + data->color_id[data->totline] = UI_TIP_LC_NORMAL; + data->totline++; + } if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* full string */ @@ -614,6 +622,8 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) MEM_freeN(enum_tip.strinfo); if (op_keymap.strinfo) MEM_freeN(op_keymap.strinfo); + if (prop_keymap.strinfo) + MEM_freeN(prop_keymap.strinfo); if (rna_struct.strinfo) MEM_freeN(rna_struct.strinfo); if (rna_prop.strinfo) |