Context:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 28 May 2009 23:13:42 +0000 (23:13 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 28 May 2009 23:13:42 +0000 (23:13 +0000)
Added a system for adding a "local" context in a UI layout.
This way you can define for example within a modifier panel
all operators to get the modifier in the context.

In the layout code:

uiLayoutSetContextPointer(layout, "modifier", &ptr)
layout.set_context_pointer("modifier", md)

In the operator:

ptr = CTX_data_pointer_get(C, "modifier")
md = context.modifier

source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/intern/context.c
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_api.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_layout.c

index f08b14c7820cd7482d0a67f02562f3c97206b2da..6a43f4ca25c99b0e91efb8e205bc4e3328aeeee1 100644 (file)
@@ -72,6 +72,20 @@ typedef struct bContextDataResult bContextDataResult;
 typedef int (*bContextDataCallback)(const bContext *C,
        const char *member, bContextDataResult *result);
 
+typedef struct bContextStoreEntry {
+       struct bContextStoreEntry *next, *prev;
+
+       char name[128];
+       PointerRNA ptr;
+} bContextStoreEntry;
+
+typedef struct bContextStore {
+       struct bContextStore *next, *prev;
+
+       ListBase entries;
+       int used;
+} bContextStore;
+
 /* Context */
 
 bContext *CTX_create(void);
@@ -79,6 +93,14 @@ void CTX_free(bContext *C);
 
 bContext *CTX_copy(const bContext *C);
 
+/* Stored Context */
+
+bContextStore *CTX_store_add(ListBase *contexts, char *name, PointerRNA *ptr);
+void CTX_store_set(bContext *C, bContextStore *store);
+bContextStore *CTX_store_copy(bContextStore *store);
+void CTX_store_free(bContextStore *store);
+void CTX_store_free_list(ListBase *contexts);
+
 /* Window Manager Context */
 
 struct wmWindowManager *CTX_wm_manager(const bContext *C);
index 9d2830983e19aaae6f049e0c4a3a093a33f0caba..ae541365b1ebd5a384e529da08240724a0629a48 100644 (file)
@@ -38,6 +38,7 @@
 #include "RNA_access.h"
 
 #include "BLI_listbase.h"
+#include "BLI_string.h"
 
 #include "BKE_context.h"
 #include "BKE_main.h"
@@ -58,6 +59,7 @@ struct bContext {
                struct ScrArea *area;
                struct ARegion *region;
                struct ARegion *menu;
+               struct bContextStore *store;
        } wm;
        
        /* data context */
@@ -97,6 +99,69 @@ void CTX_free(bContext *C)
        MEM_freeN(C);
 }
 
+/* store */
+
+bContextStore *CTX_store_add(ListBase *contexts, char *name, PointerRNA *ptr)
+{
+       bContextStoreEntry *entry;
+       bContextStore *ctx, *lastctx;
+
+       /* ensure we have a context to put the entry in, if it was already used
+        * we have to copy the context to ensure */
+       ctx= contexts->last;
+
+       if(!ctx || ctx->used) {
+               if(ctx) {
+                       lastctx= ctx;
+                       ctx= MEM_dupallocN(lastctx);
+                       BLI_duplicatelist(&ctx->entries, &lastctx->entries);
+               }
+               else
+                       ctx= MEM_callocN(sizeof(bContextStore), "bContextStore");
+
+               BLI_addtail(contexts, ctx);
+       }
+
+       entry= MEM_callocN(sizeof(bContextStoreEntry), "bContextStoreEntry");
+       BLI_strncpy(entry->name, name, sizeof(entry->name));
+       entry->ptr= *ptr;
+
+       BLI_addtail(&ctx->entries, entry);
+
+       return ctx;
+}
+
+void CTX_store_set(bContext *C, bContextStore *store)
+{
+       C->wm.store= store;
+}
+
+bContextStore *CTX_store_copy(bContextStore *store)
+{
+       bContextStore *ctx;
+
+       ctx= MEM_dupallocN(store);
+       BLI_duplicatelist(&ctx->entries, &store->entries);
+
+       return ctx;
+}
+
+void CTX_store_free(bContextStore *store)
+{
+       BLI_freelistN(&store->entries);
+       MEM_freeN(store);
+}
+
+void CTX_store_free_list(ListBase *contexts)
+{
+       bContextStore *ctx;
+
+       while((ctx= contexts->first)) {
+               BLI_remlink(contexts, ctx);
+               CTX_store_free(ctx);
+       }
+}
+
 /* window manager context */
 
 wmWindowManager *CTX_wm_manager(const bContext *C)
@@ -225,19 +290,31 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res
 
        /* we check recursion to ensure that we do not get infinite
         * loops requesting data from ourselfs in a context callback */
