[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39084] trunk/blender: KEYMAP REFACTORING

Brecht Van Lommel brechtvanlommel at pandora.be
Fri Aug 5 22:45:26 CEST 2011


Revision: 39084
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39084
Author:   blendix
Date:     2011-08-05 20:45:26 +0000 (Fri, 05 Aug 2011)
Log Message:
-----------
KEYMAP REFACTORING

Diff Keymaps

User edited keymaps now no longer override the builtin keymaps entirely, but
rather save only the difference and reapply those changes. This means they can
stay better in sync when the builtin keymaps change. The diff/patch algorithm
is not perfect, but better for the common case where only a few items are changed
rather than entire keymaps The main weakness is that if a builtin keymap item
changes, user modification of that item may need to be redone in some cases.

Keymap Editor

The most noticeable change here is that there is no longer an "Edit" button for
keymaps, all are editable immediately, but a "Restore" buttons shows for keymaps
and items that have been edited. Shortcuts for addons can also be edited in the
keymap editor. 

Addons

Addons now should only modify the new addon keyconfiguration, the keymap items
there will be added to the builtin ones for handling events, and not get lost
when starting new files. Example code of register/unregister:

km = wm.keyconfigs.addon.keymaps.new("3D View", space_type="VIEW_3D")
km.keymap_items.new('my.operator', 'ESC', 'PRESS')

km = wm.keyconfigs.addon.keymaps["3D View"]
km.keymap_items.remove(km.keymap_items["my.operator"])

Compatibility

The changes made are not forward compatible, i.e. if you save user preferences
with newer versions, older versions will not have key configuration changes that
were made.

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_userpref_keymap.py
    trunk/blender/source/blender/blenkernel/intern/blender.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/editors/interface/interface_handlers.c
    trunk/blender/source/blender/editors/interface/resources.c
    trunk/blender/source/blender/makesdna/DNA_userdef_types.h
    trunk/blender/source/blender/makesdna/DNA_windowmanager_types.h
    trunk/blender/source/blender/makesrna/intern/rna_internal.h
    trunk/blender/source/blender/makesrna/intern/rna_scene.c
    trunk/blender/source/blender/makesrna/intern/rna_userdef.c
    trunk/blender/source/blender/makesrna/intern/rna_wm.c
    trunk/blender/source/blender/makesrna/intern/rna_wm_api.c
    trunk/blender/source/blender/windowmanager/WM_api.h
    trunk/blender/source/blender/windowmanager/intern/wm.c
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
    trunk/blender/source/blender/windowmanager/intern/wm_files.c
    trunk/blender/source/blender/windowmanager/intern/wm_keymap.c
    trunk/blender/source/blenderplayer/bad_level_call_stubs/stubs.c

Added Paths:
-----------
    trunk/blender/source/blender/windowmanager/WM_keymap.h

Modified: trunk/blender/release/scripts/startup/bl_ui/space_userpref_keymap.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_userpref_keymap.py	2011-08-05 20:40:57 UTC (rev 39083)
+++ trunk/blender/release/scripts/startup/bl_ui/space_userpref_keymap.py	2011-08-05 20:45:26 UTC (rev 39084)
@@ -188,10 +188,10 @@
 
         if km.is_modal:
             row.label(text="", icon='LINKED')
-        if km.is_user_defined:
+        if km.is_user_modified:
             row.operator("wm.keymap_restore", text="Restore")
         else:
-            row.operator("wm.keymap_edit", text="Edit")
+            row.label()
 
         if km.show_expanded_children:
             if children:
@@ -212,7 +212,6 @@
                 # "Add New" at end of keymap item list
                 col = self.indented_layout(col, level + 1)
                 subcol = col.split(percentage=0.2).column()
-                subcol.enabled = km.is_user_defined
                 subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
 
             col.separator()
@@ -243,7 +242,7 @@
 
         col = self.indented_layout(layout, level)
 
-        if km.is_user_defined:
+        if kmi.show_expanded:
             col = col.column(align=True)
             box = col.box()
         else:
@@ -256,7 +255,6 @@
         row.prop(kmi, "show_expanded", text="", emboss=False)
 
         row = split.row()
-        row.enabled = km.is_user_defined
         row.prop(kmi, "active", text="", emboss=False)
 
         if km.is_modal:
@@ -265,7 +263,6 @@
             row.label(text=kmi.name)
 
         row = split.row()
-        row.enabled = km.is_user_defined
         row.prop(kmi, "map_type", text="")
         if map_type == 'KEYBOARD':
             row.prop(kmi, "type", text="", full_event=True)
@@ -282,18 +279,17 @@
         else:
             row.label()
 
-        if not kmi.is_user_defined:
+        if (not kmi.is_user_defined) and kmi.is_user_modified:
             op = row.operator("wm.keyitem_restore", text="", icon='BACK')
             op.item_id = kmi.id
