Commit: 8055871e5be765958d11160e086c0e5589fefe48
Author: Campbell Barton
Date:   Thu Nov 29 17:32:35 2018 +1100
Branches: blender2.8
https://developer.blender.org/rB8055871e5be765958d11160e086c0e5589fefe48

UI: support enum key shortcut detection

Shows shortcuts in space-selector.

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

M       source/blender/editors/interface/interface.c

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

diff --git a/source/blender/editors/interface/interface.c 
b/source/blender/editors/interface/interface.c
index 6fc627d3847..aeee93b055b 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -90,6 +90,7 @@
 
 /* prototypes. */
 static void ui_but_to_pixelrect(struct rcti *rect, const struct ARegion *ar, 
struct uiBlock *block, struct uiBut *but);
+static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void 
*but_p);
 
 /* avoid unneeded calls to ui_but_value_get */
 #define UI_BUT_VALUE_UNSET DBL_MAX
@@ -1067,12 +1068,35 @@ static bool ui_but_event_property_operator_string(
                "WM_OT_context_menu_enum",
                NULL
        };
-       const size_t num_ops = sizeof(ctx_toggle_opnames) / sizeof(const char 
*);
+
+       const char *ctx_enum_opnames[] = {
+               "WM_OT_context_set_enum",
+               NULL
+       };
+
+       int  prop_enum_value = -1;
+       bool prop_enum_value_ok = false;
+       PointerRNA *ptr = &but->rnapoin;
+       PropertyRNA *prop = but->rnaprop;
+       if ((but->type == UI_BTYPE_BUT_MENU) && (but->block->handle != NULL)) {
+               uiBut *but_parent = but->block->handle->popup_create_vars.but;
+               if ((but->type == UI_BTYPE_BUT_MENU) &&
+                   but_parent && (but_parent->menu_create_func == 
ui_def_but_rna__menu))
+               {
+                       prop_enum_value = (int)but->hardmin;
+                       ptr = 
&but->block->handle->popup_create_vars.but->rnapoin;
+                       prop = 
but->block->handle->popup_create_vars.but->rnaprop;
+                       prop_enum_value_ok = true;
+               }
+       }
 
        bool found = false;
 
