WM: add keymap.find_from_operator(...)
authorCampbell Barton <ideasman42@gmail.com>
Wed, 9 Jan 2019 01:26:10 +0000 (12:26 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 9 Jan 2019 01:26:10 +0000 (12:26 +1100)
source/blender/makesrna/intern/rna_wm_api.c
source/blender/windowmanager/WM_keymap.h
source/blender/windowmanager/intern/wm_keymap.c

index 51291f70cfaa1cf61da2e8061d7ad21888ae548b..9d93bcba50886ea85c80199d8da1105b7b0a90b9 100644 (file)
@@ -309,6 +309,23 @@ static void rna_KeyMap_item_remove(wmKeyMap *km, ReportList *reports, PointerRNA
        RNA_POINTER_INVALIDATE(kmi_ptr);
 }
 
+static PointerRNA rna_KeyMap_item_find_from_operator(
+        ID *id,
+        wmKeyMap *km,
+        const char *idname,
+        PointerRNA *properties,
+        int include_mask, int exclude_mask)
+{
+       char idname_bl[OP_MAX_TYPENAME];
+       WM_operator_bl_idname(idname_bl, idname);
+
+       wmKeyMapItem *kmi = WM_key_event_operator_from_keymap(
+               km, idname_bl, properties->data, include_mask, exclude_mask);
+       PointerRNA kmi_ptr;
+       RNA_pointer_create(id, &RNA_KeyMapItem, kmi, &kmi_ptr);
+       return kmi_ptr;
+}
+
 static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, bool modal, bool tool)
 {
        wmKeyMap *keymap;
@@ -908,6 +925,20 @@ void RNA_api_keymapitems(StructRNA *srna)
        RNA_def_property_ui_text(parm, "id", "ID of the item");
        parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
        RNA_def_function_return(func, parm);
+
+       /* Keymap introspection
+        * Args follow: KeyConfigs.find_item_from_operator */
+       func = RNA_def_function(srna, "find_from_operator", "rna_KeyMap_item_find_from_operator");
+       RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+       parm = RNA_def_string(func, "idname", NULL, 0, "Operator Identifier", "");
+       RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+       parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", "");
+       RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
+       RNA_def_enum_flag(func, "include", rna_enum_event_type_mask_items, EVT_TYPE_MASK_ALL, "Include", "");
+       RNA_def_enum_flag(func, "exclude", rna_enum_event_type_mask_items, 0, "Exclude", "");
+       parm = RNA_def_pointer(func, "item", "KeyMapItem", "", "");
+       RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
+       RNA_def_function_return(func, parm);
 }
 
 void RNA_api_keymaps(StructRNA *srna)
index 8f31685e453a1046339bce8999d00746d62fdca6..7780c060243f425ca949ac839ce632f40a9abace 100644 (file)
@@ -152,6 +152,10 @@ char *WM_key_event_operator_string(
         struct IDProperty *properties, const bool is_strict,
         char *result, const int result_len);
 
+wmKeyMapItem *WM_key_event_operator_from_keymap(
+        struct wmKeyMap *keymap, const char *opname, struct IDProperty *properties,
+        const short include_mask, const short exclude_mask);
+
 const char *WM_bool_as_string(bool test);
 
 #ifdef __cplusplus
index 6048309980aee252e75a6ecafd21ca6caef2db8d..b8612363b788a3d8e9e6768ec49fec5f5c07e570 100644 (file)
@@ -1147,100 +1147,110 @@ char *WM_modalkeymap_operator_items_to_string_buf(
        return ret;
 }
 
