Context
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 19 Mar 2009 19:03:38 +0000 (19:03 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 19 Mar 2009 19:03:38 +0000 (19:03 +0000)
* Made it based on string lookups rather than fixed enum, to make
  it extensible by python scripts.
* Context callbacks now also have to specify RNA type when returning
  pointers or collections. For non-RNA wrapped data, UnknownType can
  be used.
* RNA wrapped context. The WM entries are fixed, for data context
  only main and scene are defined properties. Other data entries have
  to be dynamically looked up.
* I've added some special code in python for the dynamic context
  lookups. Tried to hide it behind RNA but didn't find a clean way to
  do it yet. Still unused/untested.

* Also minor fix for warning about propertional edit property in
  transform code, and fix for usage of operator poll with checking if
  it was NULL.

25 files changed:
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_screen.h
source/blender/blenkernel/intern/context.c
source/blender/editors/interface/interface.c
source/blender/editors/screen/screen_context.c
source/blender/editors/screen/screen_intern.h
source/blender/editors/space_image/space_image.c
source/blender/editors/space_info/Makefile
source/blender/editors/space_info/SConscript
source/blender/editors/space_nla/Makefile
source/blender/editors/space_nla/SConscript
source/blender/editors/space_node/space_node.c
source/blender/editors/space_sound/Makefile
source/blender/editors/space_sound/SConscript
source/blender/editors/space_text/space_text.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/transform/transform_ops.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_types.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_rna.c
source/blender/python/intern/bpy_rna.c

index e384900e0cb77a3d9b6ca93a96a871ad7c21e9a3..dbe5c610688b52e4fbb5b8f0fd7bf1c2d99ff482 100644 (file)
@@ -33,6 +33,7 @@ extern "C" {
 #endif
 
 #include "DNA_listBase.h"
+#include "RNA_types.h"
 
 struct ARegion;
 struct bScreen;
@@ -58,6 +59,7 @@ struct wmWindow;
 struct wmWindowManager;
 struct SpaceText;
 struct SpaceImage;
+struct ID;
 
 /* Structs */
 
@@ -67,45 +69,8 @@ typedef struct bContext bContext;
 struct bContextDataResult;
 typedef struct bContextDataResult bContextDataResult;
 
-enum {
-       CTX_DATA_MAIN,
-       CTX_DATA_SCENE,
-       CTX_DATA_TOOL_SETTINGS,
-
-       CTX_DATA_SELECTED_OBJECTS,
-       CTX_DATA_SELECTED_BASES,
-       CTX_DATA_SELECTED_EDITABLE_OBJECTS,
-       CTX_DATA_SELECTED_EDITABLE_BASES,
-       CTX_DATA_VISIBLE_OBJECTS,
-       CTX_DATA_VISIBLE_BASES,
-
-       CTX_DATA_ACTIVE_OBJECT,
-       CTX_DATA_ACTIVE_BASE,
-       CTX_DATA_EDIT_OBJECT,
-
-       CTX_DATA_EDIT_IMAGE,
-       CTX_DATA_EDIT_IMAGE_BUFFER,
-
-       CTX_DATA_EDIT_TEXT,
-
-       CTX_DATA_SELECTED_NODES,
-       
-       CTX_DATA_SELECTED_BONES,
-       CTX_DATA_SELECTED_EDITABLE_BONES,
-       CTX_DATA_SELECTED_PCHANS,
-       
-       CTX_DATA_ACTIVE_BONE,
-       CTX_DATA_ACTIVE_PCHAN,
-       
-       CTX_DATA_VISIBLE_BONES,
-       CTX_DATA_EDITABLE_BONES,
-       CTX_DATA_VISIBLE_PCHANS,
-};
-
-typedef int bContextDataMember;
-
 typedef int (*bContextDataCallback)(const bContext *C,
-       bContextDataMember member, bContextDataResult *result);
+       const char *member, bContextDataResult *result);
 
 /* Context */
 
@@ -158,16 +123,28 @@ void CTX_wm_ui_block_set(bContext *C, struct uiBlock *block, bContextDataCallbac
    - note: listbases consist of LinkData items and must be
      freed with BLI_freelistN! */
 
-void CTX_data_pointer_set(bContextDataResult *result, void *data);
-void CTX_data_list_add(bContextDataResult *result, void *data);
+PointerRNA CTX_data_pointer_get(bContext *C, const char *member);
+ListBase CTX_data_collection_get(bContext *C, const char *member);
+void CTX_data_get(bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb);
+
+void CTX_data_id_pointer_set(bContextDataResult *result, struct ID *id);
+void CTX_data_pointer_set(bContextDataResult *result, struct ID *id, StructRNA *type, void *data);
+
+void CTX_data_id_list_add(bContextDataResult *result, struct ID *id);
+void CTX_data_list_add(bContextDataResult *result, struct ID *id, StructRNA *type, void *data);
+
+int CTX_data_equals(const char *member, const char *str);
+
+/*void CTX_data_pointer_set(bContextDataResult *result, void *data);
+void CTX_data_list_add(bContextDataResult *result, void *data);*/
 
 #define CTX_DATA_BEGIN(C, Type, instance, member) \
        { \
                ListBase ctx_data_list; \
-               LinkData *link; \
+               CollectionPointerLink *ctx_link; \
                CTX_data_##member(C, &ctx_data_list); \
-               for(link=ctx_data_list.first; link; link=link->next) { \
-                       Type instance= link->data;
+               for(ctx_link=ctx_data_list.first; ctx_link; ctx_link=ctx_link->next) { \
+                       Type instance= ctx_link->ptr.data;
 
 #define CTX_DATA_END \
                } \
@@ -202,7 +179,6 @@ struct Base *CTX_data_active_base(const bContext *C);
 struct Object *CTX_data_edit_object(const bContext *C);
 
 struct Image *CTX_data_edit_image(const bContext *C);
-struct ImBuf *CTX_data_edit_image_buffer(const bContext *C);
 
 struct Text *CTX_data_edit_text(const bContext *C);
 
index 302f7b4fdd9f252d5fa12f3c5ae8ba17a4a5cd5a..dc1233e7db33756d1f50c4d1516d56a1baa27266 100644 (file)
@@ -77,7 +77,7 @@ typedef struct SpaceType {
        void            (*keymap)(struct wmWindowManager *);
 
        /* return context data */
-       int                     (*context)(const struct bContext *, int, struct bContextDataResult *);
+       int                     (*context)(const struct bContext *, const char*, struct bContextDataResult *);
 
        /* region type definitions */
        ListBase        regiontypes;
@@ -117,7 +117,7 @@ typedef struct ARegionType {
        void            (*cursor)(struct wmWindow *, struct ScrArea *, struct ARegion *ar);
 
        /* return context data */
-       int                     (*context)(const struct bContext *, int, struct bContextDataResult *);
+       int                     (*context)(const struct bContext *, const char *, struct bContextDataResult *);
 
        /* custom drawing callbacks */
        ListBase        drawcalls;
index fc338e1bc954b6072801cc4a4b0010f670aab369..df71dd6037a574787d8cc0723f8a4029729c6857 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_ID.h"
 #include "DNA_listBase.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -254,11 +255,11 @@ void CTX_wm_ui_block_set(bContext *C, struct uiBlock *block, bContextDataCallbac
 /* data context utility functions */
 
 struct bContextDataResult {
-       void *pointer;
+       PointerRNA ptr;
        ListBase list;
 };
 
-static int ctx_data_get(bContext *C, bContextDataMember member, bContextDataResult *result)
+static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
 {
        int done= 0, recursion= C->data.recursion;
 
@@ -292,22 +293,22 @@ static int ctx_data_get(bContext *C, bContextDataMember member, bContextDataResu
        return done;
 }
 
-static void *ctx_data_pointer_get(const bContext *C, bContextDataMember member)
+static void *ctx_data_pointer_get(const bContext *C, const char *member)
 {
        bContextDataResult result;
 
        if(ctx_data_get((bContext*)C, member, &result))
-               return result.pointer;
+               return result.ptr.data;
 
        return NULL;
 }
 
-static int ctx_data_pointer_verify(const bContext *C, bContextDataMember member, void **pointer)
+static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
 {
        bContextDataResult result;
 
        if(ctx_data_get((bContext*)C, member, &result)) {
-               *pointer= result.pointer;
+               *pointer= result.ptr.data;
                return 1;
        }
        else {
@@ -316,7 +317,7 @@ static int ctx_data_pointer_verify(const bContext *C, bContextDataMember member,
        }
 }
 
-static int ctx_data_collection_get(const bContext *C, bContextDataMember member, ListBase *list)
+static int ctx_data_collection_get(const bContext *C, const char *member, ListBase *list)
 {
        bContextDataResult result;
 
@@ -328,17 +329,80 @@ static int ctx_data_collection_get(const bContext *C, bContextDataMember member,
        return 0;
 }
 
-void CTX_data_pointer_set(bContextDataResult *result, void *data)
+PointerRNA CTX_data_pointer_get(bContext *C, const char *member)
 {
-       result->pointer= data;
+       bContextDataResult result;
+
+       if(ctx_data_get((bContext*)C, member, &result)) {
+               return result.ptr;
+       }
+       else {
+               PointerRNA ptr;
+               memset(&ptr, 0, sizeof(ptr));
+               return ptr;
+       }
+
 }
 
-void CTX_data_list_add(bContextDataResult *result, void *data)
+ListBase CTX_data_collection_get(bContext *C, const char *member)
 {
-       LinkData *link;
-       
-       link= MEM_callocN(sizeof(LinkData), "LinkData");
-       link->data= data;
+       bContextDataResult result;
+
+       if(ctx_data_get((bContext*)C, member, &result)) {
+               return result.list;
+       }
+       else {
+               ListBase list;
+               memset(&list, 0, sizeof(list));
+               return list;
+       }
+}
+
+void CTX_data_get(bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb)
+{
+       bContextDataResult result;
+
+       if(ctx_data_get((bContext*)C, member, &result)) {
+               *r_ptr= result.ptr;
+               *r_lb= result.list;
+       }
+       else {
+               memset(r_ptr, 0, sizeof(*r_ptr));
+               memset(r_lb, 0, sizeof(*r_lb));
+       }
+}
+
+int CTX_data_equals(const char *member, const char *str)
+{
+       return (strcmp(member, str) == 0);
+}
+
+void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
+{
+       RNA_id_pointer_create(id, &result->ptr);
+}
+
+void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
+{
+       RNA_pointer_create(id, type, data, &result->ptr);
+}
+
+void CTX_data_id_list_add(bContextDataResult *result, ID *id)
+{
+       CollectionPointerLink *link;
+
+       link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_id_list_add");
+       RNA_id_pointer_create(id, &link->ptr);
+
+       BLI_addtail(&result->list, link);
+}
+
+void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data)
+{
+       CollectionPointerLink *link;
+
+       link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_list_add");
+       RNA_pointer_create(id, type, data, &link->ptr);
 
        BLI_addtail(&result->list, link);
 }
@@ -362,7 +426,7 @@ Main *CTX_data_main(const bContext *C)
 {
        Main *bmain;
 
-       if(ctx_data_pointer_verify(C, CTX_DATA_MAIN, (void*)&bmain))
+       if(ctx_data_pointer_verify(C, "main", (void*)&bmain))
                return bmain;
        else
                return C->data.main;
@@ -377,7 +441,7 @@ Scene *CTX_data_scene(const bContext *C)
 {
        Scene *scene;
 
-       if(ctx_data_pointer_verify(C, CTX_DATA_SCENE, (void*)&scene))
+       if(ctx_data_pointer_verify(C, "scene", (void*)&scene))
                return scene;
        else
                return C->data.scene;
@@ -400,107 +464,102 @@ ToolSettings *CTX_data_tool_settings(const bContext *C)
 
 int CTX_data_selected_nodes(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_SELECTED_NODES, list);
+       return ctx_data_collection_get(C, "selected_nodes", list);
 }
 
 int CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_SELECTED_EDITABLE_OBJECTS, list);
+       return ctx_data_collection_get(C, "selected_editable_objects", list);
 }
 
 int CTX_data_selected_editable_bases(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_SELECTED_EDITABLE_BASES, list);
+       return ctx_data_collection_get(C, "selected_editable_bases", list);
 }
 
 int CTX_data_selected_objects(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_SELECTED_OBJECTS, list);
+       return ctx_data_collection_get(C, "selected_objects", list);
 }
 
 int CTX_data_selected_bases(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_SELECTED_BASES, list);
+       return ctx_data_collection_get(C, "selected_bases", list);
 }
 
 int CTX_data_visible_objects(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_VISIBLE_OBJECTS, list);
+       return ctx_data_collection_get(C, "visible_objects", list);
 }
 
 int CTX_data_visible_bases(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_VISIBLE_BASES, list);
+       return ctx_data_collection_get(C, "visible_bases", list);
 }
 
 struct Object *CTX_data_active_object(const bContext *C)
 {
-       return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_OBJECT);
+       return ctx_data_pointer_get(C, "active_object");
 }
 
 struct Base *CTX_data_active_base(const bContext *C)
 {
-       return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_BASE);
+       return ctx_data_pointer_get(C, "active_base");
 }
 
 struct Object *CTX_data_edit_object(const bContext *C)
 {
-       return ctx_data_pointer_get(C, CTX_DATA_EDIT_OBJECT);
+       return ctx_data_pointer_get(C, "edit_object");
 }
 
 struct Image *CTX_data_edit_image(const bContext *C)
 {
-       return ctx_data_pointer_get(C, CTX_DATA_EDIT_IMAGE);
-}
-
-struct ImBuf *CTX_data_edit_image_buffer(const bContext *C)
-{
-       return ctx_data_pointer_get(C, CTX_DATA_EDIT_IMAGE_BUFFER);
+       return ctx_data_pointer_get(C, "edit_image");
 }
 
 struct Text *CTX_data_edit_text(const bContext *C)
 {
-       return ctx_data_pointer_get(C, CTX_DATA_EDIT_TEXT);
+       return ctx_data_pointer_get(C, "edit_text");
 }
 
 struct EditBone *CTX_data_active_bone(const bContext *C)
 {
-       return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_BONE);
+       return ctx_data_pointer_get(C, "active_bone");
 }
 
 int CTX_data_selected_bones(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_SELECTED_BONES, list);