-       if(!done && recursion < 1 && C->wm.region) {
+       if(!done && recursion < 1 && C->wm.store) {
+               bContextStoreEntry *entry;
+
                C->data.recursion= 1;
+
+               for(entry=C->wm.store->entries.first; entry; entry=entry->next) {
+                       if(strcmp(entry->name, member) == 0) {
+                               result->ptr= entry->ptr;
+                               done= 1;
+                       }
+               }
+       }
+       if(!done && recursion < 2 && C->wm.region) {
+               C->data.recursion= 2;
                if(C->wm.region->type && C->wm.region->type->context)
                        done= C->wm.region->type->context(C, member, result);
        }
-       if(!done && recursion < 2 && C->wm.area) {
-               C->data.recursion= 2;
+       if(!done && recursion < 3 && C->wm.area) {
+               C->data.recursion= 3;
                if(C->wm.area->type && C->wm.area->type->context)
                        done= C->wm.area->type->context(C, member, result);
        }
-       if(!done && recursion < 3 && C->wm.screen) {
+       if(!done && recursion < 4 && C->wm.screen) {
                bContextDataCallback cb= C->wm.screen->context;
-               C->data.recursion= 3;
+               C->data.recursion= 4;
                if(cb)
                        done= cb(C, member, result);
        }
index b5ed2c59a260f634a68b57e258419a4659b9d312..981bc23162cb55d77d7bb55c4f5ef209bff15eae 100644 (file)
@@ -541,12 +541,13 @@ uiBut *uiDefMenuTogR(uiBlock *block, struct PointerRNA *ptr, char *propname, cha
 uiLayout *uiBlockLayout(uiBlock *block, int dir, int type, int x, int y, int size, int em, struct uiStyle *style);
 void uiBlockSetCurLayout(uiBlock *block, uiLayout *layout);
 void uiBlockLayoutResolve(const struct bContext *C, uiBlock *block, int *x, int *y);
-float uiBlockAspect(uiBlock *block); /* temporary */
 
 void uiLayoutContext(uiLayout *layout, int opcontext);
 void uiLayoutFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv);
 uiBlock *uiLayoutBlock(uiLayout *layout);
 
+void uiLayoutSetContextPointer(uiLayout *layout, char *name, struct PointerRNA *ptr);
+
 /* layout specifiers */
 uiLayout *uiLayoutRow(uiLayout *layout, int align);
 uiLayout *uiLayoutColumn(uiLayout *layout, int align);
index e86e79f7887500761d78eb99cb9701ced32f3f8f..e9a886375c3b053f6a656e9d4affc46bf27fce7b 100644 (file)
@@ -1692,6 +1692,8 @@ void uiFreeBlock(const bContext *C, uiBlock *block)
                ui_free_but(C, but);
        }
 
+       CTX_store_free_list(&block->contexts);
+
        BLI_freelistN(&block->saferct);
        
        MEM_freeN(block);
index 1bb34a71d0ac89e67a6da3954f15111d55cb7583..9c63859dd6f566fee2b286222557a63f5414286c 100644 (file)
@@ -175,6 +175,13 @@ void RNA_api_ui_layout(StructRNA *srna)
 
        func= RNA_def_function(srna, "itemS", "uiItemS");
 
+       /* context */
+       func= RNA_def_function(srna, "set_context_pointer", "uiLayoutSetContextPointer");
+       parm= RNA_def_string(func, "name", "", 0, "Name", "Name of entry in the context.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm= RNA_def_pointer(func, "data", "AnyType", "", "Pointer to put in context.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+
        /* templates */
        func= RNA_def_function(srna, "template_header", "uiTemplateHeader");
        parm= RNA_def_pointer(func, "context", "Context", "", "Current context.");
index b59846738ce05a227ef6679f00c5336b43ca103c..090c0313dae269ec0b551a904017a949b8a8c7b3 100644 (file)
@@ -43,6 +43,7 @@ struct wmWindow;
 struct uiStyle;
 struct uiWidgetColors;
 struct uiLayout;
+struct bContextStore;
 
 /* ****************** general defines ************** */
 
@@ -166,6 +167,8 @@ struct uiBut {
        uiButHandleNFunc funcN;
        void *func_argN;
 
+       struct bContextStore *context;
+
        void (*embossfunc)(int , int , float, float, float, float, float, int);
        void (*sliderfunc)(int , float, float, float, float, float, float, int);
 
@@ -224,6 +227,8 @@ struct uiBlock {
 
        ListBase layouts;
        struct uiLayout *curlayout;
+
+       ListBase contexts;
        
        char name[UI_MAX_NAME_STR];
        
index 1b633c0fd774022847495423c41d38b7c58b39c5..b85d12cd9b7243372531bbc732a3a8c21e999c5c 100644 (file)
@@ -126,6 +126,7 @@ struct uiLayout {
        uiItem item;
 
        uiLayoutRoot *root;
+       bContextStore *context;
        ListBase items;
 
        int x, y, w, h;
@@ -1731,6 +1732,11 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
        bitem->item.type= ITEM_BUTTON;
        bitem->but= but;
        BLI_addtail(&layout->items, bitem);
+
+       if(layout->context) {
+               but->context= layout->context;
+               but->context->used= 1;
+       }
 }
 
 void uiLayoutContext(uiLayout *layout, int opcontext)
@@ -1769,8 +1775,9 @@ void uiBlockLayoutResolve(const bContext *C, uiBlock *block, int *x, int *y)
        }
 }
 
-float uiBlockAspect(uiBlock *block)
+void uiLayoutSetContextPointer(uiLayout *layout, char *name, PointerRNA *ptr)
 {
-       return block->aspect; /* temporary */
+       uiBlock *block= layout->root->block;
+       layout->context= CTX_store_add(&block->contexts, name, ptr);
 }