Keymap: event type filter w/ finding keymap items
authorCampbell Barton <ideasman42@gmail.com>
Wed, 12 Dec 2018 10:39:55 +0000 (21:39 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 12 Dec 2018 10:43:26 +0000 (21:43 +1100)
Now its possibly to ask for only keyboard/mouse/ndof events
when finding key map items.

release/scripts/modules/bl_keymap_utils/keymap_from_toolbar.py
source/blender/editors/interface/interface_context_menu.c
source/blender/editors/interface/interface_handlers.c
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/rna_wm.c
source/blender/makesrna/intern/rna_wm_api.c
source/blender/windowmanager/WM_keymap.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_keymap.c
source/blender/windowmanager/wm_event_types.h

index 7f85faa..ddba256 100644 (file)
@@ -131,7 +131,6 @@ def generate(context, space_type):
     if use_release_confirm or use_tap_reset:
         kmi_toolbar = wm.keyconfigs.find_item_from_operator(
             idname="wm.toolbar",
-            is_hotkey=True,
         )[1]
         kmi_toolbar_type = None if not kmi_toolbar else kmi_toolbar.type
         if use_tap_reset and kmi_toolbar_type is not None:
@@ -151,7 +150,7 @@ def generate(context, space_type):
                 context='INVOKE_REGION_WIN',
                 # properties={"name": item.text},
                 properties=kmi_hack_properties,
-                is_hotkey=True,
+                include={'KEYBOARD'},
             )[1]
             if kmi_found:
                 use_tap_reset = False
@@ -184,7 +183,7 @@ def generate(context, space_type):
                 context='INVOKE_REGION_WIN',
                 # properties={"name": item.text},
                 properties=kmi_hack_properties,
-                is_hotkey=True,
+                include={'KEYBOARD'},
             )[1]
 
             if kmi_found is None:
@@ -205,7 +204,7 @@ def generate(context, space_type):
                             idname="paint.brush_select",
                             context='INVOKE_REGION_WIN',
                             properties=kmi_hack_brush_select_properties,
-                            is_hotkey=True,
+                            include={'KEYBOARD'},
                         )[1]
                     else:
                         print("Unsupported mode:", mode)
@@ -220,7 +219,7 @@ def generate(context, space_type):
             kmi_found = wm.keyconfigs.find_item_from_operator(
                 idname=item.operator,
                 context='INVOKE_REGION_WIN',
-                is_hotkey=True,
+                include={'KEYBOARD'},
             )[1]
         elif item.keymap is not None:
             km = keyconf.keymaps.get(item.keymap[0])
@@ -235,7 +234,7 @@ def generate(context, space_type):
                         idname=kmi_first.idname,
                         # properties=kmi_first.properties,  # prevents matches, don't use.
                         context='INVOKE_REGION_WIN',
-                        is_hotkey=True,
+                        include={'KEYBOARD'},
                     )[1]
                 else:
                     kmi_found = None
index bbc0f66..84460f9 100644 (file)
@@ -96,7 +96,10 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
        uiStyle *style = UI_style_get_dpi();
        IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
 
-       kmi = WM_key_event_operator(C, but->optype->idname, but->opcontext, prop, true, &km);
+       kmi = WM_key_event_operator(
+               C, but->optype->idname, but->opcontext, prop,
+               EVT_TYPE_MASK_HOTKEY_INCLUDE, EVT_TYPE_MASK_HOTKEY_EXCLUDE,
+               &km);
        BLI_assert(kmi != NULL);
 
        RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
@@ -202,7 +205,10 @@ static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
        wmKeyMapItem *kmi;
        IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
 
-       kmi = WM_key_event_operator(C, but->optype->idname, but->opcontext, prop, true, &km);
+       kmi = WM_key_event_operator(
+               C, but->optype->idname, but->opcontext, prop,
+               EVT_TYPE_MASK_HOTKEY_INCLUDE, EVT_TYPE_MASK_HOTKEY_EXCLUDE,
+               &km);
        BLI_assert(kmi != NULL);
 
        WM_keymap_remove_item(km, kmi);
@@ -708,7 +714,10 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
                int w = uiLayoutGetWidth(layout);
                wmKeyMap *km;
                /* We want to know if this op has a shortcut, be it hotkey or not. */
