Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2011-08-06 00:45:26 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-08-06 00:45:26 +0400
commite6e4c7ef8bd53b06c879302bbfd3d6a00c6c48af (patch)
tree4147f9502e965705092d773380d70792633daffa /source
parent7368298a45f96667a548e10cfe9d227fcf18e114 (diff)
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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/blender.c33
-rw-r--r--source/blender/blenloader/intern/readfile.c40
-rw-r--r--source/blender/blenloader/intern/writefile.c24
-rw-r--r--source/blender/editors/interface/interface_handlers.c25
-rw-r--r--source/blender/editors/interface/resources.c2
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h3
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h24
-rw-r--r--source/blender/makesrna/intern/rna_internal.h3
-rw-r--r--source/blender/makesrna/intern/rna_scene.c2
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c6
-rw-r--r--source/blender/makesrna/intern/rna_wm.c247
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c183
-rw-r--r--source/blender/windowmanager/WM_api.h44
-rw-r--r--source/blender/windowmanager/WM_keymap.h104
-rw-r--r--source/blender/windowmanager/intern/wm.c10
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c6
-rw-r--r--source/blender/windowmanager/intern/wm_files.c13
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c718
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c2
19 files changed, 1024 insertions, 465 deletions
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 8b4bbbd3c83..7e2097d1233 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -330,28 +330,45 @@ static int handle_subversion_warning(Main *main)
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(kmdi->remove_item) {
+ keymap_item_free(kmdi->remove_item);
+ MEM_freeN(kmdi->remove_item);
}
- if(kmi->ptr)
- MEM_freeN(kmi->ptr);
}
+ 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);
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 44c8ca97be9..bd12677485c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4726,6 +4726,8 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
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 @@ static void lib_link_all(FileData *fd, Main *main)
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);
}
// XXX
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index bf86527b9d3..7d65248c0e9 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -717,11 +717,19 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) /* for renderdeamon
}
}
+static void write_keymapitem(WriteData *wd, wmKeyMapItem *kmi)
+{
+ writestruct(wd, DATA, "wmKeyMapItem", 1, kmi);
+ if(kmi->properties)
+ IDP_WriteProperty(kmi->properties, wd);
+}
+
static void write_userdef(WriteData *wd)
{
bTheme *btheme;
wmKeyMap *keymap;
wmKeyMapItem *kmi;
+ wmKeyMapDiffItem *kmdi;
bAddon *bext;
uiStyle *style;
@@ -730,15 +738,19 @@ static void write_userdef(WriteData *wd)
for(btheme= U.themes.first; btheme; btheme=btheme->next)
writestruct(wd, DATA, "bTheme", 1, btheme);
- for(keymap= U.keymaps.first; keymap; keymap=keymap->next) {
+ for(keymap= U.user_keymaps.first; keymap; keymap=keymap->next) {
writestruct(wd, DATA, "wmKeyMap", 1, keymap);
- for(kmi=keymap->items.first; kmi; kmi=kmi->next) {
- writestruct(wd, DATA, "wmKeyMapItem", 1, kmi);
-
- if(kmi->properties)
- IDP_WriteProperty(kmi->properties, wd);
+ for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) {
+ writestruct(wd, DATA, "wmKeyMapDiffItem", 1, kmdi);
+ if(kmdi->remove_item)
+ write_keymapitem(wd, kmdi->remove_item);
+ if(kmdi->add_item)
+ write_keymapitem(wd, kmdi->add_item);
}
+
+ for(kmi=keymap->items.first; kmi; kmi=kmi->next)
+ write_keymapitem(wd, kmi);
}
for(bext= U.addons.first; bext; bext=bext->next)
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b3272a2e3d4..d8d8354b0b9 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -4067,7 +4067,6 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
/* complex code to change name of button */
if(WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, buf, sizeof(buf))) {
- wmKeyMap *km= NULL;
char *butstr_orig;
// XXX but->str changed... should not, remove the hotkey from it
@@ -4080,10 +4079,6 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
but->str= but->strdata;
ui_check_but(but);
-
- /* set the keymap editable else the key wont save */
- WM_key_event_operator_id(C, but->optype->idname, but->opcontext, prop, 1, &km);
- WM_keymap_copy_to_user(km);
}
else {
/* shortcut was removed */
@@ -4095,6 +4090,7 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event))
static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
{
+ wmWindowManager *wm= CTX_wm_manager(C);
uiBlock *block;
uiBut *but = (uiBut *)arg;
wmKeyMap *km;
@@ -4107,7 +4103,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
kmi = WM_keymap_item_find_id(km, kmi_id);
- RNA_pointer_create(NULL, &RNA_KeyMapItem, kmi, &ptr);
+ RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetHandleFunc(block, but_shortcut_name_func, but);
@@ -4126,6 +4122,7 @@ static uiBlock *menu_change_shortcut(bContext *C, ARegion *ar, void *arg)
static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
{
+ wmWindowManager *wm= CTX_wm_manager(C);
uiBlock *block;
uiBut *but = (uiBut *)arg;
wmKeyMap *km;
@@ -4134,19 +4131,25 @@ static uiBlock *menu_add_shortcut(bContext *C, ARegion *ar, void *arg)
uiLayout *layout;
uiStyle *style= U.uistyles.first;
IDProperty *prop= (but->opptr)? but->opptr->data: NULL;
+ int kmi_id;
/* XXX this guess_opname can potentially return a different keymap than being found on adding later... */
km = WM_keymap_guess_opname(C, but->optype->idname);
kmi = WM_keymap_add_item(km, but->optype->idname, AKEY, KM_PRESS, 0, 0);
+ kmi_id = kmi->id;
- if (prop) {
+ /* copy properties, prop can be NULL for reset */
+ if(prop)
prop= IDP_CopyProperty(prop);
- }
-
- /* prop can be NULL */
WM_keymap_properties_reset(kmi, prop);
- RNA_pointer_create(NULL, &RNA_KeyMapItem, kmi, &ptr);
+ /* update and get pointers again */
+ WM_keyconfig_update(wm);
+
+ km = WM_keymap_guess_opname(C, but->optype->idname);
+ kmi = WM_keymap_item_find_id(km, kmi_id);
+
+ RNA_pointer_create(&wm->id, &RNA_KeyMapItem, kmi, &ptr);
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetHandleFunc(block, but_shortcut_name_func, but);
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 32e87b3a793..f3db6ad11ae 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -1425,7 +1425,7 @@ void init_userdef_do_versions(void)
if (bmain->versionfile < 250 || (bmain->versionfile == 250 && bmain->subversionfile < 8)) {
wmKeyMap *km;
- for(km=U.keymaps.first; km; km=km->next) {
+ for(km=U.user_keymaps.first; km; km=km->next) {
if (strcmp(km->idname, "Armature_Sketch")==0)
strcpy(km->idname, "Armature Sketch");
else if (strcmp(km->idname, "View3D")==0)
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index aa6da3aaeca..a555a196060 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -341,7 +341,8 @@ typedef struct UserDef {
struct ListBase themes;
struct ListBase uifonts;
struct ListBase uistyles;
- struct ListBase keymaps;
+ struct ListBase keymaps; /* deprecated in favor of user_keymaps */
+ struct ListBase user_keymaps;
struct ListBase addons;
char keyconfigstr[64];
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 31e59f18626..1f0ae28a00d 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -144,7 +144,9 @@ typedef struct wmWindowManager {
ListBase drags; /* active dragged items */
ListBase keyconfigs; /* known key configurations */
- struct wmKeyConfig *defaultconf; /* default configuration, not saved */
+ struct wmKeyConfig *defaultconf; /* default configuration */
+ struct wmKeyConfig *addonconf; /* addon configuration */
+ struct wmKeyConfig *userconf; /* user configuration */
ListBase timers; /* active timers */
struct wmTimer *autosavetimer; /* timer for auto save */
@@ -239,15 +241,26 @@ typedef struct wmKeyMapItem {
struct PointerRNA *ptr; /* rna pointer to access properties */
} wmKeyMapItem;
+/* used instead of wmKeyMapItem for diff keymaps */
+typedef struct wmKeyMapDiffItem {
+ struct wmKeyMapDiffItem *next, *prev;
+
+ wmKeyMapItem *remove_item;
+ wmKeyMapItem *add_item;
+} wmKeyMapDiffItem;
+
/* wmKeyMapItem.flag */
-#define KMI_INACTIVE 1
-#define KMI_EXPANDED 2
+#define KMI_INACTIVE 1
+#define KMI_EXPANDED 2
+#define KMI_USER_MODIFIED 4
+#define KMI_UPDATE 8
/* stored in WM, the actively used keymaps */
typedef struct wmKeyMap {
struct wmKeyMap *next, *prev;
ListBase items;
+ ListBase diff_items;
char idname[64]; /* global editor keymaps, or for more per space/region */
short spaceid; /* same IDs as in DNA_space_types.h */
@@ -263,9 +276,12 @@ typedef struct wmKeyMap {
/* wmKeyMap.flag */
#define KEYMAP_MODAL 1 /* modal map, not using operatornames */
-#define KEYMAP_USER 2 /* user created keymap */
+#define KEYMAP_USER 2 /* user keymap */
#define KEYMAP_EXPANDED 4
#define KEYMAP_CHILDREN_EXPANDED 8
+#define KEYMAP_DIFF 16 /* diff keymap for user preferences */
+#define KEYMAP_USER_MODIFIED 32 /* keymap has user modifications */
+#define KEYMAP_UPDATE 64
typedef struct wmKeyConfig {
struct wmKeyConfig *next, *prev;
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 9175806e2bb..c0ae7b02b1a 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -238,9 +238,12 @@ void RNA_api_image(struct StructRNA *srna);
void RNA_api_operator(struct StructRNA *srna);
void RNA_api_macro(struct StructRNA *srna);
void RNA_api_keyconfig(struct StructRNA *srna);
+void RNA_api_keyconfigs(struct StructRNA *srna);
void RNA_api_keyingset(struct StructRNA *srna);
void RNA_api_keymap(struct StructRNA *srna);
+void RNA_api_keymaps(struct StructRNA *srna);
void RNA_api_keymapitem(struct StructRNA *srna);
+void RNA_api_keymapitems(struct StructRNA *srna);
void RNA_api_area(struct StructRNA *srna);
void RNA_api_main(struct StructRNA *srna);
void RNA_api_material(StructRNA *srna);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index b3d8bc8ea18..29cfc695911 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1409,7 +1409,7 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
prop= RNA_def_property(srna, "layers_zmask", PROP_BOOLEAN, PROP_LAYER);
RNA_def_property_boolean_sdna(prop, NULL, "lay_zmask", 1);
RNA_def_property_array(prop, 20);
- RNA_def_property_ui_text(prop, "Zmask Layers", "Zmask scene layers");
+ RNA_def_property_ui_text(prop, "Zmask Layers", "Zmask scene layers for solid faces");
if(scene) RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index a1a99c34e70..b3dbafeab7d 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -2795,12 +2795,6 @@ static void rna_def_userdef_input(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 32);
RNA_def_property_ui_text(prop, "Wheel Scroll Lines", "The number of lines scrolled at a time with the mouse wheel");
- /* U.keymaps - custom keymaps that have been edited from default configs */
- prop= RNA_def_property(srna, "edited_keymaps", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "keymaps", NULL);
- RNA_def_property_struct_type(prop, "KeyMap");
- RNA_def_property_ui_text(prop, "Edited Keymaps", "");
-
prop= RNA_def_property(srna, "active_keyconfig", PROP_STRING, PROP_DIRPATH);
RNA_def_property_string_sdna(prop, NULL, "keyconfigstr");
RNA_def_property_ui_text(prop, "Key Config", "The name of the active key configuration");
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index a046be59ab5..307cf0e175a 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -578,22 +578,6 @@ static EnumPropertyItem *rna_KeyMapItem_propvalue_itemf(bContext *C, PointerRNA
wmKeyConfig *kc;
wmKeyMap *km;
- /* check user keymaps */
- for(km=U.keymaps.first; km; km=km->next) {
- wmKeyMapItem *kmi;
- for (kmi=km->items.first; kmi; kmi=kmi->next) {
- if (kmi == 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) {
for(km=kc->keymaps.first; km; km=km->next) {
/* only check if it's a modal keymap */
@@ -654,12 +638,13 @@ static PointerRNA rna_WindowManager_active_keyconfig_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_KeyConfig, kc);
}
-static void rna_WindowManager_active_keyconfig_set(PointerRNA *UNUSED(ptr), PointerRNA value)
+static void rna_WindowManager_active_keyconfig_set(PointerRNA *ptr, PointerRNA value)
{
+ wmWindowManager *wm= ptr->data;
wmKeyConfig *kc= value.data;
if(kc)
- BLI_strncpy(U.keyconfigstr, kc->idname, sizeof(U.keyconfigstr));
+ WM_keyconfig_set_active(wm, kc->idname);
}
static void rna_wmKeyMapItem_idname_get(PointerRNA *ptr, char *value)
@@ -1130,93 +1115,6 @@ static StructRNA* rna_MacroOperator_refine(PointerRNA *opr)
return (op->type && op->type->ext.srna)? op->type->ext.srna: &RNA_Macro;
}
-static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier)
-{
-// wmWindowManager *wm = CTX_wm_manager(C);
- char idname_bl[OP_MAX_TYPENAME];
- int modifier= 0;
-
- /* only on non-modal maps */
- if (km->flag & KEYMAP_MODAL) {
- BKE_report(reports, RPT_ERROR, "Not a non-modal keymap.");
- return NULL;
- }
-
- WM_operator_bl_idname(idname_bl, idname);
-
- if(shift) modifier |= KM_SHIFT;
- if(ctrl) modifier |= KM_CTRL;
- if(alt) modifier |= KM_ALT;
- if(oskey) modifier |= KM_OSKEY;
-
- if(any) modifier = KM_ANY;
-
- return WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier);
-}
-
-static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, bContext *C, ReportList *reports, const char *propvalue_str, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier)
-{
- wmWindowManager *wm = CTX_wm_manager(C);
- int modifier= 0;
- int propvalue = 0;
-
- /* only modal maps */
- if ((km->flag & KEYMAP_MODAL) == 0) {
- BKE_report(reports, RPT_ERROR, "Not a modal keymap.");
- return NULL;
- }
-
- if (!km->modal_items) {
- if(!WM_keymap_user_init(wm, km)) {
- BKE_report(reports, RPT_ERROR, "User defined keymap doesn't correspond to a system keymap.");
- 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;
- if(oskey) modifier |= KM_OSKEY;
-
- if(any) modifier = KM_ANY;
-
- return WM_modalkeymap_add_item(km, type, value, modifier, keymodifier, propvalue);
-}
-
-static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, int modal)
-{
- if (modal == 0) {
- return WM_keymap_find(keyconf, idname, spaceid, regionid);
- } else {
- return WM_modalkeymap_add(keyconf, idname, NULL); /* items will be lazy init */
- }
-}
-
-static wmKeyMap *rna_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
-{
- return WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
-}
-
-static wmKeyMap *rna_keymap_find_modal(wmKeyConfig *UNUSED(keyconf), const char *idname)
-{
- wmOperatorType *ot = WM_operatortype_find(idname, 0);
-
- if (!ot)
- return NULL;
- else
- return ot->modalkeymap;
-}
-
/* just to work around 'const char *' warning and to ensure this is a python op */
static void rna_Operator_bl_idname_set(PointerRNA *ptr, const char *value)
{
@@ -1242,6 +1140,12 @@ static void rna_Operator_bl_description_set(PointerRNA *ptr, const char *value)
else assert(!"setting the bl_description on a non-builtin operator");
}
+static void rna_KeyMapItem_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ wmKeyMapItem *kmi= ptr->data;
+ WM_keyconfig_update_tag(NULL, kmi);
+}
+
#else /* RNA_RUNTIME */
static void rna_def_operator(BlenderRNA *brna)
@@ -1566,9 +1470,6 @@ static void rna_def_wm_keyconfigs(BlenderRNA *brna, PropertyRNA *cprop)
StructRNA *srna;
PropertyRNA *prop;
- FunctionRNA *func;
- PropertyRNA *parm;
-
RNA_def_property_srna(cprop, "KeyConfigurations");
srna= RNA_def_struct(brna, "KeyConfigurations", NULL);
RNA_def_struct_sdna(srna, "wmWindowManager");
@@ -1578,23 +1479,24 @@ static void rna_def_wm_keyconfigs(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_property_struct_type(prop, "KeyConfig");
RNA_def_property_pointer_funcs(prop, "rna_WindowManager_active_keyconfig_get", "rna_WindowManager_active_keyconfig_set", NULL, NULL);
RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Active KeyConfig", "Active wm KeyConfig");
+ RNA_def_property_ui_text(prop, "Active KeyConfig", "Active key configuration (preset)");
prop= RNA_def_property(srna, "default", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "defaultconf");
RNA_def_property_struct_type(prop, "KeyConfig");
- RNA_def_property_ui_text(prop, "Default Key Configuration", "");
+ RNA_def_property_ui_text(prop, "Default Key Configuration", "Default builtin key configuration");
+
+ prop= RNA_def_property(srna, "addon", PROP_POINTER, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "addonconf");
+ RNA_def_property_struct_type(prop, "KeyConfig");
+ RNA_def_property_ui_text(prop, "Addon Key Configuration", "Key configuration that can be extended by addons, and is added to the active configuration when handling events");
+
+ prop= RNA_def_property(srna, "user", PROP_POINTER, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "userconf");
+ RNA_def_property_struct_type(prop, "KeyConfig");
+ RNA_def_property_ui_text(prop, "User Key Configuration", "Final key configuration that combines keymaps from the active and addon configurations, and can be edited by the user");
- /* funcs */
- func= RNA_def_function(srna, "new", "WM_keyconfig_new_user"); // add_keyconfig
- parm= RNA_def_string(func, "name", "", 0, "Name", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Added key configuration.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "remove", "WM_keyconfig_remove"); // remove_keyconfig
- parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Removed key configuration.");
- RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_api_keyconfigs(srna);
}
static void rna_def_windowmanager(BlenderRNA *brna)
@@ -1631,107 +1533,30 @@ static void rna_def_windowmanager(BlenderRNA *brna)
static void rna_def_keymap_items(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
-// PropertyRNA *prop;
-
- FunctionRNA *func;
- PropertyRNA *parm;
RNA_def_property_srna(cprop, "KeyMapItems");
srna= RNA_def_struct(brna, "KeyMapItems", NULL);
RNA_def_struct_sdna(srna, "wmKeyMap");
RNA_def_struct_ui_text(srna, "KeyMap Items", "Collection of keymap items");
- func= RNA_def_function(srna, "new", "rna_KeyMap_item_new");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
- parm= RNA_def_string(func, "idname", "", 0, "Operator Identifier", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_boolean(func, "any", 0, "Any", "");
- RNA_def_boolean(func, "shift", 0, "Shift", "");
- RNA_def_boolean(func, "ctrl", 0, "Ctrl", "");
- RNA_def_boolean(func, "alt", 0, "Alt", "");
- RNA_def_boolean(func, "oskey", 0, "OS Key", "");
- RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", "");
- parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "new_modal", "rna_KeyMap_item_new_modal");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT|FUNC_USE_REPORTS);
- parm= RNA_def_string(func, "propvalue", "", 0, "Property Value", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_boolean(func, "any", 0, "Any", "");
- RNA_def_boolean(func, "shift", 0, "Shift", "");
- RNA_def_boolean(func, "ctrl", 0, "Ctrl", "");
- RNA_def_boolean(func, "alt", 0, "Alt", "");
- RNA_def_boolean(func, "oskey", 0, "OS Key", "");
- RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", "");
- parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "remove", "WM_keymap_remove_item");
- parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
-
- func= RNA_def_function(srna, "from_id", "WM_keymap_item_find_id");
- parm= RNA_def_property(func, "id", PROP_INT, PROP_NONE);
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_property_ui_text(parm, "id", "ID of the item");
- parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
- RNA_def_function_return(func, parm);
-
+ RNA_api_keymapitems(srna);
}
static void rna_def_wm_keymaps(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
- //PropertyRNA *prop;
-
- FunctionRNA *func;
- PropertyRNA *parm;
-
RNA_def_property_srna(cprop, "KeyMaps");
srna= RNA_def_struct(brna, "KeyMaps", NULL);
RNA_def_struct_sdna(srna, "wmKeyConfig");
RNA_def_struct_ui_text(srna, "Key Maps", "Collection of keymaps");
- func= RNA_def_function(srna, "new", "rna_keymap_new"); // add_keymap
- parm= RNA_def_string(func, "name", "", 0, "Name", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", "");
- RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
- RNA_def_boolean(func, "modal", 0, "Modal", "");
- parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Added key map.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "find", "rna_keymap_find"); // find_keymap
- parm= RNA_def_string(func, "name", "", 0, "Name", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", "");
- RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
- parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map.");
- RNA_def_function_return(func, parm);
-
- func= RNA_def_function(srna, "find_modal", "rna_keymap_find_modal"); // find_keymap_modal
- parm= RNA_def_string(func, "name", "", 0, "Operator Name", "");
- RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map.");
- RNA_def_function_return(func, parm);
-
+ RNA_api_keymaps(srna);
}
static void rna_def_keyconfig(BlenderRNA *brna)
{
StructRNA *srna;
- // FunctionRNA *func;
- // PropertyRNA *parm;
PropertyRNA *prop;
static EnumPropertyItem map_type_items[] = {
@@ -1794,8 +1619,8 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Items", "Items in the keymap, linking an operator to an input event");
rna_def_keymap_items(brna, prop);
- prop= RNA_def_property(srna, "is_user_defined", PROP_BOOLEAN, PROP_NEVER_NULL);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_USER);
+ prop= RNA_def_property(srna, "is_user_modified", PROP_BOOLEAN, PROP_NEVER_NULL);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYMAP_USER_MODIFIED);
RNA_def_property_ui_text(prop, "User Defined", "Keymap is defined by the user");
prop= RNA_def_property(srna, "is_modal", PROP_BOOLEAN, PROP_NONE);
@@ -1826,6 +1651,7 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Identifier", "Identifier of operator to call on input event");
RNA_def_property_string_funcs(prop, "rna_wmKeyMapItem_idname_get", "rna_wmKeyMapItem_idname_length", "rna_wmKeyMapItem_idname_set");
RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1836,62 +1662,73 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "OperatorProperties");
RNA_def_property_pointer_funcs(prop, "rna_KeyMapItem_properties_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Properties", "Properties to set when the operator is called");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "map_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "maptype");
RNA_def_property_enum_items(prop, map_type_items);
RNA_def_property_enum_funcs(prop, "rna_wmKeyMapItem_map_type_get", "rna_wmKeyMapItem_map_type_set", NULL);
RNA_def_property_ui_text(prop, "Map Type", "Type of event mapping");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, event_type_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_type_itemf");
RNA_def_property_ui_text(prop, "Type", "Type of event");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "value", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "val");
RNA_def_property_enum_items(prop, event_value_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_value_itemf");
RNA_def_property_ui_text(prop, "Value", "");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "id", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "id");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "id", "ID of the item");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
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");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
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");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
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");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
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");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
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");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "key_modifier", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "keymodifier");
RNA_def_property_enum_items(prop, event_type_items);
RNA_def_property_ui_text(prop, "Key Modifier", "Regular key pressed as a modifier");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", KMI_EXPANDED);
@@ -1903,15 +1740,21 @@ static void rna_def_keyconfig(BlenderRNA *brna)
RNA_def_property_enum_items(prop, keymap_propvalue_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_KeyMapItem_propvalue_itemf");
RNA_def_property_ui_text(prop, "Property Value", "The value this event translates to in a modal keymap");
+ RNA_def_property_update(prop, 0, "rna_KeyMapItem_update");
prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", KMI_INACTIVE);
RNA_def_property_ui_text(prop, "Active", "Activate or deactivate item");
RNA_def_property_ui_icon(prop, ICON_CHECKBOX_DEHLT, 1);
+ prop= RNA_def_property(srna, "is_user_modified", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", KMI_USER_MODIFIED);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "User Modified", "Is this keymap item modified by the user");
+
prop= RNA_def_property(srna, "is_user_defined", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "User Defined", "Is this keymap item user defined (doesn't just override a builtin item)");
+ RNA_def_property_ui_text(prop, "User Defined", "Is this keymap item user defined (doesn't just replace a builtin item)");
RNA_def_property_boolean_funcs(prop, "rna_KeyMapItem_userdefined_get", NULL);
RNA_api_keymapitem(srna);
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index d44b68950f7..89e946f498a 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -84,6 +84,85 @@ void rna_event_timer_remove(struct wmWindowManager *wm, wmTimer *timer)
WM_event_remove_timer(wm, timer->win, timer);
}
+static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier)
+{
+// wmWindowManager *wm = CTX_wm_manager(C);
+ char idname_bl[OP_MAX_TYPENAME];
+ int modifier= 0;
+
+ /* only on non-modal maps */
+ if (km->flag & KEYMAP_MODAL) {
+ BKE_report(reports, RPT_ERROR, "Not a non-modal keymap.");
+ return NULL;
+ }
+
+ WM_operator_bl_idname(idname_bl, idname);
+
+ if(shift) modifier |= KM_SHIFT;
+ if(ctrl) modifier |= KM_CTRL;
+ if(alt) modifier |= KM_ALT;
+ if(oskey) modifier |= KM_OSKEY;
+
+ if(any) modifier = KM_ANY;
+
+ return WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier);
+}
+
+static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, ReportList *reports, const char *propvalue_str, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier)
+{
+ int modifier= 0;
+ int propvalue = 0;
+
+ /* only modal maps */
+ if ((km->flag & KEYMAP_MODAL) == 0) {
+ BKE_report(reports, RPT_ERROR, "Not a modal keymap.");
+ 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;
+ if(oskey) modifier |= KM_OSKEY;
+
+ if(any) modifier = KM_ANY;
+
+ return WM_modalkeymap_add_item(km, type, value, modifier, keymodifier, propvalue);
+}
+
+static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, int modal)
+{
+ if (modal == 0) {
+ return WM_keymap_find(keyconf, idname, spaceid, regionid);
+ } else {
+ return WM_modalkeymap_add(keyconf, idname, NULL); /* items will be lazy init */
+ }
+}
+
+static wmKeyMap *rna_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
+{
+ return WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
+}
+
+static wmKeyMap *rna_keymap_find_modal(wmKeyConfig *UNUSED(keyconf), const char *idname)
+{
+ wmOperatorType *ot = WM_operatortype_find(idname, 0);
+
+ if (!ot)
+ return NULL;
+ else
+ return ot->modalkeymap;
+}
+
#else
#define WM_GEN_INVOKE_EVENT (1<<0)
@@ -301,11 +380,8 @@ void RNA_api_keymap(StructRNA *srna)
parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Active key map.");
RNA_def_function_return(func, parm);
- func= RNA_def_function(srna, "copy_to_user", "WM_keymap_copy_to_user");
- parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "User editable key map.");
- RNA_def_function_return(func, parm);
-
- RNA_def_function(srna, "restore_to_default", "WM_keymap_restore_to_default");
+ func= RNA_def_function(srna, "restore_to_default", "WM_keymap_restore_to_default");
+ RNA_def_function_flag(func, FUNC_USE_CONTEXT);
func= RNA_def_function(srna, "restore_item_to_default", "rna_keymap_restore_item_to_default");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
@@ -324,5 +400,102 @@ void RNA_api_keymapitem(StructRNA *srna)
parm= RNA_def_boolean(func, "result", 0, "Comparison result", "");
RNA_def_function_return(func, parm);
}
+
+void RNA_api_keymapitems(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func= RNA_def_function(srna, "new", "rna_KeyMap_item_new");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm= RNA_def_string(func, "idname", "", 0, "Operator Identifier", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_boolean(func, "any", 0, "Any", "");
+ RNA_def_boolean(func, "shift", 0, "Shift", "");
+ RNA_def_boolean(func, "ctrl", 0, "Ctrl", "");
+ RNA_def_boolean(func, "alt", 0, "Alt", "");
+ RNA_def_boolean(func, "oskey", 0, "OS Key", "");
+ RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", "");
+ parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "new_modal", "rna_KeyMap_item_new_modal");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm= RNA_def_string(func, "propvalue", "", 0, "Property Value", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_enum(func, "type", event_type_items, 0, "Type", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_enum(func, "value", event_value_items, 0, "Value", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_boolean(func, "any", 0, "Any", "");
+ RNA_def_boolean(func, "shift", 0, "Shift", "");
+ RNA_def_boolean(func, "ctrl", 0, "Ctrl", "");
+ RNA_def_boolean(func, "alt", 0, "Alt", "");
+ RNA_def_boolean(func, "oskey", 0, "OS Key", "");
+ RNA_def_enum(func, "key_modifier", event_type_items, 0, "Key Modifier", "");
+ parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "remove", "WM_keymap_remove_item");
+ parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+
+ func= RNA_def_function(srna, "from_id", "WM_keymap_item_find_id");
+ parm= RNA_def_property(func, "id", PROP_INT, PROP_NONE);
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_property_ui_text(parm, "id", "ID of the item");
+ parm= RNA_def_pointer(func, "item", "KeyMapItem", "Item", "");
+ RNA_def_function_return(func, parm);
+}
+
+void RNA_api_keymaps(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func= RNA_def_function(srna, "new", "rna_keymap_new"); // add_keymap
+ parm= RNA_def_string(func, "name", "", 0, "Name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", "");
+ RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
+ RNA_def_boolean(func, "modal", 0, "Modal", "");
+ parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Added key map.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "find", "rna_keymap_find"); // find_keymap
+ parm= RNA_def_string(func, "name", "", 0, "Name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_enum(func, "space_type", space_type_items, SPACE_EMPTY, "Space Type", "");
+ RNA_def_enum(func, "region_type", region_type_items, RGN_TYPE_WINDOW, "Region Type", "");
+ parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "find_modal", "rna_keymap_find_modal"); // find_keymap_modal
+ parm= RNA_def_string(func, "name", "", 0, "Operator Name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "keymap", "KeyMap", "Key Map", "Corresponding key map.");
+ RNA_def_function_return(func, parm);
+}
+
+void RNA_api_keyconfigs(StructRNA *srna)
+{
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ func= RNA_def_function(srna, "new", "WM_keyconfig_new_user"); // add_keyconfig
+ parm= RNA_def_string(func, "name", "", 0, "Name", "");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+ parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Added key configuration.");
+ RNA_def_function_return(func, parm);
+
+ func= RNA_def_function(srna, "remove", "WM_keyconfig_remove"); // remove_keyconfig
+ parm= RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Removed key configuration.");
+ RNA_def_property_flag(parm, PROP_REQUIRED);
+}
+
#endif
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index e6325e2101a..42c3096dfc9 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -41,6 +41,7 @@
/* dna-savable wmStructs here */
#include "DNA_windowmanager_types.h"
+#include "WM_keymap.h"
#ifdef __cplusplus
extern "C" {
@@ -114,50 +115,9 @@ void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle);
void WM_cursor_warp (struct wmWindow *win, int x, int y);
- /* keyconfig and keymap */
-wmKeyConfig *WM_keyconfig_new (struct wmWindowManager *wm, const char *idname);
-wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, const char *idname);
-void WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf);
-void WM_keyconfig_free (struct wmKeyConfig *keyconf);
-void WM_keyconfig_userdef(void);
-
-void WM_keymap_init (struct bContext *C);
-void WM_keymap_free (struct wmKeyMap *keymap);
-
-wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, const char *idname, int type,
- int val, int modifier, int keymodifier);
-wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, int type,
- int val, int modifier, int keymodifier);
-wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type,
- int val, int modifier, int keymodifier);
-
-void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
-char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len);
-
-wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid);
-wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid);
-wmKeyMap *WM_keymap_find_all(const struct bContext *C, const char *idname, int spaceid, int regionid);
-wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap);
-wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname);
-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);
-void WM_keymap_properties_reset(struct wmKeyMapItem *kmi, struct IDProperty *properties);
-void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
-
-wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id);
-int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2);
+ /* event map */
int WM_userdef_event_map(int kmitype);
-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);
-void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname);
-
-const char *WM_key_event_string(short type);
-int WM_key_event_operator_id(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, int hotkey, struct wmKeyMap **keymap_r);
-char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len);
-
/* handlers */
struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap);
diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h
new file mode 100644
index 00000000000..e00cd288c9a
--- /dev/null
+++ b/source/blender/windowmanager/WM_keymap.h
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef WM_KEYMAP_H
+#define WM_KEYMAP_H
+
+/** \file WM_keymap.h
+ * \ingroup wm
+ */
+
+/* dna-savable wmStructs here */
+#include "DNA_windowmanager_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct EnumPropertyItem;
+
+/* Key Configuration */
+
+wmKeyConfig *WM_keyconfig_new (struct wmWindowManager *wm, const char *idname);
+wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, const char *idname);
+void WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf);
+void WM_keyconfig_free (struct wmKeyConfig *keyconf);
+
+void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname);
+
+void WM_keyconfig_update(struct wmWindowManager *wm);
+void WM_keyconfig_update_tag(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
+
+/* Keymap */
+
+void WM_keymap_init (struct bContext *C);
+void WM_keymap_free (struct wmKeyMap *keymap);
+
+wmKeyMapItem *WM_keymap_verify_item(struct wmKeyMap *keymap, const char *idname, int type,
+ int val, int modifier, int keymodifier);
+wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, int type,
+ int val, int modifier, int keymodifier);
+wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type,
+ int val, int modifier, int keymodifier);
+
+void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
+char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len);
+
+wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid);
+wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid);
+wmKeyMap *WM_keymap_find_all(const struct bContext *C, const char *idname, int spaceid, int regionid);
+wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap);
+wmKeyMap *WM_keymap_guess_opname(const struct bContext *C, const char *opname);
+
+wmKeyMapItem *WM_keymap_item_find_id(struct wmKeyMap *keymap, int id);
+int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2);
+
+/* Modal Keymap */
+
+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);
+void WM_modalkeymap_assign(struct wmKeyMap *km, const char *opname);
+
+/* Keymap Editor */
+
+void WM_keymap_restore_to_default(struct wmKeyMap *keymap, struct bContext *C);
+void WM_keymap_properties_reset(struct wmKeyMapItem *kmi, struct IDProperty *properties);
+void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
+
+/* Key Event */
+
+const char *WM_key_event_string(short type);
+int WM_key_event_operator_id(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, int hotkey, struct wmKeyMap **keymap_r);
+char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, char *str, int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WM_KEYMAP_H */
+
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index a535c0bc1f8..1d5cf1cdc53 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -210,12 +210,18 @@ void WM_keymap_init(bContext *C)
if(!wm->defaultconf)
wm->defaultconf= WM_keyconfig_new(wm, "Blender");
+ if(!wm->addonconf)
+ wm->addonconf= WM_keyconfig_new(wm, "Blender Addon");
+ if(!wm->userconf)
+ wm->userconf= WM_keyconfig_new(wm, "Blender User");
- if(wm && CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) {
+ if(CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) {
/* create default key config */
wm_window_keymap(wm->defaultconf);
ED_spacetypes_keymap(wm->defaultconf);
- WM_keyconfig_userdef();
+
+ WM_keyconfig_update_tag(NULL, NULL);
+ WM_keyconfig_update(wm);
wm->initialized |= WM_INIT_KEYMAP;
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 2f0c1a72be9..0dac0bd7401 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1735,6 +1735,9 @@ void wm_event_do_handlers(bContext *C)
wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *win;
+ /* update key configuration before handling events */
+ WM_keyconfig_update(wm);
+
for(win= wm->windows.first; win; win= win->next) {
wmEvent *event;
@@ -1938,6 +1941,9 @@ void wm_event_do_handlers(bContext *C)
CTX_wm_window_set(C, NULL);
}
+
+ /* update key configuration after handling events */
+ WM_keyconfig_update(wm);
}
/* ********** filesector handling ************ */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 27fc0caeccc..20f9d2237c2 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -224,6 +224,14 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
oldwm= oldwmlist->first;
wm= G.main->wm.first;
+ /* move addon key configuration to new wm, to preserve their keymaps */
+ if(oldwm->addonconf) {
+ wm->addonconf= oldwm->addonconf;
+ BLI_remlink(&oldwm->keyconfigs, oldwm->addonconf);
+ oldwm->addonconf= NULL;
+ BLI_addtail(&wm->keyconfigs, wm->addonconf);
+ }
+
/* ensure making new keymaps and set space types */
wm->initialized= 0;
wm->winactive= NULL;
@@ -794,11 +802,14 @@ int WM_write_homefile(bContext *C, wmOperator *op)
wmWindow *win= CTX_wm_window(C);
char filepath[FILE_MAXDIR+FILE_MAXFILE];
int fileflags;
-
+
/* check current window and close it if temp */
if(win->screen->temp)
wm_window_close(C, wm, win);
+ /* update keymaps in user preferences */
+ WM_keyconfig_update(wm);
+
BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE);
printf("trying to save homefile at %s ", filepath);
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 1720c738dd7..bf48f0e21e4 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -61,14 +61,67 @@
#include "wm_event_system.h"
#include "wm_event_types.h"
-/* ********************* key config ***********************/
+/******************************* Keymap Item **********************************
+ * Item in a keymap, that maps from an event to an operator or modal map item */
-static void keymap_properties_set(wmKeyMapItem *kmi)
+static wmKeyMapItem *wm_keymap_item_copy(wmKeyMapItem *kmi)
+{
+ wmKeyMapItem *kmin = MEM_dupallocN(kmi);
+
+ kmin->prev= kmin->next= NULL;
+ kmin->flag &= ~KMI_UPDATE;
+
+ if(kmin->properties) {
+ kmin->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr");
+ WM_operator_properties_create(kmin->ptr, kmin->idname);
+
+ kmin->properties= IDP_CopyProperty(kmin->properties);
+ kmin->ptr->data= kmin->properties;
+ }
+
+ return kmin;
+}
+
+static void wm_keymap_item_free(wmKeyMapItem *kmi)
+{
+ /* not kmi itself */
+ if(kmi->ptr) {
+ WM_operator_properties_free(kmi->ptr);
+ MEM_freeN(kmi->ptr);
+ }
+}
+
+static void wm_keymap_item_properties_set(wmKeyMapItem *kmi)
{
WM_operator_properties_alloc(&(kmi->ptr), &(kmi->properties), kmi->idname);
WM_operator_properties_sanitize(kmi->ptr, 1);
}
+static int wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b)
+{
+ if(strcmp(a->idname, b->idname) != 0)
+ return 0;
+
+ if(!((a->ptr==NULL && b->ptr==NULL) ||
+ (a->ptr && b->ptr && IDP_EqualsProperties(a->ptr->data, b->ptr->data))))
+ return 0;
+
+ return (a->propvalue == b->propvalue);
+}
+
+static int wm_keymap_item_equals(wmKeyMapItem *a, wmKeyMapItem *b)
+{
+ return (wm_keymap_item_equals_result(a, b) &&
+ a->type == b->type &&
+ a->val == b->val &&
+ a->shift == b->shift &&
+ a->ctrl == b->ctrl &&
+ a->alt == b->alt &&
+ a->oskey == b->oskey &&
+ a->keymodifier == b->keymodifier &&
+ a->maptype == b->maptype);
+}
+
/* properties can be NULL, otherwise the arg passed is used and ownership is given to the kmi */
void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties)
{
@@ -78,9 +131,41 @@ void WM_keymap_properties_reset(wmKeyMapItem *kmi, struct IDProperty *properties
kmi->ptr = NULL;
kmi->properties = properties;
- keymap_properties_set(kmi);
+ wm_keymap_item_properties_set(kmi);
+}
+
+/**************************** Keymap Diff Item *********************************
+ * Item in a diff keymap, used for saving diff of keymaps in user preferences */
+
+static wmKeyMapDiffItem *wm_keymap_diff_item_copy(wmKeyMapDiffItem *kmdi)
+{
+ wmKeyMapDiffItem *kmdin = MEM_dupallocN(kmdi);
+
+ kmdin->next = kmdin->prev = NULL;
+ if(kmdi->add_item)
+ kmdin->add_item = wm_keymap_item_copy(kmdi->add_item);
+ if(kmdi->remove_item)
+ kmdin->remove_item = wm_keymap_item_copy(kmdi->remove_item);
+
+ return kmdin;
+}
+
+static void wm_keymap_diff_item_free(wmKeyMapDiffItem *kmdi)
+{
+ if(kmdi->remove_item) {
+ wm_keymap_item_free(kmdi->remove_item);
+ MEM_freeN(kmdi->remove_item);
+ }
+ if(kmdi->add_item) {
+ wm_keymap_item_free(kmdi->add_item);
+ MEM_freeN(kmdi->add_item);
+ }
}
+/***************************** Key Configuration ******************************
+ * List of keymaps for all editors, modes, ... . There is a builtin default key
+ * configuration, a user key configuration, and other preset configurations. */
+
wmKeyConfig *WM_keyconfig_new(wmWindowManager *wm, const char *idname)
{
wmKeyConfig *keyconf;
@@ -106,6 +191,7 @@ void WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
if (keyconf) {
if (strncmp(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr)) == 0) {
BLI_strncpy(U.keyconfigstr, wm->defaultconf->idname, sizeof(U.keyconfigstr));
+ WM_keyconfig_update_tag(NULL, NULL);
}
BLI_remlink(&wm->keyconfigs, keyconf);
@@ -125,21 +211,6 @@ void WM_keyconfig_free(wmKeyConfig *keyconf)
MEM_freeN(keyconf);
}
-void WM_keyconfig_userdef(void)
-{
- wmKeyMap *km;
- wmKeyMapItem *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)
{
wmKeyConfig *kc;
@@ -151,23 +222,84 @@ static wmKeyConfig *wm_keyconfig_list_find(ListBase *lb, char *idname)
return NULL;
}
-/* ************************ free ************************* */
+wmKeyConfig *WM_keyconfig_active(wmWindowManager *wm)
+{
+ wmKeyConfig *keyconf;
-void WM_keymap_free(wmKeyMap *keymap)
+ /* first try from preset */
+ keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr);
+ if(keyconf)
+ return keyconf;
+
+ /* otherwise use default */
+ return wm->defaultconf;
+}
+
+void WM_keyconfig_set_active(wmWindowManager *wm, const char *idname)
{
- wmKeyMapItem *kmi;
+ /* setting a different key configuration as active: we ensure all is
+ updated properly before and after making the change */
+
+ WM_keyconfig_update(wm);
+
+ BLI_strncpy(U.keyconfigstr, idname, sizeof(U.keyconfigstr));
+
+ WM_keyconfig_update_tag(NULL, NULL);
+ WM_keyconfig_update(wm);
+}
+
+/********************************** Keymap *************************************
+ * List of keymap items for one editor, mode, modal operator, ... */
+
+static wmKeyMap *wm_keymap_new(const char *idname, int spaceid, int regionid)
+{
+ wmKeyMap *km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list");
+
+ BLI_strncpy(km->idname, idname, KMAP_MAX_NAME);
+ km->spaceid= spaceid;
+ km->regionid= regionid;
+
+ return km;
+}
+
+static wmKeyMap *wm_keymap_copy(wmKeyMap *keymap)
+{
+ wmKeyMap *keymapn = MEM_dupallocN(keymap);
+ wmKeyMapItem *kmi, *kmin;
+ wmKeyMapDiffItem *kmdi, *kmdin;
+
+ keymapn->modal_items= keymap->modal_items;
+ keymapn->poll= keymap->poll;
+ keymapn->items.first= keymapn->items.last= NULL;
+ keymapn->flag &= ~(KEYMAP_UPDATE|KEYMAP_EXPANDED);
+
+ for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next) {
+ kmdin= wm_keymap_diff_item_copy(kmdi);
+ BLI_addtail(&keymapn->items, kmdin);
+ }
for(kmi=keymap->items.first; kmi; kmi=kmi->next) {
- if(kmi->ptr) {
- WM_operator_properties_free(kmi->ptr);
- MEM_freeN(kmi->ptr);
- }
+ kmin= wm_keymap_item_copy(kmi);
+ BLI_addtail(&keymapn->items, kmin);
}
- BLI_freelistN(&keymap->items);
+ return keymapn;
}
-/* ***************** generic call, exported **************** */
+void WM_keymap_free(wmKeyMap *keymap)
+{
+ wmKeyMapItem *kmi;
+ wmKeyMapDiffItem *kmdi;
+
+ for(kmdi=keymap->diff_items.first; kmdi; kmdi=kmdi->next)
+ wm_keymap_diff_item_free(kmdi);
+
+ for(kmi=keymap->items.first; kmi; kmi=kmi->next)
+ wm_keymap_item_free(kmi);
+
+ BLI_freelistN(&keymap->diff_items);
+ BLI_freelistN(&keymap->items);
+}
static void keymap_event_set(wmKeyMapItem *kmi, short type, short val, int modifier, short keymodifier)
{
@@ -229,7 +361,7 @@ wmKeyMapItem *WM_keymap_verify_item(wmKeyMap *keymap, const char *idname, int ty
keymap_item_set_id(keymap, kmi);
keymap_event_set(kmi, type, val, modifier, keymodifier);
- keymap_properties_set(kmi);
+ wm_keymap_item_properties_set(kmi);
}
return kmi;
}
@@ -243,10 +375,12 @@ wmKeyMapItem *WM_keymap_add_item(wmKeyMap *keymap, const char *idname, int type,
BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME);
keymap_event_set(kmi, type, val, modifier, keymodifier);
- keymap_properties_set(kmi);
+ wm_keymap_item_properties_set(kmi);
keymap_item_set_id(keymap, kmi);
+ WM_keyconfig_update_tag(keymap, kmi);
+
return kmi;
}
@@ -266,6 +400,232 @@ void WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
MEM_freeN(kmi->ptr);
}
BLI_freelinkN(&keymap->items, kmi);
+
+ WM_keyconfig_update_tag(keymap, kmi);
+ }
+}
+
+/************************** Keymap Diff and Patch ****************************
+ * Rather than saving the entire keymap for user preferences, we only save a
+ * diff so that changes in the defaults get synced. This system is not perfect
+ * but works better than overriding the keymap entirely when only few items
+ * are changed. */
+
+static void wm_keymap_addon_add(wmKeyMap *keymap, wmKeyMap *addonmap)
+{
+ wmKeyMapItem *kmi, *kmin;
+
+ for(kmi=addonmap->items.first; kmi; kmi=kmi->next) {
+ kmin = wm_keymap_item_copy(kmi);
+ keymap_item_set_id(keymap, kmin);
+ BLI_addhead(&keymap->items, kmin);
+ }
+}
+
+static wmKeyMapItem *wm_keymap_find_item_equals(wmKeyMap *km, wmKeyMapItem *needle)
+{
+ wmKeyMapItem *kmi;
+
+ for(kmi=km->items.first; kmi; kmi=kmi->next)
+ if(wm_keymap_item_equals(kmi, needle))
+ return kmi;
+
+ return NULL;
+}
+
+static wmKeyMapItem *wm_keymap_find_item_equals_result(wmKeyMap *km, wmKeyMapItem *needle)
+{
+ wmKeyMapItem *kmi;
+
+ for(kmi=km->items.first; kmi; kmi=kmi->next)
+ if(wm_keymap_item_equals_result(kmi, needle))
+ return kmi;
+
+ return NULL;
+}
+
+static void wm_keymap_diff(wmKeyMap *diff_km, wmKeyMap *from_km, wmKeyMap *to_km, wmKeyMap *orig_km, wmKeyMap *addon_km)
+{
+ wmKeyMapItem *kmi, *to_kmi, *orig_kmi;
+ wmKeyMapDiffItem *kmdi;
+
+ for(kmi=from_km->items.first; kmi; kmi=kmi->next) {
+ to_kmi = WM_keymap_item_find_id(to_km, kmi->id);
+
+ if(!to_kmi) {
+ /* remove item */
+ kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
+ kmdi->remove_item = wm_keymap_item_copy(kmi);
+ BLI_addtail(&diff_km->diff_items, kmdi);
+ }
+ else if(to_kmi && !wm_keymap_item_equals(kmi, to_kmi)) {
+ /* replace item */
+ kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
+ kmdi->remove_item = wm_keymap_item_copy(kmi);
+ kmdi->add_item = wm_keymap_item_copy(to_kmi);
+ BLI_addtail(&diff_km->diff_items, kmdi);
+ }
+
+ /* sync expanded flag back to original so we don't loose it on repatch */
+ if(to_kmi) {
+ orig_kmi = WM_keymap_item_find_id(orig_km, kmi->id);
+
+ if(!orig_kmi)
+ orig_kmi = wm_keymap_find_item_equals(addon_km, kmi);
+
+ if(orig_kmi) {
+ orig_kmi->flag &= ~KMI_EXPANDED;
+ orig_kmi->flag |= (to_kmi->flag & KMI_EXPANDED);
+ }
+ }
+ }
+
+ for(kmi=to_km->items.first; kmi; kmi=kmi->next) {
+ if(kmi->id < 0) {
+ /* add item */
+ kmdi = MEM_callocN(sizeof(wmKeyMapDiffItem), "wmKeyMapDiffItem");
+ kmdi->add_item = wm_keymap_item_copy(kmi);
+ BLI_addtail(&diff_km->diff_items, kmdi);
+ }
+ }
+}
+
+static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km)
+{
+ wmKeyMapDiffItem *kmdi;
+ wmKeyMapItem *kmi_remove, *kmi_add;
+
+ for(kmdi=diff_km->diff_items.first; kmdi; kmdi=kmdi->next) {
+ /* find item to remove */
+ kmi_remove = NULL;
+ if(kmdi->remove_item) {
+ kmi_remove = wm_keymap_find_item_equals(km, kmdi->remove_item);
+ if(!kmi_remove)
+ kmi_remove = wm_keymap_find_item_equals_result(km, kmdi->remove_item);
+ }
+
+ /* add item */
+ if(kmdi->add_item) {
+ /* only if nothing to remove or item to remove found */
+ if(!kmdi->remove_item || kmi_remove) {
+ kmi_add = wm_keymap_item_copy(kmdi->add_item);
+ kmi_add->flag |= KMI_USER_MODIFIED;
+
+ if(kmi_remove) {
+ kmi_add->flag &= ~KMI_EXPANDED;
+ kmi_add->flag |= (kmi_remove->flag & KMI_EXPANDED);
+ kmi_add->id = kmi_remove->id;
+ BLI_insertlinkbefore(&km->items, kmi_remove, kmi_add);
+ }
+ else {
+ keymap_item_set_id(km, kmi_add);
+ BLI_addtail(&km->items, kmi_add);
+ }
+ }
+ }
+
+ /* remove item */
+ if(kmi_remove) {
+ wm_keymap_item_free(kmi_remove);
+ BLI_freelinkN(&km->items, kmi_remove);
+ }
+ }
+}
+
+static void wm_keymap_patch_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *usermap)
+{
+ wmKeyMap *km;
+ int expanded = 0;
+
+ /* remove previous keymap in list, we will replace it */
+ km = WM_keymap_list_find(lb, defaultmap->idname, defaultmap->spaceid, defaultmap->regionid);
+ if(km) {
+ expanded = (km->flag & (KEYMAP_EXPANDED|KEYMAP_CHILDREN_EXPANDED));
+ WM_keymap_free(km);
+ BLI_freelinkN(lb, km);
+ }
+
+ /* copy new keymap from an existing one */
+ if(usermap && !(usermap->flag & KEYMAP_DIFF)) {
+ /* for compatibiltiy with old user preferences with non-diff
+ keymaps we override the original entirely */
+ wmKeyMapItem *kmi, *orig_kmi;
+
+ km = wm_keymap_copy(usermap);
+ km->modal_items = defaultmap->modal_items;
+ km->poll = defaultmap->poll;
+
+ /* try to find corresponding id's for items */
+ for(kmi=km->items.first; kmi; kmi=kmi->next) {
+ orig_kmi = wm_keymap_find_item_equals(defaultmap, kmi);
+ if(!orig_kmi)
+ orig_kmi = wm_keymap_find_item_equals_result(defaultmap, kmi);
+
+ if(orig_kmi)
+ kmi->id = orig_kmi->id;
+ else
+ kmi->id = -(km->kmi_id++);
+ }
+
+ km->flag |= KEYMAP_UPDATE; /* update again to create diff */
+ }
+ else
+ km = wm_keymap_copy(defaultmap);
+
+ /* add addon keymap items */
+ if(addonmap)
+ wm_keymap_addon_add(km, addonmap);
+
+ /* tag as being user edited */
+ if(usermap)
+ km->flag |= KEYMAP_USER_MODIFIED;
+ km->flag |= KEYMAP_USER|expanded;
+
+ /* apply user changes of diff keymap */
+ if(usermap && (usermap->flag & KEYMAP_DIFF))
+ wm_keymap_patch(km, usermap);
+
+ /* add to list */
+ BLI_addtail(lb, km);
+}
+
+static void wm_keymap_diff_update(ListBase *lb, wmKeyMap *defaultmap, wmKeyMap *addonmap, wmKeyMap *km)
+{
+ wmKeyMap *diffmap, *prevmap, *origmap;
+
+ /* create temporary default + addon keymap for diff */
+ origmap = defaultmap;
+
+ if(addonmap) {
+ defaultmap = wm_keymap_copy(defaultmap);
+ wm_keymap_addon_add(defaultmap, addonmap);
+ }
+
+ /* remove previous diff keymap in list, we will replace it */
+ prevmap = WM_keymap_list_find(lb, km->idname, km->spaceid, km->regionid);
+ if(prevmap) {
+ WM_keymap_free(prevmap);
+ BLI_freelinkN(lb, prevmap);
+ }
+
+ /* create diff keymap */
+ diffmap= wm_keymap_new(km->idname, km->spaceid, km->regionid);
+ diffmap->flag |= KEYMAP_DIFF;
+ wm_keymap_diff(diffmap, defaultmap, km, origmap, addonmap);
+
+ /* add to list if not empty */
+ if(diffmap->diff_items.first) {
+ BLI_addtail(lb, diffmap);
+ }
+ else {
+ WM_keymap_free(diffmap);
+ MEM_freeN(diffmap);
+ }
+
+ /* free temporary default map */
+ if(addonmap) {
+ WM_keymap_free(defaultmap);
+ MEM_freeN(defaultmap);
}
}
@@ -292,11 +652,10 @@ wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid,
wmKeyMap *km= WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
if(km==NULL) {
- km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list");
- BLI_strncpy(km->idname, idname, KMAP_MAX_NAME);
- km->spaceid= spaceid;
- km->regionid= regionid;
+ km= wm_keymap_new(idname, spaceid, regionid);
BLI_addtail(&keyconf->keymaps, km);
+
+ WM_keyconfig_update_tag(km, NULL);
}
return km;
@@ -304,29 +663,9 @@ wmKeyMap *WM_keymap_find(wmKeyConfig *keyconf, const char *idname, int spaceid,
wmKeyMap *WM_keymap_find_all(const bContext *C, const char *idname, int spaceid, int regionid)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- wmKeyConfig *keyconf;
- wmKeyMap *km;
-
- /* first user defined keymaps */
- km= WM_keymap_list_find(&U.keymaps, idname, spaceid, regionid);
- if (km)
- return km;
-
- /* then user key config */
- keyconf= wm_keyconfig_list_find(&wm->keyconfigs, U.keyconfigstr);
- if(keyconf) {
- km= WM_keymap_list_find(&keyconf->keymaps, idname, spaceid, regionid);
- if (km)
- return km;
- }
-
- /* then use default */
- km= WM_keymap_list_find(&wm->defaultconf->keymaps, idname, spaceid, regionid);
- if (km)
- return km;
- else
- return NULL;
+ wmWindowManager *wm= CTX_wm_manager(C);
+
+ return WM_keymap_list_find(&wm->userconf->keymaps, idname, spaceid, regionid);
}
/* ****************** modal keymaps ************ */
@@ -366,6 +705,8 @@ wmKeyMapItem *WM_modalkeymap_add_item(wmKeyMap *km, int type, int val, int modif
keymap_item_set_id(km, kmi);
+ WM_keyconfig_update_tag(km, kmi);
+
return kmi;
}
@@ -588,169 +929,209 @@ int WM_keymap_item_compare(wmKeyMapItem *k1, wmKeyMapItem *k2)
return 1;
}
-/* ***************** user preferences ******************* */
+/************************* Update Final Configuration *************************
+ * On load or other changes, the final user key configuration is rebuilt from
+ * the preset, addon and user preferences keymaps. We also test if the final
+ * configuration changed and write the changes to the user preferences. */
+
+static int WM_KEYMAP_UPDATE = 0;
-int WM_keymap_user_init(wmWindowManager *wm, wmKeyMap *keymap)
+void WM_keyconfig_update_tag(wmKeyMap *km, wmKeyMapItem *kmi)
{
- wmKeyConfig *keyconf;
- wmKeyMap *km;
+ /* quick tag to do delayed keymap updates */
+ WM_KEYMAP_UPDATE= 1;
- if(!keymap)
- return 0;
+ if(km)
+ km->flag |= KEYMAP_UPDATE;
+ if(kmi)
+ kmi->flag |= KMI_UPDATE;
+}
- /* 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;
- }
- }
+static int wm_keymap_test_and_clear_update(wmKeyMap *km)
+{
+ wmKeyMapItem *kmi;
+ int update;
+
+ update= (km->flag & KEYMAP_UPDATE);
+ km->flag &= ~KEYMAP_UPDATE;
- /* 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;
+ for(kmi=km->items.first; kmi; kmi=kmi->next) {
+ update= update || (kmi->flag & KMI_UPDATE);
+ kmi->flag &= ~KMI_UPDATE;
}
-
- return 0;
+
+ return update;
}
-wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap)
+static wmKeyMap *wm_keymap_preset(wmWindowManager *wm, wmKeyMap *km)
{
- wmKeyConfig *keyconf;
- wmKeyMap *km;
+ wmKeyConfig *keyconf= WM_keyconfig_active(wm);
+ wmKeyMap *keymap;
+ keymap= WM_keymap_list_find(&keyconf->keymaps, km->idname, km->spaceid, km->regionid);
if(!keymap)
- return NULL;
-
- /* first user defined keymaps */
- 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;
- }
-
- /* then 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) {
- km->poll= keymap->poll; /* lazy init */
- km->modal_items= keymap->modal_items;
- return km;
- }
- }
+ keymap= WM_keymap_list_find(&wm->defaultconf->keymaps, km->idname, km->spaceid, km->regionid);
- /* then use default */
- km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
- return km;
+ return keymap;
}
-wmKeyMap *WM_keymap_copy_to_user(wmKeyMap *keymap)
+void WM_keyconfig_update(wmWindowManager *wm)
{
- wmKeyMap *usermap;
+ wmKeyMap *km, *defaultmap, *addonmap, *usermap;
wmKeyMapItem *kmi;
+ wmKeyMapDiffItem *kmdi;
+ int compat_update = 0;
- usermap= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
-
- /* XXX this function is only used by RMB setting hotkeys, and it clears maps on 2nd try this way */
- if(keymap==usermap)
- return keymap;
+ if(!WM_KEYMAP_UPDATE)
+ return;
- if(!usermap) {
- /* not saved yet, duplicate existing */
- usermap= MEM_dupallocN(keymap);
- usermap->modal_items= NULL;
- usermap->poll= NULL;
- usermap->flag |= KEYMAP_USER;
+ /* update operator properties for non-modal user keymaps */
+ for(km=U.user_keymaps.first; km; km=km->next) {
+ if((km->flag & KEYMAP_MODAL) == 0) {
+ for(kmdi=km->diff_items.first; kmdi; kmdi=kmdi->next) {
+ if(kmdi->add_item)
+ wm_keymap_item_properties_set(kmdi->add_item);
+ if(kmdi->remove_item)
+ wm_keymap_item_properties_set(kmdi->remove_item);
+ }
- BLI_addtail(&U.keymaps, usermap);
+ for(kmi=km->items.first; kmi; kmi=kmi->next)
+ wm_keymap_item_properties_set(kmi);
+ }
}
- else {
- /* already saved, free items for re-copy */
- WM_keymap_free(usermap);
+
+ /* update U.user_keymaps with user key configuration changes */
+ for(km=wm->userconf->keymaps.first; km; km=km->next) {
+ /* only diff if the user keymap was modified */
+ if(wm_keymap_test_and_clear_update(km)) {
+ /* find keymaps */
+ defaultmap= wm_keymap_preset(wm, km);
+ addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, km->idname, km->spaceid, km->regionid);
+
+ /* diff */
+ wm_keymap_diff_update(&U.user_keymaps, defaultmap, addonmap, km);
+ }
}
- BLI_duplicatelist(&usermap->items, &keymap->items);
+ /* create user key configuration from preset + addon + user preferences */
+ for(km=wm->defaultconf->keymaps.first; km; km=km->next) {
+ /* find keymaps */
+ defaultmap= wm_keymap_preset(wm, km);
+ 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);
- for(kmi=usermap->items.first; kmi; kmi=kmi->next) {
- if(kmi->properties) {
- kmi->ptr= MEM_callocN(sizeof(PointerRNA), "UserKeyMapItemPtr");
- WM_operator_properties_create(kmi->ptr, kmi->idname);
+ /* add */
+ wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap);
- kmi->properties= IDP_CopyProperty(kmi->properties);
- kmi->ptr->data= kmi->properties;
- }
+ /* in case of old non-diff keymaps, force extra update to create diffs */
+ compat_update = compat_update || (usermap && !(usermap->flag & KEYMAP_DIFF));
}
- for(kmi=keymap->items.first; kmi; kmi=kmi->next)
- kmi->flag &= ~KMI_EXPANDED;
+ WM_KEYMAP_UPDATE= 0;
+
+ if(compat_update) {
+ WM_keyconfig_update_tag(NULL, NULL);
+ WM_keyconfig_update(wm);
+ }
+}
+
+/********************************* Event Handling *****************************
+ * Handlers have pointers to the keymap in the default configuration. During
+ * event handling this function is called to get the keymap from the final
+ * configuration. */
+
+wmKeyMap *WM_keymap_active(wmWindowManager *wm, wmKeyMap *keymap)
+{
+ wmKeyMap *km;
+
+ if(!keymap)
+ return NULL;
+
+ /* first user defined keymaps */
+ km= WM_keymap_list_find(&wm->userconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
+
+ if(km)
+ return km;
- return usermap;
+ return keymap;
}
+/******************************* Keymap Editor ********************************
+ * In the keymap editor the user key configuration is edited. */
+
void WM_keymap_restore_item_to_default(bContext *C, wmKeyMap *keymap, wmKeyMapItem *kmi)
{
wmWindowManager *wm = CTX_wm_manager(C);
- wmKeyConfig *keyconf;
- wmKeyMap *km = NULL;
+ wmKeyMap *defaultmap, *addonmap;
+ wmKeyMapItem *orig;
- /* look in 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(!keymap)
+ return;
+
+ /* construct default keymap from preset + addons */
+ defaultmap= wm_keymap_preset(wm, keymap);
+ addonmap= WM_keymap_list_find(&wm->addonconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
- if (!km) {
- /* or from default */
- km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
+ if(addonmap) {
+ defaultmap = wm_keymap_copy(defaultmap);
+ wm_keymap_addon_add(defaultmap, addonmap);
}
- if (km) {
- wmKeyMapItem *orig = WM_keymap_item_find_id(km, kmi->id);
+ /* find original item */
+ orig = WM_keymap_item_find_id(defaultmap, kmi->id);
- if (orig) {
- if(strcmp(orig->idname, kmi->idname) != 0) {
- BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname));
+ if(orig) {
+ /* restore to original */
+ if(strcmp(orig->idname, kmi->idname) != 0) {
+ BLI_strncpy(kmi->idname, orig->idname, sizeof(kmi->idname));
+ WM_keymap_properties_reset(kmi, NULL);
+ }
- WM_keymap_properties_reset(kmi, NULL);
- }
-
- if (orig->properties) {
- kmi->properties= IDP_CopyProperty(orig->properties);
- kmi->ptr->data= kmi->properties;
+ if (orig->properties) {
+ if(kmi->properties) {
+ IDP_FreeProperty(kmi->properties);
+ MEM_freeN(kmi->properties);
+ kmi->properties= NULL;
}
- kmi->propvalue = orig->propvalue;
- kmi->type = orig->type;
- kmi->val = orig->val;
- kmi->shift = orig->shift;
- kmi->ctrl = orig->ctrl;
- kmi->alt = orig->alt;
- kmi->oskey = orig->oskey;
- kmi->keymodifier = orig->keymodifier;
- kmi->maptype = orig->maptype;
-
+ kmi->properties= IDP_CopyProperty(orig->properties);
+ kmi->ptr->data= kmi->properties;
}
+ kmi->propvalue = orig->propvalue;
+ kmi->type = orig->type;
+ kmi->val = orig->val;
+ kmi->shift = orig->shift;
+ kmi->ctrl = orig->ctrl;
+ kmi->alt = orig->alt;
+ kmi->oskey = orig->oskey;
+ kmi->keymodifier = orig->keymodifier;
+ kmi->maptype = orig->maptype;
+
+ WM_keyconfig_update_tag(keymap, kmi);
+ }
+
+ /* free temporary keymap */
+ if(addonmap) {
+ WM_keymap_free(defaultmap);
+ MEM_freeN(defaultmap);
}
}
-void WM_keymap_restore_to_default(wmKeyMap *keymap)
+void WM_keymap_restore_to_default(wmKeyMap *keymap, bContext *C)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
wmKeyMap *usermap;
- usermap= WM_keymap_list_find(&U.keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
+ /* remove keymap from U.user_keymaps and update */
+ usermap= WM_keymap_list_find(&U.user_keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
if(usermap) {
WM_keymap_free(usermap);
- BLI_freelinkN(&U.keymaps, usermap);
+ BLI_freelinkN(&U.user_keymaps, usermap);
+
+ WM_keyconfig_update_tag(NULL, NULL);
+ WM_keyconfig_update(wm);
}
}
@@ -951,3 +1332,4 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
return km;
}
+
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 548d272ffd2..983d4ecf5f8 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -208,10 +208,12 @@ struct wmKeyMap *WM_keymap_list_find(struct ListBase *lb, char *idname, int spac
struct wmKeyConfig *WM_keyconfig_new(struct wmWindowManager *wm, char *idname){return (struct wmKeyConfig *) NULL;}
struct wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, char *idname){return (struct wmKeyConfig *) NULL;}
void WM_keyconfig_remove(struct wmWindowManager *wm, char *idname){}
+void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname) {}
void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi){}
void WM_keymap_restore_to_default(struct wmKeyMap *keymap){}
void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *keymap, struct wmKeyMapItem *kmi){}
void WM_keymap_properties_reset(struct wmKeyMapItem *kmi){}
+void WM_keyconfig_update_tag(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi) {}
int WM_keymap_user_init(struct wmWindowManager *wm, struct wmKeyMap *keymap) {return 0;}
int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2){return 0;}