-        op = row.operator("wm.keyitem_remove", text="", icon='X')
-        op.item_id = kmi.id
+        else:
+            op = row.operator("wm.keyitem_remove", text="", icon='X')
+            op.item_id = kmi.id
 
         # Expanded, additional event settings
         if kmi.show_expanded:
             box = col.box()
 
-            box.enabled = km.is_user_defined
-
             if map_type not in {'TEXTINPUT', 'TIMER'}:
                 split = box.split(percentage=0.4)
                 sub = split.row()
@@ -352,10 +348,10 @@
                 row.label()
                 row.label()
 
-                if km.is_user_defined:
+                if km.is_user_modified:
                     row.operator("wm.keymap_restore", text="Restore")
                 else:
-                    row.operator("wm.keymap_edit", text="Edit")
+                    row.label()
 
                 for kmi in filtered_items:
                     self.draw_kmi(display_keymaps, kc, km, kmi, col, 1)
@@ -363,7 +359,6 @@
                 # "Add New" at end of keymap item list
                 col = self.indented_layout(layout, 1)
                 subcol = col.split(percentage=0.2).column()
-                subcol.enabled = km.is_user_defined
                 subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
 
     def draw_hierarchy(self, display_keymaps, layout):
@@ -372,8 +367,7 @@
 
     def draw_keymaps(self, context, layout):
         wm = context.window_manager
-        kc = wm.keyconfigs.active
-        defkc = wm.keyconfigs.default
+        kc = wm.keyconfigs.user
 
         col = layout.column()
         sub = col.column()
@@ -398,7 +392,7 @@
 
         col.separator()
 
-        display_keymaps = _merge_keymaps(kc, defkc)
+        display_keymaps = _merge_keymaps(kc, kc)
         if context.space_data.filter_text != "":
             filter_text = context.space_data.filter_text.lower()
             self.draw_filtered(display_keymaps, filter_text, col)
@@ -609,7 +603,7 @@
 
         # Generate a list of keymaps to export:
         #
-        # First add all user_defined keymaps (found in inputs.edited_keymaps list),
+        # First add all user_modified keymaps (found in keyconfigs.user.keymaps list),
         # then add all remaining keymaps from the currently active custom keyconfig.
         #
         # This will create a final list of keymaps that can be used as a 'diff' against
@@ -619,7 +613,9 @@
         class FakeKeyConfig():
             keymaps = []
         edited_kc = FakeKeyConfig()
-        edited_kc.keymaps.extend(context.user_preferences.inputs.edited_keymaps)
+        for km in wm.keyconfigs.user.keymaps:
+            if km.is_user_modified:
+                edited_kc.keymaps.append(km)
         # merge edited keymaps with non-default keyconfig, if it exists
         if kc != wm.keyconfigs.default:
             export_keymaps = _merge_keymaps(edited_kc, kc)
@@ -669,17 +665,6 @@
         return {'RUNNING_MODAL'}
 
 
-class WM_OT_keymap_edit(bpy.types.Operator):
-    "Edit stored key map"
-    bl_idname = "wm.keymap_edit"
-    bl_label = "Edit Key Map"
-
-    def execute(self, context):
-        km = context.keymap
-        km.copy_to_user()
-        return {'FINISHED'}
-
-
 class WM_OT_keymap_restore(bpy.types.Operator):
     "Restore key map(s)"
     bl_idname = "wm.keymap_restore"
@@ -691,7 +676,7 @@
         wm = context.window_manager
 
         if self.all:
-            for km in wm.keyconfigs.default.keymaps:
+            for km in wm.keyconfigs.user.keymaps:
                 km.restore_to_default()
         else:
             km = context.keymap
@@ -710,13 +695,13 @@
     @classmethod
     def poll(cls, context):
         keymap = getattr(context, "keymap", None)
-        return keymap and keymap.is_user_defined
+        return keymap
 
     def execute(self, context):
         km = context.keymap
         kmi = km.keymap_items.from_id(self.item_id)
 
-        if not kmi.is_user_defined:
+        if (not kmi.is_user_defined) and kmi.is_user_modified:
             km.restore_item_to_default(kmi)
 
         return {'FINISHED'}
@@ -753,7 +738,7 @@
 
     @classmethod
     def poll(cls, context):
-        return hasattr(context, "keymap") and context.keymap.is_user_defined
+        return hasattr(context, "keymap")
 
     def execute(self, context):
         km = context.keymap

Modified: trunk/blender/source/blender/blenkernel/intern/blender.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/blender.c	2011-08-05 20:40:57 UTC (rev 39083)
+++ trunk/blender/source/blender/blenkernel/intern/blender.c	2011-08-05 20:45:26 UTC (rev 39084)
@@ -330,28 +330,45 @@
 	return 1;
 }
 
