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
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.");
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user