+       return ctx_data_collection_get(C, "selected_bones", list);
 }
 
 int CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_SELECTED_EDITABLE_BONES, list);
+       return ctx_data_collection_get(C, "selected_editable_bones", list);
 }
 
 int CTX_data_visible_bones(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_VISIBLE_BONES, list);
+       return ctx_data_collection_get(C, "visible_bones", list);
 }
 
 int CTX_data_editable_bones(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_EDITABLE_BONES, list);
+       return ctx_data_collection_get(C, "editable_bones", list);
 }
 
 struct bPoseChannel *CTX_data_active_pchan(const bContext *C)
 {
-       return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_PCHAN);
+       return ctx_data_pointer_get(C, "active_pchan");
 }
 
 int CTX_data_selected_pchans(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_SELECTED_PCHANS, list);
+       return ctx_data_collection_get(C, "selected_pchans", list);
 }
 
 int CTX_data_visible_pchans(const bContext *C, ListBase *list)
 {
-       return ctx_data_collection_get(C, CTX_DATA_VISIBLE_PCHANS, list);
+       return ctx_data_collection_get(C, "visible_pchans", list);
 }
 
 
index 194ccd285bf3c980e20228cf0742ee992856c8d3..2f78c4e8ffff2fdcb70e1ed274f7651819f0784d 100644 (file)
@@ -600,7 +600,7 @@ void uiEndBlock(const bContext *C, uiBlock *block)
                /* temp? Proper check for greying out */
                if(but->opname) {
                        wmOperatorType *ot= WM_operatortype_find(but->opname);
-                       if(ot==NULL || ot->poll((bContext *)C)==0) {
+                       if(ot==NULL || (ot->poll && ot->poll((bContext *)C)==0)) {
                                but->flag |= UI_BUT_DISABLED;
                                but->lock = 1;
                        }
index 2406c1c5e3297554c4888ccb73343457c69e033b..11d1d019005a641824f720212903c9703b5b5650 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include <stdlib.h>
+#include <string.h>
 
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "BKE_context.h"
 #include "BKE_utildefines.h"
 
-int ed_screen_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
+#include "RNA_access.h"
+
+int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
 {
        bScreen *sc= CTX_wm_screen(C);
        Scene *scene= sc->scene;
        Base *base;
 
-       if(member == CTX_DATA_SCENE) {
-               CTX_data_pointer_set(result, scene);
+       if(CTX_data_equals(member, "scene")) {
+               CTX_data_id_pointer_set(result, &scene->id);
                return 1;
        }
-       else if(ELEM(member, CTX_DATA_SELECTED_OBJECTS, CTX_DATA_SELECTED_BASES)) {
+       else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
+               int selected_objects= CTX_data_equals(member, "selected_objects");
+
                for(base=scene->base.first; base; base=base->next) {
                        if((base->flag & SELECT) && (base->lay & scene->lay)) {
-                               if(member == CTX_DATA_SELECTED_OBJECTS)
-                                       CTX_data_list_add(result, base->object);
+                               if(selected_objects)
+                                       CTX_data_id_list_add(result, &base->object->id);
                                else
-                                       CTX_data_list_add(result, base);
+                                       CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
                        }
                }
 
                return 1;
        }
-       else if(member == CTX_DATA_ACTIVE_BASE) {
+       else if(CTX_data_equals(member, "active_base")) {
                if(scene->basact)
-                       CTX_data_pointer_set(result, scene->basact);
+                       CTX_data_pointer_set(result, &scene->id, &RNA_UnknownType, &scene->basact);
 
                return 1;
        }
-       else if(member == CTX_DATA_ACTIVE_OBJECT) {
+       else if(CTX_data_equals(member, "active_object")) {
                if(scene->basact)
-                       CTX_data_pointer_set(result, scene->basact->object);
+                       CTX_data_id_pointer_set(result, &scene->basact->object->id);
 
                return 1;
        }
-       else if(member == CTX_DATA_EDIT_OBJECT) {
+       else if(CTX_data_equals(member, "edit_object")) {
                /* convenience for now, 1 object per scene in editmode */
                if(scene->obedit)
-                       CTX_data_pointer_set(result, scene->obedit);
+                       CTX_data_id_pointer_set(result, &scene->obedit->id);
                
                return 1;
        }
index f39ca7d4c3e178072a7135782bdb2e1cdb876ead..a0804f3e633a55230918981c78cef1bf0bd0b41a 100644 (file)
@@ -55,7 +55,7 @@ AZone         *is_in_area_actionzone(ScrArea *sa, int x, int y);
 void           ed_screen_fullarea(bContext *C, ScrArea *sa);
 
 /* screen_context.c */
-void ed_screen_context(const bContext *C, bContextDataMember member, bContextDataResult *result);
+void ed_screen_context(const bContext *C, const char *member, bContextDataResult *result);
 
 /* screendump.c */
 void SCREEN_OT_screenshot(struct wmOperatorType *ot);
index 419eb913eddf52ab4afe0acf000e771c0f7a47ee..deff9935b7e213f76e41fceb32ca2efb173fd346 100644 (file)
@@ -304,16 +304,12 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn)
        }
 }
 
-static int image_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
+static int image_context(const bContext *C, const char *member, bContextDataResult *result)
 {
        SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
 
-       if(member == CTX_DATA_EDIT_IMAGE) {
-               CTX_data_pointer_set(result, ED_space_image(sima));
-               return 1;
-       }
-       else if(member == CTX_DATA_EDIT_IMAGE_BUFFER) {
-               CTX_data_pointer_set(result, ED_space_image_buffer(sima));
+       if(CTX_data_equals(member, "edit_image")) {
+               CTX_data_id_pointer_set(result, (ID*)ED_space_image(sima));
                return 1;
        }
 
index 13f7a0d169f837525ed3cd82a6628a571d1729f2..bc04ddc78246f53197fac03b5ce9dceaa5d5da83 100644 (file)
@@ -44,6 +44,7 @@ CPPFLAGS += -I../../blenloader
 CPPFLAGS += -I../../blenkernel
 CPPFLAGS += -I../../blenlib
 CPPFLAGS += -I../../makesdna
+CPPFLAGS += -I../../makesrna
 CPPFLAGS += -I../../imbuf
 CPPFLAGS += -I../../python
 CPPFLAGS += -I../../blenfont
index 9723a7fcfe2d6b9a08fb18815a96109186eb6fed..05afcae162e100fcd3aab04e151b48b7ea83f9f2 100644 (file)
@@ -3,7 +3,7 @@ Import ('env')
 
 sources = env.Glob('*.c')
 
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf ../../blenfont'
+incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../imbuf ../../blenfont'
 incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
 
 defs = []
index 85405a2a3f5a02e96bc52c66a0a1b47c774ad68f..43f010e6adc2a3d3dc07dee4bb2e4b2c21e01641 100644 (file)
@@ -44,6 +44,7 @@ CPPFLAGS += -I../../blenloader
 CPPFLAGS += -I../../blenkernel
 CPPFLAGS += -I../../blenlib
 CPPFLAGS += -I../../makesdna
+CPPFLAGS += -I../../makesrna
 CPPFLAGS += -I../../imbuf
 CPPFLAGS += -I../../python
 CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
index c6a4f34292fc5f97abf2bc1d095e7590afb05956..790e3ad822c7ace1aa2353dcf65726d46d2d3b25 100644 (file)
@@ -3,7 +3,7 @@ Import ('env')
 
 sources = env.Glob('*.c')
 
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../imbuf'
 incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
 
 env.BlenderLib ( 'bf_editors_space_nla', sources, Split(incs), [], libtype=['core'], priority=[85] )
index 1d2aa148e1846969229a19c6faf01d4fcec75a65..493ef6954b5d4fd76ccf13e7c5a4cb4656691ba4 100644 (file)
@@ -60,6 +60,8 @@
 #include "UI_resources.h"
 #include "UI_view2d.h"
 
+#include "RNA_access.h"
+
 #include "node_intern.h"       // own include
 
 /* ******************** default callbacks for node space ***************** */
@@ -277,16 +279,16 @@ static void node_region_listener(ARegion *ar, wmNotifier *wmn)
        }
 }
 
-static int node_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
+static int node_context(const bContext *C, const char *member, bContextDataResult *result)
 {
        SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
        
-       if(member == CTX_DATA_SELECTED_NODES) {
+       if(CTX_data_equals(member, "selected_nodes")) {
                bNode *node;
                
                for(next_node(snode->edittree); (node=next_node(NULL));) {
                        if(node->flag & SELECT) {
-                               CTX_data_list_add(result, node);
+                               CTX_data_list_add(result, &snode->edittree->id, &RNA_Node, node);
                        }
                }
                return 1;
index 9b1e95bf3a61942f28ec88bfb6de207e1647678b..4d375282223e8474c43a9717a69e38186eba84d2 100644 (file)
@@ -44,6 +44,7 @@ CPPFLAGS += -I../../blenloader
 CPPFLAGS += -I../../blenkernel
 CPPFLAGS += -I../../blenlib
 CPPFLAGS += -I../../makesdna
+CPPFLAGS += -I../../makesrna
 CPPFLAGS += -I../../imbuf
 CPPFLAGS += -I../../python
 CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
index 9e57223cc2aea34c5af762dd8bb68116eecab4c3..e4fffb53e4c6cdae1f0a0ba52a63a17f865f537b 100644 (file)
@@ -3,7 +3,7 @@ Import ('env')
 
 sources = env.Glob('*.c')
 
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../imbuf'
 incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
 
 env.BlenderLib ( 'bf_editors_space_sound', sources, Split(incs), [], libtype=['core'], priority=[75] )
index a854ebe72d96198c6a3cbcbb78083bb418da37ed..363d3016adf6c7ccaf9e9d51e583fa64ec441853 100644 (file)
@@ -284,12 +284,12 @@ static void text_keymap(struct wmWindowManager *wm)
        WM_keymap_add_item(keymap, "TEXT_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
 }
 
-static int text_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
+static int text_context(const bContext *C, const char *member, bContextDataResult *result)
 {
        SpaceText *st= CTX_wm_space_text(C);
 
-       if(member == CTX_DATA_EDIT_TEXT) {
-               CTX_data_pointer_set(result, st->text);
+       if(CTX_data_equals(member, "edit_text")) {
+               CTX_data_id_pointer_set(result, &st->text->id);
                return 1;
        }
 
index 4e2a0090244e86b0a52ab3f5fd9de31f9b2833b7..ab04fbdd490fa88e63d43d1d5b3dba62aa21ee45 100644 (file)
@@ -62,6 +62,8 @@
 #include "UI_resources.h"
 #include "UI_view2d.h"
 
+#include "RNA_access.h"
+
 #include "view3d_intern.h"     // own include
 
 /* ******************** manage regions ********************* */
@@ -519,7 +521,7 @@ static int object_is_libdata(Object *ob)
        return 0;
 }
 
-static int view3d_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
+static int view3d_context(const bContext *C, const char *member, bContextDataResult *result)
 {
        View3D *v3d= CTX_wm_view3d(C);
        Scene *scene= CTX_data_scene(C);
@@ -527,29 +529,33 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
 
        if(v3d==NULL) return 0;
 
-       if(ELEM(member, CTX_DATA_SELECTED_OBJECTS, CTX_DATA_SELECTED_BASES)) {
+       if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
+               int selected_objects= CTX_data_equals(member, "selected_objects");
+
                for(base=scene->base.first; base; base=base->next) {
                        if((base->flag & SELECT) && (base->lay & v3d->lay)) {
                                if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
-                                       if(member == CTX_DATA_SELECTED_OBJECTS)
-                                               CTX_data_list_add(result, base->object);
+                                       if(selected_objects)
+                                               CTX_data_id_list_add(result, &base->object->id);
                                        else
-                                               CTX_data_list_add(result, base);
+                                               CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
                                }
                        }
                }
 
                return 1;
        }
-       else if(ELEM(member, CTX_DATA_SELECTED_EDITABLE_OBJECTS, CTX_DATA_SELECTED_EDITABLE_BASES)) {
+       else if(CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
+               int selected_editable_objects= CTX_data_equals(member, "selected_editable_objects");
+
                for(base=scene->base.first; base; base=base->next) {
                        if((base->flag & SELECT) && (base->lay & v3d->lay)) {
                                if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
                                        if(0==object_is_libdata(base->object)) {
-                                               if(member == CTX_DATA_SELECTED_EDITABLE_OBJECTS)
-                                                       CTX_data_list_add(result, base->object);
+                                               if(selected_editable_objects)
+                                                       CTX_data_id_list_add(result, &base->object->id);
                                                else
-                                                       CTX_data_list_add(result, base);
+                                                       CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
                                        }
                                }
                        }
@@ -557,38 +563,41 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
                
                return 1;
        }
-       else if(ELEM(member, CTX_DATA_VISIBLE_OBJECTS, CTX_DATA_VISIBLE_BASES)) {
+       else if(CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
+               int visible_objects= CTX_data_equals(member, "visible_objects");
+
                for(base=scene->base.first; base; base=base->next) {
                        if(base->lay & v3d->lay) {
                                if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
-                                       if(member == CTX_DATA_VISIBLE_OBJECTS)
-                                               CTX_data_list_add(result, base->object);
+                                       if(visible_objects)
+                                               CTX_data_id_list_add(result, &base->object->id);
                                        else
-                                               CTX_data_list_add(result, base);
+                                               CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
                                }
                        }
                }
                
                return 1;
        }
-       else if(member == CTX_DATA_ACTIVE_BASE) {
+       else if(CTX_data_equals(member, "active_base")) {
                if(scene->basact && (scene->basact->lay & v3d->lay))
                        if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0)
-                               CTX_data_pointer_set(result, scene->basact);
+                               CTX_data_pointer_set(result, &scene->id, &RNA_UnknownType, scene->basact);
                
                return 1;
        }
-       else if(member == CTX_DATA_ACTIVE_OBJECT) {
+       else if(CTX_data_equals(member, "active_object")) {
                if(scene->basact && (scene->basact->lay & v3d->lay))
                        if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0)
-                               CTX_data_pointer_set(result, scene->basact->object);
+                               CTX_data_id_pointer_set(result, &scene->basact->object->id);
                
                return 1;
        }
-       else if(ELEM(member, CTX_DATA_VISIBLE_BONES, CTX_DATA_EDITABLE_BONES)) {
+       else if(CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
                Object *obedit= scene->obedit; // XXX get from context?
                bArmature *arm= (obedit) ? obedit->data : NULL;
                EditBone *ebone, *flipbone=NULL;
+               int editable_bones= CTX_data_equals(member, "editable_bones");
                
                if (arm && arm->edbo) {
                        /* Attention: X-Axis Mirroring is also handled here... */
@@ -605,21 +614,21 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
                                                flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
                                        
                                        /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
-                                       if (member == CTX_DATA_EDITABLE_BONES) {
+                                       if (editable_bones) {
                                                /* only selected + editable */
                                                if (EBONE_EDITABLE(ebone)) {
-                                                       CTX_data_list_add(result, ebone);
+                                                       CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
                                                
                                                        if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
-                                                               CTX_data_list_add(result, flipbone);
+                                                               CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
                                                }
                                        }
                                        else {
                                                /* only include bones if visible */
-                                               CTX_data_list_add(result, ebone);
+                                               CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
                                                
                                                if ((flipbone) && EBONE_VISIBLE(arm, flipbone)==0)
-                                                       CTX_data_list_add(result, flipbone);
+                                                       CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
                                        }
                                }
                        }       
@@ -627,10 +636,11 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
                        return 1;
                }
        }
-       else if(ELEM(member, CTX_DATA_SELECTED_BONES, CTX_DATA_SELECTED_EDITABLE_BONES)) {
+       else if(CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) {
                Object *obedit= scene->obedit; // XXX get from context?
                bArmature *arm= (obedit) ? obedit->data : NULL;
                EditBone *ebone, *flipbone=NULL;
+               int selected_editable_bones= CTX_data_equals(member, "selected_editable_bones");
                
                if (arm && arm->edbo) {
                        /* Attention: X-Axis Mirroring is also handled here... */
@@ -647,21 +657,21 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
                                                flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
                                        
                                        /* if we're filtering for editable too, use the check for that instead, as it has selection check too */
-                                       if (member == CTX_DATA_SELECTED_EDITABLE_BONES) {
+                                       if (selected_editable_bones) {
                                                /* only selected + editable */
                                                if (EBONE_EDITABLE(ebone)) {
-                                                       CTX_data_list_add(result, ebone);
+                                                       CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
                                                
                                                        if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
-                                                               CTX_data_list_add(result, flipbone);
+                                                               CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
                                                }
                                        }
                                        else {
                                                /* only include bones if selected */
-                                               CTX_data_list_add(result, ebone);
+                                               CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
                                                
                                                if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
-                                                       CTX_data_list_add(result, flipbone);
+                                                       CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
                                        }
                                }
                        }       
@@ -669,7 +679,7 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
                        return 1;
                }
        }
-       else if(member == CTX_DATA_VISIBLE_PCHANS) {
+       else if(CTX_data_equals(member, "visible_pchans")) {
                Object *obact= OBACT;
                bArmature *arm= (obact) ? obact->data : NULL;
                bPoseChannel *pchan;
@@ -678,14 +688,14 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
                        for (pchan= obact->pose->chanbase.first; pchan; pchan= pchan->next) {
                                /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
                                if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
-                                       CTX_data_list_add(result, pchan);
+                                       CTX_data_list_add(result, &obact->id, &RNA_PoseChannel, pchan);
                                }
                        }
                        
                        return 1;
                }
        }
-       else if(member == CTX_DATA_SELECTED_PCHANS) {
+       else if(CTX_data_equals(member, "selected_pchans")) {
                Object *obact= OBACT;
                bArmature *arm= (obact) ? obact->data : NULL;
                bPoseChannel *pchan;
@@ -695,14 +705,14 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
                                /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
                                if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
                                        if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) 
-                                               CTX_data_list_add(result, pchan);
+                                               CTX_data_list_add(result, &obact->id, &RNA_PoseChannel, pchan);
                                }
                        }
                        
                        return 1;
                }
        }
-       else if(member == CTX_DATA_ACTIVE_BONE) {
+       else if(CTX_data_equals(member, "active_bone")) {
                Object *obedit= scene->obedit; // XXX get from context?
                bArmature *arm= (obedit) ? obedit->data : NULL;
                EditBone *ebone;
@@ -711,7 +721,7 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
                        for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
                                if (EBONE_VISIBLE(arm, ebone)) {
                                        if (ebone->flag & BONE_ACTIVE) {
-                                               CTX_data_pointer_set(result, ebone);
+                                               CTX_data_pointer_set(result, &arm->id, &RNA_UnknownType, ebone);
                                                
                                                return 1;
                                        }
@@ -720,13 +730,13 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
                }
                
        }
-       else if(member == CTX_DATA_ACTIVE_PCHAN) {
+       else if(CTX_data_equals(member, "active_pchan")) {
                Object *obact= OBACT;
                bPoseChannel *pchan;
                
                pchan= get_active_posechannel(obact);
                if (pchan) {
-                       CTX_data_pointer_set(result, pchan);
+                       CTX_data_pointer_set(result, &obact->id, &RNA_PoseChannel, pchan);
                        return 1;
                }
        }
index 719ae144913c4f3d2fc6ce06f8d93d590212fd38..fc4b0117bcb44ed6915c86be95466c3fb6c35f45 100644 (file)
@@ -492,8 +492,7 @@ void TFM_OT_transform(struct wmOperatorType *ot)
 
        RNA_def_float_vector(ot->srna, "value", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
 
-       RNA_def_enum(ot->srna, "proportional", proportional_mode_types, 0, "Proportional Edition", "");
-       RNA_def_float(ot->srna, "proportional_size", 1, 0, FLT_MAX, "Proportional Size", "", 0, 100);
+       Properties_Proportional(ot);
        RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
 
        RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
index 1ad9319bc1b5c48a234c22ce207d6dfbd9a0df37..0317e855b6e23dbc59fac18fbdf6a1ff068d2719 100644 (file)
@@ -25,6 +25,7 @@
 #ifndef RNA_ACCESS
 #define RNA_ACCESS
 
+#include "DNA_listBase.h"
 #include "RNA_types.h"
 
 #ifdef __cplusplus
@@ -72,6 +73,7 @@ extern StructRNA RNA_ColorRamp;
 extern StructRNA RNA_ColorRampElement;
 extern StructRNA RNA_ColorSequence;
 extern StructRNA RNA_Constraint;
+extern StructRNA RNA_Context;
 extern StructRNA RNA_ControlFluidSettings;
 extern StructRNA RNA_Controller;
 extern StructRNA RNA_Curve;
index fb29d34184de537587584db57a2a4feefaca3b30..7f59164fe59068e61cc349e6c74b5bbf7e71482f 100644 (file)
@@ -32,6 +32,7 @@ extern "C" {
 struct PropertyRNA;
 struct StructRNA;
 struct BlenderRNA;
+struct IDProperty;
 
 /* Pointer
  *
@@ -42,7 +43,6 @@ struct BlenderRNA;
 
 typedef struct PointerRNA {
        struct {
-               struct StructRNA *type;
                void *data;
        } id;
 
@@ -122,6 +122,11 @@ typedef struct CollectionPropertyIterator {
        PointerRNA ptr;
 } CollectionPropertyIterator;
 
+typedef struct CollectionPointerLink {
+       struct CollectionPointerLink *next, *prev;
+       PointerRNA ptr;
+} CollectionPointerLink;
+
 /* Iterator Utility */
 
 typedef struct EnumPropertyItem {
index 15be45ae59b4fcc13160c0de2df787d70333a674..55b9b79d334a6558b79d1d960e8541c30c0c222e 100644 (file)
@@ -34,6 +34,7 @@ SET(DEFSRC
      rna_cloth.c
      rna_color.c
      rna_constraint.c
+     rna_context.c
      rna_controller.c
      rna_curve.c
      rna_fluidsim.c
index 77c9b2279824cd97fb6994c2b9b060455d166f45..76f045464ddeac2d8506cd09eb2296cdd489a2f3 100644 (file)
@@ -1415,6 +1415,7 @@ RNAProcessItem PROCESS_ITEMS[]= {
        {"rna_cloth.c", RNA_def_cloth},
        {"rna_color.c", RNA_def_color},
        {"rna_constraint.c", RNA_def_constraint},
+       {"rna_context.c", RNA_def_context},
        {"rna_controller.c", RNA_def_controller},
        {"rna_curve.c", RNA_def_curve},
        {"rna_fluidsim.c", RNA_def_fluidsim},
index 71ebad2127ad6fe690a9105416eb3d2546de9736..55e3ae28342e5856f5c25d68ae577c927119ed1e 100644 (file)
@@ -55,7 +55,6 @@ void RNA_exit()
 
 void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
 {
-       r_ptr->id.type= NULL;
        r_ptr->id.data= NULL;
        r_ptr->type= &RNA_Main;
        r_ptr->data= main;
@@ -72,7 +71,6 @@ void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
                idtype= rna_ID_refine(&tmp);
        }
 
-       r_ptr->id.type= idtype;
        r_ptr->id.data= id;
        r_ptr->type= idtype;
        r_ptr->data= id;
@@ -89,7 +87,6 @@ void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
                idtype= rna_ID_refine(&tmp);
        }
 
-       r_ptr->id.type= idtype;
        r_ptr->id.data= id;
        r_ptr->type= type;
        r_ptr->data= data;
@@ -99,22 +96,37 @@ static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerR
 {
        if(type && type->flag & STRUCT_ID) {
                ptr->id.data= ptr->data;
-               ptr->id.type= type;
        }
        else {
                ptr->id.data= parent->id.data;
-               ptr->id.type= parent->id.type;
        }
 }
 
 void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
 {
-       r_ptr->id.type= NULL;
        r_ptr->id.data= NULL;
        r_ptr->type= &RNA_BlenderRNA;
        r_ptr->data= &BLENDER_RNA;
 }
 
+PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
+{
+       PointerRNA result;
+
+       if(data) {
+               result.data= data;
+               result.type= type;
+               rna_pointer_inherit_id(type, ptr, &result);
+
+               if(type->refine)
+                       result.type= type->refine(&result);
+       }
+       else
+               memset(&result, 0, sizeof(result));
+       
+       return result;
+}
+
 /* ID Properties */
 
 IDProperty *rna_idproperties_get(PointerRNA *ptr, int create)
@@ -1365,26 +1377,6 @@ void rna_iterator_array_end(CollectionPropertyIterator *iter)
        MEM_freeN(iter->internal);
 }
 
-/* Pointer Handling */
-
-PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
-{
-       PointerRNA result;
-
-       if(data) {
-               result.data= data;
-               result.type= type;
-               rna_pointer_inherit_id(type, ptr, &result);
-
-               if(type->refine)
-                       result.type= type->refine(&result);
-       }
-       else
-               memset(&result, 0, sizeof(result));
-       
-       return result;
-}
-
 /* RNA Path - Experiment */
 
 static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
index 2665d8eab095eb6ae2771863f4eb0446b5a71f14..4101291e825e522a45be83b00e24df7045969e55 100644 (file)
@@ -105,6 +105,7 @@ void RNA_def_camera(struct BlenderRNA *brna);
 void RNA_def_cloth(struct BlenderRNA *brna);
 void RNA_def_color(struct BlenderRNA *brna);
 void RNA_def_constraint(struct BlenderRNA *brna);
+void RNA_def_context(struct BlenderRNA *brna);
 void RNA_def_controller(struct BlenderRNA *brna);
 void RNA_def_curve(struct BlenderRNA *brna);
 void RNA_def_fluidsim(struct BlenderRNA *brna);
index 4b9c1e0067b0e0a1fbdcbf68bf98b39646a3fe1c..44191b72e366e136c6e1b3189945cab44ea4c8ab 100644 (file)
@@ -199,14 +199,10 @@ void rna_builtin_properties_begin(CollectionPropertyIterator *iter, PointerRNA *
        newptr.type= &RNA_Struct;
        newptr.data= ptr->type;
 
-       if(ptr->type->flag & STRUCT_ID) {
-               newptr.id.type= ptr->type;
+       if(ptr->type->flag & STRUCT_ID)
                newptr.id.data= ptr->data;
-       }
-       else {
-               newptr.id.type= NULL;
+       else
                newptr.id.data= NULL;
-       }
 
        iter->parent= newptr;
 
index 650475bae96d36b7f157505ea514d09b67a01c25..6215ab86500cb88fc4270a58c3c996c853173044 100644 (file)
 #include "bpy_compat.h"
 //#include "blendef.h"
 #include "BLI_dynstr.h"
+#include "BLI_listbase.h"
 #include "float.h" /* FLT_MIN/MAX */
 
 #include "RNA_define.h" /* for defining our own rna */
 
 #include "MEM_guardedalloc.h"
+#include "BKE_context.h"
 #include "BKE_global.h" /* evil G.* */
 
 static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
@@ -640,6 +642,34 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
        if (prop) {
                ret = pyrna_prop_to_py(&self->ptr, prop);
        }
+       else if (self->ptr.type == &RNA_Context) {
+               PointerRNA newptr;
+               ListBase newlb;
+
+               CTX_data_get(self->ptr.data, name, &newptr, &newlb);
+
+        if (newptr.data) {
+            ret = pyrna_struct_CreatePyObject(&newptr);
+               }
+               else if (newlb.first) {
+                       CollectionPointerLink *link;
+                       PyObject *linkptr;
+
+                       ret = PyList_New(0);
+
+                       for(link=newlb.first; link; link=link->next) {
+                               linkptr= pyrna_struct_CreatePyObject(&link->ptr);
+                               PyList_Append(ret, linkptr);
+                               Py_DECREF(linkptr);
+                       }
+               }
+        else {
+            ret = Py_None;
+            Py_INCREF(ret);
+        }
+
+               BLI_freelistN(&newlb);
+       }
        else {
                PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%s\" not found", name);
                ret = NULL;