[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24574] trunk/blender: === Better support for user defined modal keymaps ===

Martin Poirier theeth at yahoo.com
Sun Nov 15 20:25:34 CET 2009


Revision: 24574
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24574
Author:   theeth
Date:     2009-11-15 20:25:34 +0100 (Sun, 15 Nov 2009)

Log Message:
-----------
=== Better support for user defined modal keymaps ===

Fixing/Missing RNA properties:
- "virtual" property for "ANY" modifier for keymapitem
- modal property for keymap
- Look up modal_items in usermaps too

Lazy init usermaps needs to init modal_items too.

New function to initialize a user keymap (fill in modal_item and poll pointers).

Operator modal keymaps now look up if there's a user defined keymap that overwrites it.

Full Event UI buttons now show "Any" when modifier is set to that (instead of listing all of them).

Note: Having the modifiers as boolean still doesn't express the full breath of values possible for them. There is commented code in this commit to represent them as enum, which would solve this, but make the keymap editor more cryptic.

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/space_userpref.py
    trunk/blender/source/blender/makesrna/intern/rna_wm.c
    trunk/blender/source/blender/windowmanager/WM_api.h
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
    trunk/blender/source/blender/windowmanager/intern/wm_keymap.c

Modified: trunk/blender/release/scripts/ui/space_userpref.py
===================================================================
--- trunk/blender/release/scripts/ui/space_userpref.py	2009-11-15 17:10:52 UTC (rev 24573)
+++ trunk/blender/release/scripts/ui/space_userpref.py	2009-11-15 19:25:34 UTC (rev 24574)
@@ -1197,7 +1197,11 @@
             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 @@
 
                     subrow = sub.row()
                     subrow.scale_x = 0.75
+                    subrow.itemR(kmi, "any")
                     subrow.itemR(kmi, "shift")
                     subrow.itemR(kmi, "ctrl")
                     subrow.itemR(kmi, "alt")

Modified: trunk/blender/source/blender/makesrna/intern/rna_wm.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_wm.c	2009-11-15 17:10:52 UTC (rev 24573)
+++ trunk/blender/source/blender/makesrna/intern/rna_wm.c	2009-11-15 19:25:34 UTC (rev 24574)
@@ -234,6 +234,13 @@
 		{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 @@
 {
 	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 @@
 		}
 	}
 
-	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 @@
 	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 @@
 	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);

Modified: trunk/blender/source/blender/windowmanager/WM_api.h
===================================================================
--- trunk/blender/source/blender/windowmanager/WM_api.h	2009-11-15 17:10:52 UTC (rev 24573)
+++ trunk/blender/source/blender/windowmanager/WM_api.h	2009-11-15 19:25:34 UTC (rev 24574)
@@ -105,6 +105,7 @@
 
 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);
 

Modified: trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2009-11-15 17:10:52 UTC (rev 24573)
+++ trunk/blender/source/blender/windowmanager/intern/wm_event_system.c	2009-11-15 19:25:34 UTC (rev 24574)
@@ -805,12 +805,13 @@
 }
 
 /* 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 @@
 			
 			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);
 

Modified: trunk/blender/source/blender/windowmanager/intern/wm_keymap.c
===================================================================
--- trunk/blender/source/blender/windowmanager/intern/wm_keymap.c	2009-11-15 17:10:52 UTC (rev 24573)
+++ trunk/blender/source/blender/windowmanager/intern/wm_keymap.c	2009-11-15 19:25:34 UTC (rev 24574)
@@ -88,9 +88,14 @@
 	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 @@
 
 	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 @@
 
 /* ***************** 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 @@
 	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 @@
 		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;
 		}
 	}





More information about the Bf-blender-cvs mailing list