+static void keymap_item_free(wmKeyMapItem *kmi)
+{
+	if(kmi->properties) {
+		IDP_FreeProperty(kmi->properties);
+		MEM_freeN(kmi->properties);
+	}
+	if(kmi->ptr)
+		MEM_freeN(kmi->ptr);
+}
+
 void BKE_userdef_free(void)
 {
 	wmKeyMap *km;
 	wmKeyMapItem *kmi;
+	wmKeyMapDiffItem *kmdi;
 
-	for(km=U.keymaps.first; km; km=km->next) {
-		for(kmi=km->items.first; kmi; kmi=kmi->next) {
-			if(kmi->properties) {
-				IDP_FreeProperty(kmi->properties);
-				MEM_freeN(kmi->properties);
+	for(km=U.user_keymaps.first; km; km=km->next) {
+		for(kmdi=km->diff_items.first; kmdi; kmdi=kmdi->next) {
+			if(kmdi->add_item) {
+				keymap_item_free(kmdi->add_item);
+				MEM_freeN(kmdi->add_item);
 			}
-			if(kmi->ptr)
-				MEM_freeN(kmi->ptr);
+			if(kmdi->remove_item) {
+				keymap_item_free(kmdi->remove_item);
+				MEM_freeN(kmdi->remove_item);
+			}
 		}
 
+		for(kmi=km->items.first; kmi; kmi=kmi->next)
+			keymap_item_free(kmi);
+
+		BLI_freelistN(&km->diff_items);
 		BLI_freelistN(&km->items);
 	}
 	
 	BLI_freelistN(&U.uistyles);
 	BLI_freelistN(&U.uifonts);
 	BLI_freelistN(&U.themes);
-	BLI_freelistN(&U.keymaps);
+	BLI_freelistN(&U.user_keymaps);
 	BLI_freelistN(&U.addons);
 }
 

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2011-08-05 20:40:57 UTC (rev 39083)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2011-08-05 20:45:26 UTC (rev 39084)
@@ -4726,6 +4726,8 @@
 
 	wm->keyconfigs.first= wm->keyconfigs.last= NULL;
 	wm->defaultconf= NULL;
+	wm->addonconf= NULL;
+	wm->userconf= NULL;
 
 	wm->jobs.first= wm->jobs.last= NULL;
 	wm->drags.first= wm->drags.last= NULL;
@@ -11762,33 +11764,57 @@
 	lib_link_library(fd, main);		/* only init users */
 }
 
+static void direct_link_keymapitem(FileData *fd, wmKeyMapItem *kmi)
+{
+	kmi->properties= newdataadr(fd, kmi->properties);
+	if(kmi->properties)
+		IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+	kmi->ptr= NULL;
+	kmi->flag &= ~KMI_UPDATE;
+}
 
 static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
 {
 	UserDef *user;
 	wmKeyMap *keymap;
 	wmKeyMapItem *kmi;
+	wmKeyMapDiffItem *kmdi;
 
 	bfd->user= user= read_struct(fd, bhead, "user def");
 
 	/* read all data into fd->datamap */
 	bhead= read_data_into_oldnewmap(fd, bhead, "user def");
 
+	if(user->keymaps.first) {
+		/* backwards compatibility */
+		user->user_keymaps= user->keymaps;
+		user->keymaps.first= user->keymaps.last= NULL;
+	}
+
 	link_list(fd, &user->themes);
-	link_list(fd, &user->keymaps);
+	link_list(fd, &user->user_keymaps);
 	link_list(fd, &user->addons);
 
-	for(keymap=user->keymaps.first; keymap; keymap=keymap->next) {
+	for(keymap=user->user_keymaps.first; keymap; keymap=keymap->next) {
 		keymap->modal_items= NULL;
 		keymap->poll= NULL;
+		keymap->flag &= ~KEYMAP_UPDATE;
 
+		link_list(fd, &keymap->diff_items);
 		link_list(fd, &keymap->items);
-		for(kmi=keymap->items.first; kmi; kmi=kmi->next) {
-			kmi->properties= newdataadr(fd, kmi->properties);
-			if(kmi->properties)
-				IDP_DirectLinkProperty(kmi->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
-			kmi->ptr= NULL;
+		
+		for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) {
+			kmdi->remove_item= newdataadr(fd, kmdi->remove_item);
+			kmdi->add_item= newdataadr(fd, kmdi->add_item);
+
+			if(kmdi->remove_item)
+				direct_link_keymapitem(fd, kmdi->remove_item);
+			if(kmdi->add_item)
+				direct_link_keymapitem(fd, kmdi->add_item);
 		}
+
+		for(kmi=keymap->items.first; kmi; kmi=kmi->next)
+			direct_link_keymapitem(fd, kmi);
 	}

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list