diff --git a/release/scripts/ui/space_userpref.py b/release/scripts/ui/space_userpref.py index 18e82ae240d..3101996d355 100644 --- a/release/scripts/ui/space_userpref.py +++ b/release/scripts/ui/space_userpref.py @@ -1197,7 +1197,11 @@ class USERPREF_PT_input(bpy.types.Panel): itemcol = itemrow.column() itemcol.active = kmi.active row = itemcol.row() - row.itemR(kmi, "idname", text="") + + if km.modal: + row.itemR(kmi, "propvalue", text="") + else: + row.itemR(kmi, "idname", text="") sub = row.row() sub.scale_x = 0.6 @@ -1233,6 +1237,7 @@ class USERPREF_PT_input(bpy.types.Panel): subrow = sub.row() subrow.scale_x = 0.75 + subrow.itemR(kmi, "any") subrow.itemR(kmi, "shift") subrow.itemR(kmi, "ctrl") subrow.itemR(kmi, "alt") diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 0372e43171e..32308b456fc 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -234,6 +234,13 @@ EnumPropertyItem keymap_propvalue_items[] = { {0, "NONE", 0, "", ""}, {0, NULL, 0, NULL, NULL}}; +EnumPropertyItem keymap_modifiers_items[] = { + {KM_ANY, "ANY", 0, "Any", ""}, + {0, "NONE", 0, "None", ""}, + {1, "FIRST", 0, "First", ""}, + {2, "SECOND", 0, "Second", ""}, + {0, NULL, 0, NULL, NULL}}; + #define KMI_TYPE_KEYBOARD 0 #define KMI_TYPE_MOUSE 1 #define KMI_TYPE_TWEAK 2 @@ -411,10 +418,25 @@ static EnumPropertyItem *rna_KeyMapItem_propvalue_itemf(bContext *C, PointerRNA { wmWindowManager *wm = CTX_wm_manager(C); wmKeyConfig *kc; + wmKeyMap *km; + + /* check user keymaps */ + for(km=U.keymaps.first; km; km=km->next) { + wmKeyMapItem *ki; + for (ki=km->items.first; ki; ki=ki->next) { + if (ki == ptr->data) { + if (!km->modal_items) { + if (!WM_keymap_user_init(wm, km)) { + return keymap_propvalue_items; /* ERROR */ + } + } + + return km->modal_items; + } + } + } for(kc=wm->keyconfigs.first; kc; kc=kc->next) { - wmKeyMap *km; - for(km=kc->keymaps.first; km; km=km->next) { /* only check if it's a modal keymap */ if (km->modal_items) { @@ -428,9 +450,37 @@ static EnumPropertyItem *rna_KeyMapItem_propvalue_itemf(bContext *C, PointerRNA } } - return keymap_propvalue_items; + + return keymap_propvalue_items; /* ERROR */ } +static int rna_KeyMapItem_any_getf(PointerRNA *ptr) +{ + wmKeyMapItem *kmi = (wmKeyMapItem*)ptr->data; + + if (kmi->shift == KM_ANY && + kmi->ctrl == KM_ANY && + kmi->alt == KM_ANY && + kmi->oskey == KM_ANY) + + return 1; + else + return 0; +} + +static void rna_KeyMapItem_any_setf(PointerRNA *ptr, int value) +{ + wmKeyMapItem *kmi = (wmKeyMapItem*)ptr->data; + + if(value) { + kmi->shift= kmi->ctrl= kmi->alt= kmi->oskey= KM_ANY; + } + else { + kmi->shift= kmi->ctrl= kmi->alt= kmi->oskey= 0; + } +} + + static PointerRNA rna_WindowManager_active_keyconfig_get(PointerRNA *ptr) { wmWindowManager *wm= ptr->data; @@ -762,6 +812,10 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_USER); RNA_def_property_ui_text(prop, "User Defined", "Keymap is defined by the user."); + prop= RNA_def_property(srna, "modal", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_MODAL); + RNA_def_property_ui_text(prop, "Modal Keymap", "Indicates that a keymap is used for translate modal events for an operator."); + RNA_api_keymap(srna); /* KeyMapItem */ @@ -798,20 +852,32 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_value_itemf"); RNA_def_property_ui_text(prop, "Value", ""); + prop= RNA_def_property(srna, "any", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_any_getf", "rna_KeyMapItem_any_setf"); + RNA_def_property_ui_text(prop, "Any", "Any modifier keys pressed."); + prop= RNA_def_property(srna, "shift", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "shift", 0); +// RNA_def_property_enum_sdna(prop, NULL, "shift"); +// RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "Shift", "Shift key pressed."); prop= RNA_def_property(srna, "ctrl", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ctrl", 0); +// RNA_def_property_enum_sdna(prop, NULL, "ctrl"); +// RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "Ctrl", "Control key pressed."); prop= RNA_def_property(srna, "alt", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "alt", 0); +// RNA_def_property_enum_sdna(prop, NULL, "alt"); +// RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "Alt", "Alt key pressed."); prop= RNA_def_property(srna, "oskey", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "oskey", 0); +// RNA_def_property_enum_sdna(prop, NULL, "oskey"); +// RNA_def_property_enum_items(prop, keymap_modifiers_items); RNA_def_property_ui_text(prop, "OS Key", "Operating system key pressed."); prop= RNA_def_property(srna, "key_modifier", PROP_ENUM, PROP_NONE); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 554418e6483..86f68feeb9a 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -105,6 +105,7 @@ char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len); wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, char *idname, int spaceid, int regionid); wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap); +int WM_keymap_user_init(struct wmWindowManager *wm, struct wmKeyMap *keymap); wmKeyMap *WM_keymap_copy_to_user(struct wmKeyMap *keymap); void WM_keymap_restore_to_default(struct wmKeyMap *keymap); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index fc453756ffa..e5508d58145 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -805,12 +805,13 @@ static int wm_event_always_pass(wmEvent *event) } /* operator exists */ -static void wm_event_modalkeymap(wmOperator *op, wmEvent *event) +static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *event) { if(op->type->modalkeymap) { + wmKeyMap *keymap= WM_keymap_active(CTX_wm_manager(C), op->type->modalkeymap); wmKeyMapItem *kmi; - - for(kmi= op->type->modalkeymap->items.first; kmi; kmi= kmi->next) { + + for(kmi= keymap->items.first; kmi; kmi= kmi->next) { if(wm_eventmatch(event, kmi)) { event->type= EVT_MODAL_MAP; @@ -837,7 +838,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand wm_handler_op_context(C, handler); wm_region_mouse_co(C, event); - wm_event_modalkeymap(op, event); + wm_event_modalkeymap(C, op, event); retval= ot->modal(C, op, event); diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 48262e40ea7..a9cace65206 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -88,9 +88,14 @@ void WM_keyconfig_userdef(wmWindowManager *wm) wmKeyMap *km; wmKeyMapItem *kmi; - for(km=U.keymaps.first; km; km=km->next) - for(kmi=km->items.first; kmi; kmi=kmi->next) - keymap_properties_set(kmi); + for(km=U.keymaps.first; km; km=km->next) { + /* modal keymaps don't have operator properties */ + if ((km->flag & KEYMAP_MODAL) == 0) { + for(kmi=km->items.first; kmi; kmi=kmi->next) { + keymap_properties_set(kmi); + } + } + } } static wmKeyConfig *wm_keyconfig_list_find(ListBase *lb, char *idname) @@ -295,17 +300,25 @@ char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len) buf[0]= 0; - if(kmi->shift) - strcat(buf, "Shift "); + if (kmi->shift == KM_ANY && + kmi->ctrl == KM_ANY && + kmi->alt == KM_ANY && + kmi->oskey == KM_ANY) { - if(kmi->ctrl) - strcat(buf, "Ctrl "); + strcat(buf, "Any "); + } else { + if(kmi->shift) + strcat(buf, "Shift "); - if(kmi->alt) - strcat(buf, "Alt "); + if(kmi->ctrl) + strcat(buf, "Ctrl "); - if(kmi->oskey) - strcat(buf, "Cmd "); + if(kmi->alt) + strcat(buf, "Alt "); + + if(kmi->oskey) + strcat(buf, "Cmd "); + } if(kmi->keymodifier) { strcat(buf, WM_key_event_string(kmi->keymodifier)); @@ -410,6 +423,36 @@ char *WM_key_event_operator_string(const bContext *C, const char *opname, int op /* ***************** user preferences ******************* */ +int WM_keymap_user_init(wmWindowManager *wm, wmKeyMap *keymap) +{ + wmKeyConfig *keyconf; + wmKeyMap *km; + + if(!keymap) + return 0; + + /* init from user key config */ + keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr); + if(keyconf) { + km= wm_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + if(km) { + keymap->poll= km->poll; /* lazy init */ + keymap->modal_items= km->modal_items; + return 1; + } + } + + /* or from default */ + km= wm_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); + if(km) { + keymap->poll= km->poll; /* lazy init */ + keymap->modal_items= km->modal_items; + return 1; + } + + return 0; +} + wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap) { wmKeyConfig *keyconf; @@ -422,6 +465,7 @@ wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap) km= wm_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid); if(km) { km->poll= keymap->poll; /* lazy init */ + km->modal_items= keymap->modal_items; return km; } @@ -431,6 +475,7 @@ wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap) km= wm_keymap_list_find(&keyconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid); if(km) { km->poll= keymap->poll; /* lazy init */ + km->modal_items= keymap->modal_items; return km; } }