+       /* Don't use the button again. */
+       but = NULL;
+
        /* this version is only for finding hotkeys for properties (which get 
set via context using operators) */
-       if (but->rnaprop) {
+       if (prop) {
                /* to avoid massive slowdowns on property panels, for now, we 
only check the
                 * hotkeys for Editor / Scene settings...
                 *
@@ -1081,40 +1105,51 @@ static bool ui_but_event_property_operator_string(
                // TODO: value (for enum stuff)?
                char *data_path = NULL;
 
-               if (but->rnapoin.id.data) {
-                       ID *id = but->rnapoin.id.data;
+               if (ptr->id.data) {
+                       ID *id = ptr->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)) {
+                               if (RNA_struct_is_a(ptr->type, &RNA_Space)) {
+                                       /* data should be directly on here... */
+                                       data_path = 
BLI_sprintfN("space_data.%s", RNA_property_identifier(prop));
+                               }
+                               else if (RNA_struct_is_a(ptr->type, &RNA_Area)) 
{
                                        /* data should be directly on here... */
-                                       data_path = 
BLI_sprintfN("space_data.%s", RNA_property_identifier(but->rnaprop));
+                                       const char *prop_id = 
RNA_property_identifier(prop);
+                                       /* Hack since keys access 'type'. */
+                                       if (STREQ(prop_id, "ui_type")) {
+                                               prop_id = "type";
+                                               prop_enum_value >>= 16;
+                                               prop = 
RNA_struct_find_property(ptr, prop_id);
+                                       }
+                                       data_path = BLI_sprintfN("area.%s", 
prop_id);
                                }
                                else {
                                        /* special exceptions for common nested 
data in editors... */
-                                       if (RNA_struct_is_a(but->rnapoin.type, 
&RNA_DopeSheet)) {
+                                       if (RNA_struct_is_a(ptr->type, 
&RNA_DopeSheet)) {
                                                /* dopesheet filtering 
options... */
-                                               data_path = 
BLI_sprintfN("space_data.dopesheet.%s", RNA_property_identifier(but->rnaprop));
+                                               data_path = 
BLI_sprintfN("space_data.dopesheet.%s", RNA_property_identifier(prop));
                                        }
-                                       else if 
(RNA_struct_is_a(but->rnapoin.type, &RNA_FileSelectParams)) {
+                                       else if (RNA_struct_is_a(ptr->type, 
&RNA_FileSelectParams)) {
                                                /* Filebrowser options... */
-                                               data_path = 
BLI_sprintfN("space_data.params.%s", RNA_property_identifier(but->rnaprop));
+                                               data_path = 
BLI_sprintfN("space_data.params.%s", RNA_property_identifier(prop));
                                        }
                                }
                        }
                        else if (GS(id->name) == ID_SCE) {
-                               if (RNA_struct_is_a(but->rnapoin.type, 
&RNA_ToolSettings)) {
+                               if (RNA_struct_is_a(ptr->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);
+                                       data_path = 
RNA_path_from_ID_to_property(ptr, prop);
                                }
                                else {
                                        /* scene property */
-                                       char *path = 
RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);
+                                       char *path = 
RNA_path_from_ID_to_property(ptr, prop);
 
                                        if (path) {
                                                data_path = 
BLI_sprintfN("scene.%s", path);
@@ -1123,7 +1158,7 @@ static bool ui_but_event_property_operator_string(
 #if 0
                                        else {
                                                printf("ERROR in %s(): Couldn't 
get path for scene property - %s\n",
-                                                      __func__, 
RNA_property_identifier(but->rnaprop));
+                                                      __func__, 
RNA_property_identifier(prop));
                                        }
 #endif
                                }
@@ -1132,26 +1167,50 @@ static bool ui_but_event_property_operator_string(
                                //puts("other id");
                        }
 
-                       //printf("prop shortcut: '%s' (%s)\n", 
RNA_property_identifier(but->rnaprop), data_path);
+                       //printf("prop shortcut: '%s' (%s)\n", 
RNA_property_identifier(prop), 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);
-                       IDP_AddToGroup(prop_path, prop_path_value);
+                       IDP_AddToGroup(prop_path, IDP_NewString(data_path, 
"data_path", strlen(data_path) + 1));
+
+                       const char **opnames;
+                       int          opnames_len;
+
+                       if (prop_enum_value_ok && prop && 
RNA_property_type(prop) == PROP_ENUM) {
+                               opnames_len = ARRAY_SIZE(ctx_enum_opnames) - 1;
+                               opnames                = ctx_enum_opnames;
+
+                               const EnumPropertyItem *item;
+                               bool free;
+                               RNA_property_enum_items((bContext *)C, ptr, 
prop, &item, NULL, &free);
+                               int index = RNA_enum_from_value(item, 
prop_enum_value);
+                               if (index != -1) {
+                                       const char *id = item[index].identifier;
+                                       IDP_AddToGroup(prop_path, 
IDP_NewString(id, "value", strlen(id) + 1));
+                               }
+                               else {
+                                       opnames_len = 0;  /* Do nothing. */
+                               }
+                               if (free) {
+                                       MEM_freeN((void *)item);
+                               }
+                       }
+                       else {
+                               opnames_len = ARRAY_SIZE(ctx_toggle_opnames) - 
1;
+                               opnames                = ctx_toggle_opnames;
+                       }
 
                        /* check each until one works... */
-                       for (i = 0; (i < num_ops) && (ctx_toggle_opnames[i]); 
i++) {
+
+                       for (int i = 0; (i < opnames_len) && (opnames[i]); i++) 
{
                                if (WM_key_event_operator_string(
-                                           C, ctx_toggle_opnames[i], 
WM_OP_INVOKE_REGION_WIN, prop_path, false,
+                                           C, opnames[i], 
WM_OP_INVOKE_REGION_WIN, prop_path, false,
                                            buf, buf_len))
                                {
                                        found = true;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to