diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index bba5578ccc1..66b7f9f0347 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2817,7 +2817,7 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Knife Tool Modal Map"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) + if (keymap && keymap->modal_items) return NULL; keymap = WM_modalkeymap_add(keyconf, "Knife Tool Modal Map", modal_items); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index b0b5643f2ba..50eaa3b7ccc 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -599,7 +599,7 @@ void viewrotate_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Rotate Modal"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) return; + if (keymap && keymap->modal_items) return; keymap = WM_modalkeymap_add(keyconf, "View3D Rotate Modal", modal_items); @@ -1262,7 +1262,7 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Move Modal"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) return; + if (keymap && keymap->modal_items) return; keymap = WM_modalkeymap_add(keyconf, "View3D Move Modal", modal_items); @@ -1423,7 +1423,7 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Zoom Modal"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) return; + if (keymap && keymap->modal_items) return; keymap = WM_modalkeymap_add(keyconf, "View3D Zoom Modal", modal_items); @@ -1695,7 +1695,7 @@ void viewdolly_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Dolly Modal"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) return; + if (keymap && keymap->modal_items) return; keymap = WM_modalkeymap_add(keyconf, "View3D Dolly Modal", modal_items); diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 31beda3b3f9..5b6624889c8 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -113,7 +113,7 @@ void fly_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Fly Modal"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) + if (keymap && keymap->modal_items) return; keymap = WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 90c4d87d6f1..f4bfa1e0172 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -539,7 +539,7 @@ wmKeyMap* transform_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "Transform Modal Map"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) return NULL; + if (keymap && keymap->modal_items) return NULL; keymap= WM_modalkeymap_add(keyconf, "Transform Modal Map", modal_items); diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index c86d9d17b1f..5a49e45cf5e 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -222,6 +222,7 @@ typedef struct wmKeyMapItem { IDProperty *properties; /* operator properties, assigned to ptr->data and can be written to a file */ /* modal */ + char propvalue_str[64]; /* runtime temporary storage for loading */ short propvalue; /* if used, the item is from modal map */ /* event */ diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index bad122ab761..9b3634bc8ac 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -120,16 +120,6 @@ static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, ReportList *reports return NULL; } - if (!km->modal_items) { - BKE_report(reports, RPT_ERROR, "No property values defined"); - return NULL; - } - - - if (RNA_enum_value_from_id(km->modal_items, propvalue_str, &propvalue) == 0) { - BKE_report(reports, RPT_WARNING, "Property value not in enumeration"); - } - if (shift) modifier |= KM_SHIFT; if (ctrl) modifier |= KM_CTRL; if (alt) modifier |= KM_ALT; @@ -137,6 +127,13 @@ static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, ReportList *reports if (any) modifier = KM_ANY; + /* not initialized yet, do delayed lookup */ + if (!km->modal_items) + return WM_modalkeymap_add_item_str(km, type, value, modifier, keymodifier, propvalue_str); + + if (RNA_enum_value_from_id(km->modal_items, propvalue_str, &propvalue) == 0) + BKE_report(reports, RPT_WARNING, "Property value not in enumeration"); + return WM_modalkeymap_add_item(km, type, value, modifier, keymodifier, propvalue); } diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h index db448397065..78dbd253cd6 100644 --- a/source/blender/windowmanager/WM_keymap.h +++ b/source/blender/windowmanager/WM_keymap.h @@ -80,6 +80,7 @@ int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2); wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, const char *idname, struct EnumPropertyItem *items); wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, const char *idname); wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value); +wmKeyMapItem *WM_modalkeymap_add_item_str(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, const char *value); void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname); /* Keymap Editor */ diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index af56211a4e3..247eadbb698 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -710,6 +710,22 @@ wmKeyMapItem *WM_modalkeymap_add_item(wmKeyMap *km, int type, int val, int modif return kmi; } +wmKeyMapItem *WM_modalkeymap_add_item_str(wmKeyMap *km, int type, int val, int modifier, int keymodifier, const char *value) +{ + wmKeyMapItem *kmi = MEM_callocN(sizeof(wmKeyMapItem), "keymap entry"); + + BLI_addtail(&km->items, kmi); + BLI_strncpy(kmi->propvalue_str, value, sizeof(kmi->propvalue_str)); + + keymap_event_set(kmi, type, val, modifier, keymodifier); + + keymap_item_set_id(km, kmi); + + WM_keyconfig_update_tag(km, kmi); + + return kmi; +} + void WM_modalkeymap_assign(wmKeyMap *km, const char *opname) { wmOperatorType *ot = WM_operatortype_find(opname, 0); @@ -720,6 +736,33 @@ void WM_modalkeymap_assign(wmKeyMap *km, const char *opname) printf("error: modalkeymap_assign, unknown operator %s\n", opname); } +static void wm_user_modal_keymap_set_items(wmWindowManager *wm, wmKeyMap *km) +{ + /* here we convert propvalue string values delayed, due to python keymaps + * being created before the actual modal keymaps, so no modal_items */ + wmKeyMap *defaultkm; + wmKeyMapItem *kmi; + int propvalue; + + if (km && (km->flag & KEYMAP_MODAL) && !km->modal_items) { + defaultkm = WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, 0, 0); + + if (!defaultkm) + return; + + km->modal_items = defaultkm->modal_items; + km->poll = defaultkm->poll; + + for (kmi = km->items.first; kmi; kmi = kmi->next) { + if (kmi->propvalue_str[0]) { + if (RNA_enum_value_from_id(km->modal_items, kmi->propvalue_str, &propvalue)) + kmi->propvalue = propvalue; + kmi->propvalue_str[0] = '\0'; + } + } + } +} + /* ***************** get string from key events **************** */ const char *WM_key_event_string(short type) @@ -1034,6 +1077,8 @@ void WM_keyconfig_update(wmWindowManager *wm) addonmap = WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid); usermap = WM_keymap_list_find(&U.user_keymaps, km->idname, km->spaceid, km->regionid); + wm_user_modal_keymap_set_items(wm, defaultmap); + /* add */ kmn = wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b15d408df64..028f7b5c41f 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3711,7 +3711,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Gesture Circle"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) return; + if (keymap && keymap->modal_items) return; keymap = WM_modalkeymap_add(keyconf, "View3D Gesture Circle", modal_items); @@ -3758,7 +3758,7 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Straight Line"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) return; + if (keymap && keymap->modal_items) return; keymap = WM_modalkeymap_add(keyconf, "Gesture Straight Line", modal_items); @@ -3787,7 +3787,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Border"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) return; + if (keymap && keymap->modal_items) return; keymap = WM_modalkeymap_add(keyconf, "Gesture Border", modal_items); @@ -3846,7 +3846,7 @@ static void gesture_zoom_border_modal_keymap(wmKeyConfig *keyconf) wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Gesture Zoom Border"); /* this function is called for each spacetype, only needs to add map once */ - if (keymap) return; + if (keymap && keymap->modal_items) return; keymap = WM_modalkeymap_add(keyconf, "Gesture Zoom Border", modal_items);