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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/blender.c33
-rw-r--r--source/blender/blenloader/BLO_readfile.h16
-rw-r--r--source/blender/blenloader/intern/readfile.c128
-rw-r--r--source/blender/blenloader/intern/writefile.c24
-rw-r--r--source/blender/editors/curve/editfont.c6
-rw-r--r--source/blender/editors/include/UI_interface.h6
-rw-r--r--source/blender/editors/include/UI_resources.h4
-rw-r--r--source/blender/editors/interface/interface.c340
-rw-r--r--source/blender/editors/interface/interface_handlers.c46
-rw-r--r--source/blender/editors/interface/interface_icons.c3
-rw-r--r--source/blender/editors/interface/interface_layout.c18
-rw-r--r--source/blender/editors/interface/interface_regions.c29
-rw-r--r--source/blender/editors/interface/interface_style.c10
-rw-r--r--source/blender/editors/interface/interface_templates.c14
-rw-r--r--source/blender/editors/interface/interface_utils.c43
-rw-r--r--source/blender/editors/interface/interface_widgets.c15
-rw-r--r--source/blender/editors/interface/resources.c16
-rw-r--r--source/blender/editors/object/object_edit.c107
-rw-r--r--source/blender/editors/space_file/file_ops.c13
-rw-r--r--source/blender/editors/space_image/image_ops.c49
-rw-r--r--source/blender/editors/space_node/drawnode.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c318
-rw-r--r--source/blender/editors/transform/transform_generics.c3
-rw-r--r--source/blender/makesdna/DNA_space_types.h2
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h7
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h24
-rw-r--r--source/blender/makesrna/intern/rna_access.c7
-rw-r--r--source/blender/makesrna/intern/rna_internal.h3
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c5
-rw-r--r--source/blender/makesrna/intern/rna_scene.c2
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c26
-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/python/intern/bpy_driver.c17
-rw-r--r--source/blender/python/intern/bpy_library.c3
-rw-r--r--source/blender/python/intern/bpy_operator.c23
-rw-r--r--source/blender/python/intern/bpy_rna.c139
-rw-r--r--source/blender/python/intern/bpy_rna.h18
-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.c18
-rw-r--r--source/blender/windowmanager/intern/wm_files.c13
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c721
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c5
46 files changed, 1734 insertions, 1135 deletions
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index d573da603f6..a3a4c5b555b 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -335,28 +335,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/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 85d4b936c51..47931477728 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -211,7 +211,16 @@ int BLO_has_bfile_extension(char *str);
*/
int BLO_is_a_library(const char *path, char *dir, char *group);
-struct Main* BLO_library_append_begin(const struct bContext *C, BlendHandle** bh, const char *filepath);
+
+/**
+ * Initialize the BlendHandle for appending or linking library data.
+ *
+ * @param mainvar The current main database eg G.main or CTX_data_main(C).
+ * @param bh A blender file handle as returned by BLO_blendhandle_from_file or BLO_blendhandle_from_memory.
+ * @param filepath Used for relative linking, copied to the lib->name
+ * @return the library Main, to be passed to BLO_library_append_named_part as mainl.
+ */
+struct Main* BLO_library_append_begin(struct Main *mainvar, BlendHandle** bh, const char *filepath);
/**
@@ -243,11 +252,6 @@ void BLO_library_append_end(const struct bContext *C, struct Main *mainl, BlendH
void *BLO_library_read_struct(struct FileData *fd, struct BHead *bh, const char *blockname);
-/* deprecated */
-#if 1
-void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, struct Main *mainvar, struct Scene *scene, struct ReportList *reports);
-#endif
-
BlendFileData* blo_read_blendafterruntime(int file, char *name, int actualsize, struct ReportList *reports);
#ifdef __cplusplus
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 07e2bbf5bca..ef71df31df4 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4727,6 +4727,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;
@@ -11886,33 +11888,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
@@ -13110,9 +13136,8 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
/* common routine to append/link something from a library */
-static Main* library_append_begin(const bContext *C, FileData **fd, const char *filepath)
+static Main* library_append_begin(Main *mainvar, FileData **fd, const char *filepath)
{
- Main *mainvar= CTX_data_main(C);
Main *mainl;
/* make mains */
@@ -13128,64 +13153,17 @@ static Main* library_append_begin(const bContext *C, FileData **fd, const char *
return mainl;
}
-Main* BLO_library_append_begin(const bContext *C, BlendHandle** bh, const char *filepath)
+Main* BLO_library_append_begin(Main *mainvar, BlendHandle** bh, const char *filepath)
{
FileData *fd= (FileData*)(*bh);
- return library_append_begin(C, &fd, filepath);
+ return library_append_begin(mainvar, &fd, filepath);
}
-static void append_do_cursor(Scene *scene, Library *curlib, short flag)
-{
- Base *centerbase;
- Object *ob;
- float *curs, centerloc[3], vec[3], min[3], max[3];
- int count= 0;
-
- /* when not linking (appending)... */
- if(flag & FILE_LINK)
- return;
-
- /* we're not appending at cursor */
- if((flag & FILE_ATCURSOR) == 0)
- return;
-
- /* find the center of everything appended */
- INIT_MINMAX(min, max);
- centerbase= (scene->base.first);
- while(centerbase) {
- if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
- VECCOPY(vec, centerbase->object->loc);
- DO_MINMAX(vec, min, max);
- count++;
- }
- centerbase= centerbase->next;
- }
- /* we haven't found any objects to move to cursor */
- if(!count)
- return;
-
- /* move from the center of the appended objects to cursor */
- mid_v3_v3v3(centerloc, min, max);
- curs = scene->cursor;
- VECSUB(centerloc,curs,centerloc);
-
- /* now translate the center of the objects */
- centerbase= (scene->base.first);
- while(centerbase) {
- if(centerbase->object->id.lib==curlib && centerbase->object->parent==NULL) {
- ob= centerbase->object;
- ob->loc[0] += centerloc[0];
- ob->loc[1] += centerloc[1];
- ob->loc[2] += centerloc[2];
- }
- centerbase= centerbase->next;
- }
-}
+/* Context == NULL signifies not to do any scene manipulation */
static void library_append_end(const bContext *C, Main *mainl, FileData **fd, int idcode, short flag)
{
Main *mainvar;
- Scene *scene= CTX_data_scene(C);
Library *curlib;
/* make main consistent */
@@ -13214,22 +13192,26 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in
lib_verify_nodetree(mainvar, FALSE);
fix_relpaths_library(G.main->name, mainvar); /* make all relative paths, relative to the open blend file */
- /* give a base to loose objects. If group append, do it for objects too */
- if(scene) {
- const short is_link= (flag & FILE_LINK) != 0;
- if(idcode==ID_SCE) {
- /* dont instance anything when linking in scenes, assume the scene its self instances the data */
- }
- else {
- give_base_to_objects(mainvar, scene, curlib, idcode, is_link);
+ if(C) {
+ Scene *scene= CTX_data_scene(C);
- if (flag & FILE_GROUP_INSTANCE) {
- give_base_to_groups(mainvar, scene);
+ /* give a base to loose objects. If group append, do it for objects too */
+ if(scene) {
+ const short is_link= (flag & FILE_LINK) != 0;
+ if(idcode==ID_SCE) {
+ /* dont instance anything when linking in scenes, assume the scene its self instances the data */
+ }
+ else {
+ give_base_to_objects(mainvar, scene, curlib, idcode, is_link);
+
+ if (flag & FILE_GROUP_INSTANCE) {
+ give_base_to_groups(mainvar, scene);
+ }
}
}
- }
- else {
- printf("library_append_end, scene is NULL (objects wont get bases)\n");
+ else {
+ printf("library_append_end, scene is NULL (objects wont get bases)\n");
+ }
}
/* has been removed... erm, why? s..ton) */
/* 20040907: looks like they are give base already in append_named_part(); -Nathan L */
@@ -13240,8 +13222,6 @@ static void library_append_end(const bContext *C, Main *mainl, FileData **fd, in
blo_freefiledata( *fd );
*fd = NULL;
}
-
- append_do_cursor(scene, curlib, flag);
}
void BLO_library_append_end(const bContext *C, struct Main *mainl, BlendHandle** bh, int idcode, short flag)
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 319657c8968..5099b52a988 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -718,11 +718,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;
@@ -731,15 +739,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/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 649ff9e953a..6c95df53d39 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -1649,10 +1649,10 @@ static int open_exec(bContext *C, wmOperator *op)
VFont *font;
PropertyPointerRNA *pprop;
PointerRNA idptr;
- char str[FILE_MAX];
- RNA_string_get(op->ptr, "filepath", str);
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
- font = load_vfont(str);
+ font= load_vfont(filepath);
if(!font) {
if(op->customdata) MEM_freeN(op->customdata);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 61e19655f8d..3fe012ea73e 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -164,6 +164,9 @@ typedef struct uiLayout uiLayout;
/* scale fixed button widths by this to account for DPI
* 8.4852 == sqrtf(72.0f)) */
#define UI_DPI_FAC (sqrtf((float)U.dpi) / 8.48528137423857f)
+#define UI_DPI_ICON_FAC (((float)U.dpi) / 72.0f)
+/* 16 to copy ICON_DEFAULT_HEIGHT */
+#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_ICON_FAC)
/* Button types, bits stored in 1 value... and a short even!
- bits 0-4: bitnr (0-31)
@@ -407,6 +410,7 @@ uiBut *uiDefButBitS(uiBlock *block, int type, int bit, int retval, const char *s
uiBut *uiDefButC(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefButBitC(uiBlock *block, int type, int bit, int retval, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip);
+uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip);
uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip);
@@ -426,6 +430,7 @@ uiBut *uiDefIconButBitS(uiBlock *block, int type, int bit, int retval, int icon,
uiBut *uiDefIconButC(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconButBitC(uiBlock *block, int type, int bit, int retval, int icon, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip);
+uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip);
uiBut *uiDefIconTextBut(uiBlock *block,
@@ -444,6 +449,7 @@ uiBut *uiDefIconTextButBitS(uiBlock *block, int type, int bit, int retval, int i
uiBut *uiDefIconTextButC(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconTextButBitC(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, char *poin, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip);
+uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip);
uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip);
/* for passing inputs to ButO buttons */
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index ff9a1f539a1..d383bc0ab78 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -246,7 +246,9 @@ enum {
TH_DRAWEXTRA_EDGELEN,
TH_DRAWEXTRA_FACEAREA,
- TH_DRAWEXTRA_FACEANG
+ TH_DRAWEXTRA_FACEANG,
+
+ TH_NODE_CURVING
};
/* XXX WARNING: previous is saved in file, so do not change order! */
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index c7c2235097f..ccc5ac52744 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2494,138 +2494,141 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
return but;
}
-static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip)
+/* ui_def_but_rna_propname and ui_def_but_rna
+ * both take the same args except for propname vs prop, this is done so we can
+ * avoid an extra lookup on 'prop' when its already available.
+ *
+ * When this kind of change won't disrupt branches, best look into making more
+ * of our UI functions take prop rather then propname.
+ */
+
+#define UI_DEF_BUT_RNA_DISABLE(but) \
+ but->flag |= UI_BUT_DISABLED; \
+ but->lock = 1; \
+ but->lockstr = ""
+
+
+static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but;
- PropertyRNA *prop;
PropertyType proptype;
int freestr= 0, icon= 0;
- prop= RNA_struct_find_property(ptr, propname);
+ proptype= RNA_property_type(prop);
- if(prop) {
- proptype= RNA_property_type(prop);
-
- /* use rna values if parameters are not specified */
- if(!str) {
- if(type == MENU && proptype == PROP_ENUM) {
- EnumPropertyItem *item;
- DynStr *dynstr;
- int i, totitem, value, free;
-
- RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
- value= RNA_property_enum_get(ptr, prop);
-
- dynstr= BLI_dynstr_new();
- BLI_dynstr_appendf(dynstr, "%s%%t", RNA_property_ui_name(prop));
- for(i=0; i<totitem; i++) {
- if(!item[i].identifier[0]) {
- if(item[i].name)
- BLI_dynstr_appendf(dynstr, "|%s%%l", item[i].name);
- else
- BLI_dynstr_append(dynstr, "|%l");
- }
- else if(item[i].icon)
- BLI_dynstr_appendf(dynstr, "|%s %%i%d %%x%d", item[i].name, item[i].icon, item[i].value);
+ /* use rna values if parameters are not specified */
+ if(!str) {
+ if(type == MENU && proptype == PROP_ENUM) {
+ EnumPropertyItem *item;
+ DynStr *dynstr;
+ int i, totitem, value, free;
+
+ RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
+ value= RNA_property_enum_get(ptr, prop);
+
+ dynstr= BLI_dynstr_new();
+ BLI_dynstr_appendf(dynstr, "%s%%t", RNA_property_ui_name(prop));
+ for(i=0; i<totitem; i++) {
+ if(!item[i].identifier[0]) {
+ if(item[i].name)
+ BLI_dynstr_appendf(dynstr, "|%s%%l", item[i].name);
else
- BLI_dynstr_appendf(dynstr, "|%s %%x%d", item[i].name, item[i].value);
+ BLI_dynstr_append(dynstr, "|%l");
+ }
+ else if(item[i].icon)
+ BLI_dynstr_appendf(dynstr, "|%s %%i%d %%x%d", item[i].name, item[i].icon, item[i].value);
+ else
+ BLI_dynstr_appendf(dynstr, "|%s %%x%d", item[i].name, item[i].value);
- if(value == item[i].value) {
- icon= item[i].icon;
- if(!tip)
- tip= item[i].description;
- }
+ if(value == item[i].value) {
+ icon= item[i].icon;
+ if(!tip)
+ tip= item[i].description;
}
- str= BLI_dynstr_get_cstring(dynstr);
- BLI_dynstr_free(dynstr);
+ }
+ str= BLI_dynstr_get_cstring(dynstr);
+ BLI_dynstr_free(dynstr);
- if(free)
- MEM_freeN(item);
+ if(free)
+ MEM_freeN(item);
- freestr= 1;
- }
- else if(ELEM(type, ROW, LISTROW) && proptype == PROP_ENUM) {
- EnumPropertyItem *item;
- int i, totitem, free;
-
- RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
- for(i=0; i<totitem; i++) {
- if(item[i].identifier[0] && item[i].value == (int)max) {
- str= item[i].name;
- icon= item[i].icon;
- }
- }
+ freestr= 1;
+ }
+ else if(ELEM(type, ROW, LISTROW) && proptype == PROP_ENUM) {
+ EnumPropertyItem *item;
+ int i, totitem, free;
- if(!str)
- str= RNA_property_ui_name(prop);
- if(free)
- MEM_freeN(item);
+ RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
+ for(i=0; i<totitem; i++) {
+ if(item[i].identifier[0] && item[i].value == (int)max) {
+ str= item[i].name;
+ icon= item[i].icon;
+ }
}
- else {
+
+ if(!str)
str= RNA_property_ui_name(prop);
- icon= RNA_property_ui_icon(prop);
- }
+ if(free)
+ MEM_freeN(item);
}
-
- if(!tip && proptype != PROP_ENUM)
- tip= RNA_property_ui_description(prop);
+ else {
+ str= RNA_property_ui_name(prop);
+ icon= RNA_property_ui_icon(prop);
+ }
+ }
- if(min == max || a1 == -1 || a2 == -1) {
- if(proptype == PROP_INT) {
- int hardmin, hardmax, softmin, softmax, step;
+ if(!tip && proptype != PROP_ENUM)
+ tip= RNA_property_ui_description(prop);
- RNA_property_int_range(ptr, prop, &hardmin, &hardmax);
- RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step);
+ if(min == max || a1 == -1 || a2 == -1) {
+ if(proptype == PROP_INT) {
+ int hardmin, hardmax, softmin, softmax, step;
- if(!ELEM(type, ROW, LISTROW) && min == max) {
- min= hardmin;
- max= hardmax;
- }
- if(a1 == -1)
- a1= step;
- if(a2 == -1)
- a2= 0;
+ RNA_property_int_range(ptr, prop, &hardmin, &hardmax);
+ RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step);
+
+ if(!ELEM(type, ROW, LISTROW) && min == max) {
+ min= hardmin;
+ max= hardmax;
}
- else if(proptype == PROP_FLOAT) {
- float hardmin, hardmax, softmin, softmax, step, precision;
+ if(a1 == -1)
+ a1= step;
+ if(a2 == -1)
+ a2= 0;
+ }
+ else if(proptype == PROP_FLOAT) {
+ float hardmin, hardmax, softmin, softmax, step, precision;
- RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
- RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
+ RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
+ RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
- if(!ELEM(type, ROW, LISTROW) && min == max) {
- min= hardmin;
- max= hardmax;
- }
- if(a1 == -1)
- a1= step;
- if(a2 == -1)
- a2= precision;
- }
- else if(proptype == PROP_STRING) {
- min= 0;
- max= RNA_property_string_maxlength(prop);
- if(max == 0) /* interface code should ideally support unlimited length */
- max= UI_MAX_DRAW_STR;
+ if(!ELEM(type, ROW, LISTROW) && min == max) {
+ min= hardmin;
+ max= hardmax;
}
+ if(a1 == -1)
+ a1= step;
+ if(a2 == -1)
+ a2= precision;
+ }
+ else if(proptype == PROP_STRING) {
+ min= 0;
+ max= RNA_property_string_maxlength(prop);
+ if(max == 0) /* interface code should ideally support unlimited length */
+ max= UI_MAX_DRAW_STR;
}
- }
- else {
- RNA_warning("ui_def_but_rna: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname);
- str= propname;
}
/* now create button */
but= ui_def_but(block, type, retval, str, x1, y1, x2, y2, NULL, min, max, a1, a2, tip);
- if(prop) {
- but->rnapoin= *ptr;
- but->rnaprop= prop;
+ but->rnapoin= *ptr;
+ but->rnaprop= prop;
- if(RNA_property_array_length(&but->rnapoin, but->rnaprop))
- but->rnaindex= index;
- else
- but->rnaindex= 0;
- }
+ if(RNA_property_array_length(&but->rnapoin, but->rnaprop))
+ but->rnaindex= index;
+ else
+ but->rnaindex= 0;
if(icon) {
but->icon= (BIFIconID)icon;
@@ -2633,10 +2636,8 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
but->flag|= UI_ICON_LEFT;
}
- if (!prop || !RNA_property_editable(&but->rnapoin, prop)) {
- but->flag |= UI_BUT_DISABLED;
- but->lock = 1;
- but->lockstr = "";
+ if (!RNA_property_editable(&but->rnapoin, prop)) {
+ UI_DEF_BUT_RNA_DISABLE(but);
}
/* If this button uses units, calculate the step from this */
@@ -2649,6 +2650,23 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
return but;
}
+static uiBut *ui_def_but_rna_propname(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip)
+{
+ PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
+ uiBut *but;
+
+ if(prop) {
+ but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip);
+ }
+ else {
+ but= ui_def_but(block, type, retval, propname, x1, y1, x2, y2, NULL, min, max, a1, a2, tip);
+
+ UI_DEF_BUT_RNA_DISABLE(but);
+ }
+
+ return but;
+}
+
static uiBut *ui_def_but_operator(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip)
{
uiBut *but;
@@ -2816,6 +2834,16 @@ static void autocomplete_id(bContext *C, char *str, void *arg_v)
}
}
+static void ui_check_but_and_iconize(uiBut *but, int icon)
+{
+ if(icon) {
+ but->icon= (BIFIconID) icon;
+ but->flag|= UI_HAS_ICON;
+ }
+
+ ui_check_but(but);
+}
+
static uiBut *uiDefButBit(uiBlock *block, int type, int bit, int retval, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip)
{
int bitIdx= findBitIndex(bit);
@@ -2860,31 +2888,29 @@ uiBut *uiDefButBitC(uiBlock *block, int type, int bit, int retval, const char *s
uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but;
-
- but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip);
- if(but)
- ui_check_but(but);
-
+ but= ui_def_but_rna_propname(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip);
+ ui_check_but(but);
+ return but;
+}
+uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
+{
+ uiBut *but;
+ but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip);
+ ui_check_but(but);
return but;
}
uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, const char *tip)
{
uiBut *but;
-
but= ui_def_but_operator(block, type, opname, opcontext, str, x1, y1, x2, y2, tip);
- if(but)
- ui_check_but(but);
-
+ ui_check_but(but);
return but;
}
uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but= ui_def_but_operator_text(block, type, opname, opcontext, str, x1, y1, x2, y2, poin, min, max, a1, a2, tip);
-
- if(but)
- ui_check_but(but);
-
+ ui_check_but(but);
return but;
}
@@ -2892,12 +2918,7 @@ uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext
uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but= ui_def_but(block, type, retval, "", x1, y1, x2, y2, poin, min, max, a1, a2, tip);
-
- but->icon= (BIFIconID) icon;
- but->flag|= UI_HAS_ICON;
-
- ui_check_but(but);
-
+ ui_check_but_and_iconize(but, icon);
return but;
}
static uiBut *uiDefIconButBit(uiBlock *block, int type, int bit, int retval, int icon, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip)
@@ -2945,29 +2966,22 @@ uiBut *uiDefIconButBitC(uiBlock *block, int type, int bit, int retval, int icon,
uiBut *uiDefIconButR(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but;
-
- but= ui_def_but_rna(block, type, retval, "", x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip);
- if(but) {
- if(icon) {
- but->icon= (BIFIconID) icon;
- but->flag|= UI_HAS_ICON;
- }
- ui_check_but(but);
- }
-
+ but= ui_def_but_rna_propname(block, type, retval, "", x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip);
+ ui_check_but_and_iconize(but, icon);
+ return but;
+}
+uiBut *uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
+{
+ uiBut *but;
+ but= ui_def_but_rna(block, type, retval, "", x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip);
+ ui_check_but_and_iconize(but, icon);
return but;
}
uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, int x1, int y1, short x2, short y2, const char *tip)
{
uiBut *but;
-
but= ui_def_but_operator(block, type, opname, opcontext, "", x1, y1, x2, y2, tip);
- if(but) {
- but->icon= (BIFIconID) icon;
- but->flag|= UI_HAS_ICON;
- ui_check_but(but);
- }
-
+ ui_check_but_and_iconize(but, icon);
return but;
}
@@ -2975,14 +2989,8 @@ uiBut *uiDefIconButO(uiBlock *block, int type, const char *opname, int opcontext
uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but= ui_def_but(block, type, retval, str, x1, y1, x2, y2, poin, min, max, a1, a2, tip);
-
- but->icon= (BIFIconID) icon;
- but->flag|= UI_HAS_ICON;
-
+ ui_check_but_and_iconize(but, icon);
but->flag|= UI_ICON_LEFT;
-
- ui_check_but(but);
-
return but;
}
static uiBut *uiDefIconTextButBit(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, const char *tip)
@@ -3030,31 +3038,25 @@ uiBut *uiDefIconTextButBitC(uiBlock *block, int type, int bit, int retval, int i
uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, const char *propname, int index, float min, float max, float a1, float a2, const char *tip)
{
uiBut *but;
-
- but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip);
- if(but) {
- if(icon) {
- but->icon= (BIFIconID) icon;
- but->flag|= UI_HAS_ICON;
- }
- but->flag|= UI_ICON_LEFT;
- ui_check_but(but);
- }
-
+ but= ui_def_but_rna_propname(block, type, retval, str, x1, y1, x2, y2, ptr, propname, index, min, max, a1, a2, tip);
+ ui_check_but_and_iconize(but, icon);
+ but->flag|= UI_ICON_LEFT;
+ return but;
+}
+uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x1, int y1, short x2, short y2, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
+{
+ uiBut *but;
+ but= ui_def_but_rna(block, type, retval, str, x1, y1, x2, y2, ptr, prop, index, min, max, a1, a2, tip);
+ ui_check_but_and_iconize(but, icon);
+ but->flag|= UI_ICON_LEFT;
return but;
}
uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x1, int y1, short x2, short y2, const char *tip)
{
uiBut *but;
-
but= ui_def_but_operator(block, type, opname, opcontext, str, x1, y1, x2, y2, tip);
- if(but) {
- but->icon= (BIFIconID) icon;
- but->flag|= UI_HAS_ICON;
- but->flag|= UI_ICON_LEFT;
- ui_check_but(but);
- }
-
+ ui_check_but_and_iconize(but, icon);
+ but->flag|= UI_ICON_LEFT;
return but;
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b66eecb9e31..15f46b4eee4 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1290,7 +1290,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, sho
else if(ELEM(but->type, TEX, SEARCH_MENU)) {
startx += 5;
if (but->flag & UI_HAS_ICON)
- startx += 16;
+ startx += UI_DPI_ICON_SIZE;
}
/* mouse dragged outside the widget to the left */
@@ -2856,7 +2856,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
- int mx, my, click= 0;
+ int mx, my /*, click= 0 */;
int retval= WM_UI_HANDLER_CONTINUE;
int horizontal= (but->x2 - but->x1 > but->y2 - but->y1);
@@ -2878,8 +2878,10 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
retval= WM_UI_HANDLER_BREAK;
}
- else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS)
+ /* UNUSED - otherwise code is ok, add back if needed */
+ /* else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS)
click= 1;
+ */
}
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
@@ -3677,6 +3679,9 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt
return WM_UI_HANDLER_BREAK;
}
+ /* UNUSED but keep for now */
+ (void)changed;
+
return WM_UI_HANDLER_CONTINUE;
}
@@ -3691,12 +3696,12 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx
Histogram *hist = (Histogram *)but->poin;
/* rcti rect; */
int changed= 1;
- float dx, dy, yfac=1.f;
+ float /* dx, */ dy, yfac=1.f; /* UNUSED */
/* rect.xmin= but->x1; rect.xmax= but->x2; */
/* rect.ymin= but->y1; rect.ymax= but->y2; */
- dx = mx - data->draglastx;
+ /* dx = mx - data->draglastx; */ /* UNUSED */
dy = my - data->draglasty;
@@ -3774,12 +3779,12 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx,
Scopes *scopes = (Scopes *)but->poin;
/* rcti rect; */
int changed= 1;
- float dx, dy, yfac=1.f;
+ float /* dx, */ dy /* , yfac=1.f */; /* UNUSED */
/* rect.xmin= but->x1; rect.xmax= but->x2; */
/* rect.ymin= but->y1; rect.ymax= but->y2; */
- dx = mx - data->draglastx;
+ /* dx = mx - data->draglastx; */ /* UNUSED */
dy = my - data->draglasty;
@@ -3788,7 +3793,7 @@ static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx,
scopes->wavefrm_height = (but->y2 - but->y1) + (data->dragstarty - my);
} else {
/* scale waveform values */
- yfac = scopes->wavefrm_yfac;
+ /* yfac = scopes->wavefrm_yfac; */ /* UNUSED */
scopes->wavefrm_yfac += dy/200.0f;
CLAMP(scopes->wavefrm_yfac, 0.5f, 2.f);
@@ -4067,7 +4072,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 +4084,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 +4095,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 +4108,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 +4127,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 +4136,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/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 3bf2a9ddd02..412c0233c35 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -742,6 +742,7 @@ static DrawInfo *icon_create_drawinfo(void)
return di;
}
+/* note!, returns unscaled by DPI, may need to multiply result by UI_DPI_ICON_FAC */
int UI_icon_get_width(int icon_id)
{
Icon *icon = NULL;
@@ -952,7 +953,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
Icon *icon = NULL;
DrawInfo *di = NULL;
IconImage *iimg;
- float fdraw_size= UI_DPI_FAC*draw_size;
+ float fdraw_size= UI_DPI_ICON_FAC*draw_size;
int w, h;
icon = BKE_icon_get(icon_id);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 2f0bcc9d5b4..85cc944f03b 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -419,7 +419,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in
}
}
else if(subtype == PROP_DIRECTION) {
- uiDefButR(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X*3, UI_UNIT_Y*3, ptr, RNA_property_identifier(prop), 0, 0, 0, -1, -1, NULL);
+ uiDefButR_prop(block, BUT_NORMAL, 0, name, x, y, UI_UNIT_X*3, UI_UNIT_Y*3, ptr, prop, 0, 0, 0, -1, -1, NULL);
}
else {
if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && !expand)
@@ -461,11 +461,9 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt
{
uiBut *but;
EnumPropertyItem *item;
- const char *identifier;
const char *name;
int a, totitem, itemw, icon, value, free;
- identifier= RNA_property_identifier(prop);
RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1));
@@ -479,11 +477,11 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt
itemw= ui_text_icon_width(block->curlayout, name, icon, 0);
if(icon && name[0] && !icon_only)
- but= uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
+ but= uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
else if(icon)
- but= uiDefIconButR(block, ROW, 0, icon, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
+ but= uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
else
- but= uiDefButR(block, ROW, 0, name, 0, 0, itemw, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
+ but= uiDefButR_prop(block, ROW, 0, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL);
if(ui_layout_local_dir(layout) != UI_LAYOUT_HORIZONTAL)
but->flag |= UI_TEXT_LEFT;
@@ -540,7 +538,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n
WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL);
}
else if(flag & UI_ITEM_R_EVENT) {
- uiDefButR(block, KEYEVT, 0, name, x, y, w, h, ptr, RNA_property_identifier(prop), index, 0, 0, -1, -1, NULL);
+ uiDefButR_prop(block, KEYEVT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL);
}
else if(flag & UI_ITEM_R_FULL_EVENT) {
if(RNA_struct_is_a(ptr->type, &RNA_KeyMapItem)) {
@@ -548,7 +546,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n
WM_keymap_item_to_string(ptr->data, buf, sizeof(buf));
- but= uiDefButR(block, HOTKEYEVT, 0, buf, x, y, w, h, ptr, RNA_property_identifier(prop), 0, 0, 0, -1, -1, NULL);
+ but= uiDefButR_prop(block, HOTKEYEVT, 0, buf, x, y, w, h, ptr, prop, 0, 0, 0, -1, -1, NULL);
uiButSetFunc(but, ui_keymap_but_cb, but, NULL);
if (flag & UI_ITEM_R_IMMEDIATE)
uiButSetFlag(but, UI_BUT_IMMEDIATE);
@@ -1008,11 +1006,11 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
const char *identifier= RNA_property_identifier(prop);
if(icon && name[0] && !icon_only)
- uiDefIconTextButR(block, ROW, 0, icon, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
+ uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
else if(icon)
uiDefIconButR(block, ROW, 0, icon, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
else
- uiDefButR(block, ROW, 0, name, 0, 0, w, h, ptr, identifier, -1, 0, value, -1, -1, NULL);
+ uiDefButR_prop(block, ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
}
/* expanded enum */
else if(type == PROP_ENUM && (expand || RNA_property_flag(prop) & PROP_ENUM_FLAG))
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 9e7717260e6..f7460e77030 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -1934,31 +1934,31 @@ static void do_picker_new_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(a
#define PICKER_TOTAL_W (PICKER_W+PICKER_SPACE+PICKER_BAR)
-static void circle_picker(uiBlock *block, PointerRNA *ptr, const char *propname)
+static void circle_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop)
{
uiBut *bt;
/* HS circle */
- bt= uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, propname, 0, 0.0, 0.0, 0, 0, "Color");
+ bt= uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, PICKER_H, PICKER_W, ptr, prop, 0, 0.0, 0.0, 0, 0, "Color");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
/* value */
- bt= uiDefButR(block, HSVCUBE, 0, "", PICKER_W+PICKER_SPACE,0,PICKER_BAR,PICKER_H, ptr, propname, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
+ bt= uiDefButR_prop(block, HSVCUBE, 0, "", PICKER_W+PICKER_SPACE,0,PICKER_BAR,PICKER_H, ptr, prop, 0, 0.0, 0.0, UI_GRAD_V_ALT, 0, "Value");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
-static void square_picker(uiBlock *block, PointerRNA *ptr, const char *propname, int type)
+static void square_picker(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int type)
{
uiBut *bt;
int bartype = type + 3;
/* HS square */
- bt= uiDefButR(block, HSVCUBE, 0, "", 0, PICKER_BAR+PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, propname, 0, 0.0, 0.0, type, 0, "Color");
+ bt= uiDefButR_prop(block, HSVCUBE, 0, "", 0, PICKER_BAR+PICKER_SPACE, PICKER_TOTAL_W, PICKER_H, ptr, prop, 0, 0.0, 0.0, type, 0, "Color");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
/* value */
- bt= uiDefButR(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, propname, 0, 0.0, 0.0, bartype, 0, "Value");
+ bt= uiDefButR_prop(block, HSVCUBE, 0, "", 0, 0, PICKER_TOTAL_W, PICKER_BAR, ptr, prop, 0, 0.0, 0.0, bartype, 0, "Value");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
@@ -1973,7 +1973,6 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR
static char hexcol[128];
float rgb_gamma[3];
float min, max, step, precision;
- const char *propname = RNA_property_identifier(prop);
float *hsv= ui_block_hsv_get(block);
ui_block_hsv_get(block);
@@ -1999,16 +1998,16 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR
switch (U.color_picker_type) {
case USER_CP_CIRCLE:
- circle_picker(block, ptr, propname);
+ circle_picker(block, ptr, prop);
break;
case USER_CP_SQUARE_SV:
- square_picker(block, ptr, propname, UI_GRAD_SV);
+ square_picker(block, ptr, prop, UI_GRAD_SV);
break;
case USER_CP_SQUARE_HS:
- square_picker(block, ptr, propname, UI_GRAD_HS);
+ square_picker(block, ptr, prop, UI_GRAD_HS);
break;
case USER_CP_SQUARE_HV:
- square_picker(block, ptr, propname, UI_GRAD_HV);
+ square_picker(block, ptr, prop, UI_GRAD_HV);
break;
}
@@ -2027,11 +2026,11 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR
/* RGB values */
uiBlockBeginAlign(block);
- bt= uiDefButR(block, NUMSLI, 0, "R ", 0, -60, butwidth, UI_UNIT_Y, ptr, propname, 0, 0.0, 0.0, 0, 3, "Red");
+ bt= uiDefButR_prop(block, NUMSLI, 0, "R ", 0, -60, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, "Red");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
- bt= uiDefButR(block, NUMSLI, 0, "G ", 0, -80, butwidth, UI_UNIT_Y, ptr, propname, 1, 0.0, 0.0, 0, 3, "Green");
+ bt= uiDefButR_prop(block, NUMSLI, 0, "G ", 0, -80, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, "Green");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
- bt= uiDefButR(block, NUMSLI, 0, "B ", 0, -100, butwidth, UI_UNIT_Y, ptr, propname, 2, 0.0, 0.0, 0, 3, "Blue");
+ bt= uiDefButR_prop(block, NUMSLI, 0, "B ", 0, -100, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, "Blue");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
// could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE);
@@ -2048,7 +2047,7 @@ static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyR
uiBlockEndAlign(block);
if(rgb[3] != FLT_MAX) {
- bt= uiDefButR(block, NUMSLI, 0, "A ", 0, -120, butwidth, UI_UNIT_Y, ptr, propname, 3, 0.0, 0.0, 0, 0, "Alpha");
+ bt= uiDefButR_prop(block, NUMSLI, 0, "A ", 0, -120, butwidth, UI_UNIT_Y, ptr, prop, 3, 0.0, 0.0, 0, 0, "Alpha");
uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
}
else {
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 02067ec4666..704b9ae3a80 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -149,9 +149,9 @@ void uiStyleFontDrawExt(uiFontStyle *fs, rcti *rect, const char *str,
int xofs=0, yofs;
uiStyleFontSet(fs);
-
- height= BLF_height(fs->uifont_id, "2"); /* correct offset is on baseline, the j is below that */
- yofs= floor( 0.5f*(rect->ymax - rect->ymin - height));
+
+ height= BLF_ascender(fs->uifont_id);
+ yofs= ceil( 0.5f*(rect->ymax - rect->ymin - height));
if(fs->align==UI_STYLE_TEXT_CENTER) {
xofs= floor( 0.5f*(rect->xmax - rect->xmin - BLF_width(fs->uifont_id, str)));
@@ -206,9 +206,9 @@ void uiStyleFontDrawRotated(uiFontStyle *fs, rcti *rect, const char *str)
uiStyleFontSet(fs);
- height= BLF_height(fs->uifont_id, "2"); /* correct offset is on baseline, the j is below that */
+ height= BLF_ascender(fs->uifont_id);
/* becomes x-offset when rotated */
- xofs= floor( 0.5f*(rect->ymax - rect->ymin - height)) + 1;
+ xofs= ceil( 0.5f*(rect->ymax - rect->ymin - height));
/* ignore UI_STYLE, always aligned to top */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 28bfbfba6c8..c85d5ae5616 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1875,7 +1875,7 @@ void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, const char *propnam
col = uiLayoutColumn(layout, 0);
row= uiLayoutRow(col, 1);
- but= uiDefButR(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 0, 0, "");
+ but= uiDefButR_prop(block, HSVCIRCLE, 0, "", 0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, prop, -1, 0.0, 0.0, 0, 0, "");
if(lock) {
but->flag |= UI_BUT_COLOR_LOCK;
@@ -1894,7 +1894,7 @@ void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, const char *propnam
uiItemS(row);
if (value_slider)
- uiDefButR(block, HSVCUBE, 0, "", WHEEL_SIZE+6, 0, 14, WHEEL_SIZE, ptr, propname, -1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
+ uiDefButR_prop(block, HSVCUBE, 0, "", WHEEL_SIZE+6, 0, 14, WHEEL_SIZE, ptr, prop, -1, softmin, softmax, UI_GRAD_V_ALT, 0, "");
}
/********************* Layer Buttons Template ************************/
@@ -2025,7 +2025,7 @@ static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon, int
return rnaicon;
}
-static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon, PointerRNA *activeptr, const char *activepropname)
+static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon, PointerRNA *activeptr, PropertyRNA *activeprop)
{
uiBlock *block= uiLayoutGetBlock(layout);
uiBut *but;
@@ -2039,7 +2039,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
/* list item behind label & other buttons */
sub= uiLayoutRow(overlap, 0);
- but= uiDefButR(block, LISTROW, 0, "", 0,0, UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
+ but= uiDefButR_prop(block, LISTROW, 0, "", 0,0, UI_UNIT_X*10,UI_UNIT_Y, activeptr, activeprop, 0, 0, i, 0, 0, "");
uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
sub= uiLayoutRow(overlap, 0);
@@ -2201,7 +2201,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
row= uiLayoutRow(col, 0);
icon= list_item_icon_get(C, &itemptr, rnaicon, 1);
- but= uiDefIconButR(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
+ but= uiDefIconButR_prop(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activeprop, 0, 0, i, 0, 0, "");
uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
@@ -2241,7 +2241,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
/* next/prev button */
sprintf(str, "%d :", i);
- but= uiDefIconTextButR(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activepropname, 0, 0, 0, 0, 0, "");
+ but= uiDefIconTextButR_prop(block, NUM, 0, 0, str, 0,0,UI_UNIT_X*5,UI_UNIT_Y, activeptr, activeprop, 0, 0, 0, 0, 0, "");
if(i == 0)
uiButSetFlag(but, UI_BUT_DISABLED);
}
@@ -2280,7 +2280,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
/* create list items */
RNA_PROP_BEGIN(ptr, itemptr, prop) {
if(i >= pa->list_scroll && i<pa->list_scroll+items)
- list_item_row(C, col, ptr, &itemptr, i, rnaicon, activeptr, activepropname);
+ list_item_row(C, col, ptr, &itemptr, i, rnaicon, activeptr, activeprop);
i++;
}
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 1ec125c2f26..f660dbb9edd 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -51,56 +51,53 @@
uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2)
{
uiBut *but=NULL;
- const char *propname= RNA_property_identifier(prop);
- char prop_item[MAX_IDPROP_NAME+4]; /* size of the ID prop name + room for [""] */
- int arraylen= RNA_property_array_length(ptr, prop);
-
- /* support for custom props */
- if(RNA_property_is_idprop(prop)) {
- sprintf(prop_item, "[\"%s\"]", propname);
- propname= prop_item;
- }
switch(RNA_property_type(prop)) {
- case PROP_BOOLEAN: {
+ case PROP_BOOLEAN:
+ {
+ int arraylen= RNA_property_array_length(ptr, prop);
if(arraylen && index == -1)
return NULL;
if(icon && name && name[0] == '\0')
- but= uiDefIconButR(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefIconButR_prop(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else if(icon)
- but= uiDefIconTextButR(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefIconTextButR_prop(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else
- but= uiDefButR(block, OPTION, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefButR_prop(block, OPTION, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
break;
}
case PROP_INT:
case PROP_FLOAT:
+ {
+ int arraylen= RNA_property_array_length(ptr, prop);
+
if(arraylen && index == -1) {
if(ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA))
- but= uiDefButR(block, COL, 0, name, x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL);
+ but= uiDefButR_prop(block, COL, 0, name, x1, y1, x2, y2, ptr, prop, 0, 0, 0, -1, -1, NULL);
}
else if(RNA_property_subtype(prop) == PROP_PERCENTAGE || RNA_property_subtype(prop) == PROP_FACTOR)
- but= uiDefButR(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefButR_prop(block, NUMSLI, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else
- but= uiDefButR(block, NUM, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefButR_prop(block, NUM, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
break;
+ }
case PROP_ENUM:
if(icon && name && name[0] == '\0')
- but= uiDefIconButR(block, MENU, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefIconButR_prop(block, MENU, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else if(icon)
- but= uiDefIconTextButR(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefIconTextButR_prop(block, MENU, 0, icon, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else
- but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefButR_prop(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
break;
case PROP_STRING:
if(icon && name && name[0] == '\0')
- but= uiDefIconButR(block, TEX, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefIconButR_prop(block, TEX, 0, icon, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else if(icon)
- but= uiDefIconTextButR(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefIconTextButR_prop(block, TEX, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
else
- but= uiDefButR(block, TEX, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefButR_prop(block, TEX, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
break;
case PROP_POINTER: {
PointerRNA pptr;
@@ -112,7 +109,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
if(icon == ICON_DOT)
icon= 0;
- but= uiDefIconTextButR(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ but= uiDefIconTextButR_prop(block, IDPOIN, 0, icon, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
break;
}
case PROP_COLLECTION: {
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 25a64994f5c..d235fd0c16a 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -771,7 +771,6 @@ static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), rcti *rect)
/* icons have been standardized... and this call draws in untransformed coordinates */
-#define ICON_HEIGHT UI_DPI_FAC*16.0f
static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect)
{
@@ -791,15 +790,15 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect
if(aspect != but->aspect) {
/* prevent scaling up icon in pupmenu */
if (aspect < 1.0f) {
- height= ICON_HEIGHT;
+ height= UI_DPI_ICON_SIZE;
aspect = 1.0f;
}
else
- height= ICON_HEIGHT/aspect;
+ height= UI_DPI_ICON_SIZE/aspect;
}
else
- height= ICON_HEIGHT;
+ height= UI_DPI_ICON_SIZE;
/* calculate blend color */
if ELEM4(but->type, TOG, ROW, TOGN, LISTROW) {
@@ -866,7 +865,7 @@ static void ui_text_leftclip(uiFontStyle *fstyle, uiBut *but, rcti *rect)
int border= (but->flag & UI_BUT_ALIGN_RIGHT)? 8: 10;
int okwidth= rect->xmax-rect->xmin - border;
- if (but->flag & UI_HAS_ICON) okwidth -= 16;
+ if (but->flag & UI_HAS_ICON) okwidth -= UI_DPI_ICON_SIZE;
/* need to set this first */
uiStyleFontSet(fstyle);
@@ -1149,7 +1148,7 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
if (but->flag & UI_HAS_ICON) {
widget_draw_icon(but, but->icon+but->iconadd, 1.0f, rect);
- rect->xmin += UI_icon_get_width(but->icon+but->iconadd);
+ rect->xmin += (int)((float)UI_icon_get_width(but->icon+but->iconadd) * UI_DPI_ICON_FAC);
if(but->editstr || (but->flag & UI_TEXT_LEFT))
rect->xmin += 5;
@@ -3133,7 +3132,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
/* text location offset */
rect->xmin+=5;
- if(iconid) rect->xmin+= ICON_HEIGHT;
+ if(iconid) rect->xmin+= UI_DPI_ICON_SIZE;
/* cut string in 2 parts? */
cpoin= strchr(name, '|');
@@ -3158,7 +3157,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic
if(iconid) {
int xs= rect->xmin+4;
- int ys= 1 + (rect->ymin+rect->ymax- ICON_HEIGHT)/2;
+ int ys= 1 + (rect->ymin+rect->ymax- UI_DPI_ICON_SIZE)/2;
glEnable(GL_BLEND);
UI_icon_draw_aspect(xs, ys, iconid, 1.2f, 0.5f); /* XXX scale weak get from fstyle? */
glDisable(GL_BLEND);
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 00c92b85ee7..02054fbe90f 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -366,7 +366,9 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp= ts->syntaxv; break;
case TH_NODE_GROUP:
cp= ts->syntaxc; break;
-
+ case TH_NODE_CURVING:
+ cp= &ts->noodle_curving; break;
+
case TH_SEQ_MOVIE:
cp= ts->movie; break;
case TH_SEQ_IMAGE:
@@ -796,6 +798,7 @@ void ui_theme_init_default(void)
SETCOL(btheme->tnode.syntaxb, 108, 105, 111, 255); /* operator */
SETCOL(btheme->tnode.syntaxv, 104, 106, 117, 255); /* generator */
SETCOL(btheme->tnode.syntaxc, 105, 117, 110, 255); /* group */
+ btheme->tnode.noodle_curving = 5;
/* space logic */
btheme->tlogic= btheme->tv3d;
@@ -1431,7 +1434,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)
@@ -1562,7 +1565,14 @@ void init_userdef_do_versions(void)
/* clear "AUTOKEY_FLAG_ONLYKEYINGSET" flag from userprefs, so that it doesn't linger around from old configs like a ghost */
U.autokey_flag &= ~AUTOKEY_FLAG_ONLYKEYINGSET;
}
-
+
+ if (bmain->versionfile < 258 || (bmain->versionfile == 258 && bmain->subversionfile < 2)) {
+ bTheme *btheme;
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ btheme->tnode.noodle_curving = 5;
+ }
+ }
+
if (bmain->versionfile < 258 || (bmain->versionfile == 258 && bmain->subversionfile < 1)) {
bTheme *btheme;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 395705dc029..c8d38218533 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1049,109 +1049,6 @@ static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob)
}
}
-static void copymenu_modifiers(Main *bmain, Scene *scene, View3D *v3d, Object *ob)
-{
- Base *base;
- int i, event;
- char str[512];
- const char *errorstr= NULL;
-
- strcpy(str, "Copy Modifiers %t");
-
- sprintf(str+strlen(str), "|All%%x%d|%%l", NUM_MODIFIER_TYPES);
-
- for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
- ModifierTypeInfo *mti = modifierType_getInfo(i);
-
- if(ELEM3(i, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue;
-
- if(i == eModifierType_Collision)
- continue;
-
- if ( (mti->flags&eModifierTypeFlag_AcceptsCVs) ||
- (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
- sprintf(str+strlen(str), "|%s%%x%d", mti->name, i);
- }
- }
-
- event = pupmenu(str);
- if(event<=0) return;
-
- for (base= FIRSTBASE; base; base= base->next) {
- if(base->object != ob) {
- if(TESTBASELIB(v3d, base)) {
-
- base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
-
- if (base->object->type==ob->type) {
- /* copy all */
- if (event==NUM_MODIFIER_TYPES) {
- ModifierData *md;
- object_free_modifiers(base->object);
-
- for (md=ob->modifiers.first; md; md=md->next) {
- ModifierData *nmd = NULL;
-
- if(ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue;
-
- if(md->type == eModifierType_Collision)
- continue;
-
- nmd = modifier_new(md->type);
- modifier_copyData(md, nmd);
- BLI_addtail(&base->object->modifiers, nmd);
- modifier_unique_name(&base->object->modifiers, nmd);
- }
-
- copy_object_particlesystems(base->object, ob);
- copy_object_softbody(base->object, ob);
- } else {
- /* copy specific types */
- ModifierData *md, *mdn;
-
- /* remove all with type 'event' */
- for (md=base->object->modifiers.first; md; md=mdn) {
- mdn= md->next;
- if(md->type==event) {
- BLI_remlink(&base->object->modifiers, md);
- modifier_free(md);
- }
- }
-
- /* copy all with type 'event' */
- for (md=ob->modifiers.first; md; md=md->next) {
- if (md->type==event) {
-
- mdn = modifier_new(event);
- BLI_addtail(&base->object->modifiers, mdn);
- modifier_unique_name(&base->object->modifiers, mdn);
-
- modifier_copyData(md, mdn);
- }
- }
-
- if(event == eModifierType_ParticleSystem) {
- object_free_particlesystems(base->object);
- copy_object_particlesystems(base->object, ob);
- }
- else if(event == eModifierType_Softbody) {
- object_free_softbody(base->object);
- copy_object_softbody(base->object, ob);
- }
- }
- }
- else
- errorstr= "Did not copy modifiers to other Object types";
- }
- }
- }
-
-// if(errorstr) notice(errorstr);
-
- DAG_scene_sort(bmain, scene);
-
-}
-
/* both pointers should exist */
static void copy_texture_space(Object *to, Object *ob)
{
@@ -1196,6 +1093,7 @@ static void copy_texture_space(Object *to, Object *ob)
}
+/* UNUSED, keep incase we want to copy functionality for use elsewhere */
static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
{
Object *ob;
@@ -1221,7 +1119,8 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
return;
}
else if(event==24) {
- copymenu_modifiers(bmain, scene, v3d, ob);
+ /* moved to object_link_modifiers */
+ /* copymenu_modifiers(bmain, scene, v3d, ob); */
return;
}
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 77524c7e117..d4253495e97 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -64,6 +64,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <ctype.h>
/* for events */
#define NOTACTIVEFILE 0
@@ -1079,8 +1080,18 @@ static void file_expand_directory(bContext *C)
}
#ifdef WIN32
- if (sfile->params->dir[0] == '\0')
+ if (sfile->params->dir[0] == '\0') {
get_default_root(sfile->params->dir);
+ }
+ /* change "C:" --> "C:\", [#28102] */
+ else if ( (isalpha(sfile->params->dir[0]) &&
+ (sfile->params->dir[1] == ':')) &&
+ (sfile->params->dir[2] == '\0')
+
+ ) {
+ sfile->params->dir[2]= '\\';
+ sfile->params->dir[3]= '\0';
+ }
#endif
}
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index e0ebde589a8..ea8c7fc0cfa 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -447,34 +447,41 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
static int view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
{
- SpaceImage *sima= CTX_wm_space_image(C);
- ARegion *ar= CTX_wm_region(C);
+ if (event->type != NDOF_MOTION)
+ return OPERATOR_CANCELLED;
+ else {
+ SpaceImage *sima= CTX_wm_space_image(C);
+ ARegion *ar= CTX_wm_region(C);
- wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+ wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
- float dt = ndof->dt;
- /* tune these until it feels right */
- const float zoom_sensitivity = 0.5f; // 50% per second (I think)
- const float pan_sensitivity = 300.f; // screen pixels per second
+ float dt = ndof->dt;
+ /* tune these until it feels right */
+ const float zoom_sensitivity = 0.5f; // 50% per second (I think)
+ const float pan_sensitivity = 300.f; // screen pixels per second
- float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sima->zoom;
- float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sima->zoom;
+ float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sima->zoom;
+ float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sima->zoom;
- /* "mouse zoom" factor = 1 + (dx + dy) / 300
- * what about "ndof zoom" factor? should behave like this:
- * at rest -> factor = 1
- * move forward -> factor > 1
- * move backward -> factor < 1
- */
- float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tvec[2];
+ /* "mouse zoom" factor = 1 + (dx + dy) / 300
+ * what about "ndof zoom" factor? should behave like this:
+ * at rest -> factor = 1
+ * move forward -> factor > 1
+ * move backward -> factor < 1
+ */
+ float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tvec[2];
- sima_zoom_set_factor(sima, ar, zoom_factor);
- sima->xof += pan_x;
- sima->yof += pan_y;
+ if (U.ndof_flag & NDOF_ZOOM_INVERT)
+ zoom_factor = -zoom_factor;
- ED_region_tag_redraw(ar);
+ sima_zoom_set_factor(sima, ar, zoom_factor);
+ sima->xof += pan_x;
+ sima->yof += pan_y;
- return OPERATOR_FINISHED;
+ ED_region_tag_redraw(ar);
+
+ return OPERATOR_FINISHED;
+ }
}
void IMAGE_OT_view_ndof(wmOperatorType *ot)
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 50e657bbb61..c32d05e9c30 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1768,8 +1768,8 @@ int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, floa
vec[3][0]= snode->mx;
vec[3][1]= snode->my;
}
-
- dist= 0.5f*ABS(vec[0][0] - vec[3][0]);
+
+ dist= UI_GetThemeValue(TH_NODE_CURVING)*0.10f*ABS(vec[0][0] - vec[3][0]);
/* check direction later, for top sockets */
vec[1][0]= vec[0][0]+dist;
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 14dad30467f..b9f6b986691 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1788,7 +1788,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
se = give_stripelem(seq, cfra);
seq_new= seq_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME);
- BLI_addtail(&ed->seqbase, seq_new);
+ BLI_addtail(ed->seqbasep, seq_new);
seq_new->start= start_ofs;
seq_new->type= SEQ_IMAGE;
@@ -1842,7 +1842,6 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot)
ot->description="On image sequences strips, it return a strip for each image";
/* api callbacks */
- ot->invoke= WM_operator_props_popup;
ot->exec= sequencer_separate_images_exec;
ot->poll= sequencer_edit_poll;
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index e6fd9e8867b..3e6bbc13334 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -949,134 +949,125 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event
// -- zooming
// -- panning in rotationally-locked views
{
- RegionView3D* rv3d = CTX_wm_region_view3d(C);
- wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+ if (event->type != NDOF_MOTION)
+ return OPERATOR_CANCELLED;
+ else {
+ RegionView3D* rv3d = CTX_wm_region_view3d(C);
+ wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
- rv3d->rot_angle = 0.f; // off by default, until changed later this function
+ rv3d->rot_angle = 0.f; // off by default, until changed later this function
- if (ndof->progress != P_FINISHING) {
- const float dt = ndof->dt;
-
- // tune these until everything feels right
- const float rot_sensitivity = 1.f;
- const float zoom_sensitivity = 1.f;
- const float pan_sensitivity = 1.f;
-
- // rather have bool, but...
- int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec);
-
- float view_inv[4];
- invert_qt_qt(view_inv, rv3d->viewquat);
-
- //#define DEBUG_NDOF_MOTION
- #ifdef DEBUG_NDOF_MOTION
- printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n",
- ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt);
- #endif
-
- if (ndof->tvec[2]) {
- // Zoom!
- // velocity should be proportional to the linear velocity attained by rotational motion of same strength
- // [got that?]
- // proportional to arclength = radius * angle
-
- float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tvec[2];
- rv3d->dist += zoom_distance;
- }
-
- if (rv3d->viewlock == RV3D_LOCKED) {
- /* rotation not allowed -- explore panning options instead */
- float pan_vec[3] = {ndof->tvec[0], ndof->tvec[1], 0.0f};
- mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
-
- /* transform motion from view to world coordinates */
+ if (ndof->progress != P_FINISHING) {
+ const float dt = ndof->dt;
+
+ // tune these until everything feels right
+ const float rot_sensitivity = 1.f;
+ const float zoom_sensitivity = 1.f;
+ const float pan_sensitivity = 1.f;
+
+ // rather have bool, but...
+ int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec);
+
+ float view_inv[4];
invert_qt_qt(view_inv, rv3d->viewquat);
- mul_qt_v3(view_inv, pan_vec);
-
- /* move center of view opposite of hand motion (this is camera mode, not object mode) */
- sub_v3_v3(rv3d->ofs, pan_vec);
- }
-
- if (has_rotation) {
-
- const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES;
-
- rv3d->view = RV3D_VIEW_USER;
-
- if (U.flag & USER_TRACKBALL) {
- float rot[4];
- #if 0 // -------------------------- Mike's nifty original version
- float view_inv_conj[4];
-
- ndof_to_quat(ndof, rot);
- // mul_qt_fl(rot, rot_sensitivity);
- // ^^ no apparent effect
-
- if (invert)
- invert_qt(rot);
-
- copy_qt_qt(view_inv_conj, view_inv);
- conjugate_qt(view_inv_conj);
-
- // transform rotation from view to world coordinates
- mul_qt_qtqt(rot, view_inv, rot);
- mul_qt_qtqt(rot, rot, view_inv_conj);
- #else // ---------------------------------------- Mike's revised version
- float axis[3];
- float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
-
- if (invert)
- angle = -angle;
-
- // transform rotation axis from view to world coordinates
- mul_qt_v3(view_inv, axis);
-
- // update the onscreen doo-dad
- rv3d->rot_angle = angle;
- copy_v3_v3(rv3d->rot_axis, axis);
-
- axis_angle_to_quat(rot, axis, angle);
- #endif // --------------------------------------------
- // apply rotation
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
- } else {
- /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
- float angle, rot[4];
- float xvec[3] = {1,0,0};
-
- /* Determine the direction of the x vector (for rotating up and down) */
- mul_qt_v3(view_inv, xvec);
-
- /* Perform the up/down rotation */
- angle = rot_sensitivity * dt * ndof->rvec[0];
- if (invert)
- angle = -angle;
- rot[0] = cos(angle);
- mul_v3_v3fl(rot+1, xvec, sin(angle));
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
-
- /* Perform the orbital rotation */
- angle = rot_sensitivity * dt * ndof->rvec[1];
- if (invert)
- angle = -angle;
-
- // update the onscreen doo-dad
- rv3d->rot_angle = angle;
- rv3d->rot_axis[0] = 0;
- rv3d->rot_axis[1] = 0;
- rv3d->rot_axis[2] = 1;
-
- rot[0] = cos(angle);
- rot[1] = rot[2] = 0.0;
- rot[3] = sin(angle);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+
+ //#define DEBUG_NDOF_MOTION
+ #ifdef DEBUG_NDOF_MOTION
+ printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n",
+ ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt);
+ #endif
+
+ if (ndof->tvec[2]) {
+ // Zoom!
+ // velocity should be proportional to the linear velocity attained by rotational motion of same strength
+ // [got that?]
+ // proportional to arclength = radius * angle
+
+ float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tvec[2];
+
+ if (U.ndof_flag & NDOF_ZOOM_INVERT)
+ zoom_distance = -zoom_distance;
+
+ rv3d->dist += zoom_distance;
+ }
+
+ if (rv3d->viewlock == RV3D_LOCKED) {
+ /* rotation not allowed -- explore panning options instead */
+ float pan_vec[3] = {ndof->tvec[0], ndof->tvec[1], 0.0f};
+ mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
+
+ /* transform motion from view to world coordinates */
+ invert_qt_qt(view_inv, rv3d->viewquat);
+ mul_qt_v3(view_inv, pan_vec);
+
+ /* move center of view opposite of hand motion (this is camera mode, not object mode) */
+ sub_v3_v3(rv3d->ofs, pan_vec);
+ }
+
+ if (has_rotation) {
+
+ const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES;
+
+ rv3d->view = RV3D_VIEW_USER;
+
+ if (U.flag & USER_TRACKBALL) {
+ float rot[4];
+ float axis[3];
+ float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
+
+ if (invert)
+ angle = -angle;
+
+ // transform rotation axis from view to world coordinates
+ mul_qt_v3(view_inv, axis);
+
+ // update the onscreen doo-dad
+ rv3d->rot_angle = angle;
+ copy_v3_v3(rv3d->rot_axis, axis);
+
+ axis_angle_to_quat(rot, axis, angle);
+
+ // apply rotation
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+ } else {
+ /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
+ float angle, rot[4];
+ float xvec[3] = {1,0,0};
+
+ /* Determine the direction of the x vector (for rotating up and down) */
+ mul_qt_v3(view_inv, xvec);
+
+ /* Perform the up/down rotation */
+ angle = rot_sensitivity * dt * ndof->rvec[0];
+ if (invert)
+ angle = -angle;
+ rot[0] = cos(angle);
+ mul_v3_v3fl(rot+1, xvec, sin(angle));
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+
+ /* Perform the orbital rotation */
+ angle = rot_sensitivity * dt * ndof->rvec[1];
+ if (invert)
+ angle = -angle;
+
+ // update the onscreen doo-dad
+ rv3d->rot_angle = angle;
+ rv3d->rot_axis[0] = 0;
+ rv3d->rot_axis[1] = 0;
+ rv3d->rot_axis[2] = 1;
+
+ rot[0] = cos(angle);
+ rot[1] = rot[2] = 0.0;
+ rot[3] = sin(angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+ }
}
}
- }
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
+ }
}
void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
@@ -1098,57 +1089,62 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
// -- "pan" navigation
// -- zoom or dolly?
{
- RegionView3D* rv3d = CTX_wm_region_view3d(C);
- wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+ if (event->type != NDOF_MOTION)
+ return OPERATOR_CANCELLED;
+ else {
+ RegionView3D* rv3d = CTX_wm_region_view3d(C);
+ wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+
- rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators
+ rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators
- if (ndof->progress != P_FINISHING) {
- const float dt = ndof->dt;
- float view_inv[4];
+ if (ndof->progress != P_FINISHING) {
+ const float dt = ndof->dt;
+ float view_inv[4];
#if 0 // ------------------------------------------- zoom with Z
- // tune these until everything feels right
- const float zoom_sensitivity = 1.f;
- const float pan_sensitivity = 1.f;
-
- float pan_vec[3] = {
- ndof->tx, ndof->ty, 0
- };
-
- // "zoom in" or "translate"? depends on zoom mode in user settings?
- if (ndof->tz) {
- float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
- rv3d->dist += zoom_distance;
- }
-
- mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
+ // tune these until everything feels right
+ const float zoom_sensitivity = 1.f;
+ const float pan_sensitivity = 1.f;
+
+ float pan_vec[3] = {
+ ndof->tx, ndof->ty, 0
+ };
+
+ // "zoom in" or "translate"? depends on zoom mode in user settings?
+ if (ndof->tz) {
+ float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
+ rv3d->dist += zoom_distance;
+ }
+
+ mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
#else // ------------------------------------------------------- dolly with Z
- float speed = 10.f; // blender units per second
- // ^^ this is ok for default cube scene, but should scale with.. something
+ float speed = 10.f; // blender units per second
+ // ^^ this is ok for default cube scene, but should scale with.. something
- // tune these until everything feels right
- const float forward_sensitivity = 1.f;
- const float vertical_sensitivity = 0.4f;
- const float lateral_sensitivity = 0.6f;
+ // tune these until everything feels right
+ const float forward_sensitivity = 1.f;
+ const float vertical_sensitivity = 0.4f;
+ const float lateral_sensitivity = 0.6f;
- float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0],
- vertical_sensitivity * ndof->tvec[1],
- forward_sensitivity * ndof->tvec[2]
- };
+ float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0],
+ vertical_sensitivity * ndof->tvec[1],
+ forward_sensitivity * ndof->tvec[2]
+ };
- mul_v3_fl(pan_vec, speed * dt);
+ mul_v3_fl(pan_vec, speed * dt);
#endif
- /* transform motion from view to world coordinates */
- invert_qt_qt(view_inv, rv3d->viewquat);
- mul_qt_v3(view_inv, pan_vec);
+ /* transform motion from view to world coordinates */
+ invert_qt_qt(view_inv, rv3d->viewquat);
+ mul_qt_v3(view_inv, pan_vec);
- /* move center of view opposite of hand motion (this is camera mode, not object mode) */
- sub_v3_v3(rv3d->ofs, pan_vec);
- }
+ /* move center of view opposite of hand motion (this is camera mode, not object mode) */
+ sub_v3_v3(rv3d->ofs, pan_vec);
+ }
- ED_region_tag_redraw(CTX_wm_region(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
+ }
}
void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index a43fc6a31e5..8d6c56e5cce 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -911,6 +911,7 @@ void resetTransRestrictions(TransInfo *t)
t->flag &= ~T_ALL_RESTRICTIONS;
}
+/* the *op can be NULL */
int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
{
Scene *sce = CTX_data_scene(C);
@@ -1039,7 +1040,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
}
/* initialize UV transform from */
- if (RNA_struct_find_property(op->ptr, "correct_uv")) {
+ if (op && RNA_struct_find_property(op->ptr, "correct_uv")) {
if(RNA_property_is_set(op->ptr, "correct_uv")) {
if(RNA_boolean_get(op->ptr, "correct_uv")) {
t->settings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT;
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index ff9f2269f53..1549bd71748 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -703,7 +703,7 @@ enum FileSortTypeE {
#define FILE_HIDE_DOT (1<<3)
#define FILE_AUTOSELECT (1<<4)
#define FILE_ACTIVELAY (1<<5)
-#define FILE_ATCURSOR (1<<6)
+/* #define FILE_ATCURSOR (1<<6) */ /* deprecated */
#define FILE_DIRSEL_ONLY (1<<7)
#define FILE_FILTER (1<<8)
#define FILE_BOOKMARKS (1<<9)
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index e5558c1738b..e211a7c33c1 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -223,7 +223,7 @@ typedef struct ThemeSpace {
char console_cursor[4];
char vertex_size, outline_width, facedot_size;
- char bpad;
+ char noodle_curving;
char syntaxl[4], syntaxn[4], syntaxb[4]; // syntax for textwindow and nodes
char syntaxv[4], syntaxc[4];
@@ -344,7 +344,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];
@@ -606,7 +607,7 @@ extern UserDef U; /* from blenkernel blender.c */
#define NDOF_ORBIT_INVERT_AXES (1 << 6)
/* zoom is up/down if this flag is set (otherwise forward/backward) */
#define NDOF_ZOOM_UPDOWN (1 << 7)
-#define NDOF_INVERT_ZOOM (1 << 8)
+#define NDOF_ZOOM_INVERT (1 << 8)
#ifdef __cplusplus
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_access.c b/source/blender/makesrna/intern/rna_access.c
index 2ff2bf5cc7b..ac3508b9b4a 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -4115,10 +4115,13 @@ void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
{
PropertyRNA *prop= RNA_struct_find_property(ptr, name);
- if(prop)
+ if(prop) {
RNA_property_string_get(ptr, prop, value);
- else
+ }
+ else {
printf("RNA_string_get: %s.%s not found.\n", ptr->type->identifier, name);
+ value[0]= '\0';
+ }
}
char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index f0028fb331c..b1e4721bc79 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -239,9 +239,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_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 21fa28af01a..d48f1c93da8 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -45,9 +45,9 @@
// #include "ED_mesh.h"
-#include "BLI_math.h"
#ifdef RNA_RUNTIME
+#include "BLI_math.h"
#include "BKE_main.h"
#include "BKE_global.h"
@@ -544,7 +544,8 @@ void RNA_api_object(StructRNA *srna)
/* location of point for test and max distance */
parm= RNA_def_float_vector(func, "point", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_float(func, "max_dist", sqrt(FLT_MAX), 0.0, FLT_MAX, "", "", 0.0, FLT_MAX);
+ /* default is sqrt(FLT_MAX) */
+ RNA_def_float(func, "max_dist", 1.844674352395373e+19, 0.0, FLT_MAX, "", "", 0.0, FLT_MAX);
/* return location and normal */
parm= RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "The location on the object closest to the point", -1e4, 1e4);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 6d0e9661e04..7313a39e5ec 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1433,7 +1433,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 879ff3f3090..3936c9fd28b 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -1371,6 +1371,13 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Group Node", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop= RNA_def_property(srna, "noodle_curving", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "noodle_curving");
+ RNA_def_property_int_default(prop, 5);
+ RNA_def_property_range(prop, 0, 10);
+ RNA_def_property_ui_text(prop, "Noodle curving", "Curving of the noodle");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_space_logic(BlenderRNA *brna)
@@ -2759,19 +2766,32 @@ static void rna_def_userdef_input(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Drag Threshold", "Amount of pixels you have to drag before dragging UI items happens");
/* 3D mouse settings */
+ /* global options */
prop= RNA_def_property(srna, "ndof_sensitivity", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.25f, 4.0f);
RNA_def_property_ui_text(prop, "Sensitivity", "Overall sensitivity of the 3D Mouse");
+ prop= RNA_def_property(srna, "ndof_zoom_updown", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ZOOM_UPDOWN);
+ RNA_def_property_ui_text(prop, "Zoom = Up/Down", "Zoom using up/down on the device (otherwise forward/backward)");
+
+ prop= RNA_def_property(srna, "ndof_zoom_invert", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ZOOM_INVERT);
+ RNA_def_property_ui_text(prop, "Invert Zoom", "Zoom using opposite direction");
+
+ /* 3D view */
prop= RNA_def_property(srna, "ndof_show_guide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_SHOW_GUIDE);
RNA_def_property_ui_text(prop, "Show Navigation Guide", "Display the center and axis during rotation");
/* TODO: update description when fly-mode visuals are in place ("projected position in fly mode")*/
+ /* 3D view: orbit */
prop= RNA_def_property(srna, "ndof_orbit_invert_axes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ORBIT_INVERT_AXES);
RNA_def_property_ui_text(prop, "Invert Axes", "Toggle between moving the viewpoint or moving the scene being viewed");
+ /* in 3Dx docs, this is called 'object mode' vs. 'target camera mode'
+ /* 3D view: fly */
prop= RNA_def_property(srna, "ndof_lock_horizon", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_LOCK_HORIZON);
RNA_def_property_ui_text(prop, "Lock Horizon", "Keep horizon level while flying with 3D Mouse");
@@ -2808,12 +2828,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/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index bcd5df97c2c..d68fd9a9111 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -41,8 +41,6 @@
#include "bpy_driver.h"
-#include "../generic/py_capi_utils.h"
-
/* for pydrivers (drivers using one-line Python expressions to express relationships between targets) */
PyObject *bpy_pydriver_Dict= NULL;
@@ -89,7 +87,7 @@ int bpy_pydriver_create_dict(void)
void BPY_driver_reset(void)
{
PyGILState_STATE gilstate;
- int use_gil= !PYC_INTERPRETER_ACTIVE;
+ int use_gil= 1; /* !PYC_INTERPRETER_ACTIVE; */
if(use_gil)
gilstate= PyGILState_Ensure();
@@ -120,9 +118,14 @@ static void pydriver_error(ChannelDriver *driver)
/* This evals py driver expressions, 'expr' is a Python expression that
* should evaluate to a float number, which is returned.
*
- * note: PyGILState_Ensure() isnt always called because python can call the
- * bake operator which intern starts a thread which calls scene update which
- * does a driver update. to avoid a deadlock check PYC_INTERPRETER_ACTIVE if PyGILState_Ensure() is needed.
+ * (old)note: PyGILState_Ensure() isnt always called because python can call
+ * the bake operator which intern starts a thread which calls scene update
+ * which does a driver update. to avoid a deadlock check PYC_INTERPRETER_ACTIVE
+ * if PyGILState_Ensure() is needed - see [#27683]
+ *
+ * (new)note: checking if python is running is not threadsafe [#28114]
+ * now release the GIL on python operator execution instead, using
+ * PyEval_SaveThread() / PyEval_RestoreThread() so we dont lock up blender.
*/
float BPY_driver_exec(ChannelDriver *driver)
{
@@ -149,7 +152,7 @@ float BPY_driver_exec(ChannelDriver *driver)
return 0.0f;
}
- use_gil= !PYC_INTERPRETER_ACTIVE;
+ use_gil= 1; /* !PYC_INTERPRETER_ACTIVE; */
if(use_gil)
gilstate= PyGILState_Ensure();
diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c
index 85bffb5a8cc..4ce3e0356e2 100644
--- a/source/blender/python/intern/bpy_library.c
+++ b/source/blender/python/intern/bpy_library.c
@@ -39,6 +39,7 @@
#include "BKE_library.h"
#include "BKE_idcode.h"
#include "BKE_report.h"
+#include "BKE_context.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
@@ -317,7 +318,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
flag_all_listbases_ids(LIB_PRE_EXISTING, 1);
/* here appending/linking starts */
- mainl= BLO_library_append_begin(BPy_GetContext(), &(self->blo_handle), self->relpath);
+ mainl= BLO_library_append_begin(CTX_data_main(BPy_GetContext()), &(self->blo_handle), self->relpath);
{
int i= 0, code;
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index b8883e655f2..4b05a9c0c72 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -55,6 +55,10 @@
#include "BKE_report.h"
#include "BKE_context.h"
+/* so operators called can spawn threads which aquire the GIL */
+#define BPY_RELEASE_GIL
+
+
static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args)
{
wmOperatorType *ot;
@@ -219,7 +223,22 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args)
reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList");
BKE_reports_init(reports, RPT_STORE | RPT_OP_HOLD); /* own so these dont move into global reports */
- operator_ret= WM_operator_call_py(C, ot, context, &ptr, reports);
+#ifdef BPY_RELEASE_GIL
+ /* release GIL, since a thread could be started from an operator
+ * that updates a driver */
+ /* note: I havve not seen any examples of code that does this
+ * so it may not be officially supported but seems to work ok. */
+ {
+ PyThreadState *ts= PyEval_SaveThread();
+#endif
+
+ operator_ret= WM_operator_call_py(C, ot, context, &ptr, reports);
+
+#ifdef BPY_RELEASE_GIL
+ /* regain GIL */
+ PyEval_RestoreThread(ts);
+ }
+#endif
error_val= BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE);
@@ -378,7 +397,9 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
+#ifdef PYRNA_FREE_SUPPORT
pyrna->freeptr= TRUE;
+#endif
return (PyObject *)pyrna;
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 502b25842de..4447a0476f4 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -908,6 +908,13 @@ static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self)
return ret;
}
+
+static PyObject *pyrna_func_repr(BPy_FunctionRNA *self)
+{
+ return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>", Py_TYPE(self)->tp_name, RNA_struct_identifier(self->ptr.type), RNA_function_identifier(self->func));
+}
+
+
static long pyrna_struct_hash(BPy_StructRNA *self)
{
return _Py_HashPointer(self->ptr.data);
@@ -950,11 +957,13 @@ static int pyrna_struct_clear(BPy_StructRNA *self)
/* use our own dealloc so we can free a property if we use one */
static void pyrna_struct_dealloc(BPy_StructRNA *self)
{
+#ifdef PYRNA_FREE_SUPPORT
if (self->freeptr && self->ptr.data) {
IDP_FreeProperty(self->ptr.data);
MEM_freeN(self->ptr.data);
self->ptr.data= NULL;
}
+#endif /* PYRNA_FREE_SUPPORT */
#ifdef USE_WEAKREFS
if (self->in_weakreflist != NULL) {
@@ -1344,36 +1353,16 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
return error_val;
}
-static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw);
-static PyObject *pyrna_func_to_py(BPy_DummyPointerRNA *pyrna, FunctionRNA *func)
+static PyObject *pyrna_func_to_py(PointerRNA *ptr, FunctionRNA *func)
{
- static PyMethodDef func_meth= {"<generic rna function>", (PyCFunction)pyrna_func_call, METH_VARARGS|METH_KEYWORDS, "python rna function"};
- PyObject *self;
- PyObject *ret;
-
- if(func==NULL) {
- PyErr_Format(PyExc_RuntimeError,
- "%.200s: type attempted to get NULL function",
- RNA_struct_identifier(pyrna->ptr.type));
- return NULL;
- }
-
- self= PyTuple_New(2);
-
- PyTuple_SET_ITEM(self, 0, (PyObject *)pyrna);
- Py_INCREF(pyrna);
-
- PyTuple_SET_ITEM(self, 1, PyCapsule_New((void *)func, NULL, NULL));
-
- ret= PyCFunction_New(&func_meth, self);
- Py_DECREF(self);
-
- return ret;
+ BPy_FunctionRNA* pyfunc= (BPy_FunctionRNA *) PyObject_NEW(BPy_FunctionRNA, &pyrna_func_Type);
+ pyfunc->ptr= *ptr;
+ pyfunc->func= func;
+ return (PyObject *)pyfunc;
}
-
static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *value, const char *error_prefix)
{
/* XXX hard limits should be checked here */
@@ -3001,7 +2990,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
}
/* RNA function only if callback is declared (no optional functions) */
else if ((func= RNA_struct_find_function(&self->ptr, name)) && RNA_function_defined(func)) {
- ret= pyrna_func_to_py((BPy_DummyPointerRNA *)self, func);
+ ret= pyrna_func_to_py(&self->ptr, func);
}
else if (self->ptr.type == &RNA_Context) {
bContext *C= self->ptr.data;
@@ -3303,7 +3292,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject
}
else if ((func= RNA_struct_find_function(&r_ptr, name))) {
PyObject *self_collection= pyrna_struct_CreatePyObject(&r_ptr);
- ret= pyrna_func_to_py((BPy_DummyPointerRNA *)self_collection, func);
+ ret= pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func);
Py_DECREF(self_collection);
return ret;
@@ -4257,11 +4246,11 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
return ret;
}
-static PyObject *pyrna_func_call(PyObject *self, PyObject *args, PyObject *kw)
+static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw)
{
/* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here */
- PointerRNA *self_ptr= &(((BPy_DummyPointerRNA *)PyTuple_GET_ITEM(self, 0))->ptr);
- FunctionRNA *self_func= PyCapsule_GetPointer(PyTuple_GET_ITEM(self, 1), NULL);
+ PointerRNA *self_ptr= &self->ptr;
+ FunctionRNA *self_func= self->func;
PointerRNA funcptr;
ParameterList parms;
@@ -5045,6 +5034,91 @@ static PyTypeObject pyrna_prop_collection_idprop_Type= {
NULL
};
+/*-----------------------BPy_PropertyRNA method def------------------------------*/
+PyTypeObject pyrna_func_Type= {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "bpy_func", /* tp_name */
+ sizeof(BPy_FunctionRNA), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ NULL, /* tp_dealloc */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
+ (reprfunc) pyrna_func_repr, /* tp_repr */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ NULL, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ NULL, /* hashfunc tp_hash; */
+ (ternaryfunc)pyrna_func_call, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+
+ /* will only use these if this is a subtype of a py class */
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /*** Flags to define presence of optional/expanded features ***/
+ Py_TPFLAGS_DEFAULT, /* long tp_flags; */
+
+ NULL, /* char *tp_doc; Documentation string */
+ /*** Assigned meaning in release 2.0 ***/
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /*** Assigned meaning in release 2.1 ***/
+ /*** rich comparisons ***/
+ NULL, /* richcmpfunc tp_richcompare; */
+
+ /*** weak reference enabler ***/
+#ifdef USE_WEAKREFS
+ offsetof(BPy_PropertyRNA, in_weakreflist), /* long tp_weaklistoffset; */
+#else
+ 0,
+#endif
+
+ /*** Added in release 2.2 ***/
+ /* Iterators */
+ NULL, /* getiterfunc tp_iter; */
+ NULL, /* iternextfunc tp_iternext; */
+
+ /*** Attribute descriptor and subclassing stuff ***/
+ NULL, /* struct PyMethodDef *tp_methods; */
+ NULL, /* struct PyMemberDef *tp_members; */
+ NULL, /* struct PyGetSetDef *tp_getset; */
+ NULL, /* struct _typeobject *tp_base; */
+ NULL, /* PyObject *tp_dict; */
+ NULL, /* descrgetfunc tp_descr_get; */
+ NULL, /* descrsetfunc tp_descr_set; */
+ 0, /* long tp_dictoffset; */
+ NULL, /* initproc tp_init; */
+ NULL, /* allocfunc tp_alloc; */
+ NULL, /* newfunc tp_new; */
+ /* Low-level free-memory routine */
+ NULL, /* freefunc tp_free; */
+ /* For PyObject_IS_GC */
+ NULL, /* inquiry tp_is_gc; */
+ NULL, /* PyObject *tp_bases; */
+ /* method resolution order */
+ NULL, /* PyObject *tp_mro; */
+ NULL, /* PyObject *tp_cache; */
+ NULL, /* PyObject *tp_subclasses; */
+ NULL, /* PyObject *tp_weaklist; */
+ NULL
+};
+
#ifdef USE_PYRNA_ITER
/* --- collection iterator: start --- */
/* wrap rna collection iterator functions */
@@ -5423,7 +5497,9 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
}
pyrna->ptr= *ptr;
+#ifdef PYRNA_FREE_SUPPORT
pyrna->freeptr= FALSE;
+#endif
#ifdef USE_PYRNA_STRUCT_REFERENCE
pyrna->reference= NULL;
@@ -5516,6 +5592,9 @@ void BPY_rna_init(void)
if(PyType_Ready(&pyrna_prop_collection_idprop_Type) < 0)
return;
+ if(PyType_Ready(&pyrna_func_Type) < 0)
+ return;
+
#ifdef USE_PYRNA_ITER
if(PyType_Ready(&pyrna_prop_collection_iter_Type) < 0)
return;
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index 5db352af53d..30f6c02115a 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -62,6 +62,11 @@
#if defined(USE_PYRNA_INVALIDATE_GC) && defined(USE_PYRNA_INVALIDATE_WEAKREF)
#error "Only 1 reference check method at a time!"
#endif
+
+/* only used by operator introspection get_rna(), this is only used for doc gen
+ * so prefer the leak to the memory bloat for now. */
+// #define PYRNA_FREE_SUPPORT
+
/* --- end bpy build options --- */
struct ID;
@@ -71,6 +76,7 @@ extern PyTypeObject pyrna_struct_Type;
extern PyTypeObject pyrna_prop_Type;
extern PyTypeObject pyrna_prop_array_Type;
extern PyTypeObject pyrna_prop_collection_Type;
+extern PyTypeObject pyrna_func_Type;
#define BPy_StructRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_struct_Type))
#define BPy_StructRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_struct_Type)
@@ -107,7 +113,10 @@ typedef struct {
* hold onto the collection iterator to prevent it from freeing allocated data we may use */
PyObject *reference;
#endif /* !USE_PYRNA_STRUCT_REFERENCE */
+
+#ifdef PYRNA_FREE_SUPPORT
int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
+#endif /* PYRNA_FREE_SUPPORT */
} BPy_StructRNA;
typedef struct {
@@ -142,6 +151,15 @@ typedef struct {
CollectionPropertyIterator iter;
} BPy_PropertyCollectionIterRNA;
+typedef struct {
+ PyObject_HEAD /* required python macro */
+#ifdef USE_WEAKREFS
+ PyObject *in_weakreflist;
+#endif
+ PointerRNA ptr;
+ FunctionRNA *func;
+} BPy_FunctionRNA;
+
/* cheap trick */
#define BPy_BaseTypeRNA BPy_PropertyRNA
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..258d6bbc025 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 ************ */
@@ -2324,26 +2330,28 @@ static void attach_ndof_data(wmEvent* event, const GHOST_TEventNDOFMotionData* g
const float s = U.ndof_sensitivity;
data->tvec[0]= s * ghost->tx;
+
data->rvec[0]= s * ghost->rx;
+ data->rvec[1]= s * ghost->ry;
+ data->rvec[2]= s * ghost->rz;
if (U.ndof_flag & NDOF_ZOOM_UPDOWN)
{
- // swap Y and Z
+ // rotate so Y is where Z was (maintain handed-ness)
data->tvec[1]= s * ghost->tz;
- data->tvec[2]= s * ghost->ty;
+ data->tvec[2]= s * -ghost->ty;
// should this affect rotation also?
// initial guess is 'yes', but get user feedback immediately!
+#if 0 // after turning this on, my guess becomes 'no'
data->rvec[1]= s * ghost->rz;
data->rvec[2]= s * ghost->ry;
+#endif
}
else
{
data->tvec[1]= s * ghost->ty;
data->tvec[2]= s * ghost->tz;
-
- data->rvec[1]= s * ghost->ry;
- data->rvec[2]= s * ghost->rz;
}
data->dt = ghost->dt;
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index fee68be5eb7..75638382399 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;
@@ -799,11 +807,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..2fb0a1b2ab9 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 wmKeyMap *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);
+
+ /* 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);
+
+ return 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,214 @@ 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, *kmn;
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 */
+ kmn= wm_keymap_patch_update(&wm->userconf->keymaps, defaultmap, addonmap, usermap);
- kmi->properties= IDP_CopyProperty(kmi->properties);
- kmi->ptr->data= kmi->properties;
+ if(kmn) {
+ kmn->modal_items= km->modal_items;
+ kmn->poll= km->poll;
}
+
+ /* 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;
- if (!km) {
- /* or from default */
- km= WM_keymap_list_find(&wm->defaultconf->keymaps, keymap->idname, keymap->spaceid, keymap->regionid);
+ /* 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(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) {
+ if(kmi->properties) {
+ IDP_FreeProperty(kmi->properties);
+ MEM_freeN(kmi->properties);
+ kmi->properties= NULL;
}
-
- if (orig->properties) {
- 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;
+ 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 +1337,4 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
return km;
}
+
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index a47dfacf358..cea2d6b3fe5 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1621,7 +1621,6 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
int idcode, totfiles=0;
short flag;
- name[0] = '\0';
RNA_string_get(op->ptr, "filename", name);
RNA_string_get(op->ptr, "directory", dir);
@@ -1690,7 +1689,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
flag_all_listbases_ids(LIB_PRE_EXISTING, 1);
/* here appending/linking starts */
- mainl = BLO_library_append_begin(C, &bh, libname);
+ mainl = BLO_library_append_begin(bmain, &bh, libname);
if(totfiles == 0) {
BLO_library_append_named_part_ex(C, mainl, &bh, name, idcode, flag);
}
@@ -3720,7 +3719,7 @@ void wm_window_keymap(wmKeyConfig *keyconf)
/* menus that can be accessed anywhere in blender */
WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0);
- WM_keymap_add_menu(keymap, "VIEW3D_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0);
+ WM_keymap_add_menu(keymap, "USERPREF_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0);
/* Space switching */
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F2KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was DXF export */