diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-05-29 03:13:42 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-05-29 03:13:42 +0400 |
commit | 9cc638fb161c1a9795dc3351520ad16c573b4f1f (patch) | |
tree | a9b8f4a300e4bda8b9537f452be6fe88ac9d8bfa /source/blender/blenkernel | |
parent | a843d7e31612a0f9c53fe7b2131bd2b873c5ce7f (diff) |
Context:
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
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_context.h | 22 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/context.c | 87 |
2 files changed, 104 insertions, 5 deletions
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index f08b14c7820..6a43f4ca25c 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -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); diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 9d2830983e1..ae541365b1e 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -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); } |