-static wmKeyMapItem *wm_keymap_item_find_handlers(
-        const bContext *C, ListBase *handlers, const char *opname, int UNUSED(opcontext),
+static wmKeyMapItem *wm_keymap_item_find_in_keymap(
+        wmKeyMap *keymap, const char *opname,
         IDProperty *properties, const bool is_strict,
-        const struct wmKeyMapItemFind_Params *params,
-        wmKeyMap **r_keymap)
+        const struct wmKeyMapItemFind_Params *params)
 {
-       wmWindowManager *wm = CTX_wm_manager(C);
-       wmEventHandler *handler;
-       wmKeyMap *keymap;
-       wmKeyMapItem *kmi;
+       for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) {
+               /* skip disabled keymap items [T38447] */
+               if (kmi->flag & KMI_INACTIVE) {
+                       continue;
+               }
 
-       /* find keymap item in handlers */
-       for (handler = handlers->first; handler; handler = handler->next) {
-               keymap = WM_keymap_active(wm, handler->keymap);
+               bool kmi_match = false;
 
-               if (keymap && WM_keymap_poll((bContext *)C, keymap)) {
-                       for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
-                               /* skip disabled keymap items [T38447] */
-                               if (kmi->flag & KMI_INACTIVE) {
-                                       continue;
+               if (STREQ(kmi->idname, opname)) {
+                       if (properties) {
+                               /* example of debugging keymaps */
+#if 0
+                               if (kmi->ptr) {
+                                       if (STREQ("MESH_OT_rip_move", opname)) {
+                                               printf("OPERATOR\n");
+                                               IDP_print(properties);
+                                               printf("KEYMAP\n");
+                                               IDP_print(kmi->ptr->data);
+                                       }
                                }
+#endif
 
-                               bool kmi_match = false;
-
-                               if (STREQ(kmi->idname, opname)) {
-                                       if (properties) {
-                                               /* example of debugging keymaps */
-#if 0
-                                               if (kmi->ptr) {
-                                                       if (STREQ("MESH_OT_rip_move", opname)) {
+                               if (kmi->ptr && IDP_EqualsProperties_ex(properties, kmi->ptr->data, is_strict)) {
+                                       kmi_match = true;
+                               }
+                               /* Debug only, helps spotting mismatches between menu entries and shortcuts! */
+                               else if (G.debug & G_DEBUG_WM) {
+                                       if (is_strict && kmi->ptr) {
+                                               wmOperatorType *ot = WM_operatortype_find(opname, true);
+                                               if (ot) {
+                                                       /* make a copy of the properties and set unset ones to their default values. */
+                                                       PointerRNA opptr;
+                                                       IDProperty *properties_default = IDP_CopyProperty(kmi->ptr->data);
+
+                                                       RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
+                                                       WM_operator_properties_default(&opptr, true);
+
+                                                       if (IDP_EqualsProperties_ex(properties, properties_default, is_strict)) {
+                                                               char kmi_str[128];
+                                                               WM_keymap_item_to_string(kmi, false, kmi_str, sizeof(kmi_str));
+                                                               /* Note gievn properties could come from other things than menu entry... */
+                                                               printf("%s: Some set values in menu entry match default op values, "
+                                                                      "this might not be desired!\n", opname);
+                                                               printf("\tkm: '%s', kmi: '%s'\n", keymap->idname, kmi_str);
+#ifndef NDEBUG
+#ifdef WITH_PYTHON
                                                                printf("OPERATOR\n");
                                                                IDP_print(properties);
                                                                printf("KEYMAP\n");
                                                                IDP_print(kmi->ptr->data);
-                                                       }
-                                               }
-#endif
-
-                                               if (kmi->ptr && IDP_EqualsProperties_ex(properties, kmi->ptr->data, is_strict)) {
-                                                       kmi_match = true;
-                                               }
-                                               /* Debug only, helps spotting mismatches between menu entries and shortcuts! */
-                                               else if (G.debug & G_DEBUG_WM) {
-                                                       if (is_strict && kmi->ptr) {
-                                                               wmOperatorType *ot = WM_operatortype_find(opname, true);
-                                                               if (ot) {
-                                                                       /* make a copy of the properties and set unset ones to their default values. */
-                                                                       PointerRNA opptr;
-                                                                       IDProperty *properties_default = IDP_CopyProperty(kmi->ptr->data);
-
-                                                                       RNA_pointer_create(NULL, ot->srna, properties_default, &opptr);
-                                                                       WM_operator_properties_default(&opptr, true);
-
-                                                                       if (IDP_EqualsProperties_ex(properties, properties_default, is_strict)) {
-                                                                               char kmi_str[128];
-                                                                               WM_keymap_item_to_string(kmi, false, kmi_str, sizeof(kmi_str));
-                                                                               /* Note gievn properties could come from other things than menu entry... */
-                                                                               printf("%s: Some set values in menu entry match default op values, "
-                                                                                      "this might not be desired!\n", opname);
-                                                                               printf("\tkm: '%s', kmi: '%s'\n", keymap->idname, kmi_str);
-#ifndef NDEBUG
-#ifdef WITH_PYTHON
-                                                                               printf("OPERATOR\n");
-                                                                               IDP_print(properties);
-                                                                               printf("KEYMAP\n");
-                                                                               IDP_print(kmi->ptr->data);
 #endif
 #endif
-                                                                               printf("\n");
-                                                                       }
-
-                                                                       IDP_FreeProperty(properties_default);
-                                                                       MEM_freeN(properties_default);
-                                                               }
+                                                               printf("\n");
                                                        }
-                                               }
-                                       }
-                                       else {
-                                               kmi_match = true;
-                                       }
 
-                                       if (kmi_match) {
-                                               if ((params == NULL) || params->filter_fn(keymap, kmi, params->user_data)) {
-                                                       if (r_keymap) {
-                                                               *r_keymap = keymap;
-                                                       }
-                                                       return kmi;
+                                                       IDP_FreeProperty(properties_default);
+                                                       MEM_freeN(properties_default);
                                                }
                                        }
                                }
                        }
+                       else {
+                               kmi_match = true;
+                       }
+
+                       if (kmi_match) {
+                               if ((params == NULL) || params->filter_fn(keymap, kmi, params->user_data)) {
+                                       return kmi;
+                               }
+                       }
                }
        }
+       return NULL;
+}
 
+static wmKeyMapItem *wm_keymap_item_find_handlers(
+        const bContext *C, ListBase *handlers, const char *opname, int UNUSED(opcontext),
+        IDProperty *properties, const bool is_strict,
+        const struct wmKeyMapItemFind_Params *params,
+        wmKeyMap **r_keymap)
+{
+       wmWindowManager *wm = CTX_wm_manager(C);
+       wmEventHandler *handler;
+       wmKeyMap *keymap;
+
+       /* find keymap item in handlers */
+       for (handler = handlers->first; handler; handler = handler->next) {
+               keymap = WM_keymap_active(wm, handler->keymap);
+               if (keymap && WM_keymap_poll((bContext *)C, keymap)) {
+                       wmKeyMapItem *kmi = wm_keymap_item_find_in_keymap(
+                               keymap, opname, properties, is_strict, params);
+                       if (kmi != NULL) {
+                               if (r_keymap) {
+                                       *r_keymap = keymap;
+                               }
+                               return kmi;
+                       }
+               }
+       }
        /* ensure un-initialized keymap is never used */
        if (r_keymap) *r_keymap = NULL;
        return NULL;
@@ -1444,6 +1454,21 @@ wmKeyMapItem *WM_key_event_operator(
                r_keymap);
 }
 
+wmKeyMapItem *WM_key_event_operator_from_keymap(
+        wmKeyMap *keymap, const char *opname, IDProperty *properties,
+        const short include_mask, const short exclude_mask)
+{
+       short user_data_mask[2] = {include_mask, exclude_mask};
+       bool use_mask = (include_mask != EVT_TYPE_MASK_ALL) || (exclude_mask != 0);
+       return wm_keymap_item_find_in_keymap(
+               keymap, opname, properties, true,
+               &(struct wmKeyMapItemFind_Params){
+                   .filter_fn = use_mask ? kmi_filter_is_visible_type_mask : kmi_filter_is_visible,
+                   .user_data = use_mask ? user_data_mask : NULL,
+               });
+}
+
+
 bool WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2)
 {
        int k1type, k2type;