-               wmKeyMapItem *kmi = WM_key_event_operator(C, but->optype->idname, but->opcontext, prop, false, &km);
+               wmKeyMapItem *kmi = WM_key_event_operator(
+                       C, but->optype->idname, but->opcontext, prop,
+                       EVT_TYPE_MASK_ALL, 0,
+                       &km);
 
                /* We do have a shortcut, but only keyboard ones are editable that way... */
                if (kmi) {
index 5ab23ed..3a3259e 100644 (file)
@@ -3830,8 +3830,7 @@ static int ui_do_but_HOTKEYEVT(
                ED_region_tag_redraw(data->region);
 
                if (event->val == KM_PRESS) {
-                       if (ISHOTKEY(event->type)) {
-
+                       if (ISHOTKEY(event->type) && (event->type != ESCKEY)) {
                                if (WM_key_event_string(event->type, false)[0])
                                        ui_but_value_set(but, event->type);
                                else
index 6504cf8..f2eaa9d 100644 (file)
@@ -116,6 +116,7 @@ extern const EnumPropertyItem rna_enum_motionpath_bake_location_items[];
 
 extern const EnumPropertyItem rna_enum_event_value_items[];
 extern const EnumPropertyItem rna_enum_event_type_items[];
+extern const EnumPropertyItem rna_enum_event_type_mask_items[];
 extern const EnumPropertyItem rna_enum_operator_return_items[];
 extern const EnumPropertyItem rna_enum_operator_property_tags[];
 
index 77a10e6..77b9d63 100644 (file)
@@ -406,6 +406,21 @@ const EnumPropertyItem rna_enum_keymap_propvalue_items[] = {
        {0, NULL, 0, NULL, NULL}
 };
 
+
+/* Mask event types used in keymap items. */
+const EnumPropertyItem rna_enum_event_type_mask_items[] = {
+       {EVT_TYPE_MASK_KEYBOARD_MODIFIER, "KEYBOARD_MODIFIER", 0, "Keyboard Modifier", ""},
+       {EVT_TYPE_MASK_KEYBOARD, "KEYBOARD", 0, "Keyboard", ""},
+       {EVT_TYPE_MASK_MOUSE_WHEEL, "MOUSE_WHEEL", 0, "Mouse Wheel", ""},
+       {EVT_TYPE_MASK_MOUSE_GESTURE, "MOUSE_GESTURE", 0, "Mouse Gesture", ""},
+       {EVT_TYPE_MASK_MOUSE_BUTTON, "MOUSE_BUTTON", 0, "Mouse Button", ""},
+       {EVT_TYPE_MASK_MOUSE, "MOUSE", 0, "Mouse", ""},
+       {EVT_TYPE_MASK_NDOF, "NDOF", 0, "NDOF", ""},
+       {EVT_TYPE_MASK_TWEAK, "TWEAK", 0, "Tweak", ""},
+       {EVT_TYPE_MASK_ACTIONZONE, "ACTIONZONE", 0, "Action Zone", ""},
+       {0, NULL, 0, NULL, NULL}
+};
+
 #if 0
 static const EnumPropertyItem keymap_modifiers_items[] = {
        {KM_ANY, "ANY", 0, "Any", ""},
index 92a396c..f698f71 100644 (file)
@@ -44,6 +44,7 @@
 #include "UI_interface.h"
 
 #include "wm_cursors.h"
+#include "wm_event_types.h"
 
 #include "rna_internal.h"  /* own include */
 
@@ -371,14 +372,15 @@ static PointerRNA rna_KeyConfig_find_item_from_operator(
         const char *idname,
         int opcontext,
         PointerRNA *properties,
-        bool is_hotkey,
+        int include_mask, int exclude_mask,
         PointerRNA *km_ptr)
 {
        char idname_bl[OP_MAX_TYPENAME];
        WM_operator_bl_idname(idname_bl, idname);
 
        wmKeyMap *km = NULL;
-       wmKeyMapItem *kmi = WM_key_event_operator(C, idname_bl, opcontext, properties->data, (bool)is_hotkey, &km);
+       wmKeyMapItem *kmi = WM_key_event_operator(
+               C, idname_bl, opcontext, properties->data, include_mask, exclude_mask, &km);
        PointerRNA kmi_ptr;
        RNA_pointer_create(&wm->id, &RNA_KeyMap, km, km_ptr);
        RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &kmi_ptr);
@@ -972,7 +974,8 @@ void RNA_api_keyconfigs(StructRNA *srna)
        RNA_def_property_enum_items(parm, rna_enum_operator_context_items);
        parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", "");
        RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
-       RNA_def_boolean(func, "is_hotkey", 0, "Hotkey", "Event is not a modifier");
+       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, "keymap", "KeyMap", "", "");
        RNA_def_parameter_flags(parm, 0, PARM_RNAPTR | PARM_OUTPUT);
        parm = RNA_def_pointer(func, "item", "KeyMapItem", "", "");
index 7f7612c..8f31685 100644 (file)
@@ -144,8 +144,8 @@ int WM_keymap_item_raw_to_string(
         const short val, const short type, const bool compact,
         char *result, const int result_len);
 wmKeyMapItem *WM_key_event_operator(
-        const struct bContext *C, const char *opname, int opcontext,
-        struct IDProperty *properties, const bool is_hotkey,
+        const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties,
+        const short include_mask, const short exclude_mask,
         struct wmKeyMap **r_keymap);
 char *WM_key_event_operator_string(
         const struct bContext *C, const char *opname, int opcontext,
index 58773bd..81544c2 100644 (file)
@@ -3534,6 +3534,54 @@ bool WM_event_is_modal_tweak_exit(const wmEvent *event, int tweak_event)
        return 0;
 }
 
+bool WM_event_type_mask_test(const int event_type, const enum eEventType_Mask mask)
+{
+       /* Keyboard. */
+       if (mask & EVT_TYPE_MASK_KEYBOARD) {
+               if (ISKEYBOARD(event_type)) {
+                       return true;
+               }
+       }
+       else if (mask & EVT_TYPE_MASK_KEYBOARD_MODIFIER) {
+               if (ISKEYMODIFIER(event_type)) {
+                       return true;
+               }
+       }
+
+       /* Mouse. */
+       if (mask & EVT_TYPE_MASK_MOUSE) {
+               if (ISMOUSE(event_type)) {
+                       return true;
+               }
+       }
+       else if (mask & EVT_TYPE_MASK_MOUSE_WHEEL) {
+               if (ISMOUSE_WHEEL(event_type)) {
+                       return true;
+               }
+       }
+       else if (mask & EVT_TYPE_MASK_MOUSE_GESTURE) {
+               if (ISMOUSE_GESTURE(event_type)) {
+                       return true;
+               }
+       }
+
+       /* Tweak. */
+       if (mask & EVT_TYPE_MASK_TWEAK) {
+               if (ISTWEAK(event_type)) {
+                       return true;
+               }
+       }
+
+       /* Action Zone. */
+       if (mask & EVT_TYPE_MASK_ACTIONZONE) {
+               if (IS_EVENT_ACTIONZONE(event_type)) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 /* ********************* ghost stuff *************** */
 
 static int convert_key(GHOST_TKey key)
index 13744aa..2d7814b 100644 (file)
@@ -64,7 +64,6 @@
 #include "wm_event_system.h"
 #include "wm_event_types.h"
 
-
 struct wmKeyMapItemFind_Params {
        bool (*filter_fn)(const wmKeyMap *km, const wmKeyMapItem *kmi, void *user_data);
        void *user_data;
@@ -1415,21 +1414,29 @@ char *WM_key_event_operator_string(
        return NULL;
 }
 
-static bool kmi_filter_is_visible_hotkey(const wmKeyMap *km, const wmKeyMapItem *kmi, void *user_data)
+static bool kmi_filter_is_visible_type_mask(const wmKeyMap *km, const wmKeyMapItem *kmi, void *user_data)
 {
-       return (ISHOTKEY(kmi->type) && kmi_filter_is_visible(km, kmi, user_data));
+       short *mask_pair = user_data;
+       return ((WM_event_type_mask_test(kmi->type, mask_pair[0]) == true) &&
+               (WM_event_type_mask_test(kmi->type, mask_pair[1]) == false) &&
+               kmi_filter_is_visible(km, kmi, user_data));
 }
 
+/**
+ * \param include_mask, exclude_mask: Event types to include/exclude when looking up keys (#eEventType_Mask).
+ */
 wmKeyMapItem *WM_key_event_operator(
-        const bContext *C, const char *opname, int opcontext,
-        IDProperty *properties, const bool is_hotkey,
+        const bContext *C, const char *opname, int opcontext, IDProperty *properties,
+        const short include_mask, const short exclude_mask,
         wmKeyMap **r_keymap)
 {
+       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(
                C, opname, opcontext, properties, true,
                &(struct wmKeyMapItemFind_Params){
-                   .filter_fn = is_hotkey ? kmi_filter_is_visible_hotkey : kmi_filter_is_visible,
-                   .user_data = NULL,
+                   .filter_fn = use_mask ? kmi_filter_is_visible_type_mask : kmi_filter_is_visible,
+                   .user_data = use_mask ? user_data_mask : NULL,
                },
                r_keymap);
 }
index b2c4c04..0fc4899 100644 (file)
@@ -381,9 +381,7 @@ enum {
 /* test whether event type is acceptable as hotkey, excluding modifiers */
 #define ISHOTKEY(event_type)                                                  \
        ((ISKEYBOARD(event_type) || ISMOUSE(event_type) || ISNDOF(event_type)) && \
-        ((event_type) != ESCKEY) &&                                                \
-        ((event_type) >= LEFTCTRLKEY && (event_type) <= LEFTSHIFTKEY) == false &&    \
-        ((event_type) >= UNKNOWNKEY  && (event_type) <= GRLESSKEY) == false)
+        (ISKEYMODIFIER(event_type) == false))
 
 /* internal helpers*/
 #define _VA_IS_EVENT_MOD2(v, a) (CHECK_TYPE_INLINE(v, wmEvent *), \
@@ -398,6 +396,41 @@ enum {
 /* reusable IS_EVENT_MOD(event, shift, ctrl, alt, oskey), macro */
 #define IS_EVENT_MOD(...) VA_NARGS_CALL_OVERLOAD(_VA_IS_EVENT_MOD, __VA_ARGS__)
 
+enum eEventType_Mask {
+       /* ISKEYMODIFIER */
+       EVT_TYPE_MASK_KEYBOARD_MODIFIER = (1 << 0),
+       /* ISKEYBOARD */
+       EVT_TYPE_MASK_KEYBOARD = (1 << 1) | EVT_TYPE_MASK_KEYBOARD_MODIFIER,
+       /* ISMOUSE_WHEEL */
+       EVT_TYPE_MASK_MOUSE_WHEEL = (1 << 2),
+       /* ISMOUSE_BUTTON */
+       EVT_TYPE_MASK_MOUSE_GESTURE = (1 << 3),
+       /* ISMOUSE_GESTURE */
+       EVT_TYPE_MASK_MOUSE_BUTTON = (1 << 4),
+       /* ISMOUSE */
+       EVT_TYPE_MASK_MOUSE = (1 << 5) | EVT_TYPE_MASK_MOUSE_WHEEL | EVT_TYPE_MASK_MOUSE_GESTURE | EVT_TYPE_MASK_MOUSE_BUTTON,
+       /* ISNDOF */
+       EVT_TYPE_MASK_NDOF = (1 << 6),
+       /* ISTWEAK */
+       EVT_TYPE_MASK_TWEAK = (1 << 7),
+       /* IS_EVENT_ACTIONZONE */
+       EVT_TYPE_MASK_ACTIONZONE = (1 << 8),
+};
+#define EVT_TYPE_MASK_ALL \
+       (EVT_TYPE_MASK_KEYBOARD | \
+        EVT_TYPE_MASK_MOUSE | \
+        EVT_TYPE_MASK_NDOF | \
+        EVT_TYPE_MASK_TWEAK | \
+        EVT_TYPE_MASK_ACTIONZONE)
+
+#define EVT_TYPE_MASK_HOTKEY_INCLUDE \
+       (EVT_TYPE_MASK_KEYBOARD | EVT_TYPE_MASK_MOUSE | EVT_TYPE_MASK_NDOF)
+#define EVT_TYPE_MASK_HOTKEY_EXCLUDE \
+       EVT_TYPE_MASK_KEYBOARD_MODIFIER
+
+bool WM_event_type_mask_test(const int event_type, const enum eEventType_Mask mask);
+
+
 /* ********** wmEvent.val ********** */
 
 /* Gestures */