* 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.
This commit is contained in:
2008-12-30 21:28:27 +00:00
parent 445208d9d1
commit 22f05adc3a
9 changed files with 377 additions and 518 deletions

View File

@@ -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) {

View File

@@ -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;
poin= (but->editvec)? (void*)but->editvec: but->poin;
pointype= (but->editvec)? FLO: but->pointype;
if(but->editvec) {
VECCOPY(vec, but->editvec);
return;
}
if(!but->editvec && pointype == CHA) {
char *cp= (char *)poin;
if(but->rnaprop) {
prop= but->rnaprop;
vec[0]= vec[1]= vec[2]= 0.0f;
if(RNA_property_type(&but->rnapoin, prop) == PROP_FLOAT) {
tot= RNA_property_array_length(&but->rnapoin, prop);
tot= MIN2(tot, 3);
for(a=0; a<tot; a++)
vec[a]= RNA_property_float_get_array(&but->rnapoin, 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;
poin= (but->editvec)? (void*)but->editvec: but->poin;
pointype= (but->editvec)? FLO: but->pointype;
if(but->editvec) {
VECCOPY(but->editvec, vec);
return;
}
if(!but->editvec && but->pointype == CHA) {
char *cp= (char *)poin;
if(but->rnaprop) {
prop= but->rnaprop;
if(RNA_property_type(&but->rnapoin, prop) == PROP_FLOAT) {
tot= RNA_property_array_length(&but->rnapoin, prop);
tot= MIN2(tot, 3);
for(a=0; a<tot; a++)
RNA_property_float_set_array(&but->rnapoin, 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);
}
}

View File

@@ -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 */

View File

@@ -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; a<ts->usedelem; 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; a<ts->usedelem; 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= "<null>";
}
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; a<tot; a++)
outliner_add_element(soops, &te->subtree, (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; a<tot; a++) {
RNA_property_collection_lookup_int(ptr, prop, a, &pptr);
outliner_add_element(soops, &te->subtree, (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; a<tot; a++)
outliner_add_element(soops, &te->subtree, (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;
}

View File

@@ -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, "");
}

View File

@@ -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);

View File

@@ -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; col<table->cols; 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; col<table->cols; 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)
{

View File

@@ -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

View File

@@ -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);