From 22f05adc3a8f235d73b8534326c033debe38991f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 30 Dec 2008 21:28:27 +0000 Subject: RNA * The RNA viewer is now more integrated with the outliner, as a "Datablocks" view, with a tree structure. * Still some issues to be solved with persistence, and also memory usage is problematic when expanding a million vertices in a mesh for example, though it will not build closed parts of the tree. --- source/blender/blenkernel/intern/context.c | 4 +- source/blender/editors/interface/interface.c | 60 ++- source/blender/editors/interface/interface_draw.c | 19 +- source/blender/editors/space_outliner/outliner.c | 329 ++++++++++++++- .../editors/space_outliner/outliner_header.c | 21 +- .../editors/space_outliner/outliner_intern.h | 14 +- .../editors/space_outliner/space_outliner.c | 444 +-------------------- source/blender/makesdna/DNA_space_types.h | 2 +- source/blender/windowmanager/intern/wm_files.c | 2 +- 9 files changed, 377 insertions(+), 518 deletions(-) diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index aec497537cf..f4fef115990 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -239,12 +239,12 @@ static int ctx_data_get(bContext *C, const bContextDataMember *member, bContextD } if(!done && recursion < 2 && C->wm.region) { C->data.recursion= 2; - if(C->wm.region->type->context) + if(C->wm.region->type && C->wm.region->type->context) done= C->wm.region->type->context(C, member, result); } if(!done && recursion < 3 && C->wm.area) { C->data.recursion= 3; - if(C->wm.area->type->context) + if(C->wm.area->type && C->wm.area->type->context) done= C->wm.area->type->context(C, member, result); } if(!done && recursion < 4 && C->wm.screen) { diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index d1aad05294d..31629ca7621 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1021,20 +1021,35 @@ int uiIsMenu(int *x, int *y, int *sizex, int *sizey) /* for buttons pointing to color for example */ void ui_get_but_vectorf(uiBut *but, float *vec) { - void *poin; - int pointype; + PropertyRNA *prop; + int a, tot; + + if(but->editvec) { + VECCOPY(vec, but->editvec); + return; + } + + if(but->rnaprop) { + prop= but->rnaprop; + + vec[0]= vec[1]= vec[2]= 0.0f; - poin= (but->editvec)? (void*)but->editvec: but->poin; - pointype= (but->editvec)? FLO: but->pointype; + if(RNA_property_type(&but->rnapoin, prop) == PROP_FLOAT) { + tot= RNA_property_array_length(&but->rnapoin, prop); + tot= MIN2(tot, 3); - if(!but->editvec && pointype == CHA) { - char *cp= (char *)poin; + for(a=0; arnapoin, prop, a); + } + } + else if(but->pointype == CHA) { + char *cp= (char *)but->poin; vec[0]= ((float)cp[0])/255.0; vec[1]= ((float)cp[1])/255.0; vec[2]= ((float)cp[2])/255.0; } - else if(pointype == FLO) { - float *fp= (float *)poin; + else if(but->pointype == FLO) { + float *fp= (float *)but->poin; VECCOPY(vec, fp); } } @@ -1042,20 +1057,33 @@ void ui_get_but_vectorf(uiBut *but, float *vec) /* for buttons pointing to color for example */ void ui_set_but_vectorf(uiBut *but, float *vec) { - void *poin; - int pointype; + PropertyRNA *prop; + int a, tot; + + if(but->editvec) { + VECCOPY(but->editvec, vec); + return; + } + + if(but->rnaprop) { + prop= but->rnaprop; - poin= (but->editvec)? (void*)but->editvec: but->poin; - pointype= (but->editvec)? FLO: but->pointype; + if(RNA_property_type(&but->rnapoin, prop) == PROP_FLOAT) { + tot= RNA_property_array_length(&but->rnapoin, prop); + tot= MIN2(tot, 3); - if(!but->editvec && but->pointype == CHA) { - char *cp= (char *)poin; + for(a=0; arnapoin, prop, a, vec[a]); + } + } + else if(but->pointype == CHA) { + char *cp= (char *)but->poin; cp[0]= (char)(0.5 +vec[0]*255.0); cp[1]= (char)(0.5 +vec[1]*255.0); cp[2]= (char)(0.5 +vec[2]*255.0); } - else if( but->pointype == FLO ) { - float *fp= (float *)poin; + else if(but->pointype == FLO) { + float *fp= (float *)but->poin; VECCOPY(fp, vec); } } diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index bcd9a4e9ee7..5c8bdb55315 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -2370,21 +2370,14 @@ static void ui_draw_text_icon(uiBut *but) static void ui_draw_but_COL(uiBut *but) { - float *fp; + float col[3]; char colr, colg, colb; - if( but->pointype==FLO ) { - fp= (float *)but->poin; - colr= floor(255.0*fp[0]+0.5); - colg= floor(255.0*fp[1]+0.5); - colb= floor(255.0*fp[2]+0.5); - } - else { - char *cp= (char *)but->poin; - colr= cp[0]; - colg= cp[1]; - colb= cp[2]; - } + ui_get_but_vectorf(but, col); + + colr= floor(255.0*col[0]+0.5); + colg= floor(255.0*col[1]+0.5); + colb= floor(255.0*col[2]+0.5); /* exception... hrms, but can't simply use the emboss callback for this now. */ /* this button type needs review, and nice integration with rest of API here */ diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index f6047765bc5..7fc121a01f3 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -95,6 +95,8 @@ #include "UI_view2d.h" #include "UI_text.h" +#include "RNA_access.h" + #include "ED_object.h" #include "outliner_intern.h" @@ -113,7 +115,11 @@ #define OL_TOG_RESTRICT_SELECTX 36 #define OL_TOG_RESTRICT_RENDERX 18 -#define OL_TOGW OL_TOG_RESTRICT_VIEWX +#define OL_TOGW OL_TOG_RESTRICT_VIEWX + +#define OL_RNA_COLX 300 +#define OL_RNA_COL_SIZEX 150 +#define OL_RNA_COL_SPACEX 50 #define TS_CHUNK 128 @@ -150,7 +156,8 @@ static void outliner_storage_cleanup(SpaceOops *soops) /* each element used once, for ID blocks with more users to have each a treestore */ for(a=0, tselem= ts->data; ausedelem; a++, tselem++) tselem->used= 0; - /* cleanup only after reading file or undo step */ + /* cleanup only after reading file or undo step, and always for + * RNA datablocks view in order to save memory */ if(soops->storeflag & SO_TREESTORE_CLEANUP) { for(a=0, tselem= ts->data; ausedelem; a++, tselem++) { @@ -243,6 +250,8 @@ void outliner_free_tree(ListBase *lb) outliner_free_tree(&te->subtree); BLI_remlink(lb, te); + + if(te->flag & TE_FREE_NAME) MEM_freeN(te->name); MEM_freeN(te); } } @@ -273,6 +282,24 @@ static void outliner_width(SpaceOops *soops, ListBase *lb, int *w) } } +static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int startx) +{ + TreeElement *te= lb->first; + while(te) { + TreeStoreElem *tselem= TREESTORE(te); + /*if(te->xend) { + if(te->xend > *w) + *w = te->xend; + }*/ + if(startx+100 > *w) + *w = startx+100; + + if((tselem->flag & TSE_CLOSED)==0) + outliner_rna_width(soops, &te->subtree, w, startx+OL_X); + te= te->next; + } +} + static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index) { TreeElement *te= lb->first, *tes; @@ -551,7 +578,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->parent= parent; te->index= index; // for data arays - if((type!=TSE_SEQUENCE) && (type != TSE_SEQ_STRIP) && (type != TSE_SEQUENCE_DUP)) { + if(ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)); + else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)); + else { te->name= id->name+2; // default, can be overridden by Library or non-ID data te->idcode= GS(id->name); } @@ -959,6 +988,118 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->directdata= seq; te->name= seq->strip->stripdata->name; } + else if(ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { + PointerRNA pptr, propptr, *ptr= (PointerRNA*)idv; + PropertyRNA *prop, *iterprop, *nameprop; + PropertyType proptype; + PropertySubType propsubtype; + int a, tot; + + /* we do lazy build, for speed and to avoid infinite recusion */ + + if(ptr->data == NULL) { + te->name= ""; + } + else if(type == TSE_RNA_STRUCT) { + /* struct */ + nameprop= RNA_struct_name_property(ptr); + + if(nameprop) { + te->name= RNA_property_string_get_alloc(ptr, nameprop, NULL, 0); + te->flag |= TE_FREE_NAME; + } + else + te->name= (char*)RNA_struct_ui_name(ptr); + + iterprop= RNA_struct_iterator_property(ptr); + tot= RNA_property_collection_length(ptr, iterprop); + + if(!parent) + tselem->flag &= ~TSE_CLOSED; + + if(!(tselem->flag & TSE_CLOSED)) { + for(a=0; asubtree, (void*)ptr, te, TSE_RNA_PROPERTY, a); + } + else if(tot) + te->flag |= TE_LAZY_CLOSED; + + te->rnaptr= *ptr; + } + else if(type == TSE_RNA_PROPERTY) { + /* property */ + iterprop= RNA_struct_iterator_property(ptr); + RNA_property_collection_lookup_int(ptr, iterprop, index, &propptr); + + prop= propptr.data; + proptype= RNA_property_type(ptr, prop); + + te->name= (char*)RNA_property_ui_name(ptr, prop); + te->directdata= prop; + te->rnaptr= *ptr; + + if(proptype == PROP_POINTER) { + RNA_property_pointer_get(ptr, prop, &pptr); + + if(pptr.data) { + if(!(tselem->flag & TSE_CLOSED)) + outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, -1); + else + te->flag |= TE_LAZY_CLOSED; + } + } + else if(proptype == PROP_COLLECTION) { + tot= RNA_property_collection_length(ptr, prop); + + if(!(tselem->flag & TSE_CLOSED)) { + for(a=0; asubtree, (void*)&pptr, te, TSE_RNA_STRUCT, -1); + } + } + else if(tot) + te->flag |= TE_LAZY_CLOSED; + } + else if(ELEM3(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) { + tot= RNA_property_array_length(ptr, prop); + + if(!(tselem->flag & TSE_CLOSED)) { + for(a=0; asubtree, (void*)ptr, te, TSE_RNA_ARRAY_ELEM, a); + } + else if(tot) + te->flag |= TE_LAZY_CLOSED; + } + } + else if(type == TSE_RNA_ARRAY_ELEM) { + /* array property element */ + static char *vectoritem[4]= {" x", " y", " z", " w"}; + static char *quatitem[4]= {" w", " x", " y", " z"}; + static char *coloritem[4]= {" r", " g", " b", " a"}; + + prop= parent->directdata; + proptype= RNA_property_type(ptr, prop); + propsubtype= RNA_property_subtype(ptr, prop); + tot= RNA_property_array_length(ptr, prop); + + te->directdata= prop; + te->rnaptr= *ptr; + te->index= index; + + if(tot == 4 && propsubtype == PROP_ROTATION) + te->name= quatitem[index]; + else if(tot <= 4 && (propsubtype == PROP_VECTOR || propsubtype == PROP_ROTATION)) + te->name= vectoritem[index]; + else if(tot <= 4 && propsubtype == PROP_COLOR) + te->name= coloritem[index]; + else { + te->name= MEM_callocN(sizeof(char)*20, "OutlinerRNAArrayName"); + sprintf(te->name, " %d", index); + te->flag |= TE_FREE_NAME; + } + } + } + return te; } @@ -1043,7 +1184,7 @@ void add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *te, short index) } } -static void outliner_build_tree(Scene *scene, SpaceOops *soops) +static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) { Base *base; Object *ob; @@ -1187,12 +1328,23 @@ static void outliner_build_tree(Scene *scene, SpaceOops *soops) seq= seq->next; } } + else if(soops->outlinevis==SO_DATABLOCKS) { + PointerRNA mainptr; + + RNA_main_pointer_create(mainvar, &mainptr); + + ten= outliner_add_element(soops, &soops->tree, (void*)&mainptr, NULL, TSE_RNA_STRUCT, -1); + + if(show_opened) { + tselem= TREESTORE(te); + tselem->flag &= ~TSE_CLOSED; + } + } else { ten= outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0); if(ten) ten->directdata= BASACT; } - outliner_sort(soops, &soops->tree); } @@ -3270,7 +3422,7 @@ static void outliner_draw_tree_element(Scene *scene, ARegion *ar, SpaceOops *soo } /* open/close icon, only when sublevels, except for scene */ - if(te->subtree.first || (tselem->type==0 && te->idcode==ID_SCE)) { + if(te->subtree.first || (tselem->type==0 && te->idcode==ID_SCE) || (te->flag & TE_LAZY_CLOSED)) { int icon_x; if((tselem->type==0 && ELEM(te->idcode, ID_OB, ID_SCE)) || ELEM4(te->idcode,ID_VN,ID_VS, ID_MS, ID_SS)) icon_x = startx; @@ -3287,9 +3439,13 @@ static void outliner_draw_tree_element(Scene *scene, ARegion *ar, SpaceOops *soo /* datatype icon */ - // icons a bit higher - tselem_draw_icon((float)startx+offsx, (float)*starty+2, tselem, te); - offsx+= OL_X; + if(!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) { + // icons a bit higher + tselem_draw_icon((float)startx+offsx, (float)*starty+2, tselem, te); + offsx+= OL_X; + } + else + offsx+= 2; if(tselem->type==0 && tselem->id->lib) { glPixelTransferf(GL_ALPHA_SCALE, 0.5f); @@ -3303,7 +3459,8 @@ static void outliner_draw_tree_element(Scene *scene, ARegion *ar, SpaceOops *soo glDisable(GL_BLEND); /* name */ - if(active==1) UI_ThemeColor(TH_TEXT_HI); + if(active==1) UI_ThemeColor(TH_TEXT_HI); + else if(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.75f); else UI_ThemeColor(TH_TEXT); glRasterPos2i(startx+offsx, *starty+5); UI_RasterPos((float)startx+offsx, (float)*starty+5); @@ -3379,6 +3536,28 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx, } } +static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *lb, int *starty) +{ + TreeElement *te; + TreeStoreElem *tselem; + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + + /* selection status */ + if((tselem->flag & TSE_CLOSED)==0) + if(tselem->type == TSE_RNA_STRUCT) + glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+OL_H-1); + + *starty-= OL_H; + if((tselem->flag & TSE_CLOSED)==0) { + outliner_draw_struct_marks(ar, soops, &te->subtree, starty); + if(tselem->type == TSE_RNA_STRUCT) + fdrawline(0, *starty+OL_H-1, (int)ar->v2d.cur.xmax, *starty+OL_H-1); + } + } +} + static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb, int *starty) { TreeElement *te; @@ -3410,11 +3589,20 @@ static void outliner_draw_tree(Scene *scene, ARegion *ar, SpaceOops *soops) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only once - // selection first - UI_GetThemeColor3fv(TH_BACK, col); - glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f); - starty= (int)ar->v2d.tot.ymax-OL_H; - outliner_draw_selection(ar, soops, &soops->tree, &starty); + if(soops->outlinevis == SO_DATABLOCKS) { + // struct marks + UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); + //UI_ThemeColorShade(TH_BACK, -20); + starty= (int)ar->v2d.tot.ymax-OL_H; + outliner_draw_struct_marks(ar, soops, &soops->tree, &starty); + } + else { + // selection first + UI_GetThemeColor3fv(TH_BACK, col); + glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f); + starty= (int)ar->v2d.tot.ymax-OL_H; + outliner_draw_selection(ar, soops, &soops->tree, &starty); + } // grey hierarchy lines UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.2f); @@ -3765,6 +3953,101 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar } } +static void outliner_draw_rnacols(ARegion *ar, SpaceOops *soops, int sizex) +{ + int xstart= MAX2(OL_RNA_COLX, sizex+OL_RNA_COL_SPACEX); + + UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); + + /* view */ + fdrawline(xstart, + ar->v2d.cur.ymax, + xstart, + ar->v2d.cur.ymin); + + fdrawline(xstart+OL_RNA_COL_SIZEX, + ar->v2d.cur.ymax, + xstart+OL_RNA_COL_SIZEX, + ar->v2d.cur.ymin); +} + +static uiBut *outliner_draw_rnabut(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, int x1, int y1, int x2, int y2) +{ + uiBut *but; + const char *propname= RNA_property_identifier(ptr, prop); + int arraylen= RNA_property_array_length(ptr, prop); + + switch(RNA_property_type(ptr, prop)) { + case PROP_BOOLEAN: { + int value, length; + + if(arraylen && index == -1) + return NULL; + + length= RNA_property_array_length(ptr, prop); + + if(length) + value= RNA_property_boolean_get_array(ptr, prop, index); + else + value= RNA_property_boolean_get(ptr, prop); + + but= uiDefButR(block, TOG, 0, (value)? "True": "False", x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + break; + } + case PROP_INT: + case PROP_FLOAT: + if(arraylen && index == -1) { + if(RNA_property_subtype(ptr, prop) == PROP_COLOR) + but= uiDefButR(block, COL, 0, "", x1, y1, x2, y2, ptr, propname, 0, 0, 0, -1, -1, NULL); + } + else + but= uiDefButR(block, NUM, 0, "", x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + break; + case PROP_ENUM: + but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + break; + case PROP_STRING: + but= uiDefButR(block, TEX, 0, "", x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); + break; + default: + but= NULL; + break; + } + + return but; +} + +static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, int sizex, ListBase *lb) +{ + TreeElement *te; + TreeStoreElem *tselem; + PointerRNA *ptr; + PropertyRNA *prop; + int xstart= MAX2(OL_RNA_COLX, sizex+OL_RNA_COL_SPACEX); + + uiBlockSetEmboss(block, UI_EMBOSST); + + for(te= lb->first; te; te= te->next) { + tselem= TREESTORE(te); + if(te->ys >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { + if(tselem->type == TSE_RNA_PROPERTY) { + ptr= &te->rnaptr; + prop= te->directdata; + + outliner_draw_rnabut(block, ptr, prop, -1, xstart, te->ys, OL_RNA_COL_SIZEX, OL_H-1); + } + else if(tselem->type == TSE_RNA_ARRAY_ELEM) { + ptr= &te->rnaptr; + prop= te->directdata; + + outliner_draw_rnabut(block, ptr, prop, te->index, xstart, te->ys, OL_RNA_COL_SIZEX, OL_H-1); + } + } + + if((tselem->flag & TSE_CLOSED)==0) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree); + } +} + static void outliner_buttons(uiBlock *block, ARegion *ar, SpaceOops *soops, ListBase *lb) { uiBut *bt; @@ -3807,13 +4090,14 @@ static void outliner_buttons(uiBlock *block, ARegion *ar, SpaceOops *soops, List void draw_outliner(const bContext *C) { + Main *mainvar= CTX_data_main(C); Scene *scene= CTX_data_scene(C); ARegion *ar= CTX_wm_region(C); SpaceOops *soops= (SpaceOops*)CTX_wm_space_data(C); uiBlock *block; int sizey= 0, sizex= 0; - outliner_build_tree(scene, soops); // always + outliner_build_tree(mainvar, scene, soops); // always outliner_height(soops, &soops->tree, &sizey); outliner_width(soops, &soops->tree, &sizex); @@ -3852,8 +4136,14 @@ void draw_outliner(const bContext *C) block= uiBeginBlock(C, ar, "outliner buttons", UI_EMBOSS, UI_HELV); outliner_buttons(block, ar, soops, &soops->tree); - /* draw restriction columns */ - if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) { + if(soops->outlinevis==SO_DATABLOCKS) { + /* draw rna buttons */ + outliner_rna_width(soops, &soops->tree, &sizex, 0); + outliner_draw_rnacols(ar, soops, sizex); + outliner_draw_rnabuts(block, scene, ar, soops, sizex, &soops->tree); + } + else if (!(soops->flag & SO_HIDE_RESTRICTCOLS)) { + /* draw restriction columns */ outliner_draw_restrictcols(ar, soops); outliner_draw_restrictbuts(block, scene, ar, soops, &soops->tree); } @@ -3863,6 +4153,5 @@ void draw_outliner(const bContext *C) /* clear flag that allows quick redraws */ soops->storeflag &= ~SO_TREESTORE_REDRAW; - - } + diff --git a/source/blender/editors/space_outliner/outliner_header.c b/source/blender/editors/space_outliner/outliner_header.c index 5f2d2809497..e6eed0592e2 100644 --- a/source/blender/editors/space_outliner/outliner_header.c +++ b/source/blender/editors/space_outliner/outliner_header.c @@ -84,8 +84,6 @@ static void do_viewmenu(bContext *C, void *arg, int event) case 4: /* Maximize Window */ /* using event B_FULL */ break; - case 5: /* show rna viewer */ - soops->type= SO_RNA; break; case 14: /* show outliner viewer */ soops->type= SO_OUTLINER; @@ -123,14 +121,7 @@ static uiBlock *outliner_viewmenu(bContext *C, uiMenuBlockHandle *handle, void * block= uiBeginBlock(C, handle->region, "outliner_viewmenu", UI_EMBOSSP, UI_HELV); uiBlockSetButmFunc(block, do_viewmenu, NULL); - if(soops->type==SO_RNA) { - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Outliner", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, ""); - } if(soops->type==SO_OUTLINER) { - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show RNA Viewer", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, ""); - - uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - if (soops->flag & SO_HIDE_RESTRICTCOLS) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Show Restriction Columns", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, ""); else @@ -186,7 +177,6 @@ void outliner_header_buttons(const bContext *C, ARegion *ar) SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C); uiBlock *block; int xco, yco= 3, xmax; - char *path; block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS, UI_HELV); uiBlockSetHandleFunc(block, do_outliner_buttons, NULL); @@ -209,18 +199,11 @@ void outliner_header_buttons(const bContext *C, ARegion *ar) uiBlockSetEmboss(block, UI_EMBOSS); } - if(soutliner->type==SO_RNA) { - path= (soutliner->rnapath)? soutliner->rnapath: "Main"; - xmax= GetButStringLength(path); - uiDefBut(block, LABEL, 0, path, xco, yco-2, xmax-3, 24, 0, 0, 0, 0, 0, "Current RNA Path"); - xco += xmax; - } - if(soutliner->type==SO_OUTLINER) { if(G.main->library.first) - uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10", xco, yco, 100, 20, &soutliner->outlinevis, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11", xco, yco, 100, 20, &soutliner->outlinevis, 0, 0, 0, 0, ""); else - uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10", xco, yco, 100, 20, &soutliner->outlinevis, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11", xco, yco, 100, 20, &soutliner->outlinevis, 0, 0, 0, 0, ""); } diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index e9ed3677ee7..84b6babb269 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -29,6 +29,8 @@ #ifndef ED_OUTLINER_INTERN_H #define ED_OUTLINER_INTERN_H +#include "RNA_types.h" + /* internal exports only */ struct wmWindowManager; @@ -48,11 +50,14 @@ typedef struct TreeElement { short xend; // width of item display, for select char *name; void *directdata; // Armature Bones, Base, Sequence, Strip... + PointerRNA rnaptr; // RNA Pointer } TreeElement; /* TreeElement->flag */ -#define TE_ACTIVE 1 -#define TE_ICONROW 2 +#define TE_ACTIVE 1 +#define TE_ICONROW 2 +#define TE_LAZY_CLOSED 4 +#define TE_FREE_NAME 8 /* TreeStoreElem types */ #define TSE_NLA 1 @@ -83,6 +88,9 @@ typedef struct TreeElement { #define TSE_SEQ_STRIP 27 #define TSE_SEQUENCE_DUP 28 #define TSE_LINKED_PSYS 29 +#define TSE_RNA_STRUCT 30 +#define TSE_RNA_PROPERTY 31 +#define TSE_RNA_ARRAY_ELEM 32 /* outliner search flags */ #define OL_FIND 0 @@ -102,6 +110,7 @@ void outliner_keymap(struct wmWindowManager *wm); void outliner_header_buttons(const struct bContext *C, struct ARegion *ar); /* outliner.c */ +void outliner_free_tree(struct ListBase *lb); void outliner_operation_menu(struct Scene *scene, struct ARegion *ar, struct SpaceOops *soops); void outliner_select(struct ARegion *ar, struct SpaceOops *so); void draw_outliner(const struct bContext *C); @@ -109,7 +118,6 @@ void draw_outliner(const struct bContext *C); void OUTLINER_OT_activate_click(struct wmOperatorType *ot); #if 0 -extern void outliner_free_tree(struct ListBase *lb); extern void outliner_mouse_event(Scene *scene, ARegion *ar, SpaceOops *soops, short event); extern void outliner_toggle_visible(SpaceOops *soops); extern void outliner_show_active(ARegion *ar, SpaceOops *soops); diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 35fb0cd0371..26d8aec3672 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -71,328 +71,6 @@ #include "outliner_intern.h" -#define SET_INT_IN_POINTER(i) ((void*)(intptr_t)(i)) -#define GET_INT_FROM_POINTER(i) ((int)(intptr_t)(i)) - -#define ROW_HEIGHT 19 -#define COLUMN_WIDTH 150 - -typedef void (*uiTableCellFunc)(void *userdata, int row, int col, struct rcti *rct, struct uiBlock *block); - -typedef struct uiTable { - rcti rct; - int rows, cols; - - uiTableCellFunc cellfunc; - void *userdata; -} uiTable; - -uiTable *UI_table_create(int rows, int cols, rcti *rct, uiTableCellFunc cellfunc, void *userdata) -{ - uiTable *table; - - table= MEM_callocN(sizeof(uiTable), "uiTable"); - table->rct= *rct; - table->cellfunc= cellfunc; - table->rows= rows; - table->cols= cols; - table->userdata= userdata; - - return table; -} - -void UI_table_free(uiTable *table) -{ - MEM_freeN(table); -} - -void UI_table_draw(const bContext *C, uiTable *table) -{ - ARegion *ar= CTX_wm_region(C); - uiBlock *block; - View2D *v2d; - rcti *rct, cellrct; - int y, row, col; - - v2d= &ar->v2d; - rct= &table->rct; - - block= uiBeginBlock(C, ar, "table outliner", UI_EMBOSST, UI_HELV); - - for(y=rct->ymax, row=0; y>rct->ymin; y-=ROW_HEIGHT, row++) { - if(row%2 == 0) { - UI_ThemeColorShade(TH_BACK, 6); - glRecti(v2d->cur.xmin, y-ROW_HEIGHT, v2d->cur.xmax, y); - } - - if(row >= table->rows) - continue; - - for(col=0; colcols; col++) { - cellrct.xmin= rct->xmin+COLUMN_WIDTH*col + 1; - cellrct.xmax= rct->xmin+COLUMN_WIDTH*(col+1); - cellrct.ymin= y-ROW_HEIGHT; - cellrct.ymax= y; - - table->cellfunc(table->userdata, row, col, &cellrct, block); - } - } - - UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); - - for(col=0; colcols; col++) - fdrawline(rct->xmin+COLUMN_WIDTH*(col+1), rct->ymin, rct->xmin+COLUMN_WIDTH*(col+1), rct->ymax); - - uiEndBlock(C, block); - uiDrawBlock(C, block); -} - - -/* ************************ main outliner area region *********************** */ - -typedef struct CellRNA { - SpaceOops *space; - StructRNA *srna; - PropertyRNA *prop; - PointerRNA ptr; - int lastrow, index; - - CollectionPropertyIterator iter; -} CellRNA; - -static void rna_back_cb(bContext *C, void *arg_unused, void *arg_unused2) -{ - SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C); - char *newpath; - - newpath= RNA_path_back(soutliner->rnapath); - if(soutliner->rnapath) - MEM_freeN(soutliner->rnapath); - soutliner->rnapath= newpath; -} - -static void rna_pointer_cb(bContext *C, void *arg_prop, void *arg_index) -{ - SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C); - PropertyRNA *prop= arg_prop; - char *newpath; - int index= GET_INT_FROM_POINTER(arg_index);; - - newpath= RNA_path_append(soutliner->rnapath, NULL, prop, index, NULL); - if(soutliner->rnapath) - MEM_freeN(soutliner->rnapath); - soutliner->rnapath= newpath; -} - -static void rna_label(CellRNA *cell, rcti *rct, uiBlock *block) -{ - PropertySubType subtype; - PropertyType type; - PropertyRNA *prop; - char *vectoritem[4]= {"x", "y", "z", "w"}; - char *quatitem[4]= {"w", "x", "y", "z"}; - char *coloritem[4]= {"r", "g", "b", "a"}; - char item[32]; - int arraylength; - - prop= cell->prop; - type= RNA_property_type(&cell->ptr, prop); - subtype= RNA_property_subtype(&cell->ptr, prop); - arraylength= RNA_property_array_length(&cell->ptr, prop); - - if(cell->index == -1) { - uiDefBut(block, LABEL, 0, (char*)RNA_property_ui_name(&cell->ptr, prop), rct->xmin, rct->ymin, rct->xmax-rct->xmin, rct->ymax-rct->ymin, 0, 0, 0, 0, 0, (char*)RNA_property_ui_description(&cell->ptr, prop)); - } - else if (type != PROP_COLLECTION) { - if(arraylength == 4 && subtype == PROP_ROTATION) - sprintf(item, " %s", quatitem[cell->index]); - else if(arraylength <= 4 && (subtype == PROP_VECTOR || subtype == PROP_ROTATION)) - sprintf(item, " %s", vectoritem[cell->index]); - else if(arraylength <= 4 && subtype == PROP_COLOR) - sprintf(item, " %s", coloritem[cell->index]); - else - sprintf(item, " %d", cell->index+1); - - uiDefBut(block, LABEL, 0, item, rct->xmin, rct->ymin, rct->xmax-rct->xmin, rct->ymax-rct->ymin, 0, 0, 0, 0, 0, ""); - } -} - -static void rna_collection_but(CellRNA *cell, rcti *rct, uiBlock *block) -{ - uiBut *but; - PointerRNA lookup; - PropertyRNA *nameprop; - char name[256]= "", *nameptr= name; - - RNA_property_collection_lookup_int(&cell->ptr, cell->prop, cell->index, &lookup); - - if(lookup.data) { - nameprop= RNA_struct_name_property(&lookup); - - if(nameprop) - nameptr= RNA_property_string_get_alloc(&lookup, nameprop, name, sizeof(name)); - - if(!nameprop || strlen(nameptr) == 0) - sprintf(nameptr, "%d", cell->index+1); - } - - but= uiDefBut(block, BUT, 0, nameptr, rct->xmin, rct->ymin, rct->xmax-rct->xmin, rct->ymax-rct->ymin, 0, 0, 0, 0, 0, ""); - uiButSetFlag(but, UI_TEXT_LEFT); - - if(nameptr != name) - MEM_freeN(nameptr); - - uiButSetFunc(but, rna_pointer_cb, cell->prop, SET_INT_IN_POINTER(cell->index)); -} - -static uiBut *rna_auto_but(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, int x1, int y1, int x2, int y2) -{ - uiBut *but; - const char *propname= RNA_property_identifier(ptr, prop); - - switch(RNA_property_type(ptr, prop)) { - case PROP_BOOLEAN: { - int value, length; - - length= RNA_property_array_length(ptr, prop); - - if(length) - value= RNA_property_boolean_get_array(ptr, prop, index); - else - value= RNA_property_boolean_get(ptr, prop); - - but= uiDefButR(block, TOG, 0, (value)? "True": "False", x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); - break; - } - case PROP_INT: - case PROP_FLOAT: - but= uiDefButR(block, NUM, 0, "", x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); - break; - case PROP_ENUM: - but= uiDefButR(block, MENU, 0, NULL, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); - break; - case PROP_STRING: - but= uiDefButR(block, TEX, 0, "", x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL); - break; - case PROP_POINTER: { - PointerRNA pptr; - PropertyRNA *nameprop; - char name[256]= "", *nameptr= name; - - RNA_property_pointer_get(ptr, prop, &pptr); - - if(pptr.data) { - nameprop= RNA_struct_name_property(&pptr); - if(pptr.type && nameprop) - nameptr= RNA_property_string_get_alloc(&pptr, nameprop, name, sizeof(name)); - else - strcpy(nameptr, "->"); - } - - but= uiDefButR(block, BUT, 0, nameptr, x1, y1, x2, y2, ptr, propname, index, 0, 0, 0, 0, NULL); - uiButSetFlag(but, UI_TEXT_LEFT); - - if(nameptr != name) - MEM_freeN(nameptr); - - break; - } - default: - but= NULL; - break; - } - - return but; -} - -static void rna_but(CellRNA *cell, rcti *rct, uiBlock *block) -{ - uiBut *but; - PropertyRNA *prop; - PropertyType type; - int arraylength, index; - - prop= cell->prop; - type= RNA_property_type(&cell->ptr, prop); - arraylength= RNA_property_array_length(&cell->ptr, prop); - - if(type == PROP_COLLECTION) { - /* item in a collection */ - if(cell->index >= 0) - rna_collection_but(cell, rct, block); - } - else { - /* other cases */ - index= (arraylength)? cell->index: 0; - - if(index >= 0) { - but= rna_auto_but(block, &cell->ptr, prop, index, rct->xmin, rct->ymin, rct->xmax-rct->xmin, rct->ymax-rct->ymin); - - if(type == PROP_POINTER) - uiButSetFunc(but, rna_pointer_cb, prop, SET_INT_IN_POINTER(0)); - } - } -} - -static void rna_path_but(CellRNA *cell, rcti *rct, uiBlock *block) -{ - uiBut *but; - - but= uiDefBut(block, BUT, 0, (cell->space->rnapath)? "..": ".", rct->xmin, rct->ymin, rct->xmax-rct->xmin, rct->ymax-rct->ymin, 0, 0, 0, 0, 0, ""); - uiButSetFlag(but, UI_TEXT_LEFT); - uiButSetFunc(but, rna_back_cb, cell->space, NULL); -} - -static void rna_table_cell_func(void *userdata, int row, int col, rcti *rct, uiBlock *block) -{ - CellRNA *cell= userdata; - PropertyType type; - int length; - - /* path button */ - if(row == 0) { - if(col == 0) - rna_path_but(cell, rct, block); - - return; - } - - /* set next property for new row */ - if(row != cell->lastrow) { - if(cell->prop) { - cell->index++; - - type= RNA_property_type(&cell->ptr, cell->prop); - if(type == PROP_COLLECTION) - length= RNA_property_collection_length(&cell->ptr, cell->prop); - else - length= RNA_property_array_length(&cell->ptr, cell->prop); - - /* verify if we need to go to the next property */ - if(type == PROP_COLLECTION && cell->index < length); - else if(length && cell->index < length); - else { - RNA_property_collection_next(&cell->iter); - cell->prop= cell->iter.ptr.data; - cell->index= -1; - } - } - else { - /* initialize */ - cell->prop= cell->iter.ptr.data; - cell->index= -1; - } - - cell->lastrow= row; - } - - /* make button */ - if(col == 0) - rna_label(cell, rct, block); - else if(col == 1) - rna_but(cell, rct, block); -} - static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar) { ListBase *keymap; @@ -404,105 +82,7 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar) WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } -static void outliner_rna_draw(const bContext *C, ARegion *ar) -{ - uiTable *table; - rcti rct; - CellRNA cell; - PropertyRNA *prop, *iterprop; - PointerRNA newptr; - float col[3]; - int rows, cols, awidth, aheight, width, height; - SpaceOops *soutliner= (SpaceOops*)CTX_wm_space_data(C); - View2D *v2d= &ar->v2d; - View2DScrollers *scrollers; - - /* clear */ - UI_GetThemeColor3fv(TH_BACK, col); - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - awidth= width= ar->winx; - aheight= height= ar->winy; - - /* create table */ - cell.space= soutliner; - cell.lastrow= -1; - RNA_main_pointer_create(CTX_data_main(C), &cell.ptr); - cell.prop= NULL; - - /* solve RNA path or reset if fails */ - if(soutliner->rnapath) { - if(!RNA_path_resolve(&cell.ptr, soutliner->rnapath, &newptr, &prop)) { - newptr.data= NULL; - printf("RNA outliner: failed resolving path. (%s)\n", soutliner->rnapath); - } - - if(newptr.data && newptr.type) { - cell.ptr= newptr; - } - else { - MEM_freeN(soutliner->rnapath); - soutliner->rnapath= NULL; - } - } - - /* compute number of rows and columns */ - rows= 1; - cols= 2; - - iterprop= RNA_struct_iterator_property(&cell.ptr); - RNA_property_collection_begin(&cell.ptr, iterprop, &cell.iter); - - for(; cell.iter.valid; RNA_property_collection_next(&cell.iter)) { - prop= cell.iter.ptr.data; - - rows += 1 + RNA_property_array_length(&cell.ptr, prop); - if(RNA_property_type(&cell.ptr, prop) == PROP_COLLECTION) - rows += RNA_property_collection_length(&cell.ptr, prop); - } - - RNA_property_collection_end(&cell.iter); - - /* determine extents of data - * - height must be at least the height of the mask area - * - width is columns + 1, as otherwise, part of last column - * will be obscured by scrollers - */ - if ((rows*ROW_HEIGHT) > height) - height= rows * ROW_HEIGHT; - width= (cols + 1) * COLUMN_WIDTH; - - /* update size of tot-rect (extents of data/viewable area) */ - UI_view2d_totRect_set(v2d, width, height); - - rct.xmin= 0; - rct.ymin= -height; - rct.xmax= width; - rct.ymax= 0; - - /* set matrix for 2d-view controls */ - UI_view2d_view_ortho(C, v2d); - - /* create and draw table */ - table= UI_table_create(rows, 2, &rct, rna_table_cell_func, &cell); - - RNA_property_collection_begin(&cell.ptr, iterprop, &cell.iter); - UI_table_draw(C, table); - RNA_property_collection_end(&cell.iter); - - UI_table_free(table); - - /* reset view matrix */ - UI_view2d_view_restore(C); - - /* scrollers */ - scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY); - UI_view2d_scrollers_draw(C, v2d, scrollers); - UI_view2d_scrollers_free(scrollers); -} - -static void outliner_tree_draw(const bContext *C, ARegion *ar) +static void outliner_main_area_draw(const bContext *C, ARegion *ar) { View2D *v2d= &ar->v2d; View2DScrollers *scrollers; @@ -524,16 +104,6 @@ static void outliner_tree_draw(const bContext *C, ARegion *ar) UI_view2d_scrollers_free(scrollers); } -static void outliner_main_area_draw(const bContext *C, ARegion *ar) -{ - SpaceOops *so= (SpaceOops *)CTX_wm_space_data(C); - - if(so->type==SO_RNA) - outliner_rna_draw(C, ar); - else - outliner_tree_draw(C, ar); -} - static void outliner_main_area_free(ARegion *ar) { @@ -633,18 +203,6 @@ static void free_oops(Oops *oops) /* also oops itself */ MEM_freeN(oops); } -static void outliner_free_tree(ListBase *lb) -{ - - while(lb->first) { - TreeElement *te= lb->first; - - outliner_free_tree(&te->subtree); - BLI_remlink(lb, te); - MEM_freeN(te); - } -} - /* not spacelink itself */ static void outliner_free(SpaceLink *sl) { diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index f5b3ffbd687..9cd1675cd88 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -619,7 +619,6 @@ typedef struct SpaceImaSel { #define SO_OOPS 0 #define SO_OUTLINER 1 #define SO_DEPSGRAPH 2 -#define SO_RNA 3 /* SpaceOops->flag */ #define SO_TESTBLOCKS 1 @@ -656,6 +655,7 @@ typedef struct SpaceImaSel { #define SO_VERSE_SESSION 8 #define SO_VERSE_MS 9 #define SO_SEQUENCE 10 +#define SO_DATABLOCKS 11 /* SpaceOops->storeflag */ #define SO_TREESTORE_CLEANUP 1 diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 4c16a857251..00f1d1358b0 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -898,7 +898,7 @@ int WM_write_homefile(bContext *C, wmOperator *op) char tstr[FILE_MAXDIR+FILE_MAXFILE]; int write_flags; - BLI_make_file_string("/", tstr, "/", ".B.blend"); + BLI_make_file_string("/", tstr, BLI_gethome(), ".B.blend"); /* force save as regular blend file */ write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN); -- cgit v1.2.3