Page MenuHome

outlinersearch2.patch

Authored By
Shane Ambler (sambler)
Nov 13 2013, 2:23 PM
Size
20 KB
Subscribers
None

outlinersearch2.patch

diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index 16021e0..38fa94c 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -132,6 +132,10 @@ static int group_select_flag(Group *gr);
/* ******************** PERSISTANT DATA ***************** */
+/* are we searching through the outliner contents?
+ see outliner_build_tree for more info */
+static int searching=0;
+
static void outliner_storage_cleanup(SpaceOops *soops)
{
TreeStore *ts= soops->treestore;
@@ -248,7 +252,7 @@ static void outliner_height(SpaceOops *soops, ListBase *lb, int *h)
TreeElement *te= lb->first;
while(te) {
TreeStoreElem *tselem= TREESTORE(te);
- if((tselem->flag & TSE_CLOSED)==0)
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
outliner_height(soops, &te->subtree, h);
(*h) += OL_H;
te= te->next;
@@ -263,7 +267,7 @@ static void outliner_width(SpaceOops *soops, ListBase *lb, int *w)
// TreeStoreElem *tselem= TREESTORE(te);
// XXX fixme... te->xend is not set yet
- if(tselem->flag & TSE_CLOSED) {
+ if((tselem->flag & TSE_CLOSED) && !(searching && (tselem->flag & TSE_CHILDSEARCH))) { // not tested this searching
if (te->xend > *w)
*w = te->xend;
}
@@ -286,7 +290,7 @@ static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int start
if(startx+100 > *w)
*w = startx+100;
- if((tselem->flag & TSE_CLOSED)==0)
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
outliner_rna_width(soops, &te->subtree, w, startx+OL_X);
te= te->next;
}
@@ -446,7 +450,7 @@ static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, Sc
/* save cpu cycles, but we add the first to invoke an open/close triangle */
tselem = TREESTORE(tenla);
- if(tselem->flag & TSE_CLOSED)
+ if( (tselem->flag & TSE_CLOSED) && !(searching && (tselem->flag & TSE_CHILDSEARCH)) )
return;
te= outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_Z));
@@ -576,6 +580,11 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
check_persistant(soops, te, id, type, index);
tselem= TREESTORE(te);
+ /* if we are searching for something expand to see child elements
+ - user prefs need individual treatment later to not expand rna entries */
+ if(searching && soops->outlinevis!=SO_USERDEF && soops->outlinevis!=SO_DATABLOCKS)
+ tselem->flag |= TSE_CHILDSEARCH;
+
te->parent= parent;
te->index= index; // for data arays
if(ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP));
@@ -1036,6 +1045,9 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
else
te->name= (char*)RNA_struct_ui_name(ptr->type);
+ /* If searching don't expand RNA entries */
+ if(searching && BLI_strcasecmp("RNA",te->name)!=0) tselem->flag &= ~TSE_CHILDSEARCH;
+
iterprop= RNA_struct_iterator_property(ptr->type);
tot= RNA_property_collection_length(ptr, iterprop);
@@ -1044,7 +1056,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if(!tselem->used)
tselem->flag &= ~TSE_CLOSED;
- if(!(tselem->flag & TSE_CLOSED)) {
+ if(!(tselem->flag & TSE_CLOSED) || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
for(a=0; a<tot; a++)
outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_PROPERTY, a);
}
@@ -1065,11 +1077,14 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
te->directdata= prop;
te->rnaptr= *ptr;
+ /* If searching don't expand RNA entries */
+ if(searching && BLI_strcasecmp("RNA",te->name)!=0) tselem->flag &= ~TSE_CHILDSEARCH;
+
if(proptype == PROP_POINTER) {
pptr= RNA_property_pointer_get(ptr, prop);
if(pptr.data) {
- if(!(tselem->flag & TSE_CLOSED))
+ if(!(tselem->flag & TSE_CLOSED) || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, -1);
else
te->flag |= TE_LAZY_CLOSED;
@@ -1078,7 +1093,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
else if(proptype == PROP_COLLECTION) {
tot= RNA_property_collection_length(ptr, prop);
- if(!(tselem->flag & TSE_CLOSED)) {
+ if(!(tselem->flag & TSE_CLOSED) || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
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);
@@ -1090,7 +1105,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
else if(ELEM3(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
tot= RNA_property_array_length(ptr, prop);
- if(!(tselem->flag & TSE_CLOSED)) {
+ if(!(tselem->flag & TSE_CLOSED) || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
for(a=0; a<tot; a++)
outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_ARRAY_ELEM, a);
}
@@ -1123,7 +1138,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
te->directdata= idv;
te->name= km->idname;
- if(!(tselem->flag & TSE_CLOSED)) {
+ if(!(tselem->flag & TSE_CLOSED) || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
a= 0;
for (kmi= km->items.first; kmi; kmi= kmi->next, a++) {
@@ -1302,7 +1317,10 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
*/
tselem= TREESTORE(te);
- if ((tselem->flag & TSE_CLOSED) || outliner_filter_tree(soops, &te->subtree)==0) {
+ /* flag as not a found item */
+ tselem->flag &= ~TSE_SEARCHMATCH;
+
+ if ( ((tselem->flag & TSE_CLOSED) && !(searching && (tselem->flag & TSE_CHILDSEARCH))) || outliner_filter_
outliner_free_tree(&te->subtree);
BLI_remlink(lb, te);
@@ -1311,6 +1329,11 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb)
}
}
else {
+ tselem= TREESTORE(te);
+
+ /* flag as a found item - we can then highlight it */
+ tselem->flag |= TSE_SEARCHMATCH;
+
/* filter subtree too */
outliner_filter_tree(soops, &te->subtree);
}
@@ -1329,6 +1352,11 @@ static void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
TreeStoreElem *tselem;
int show_opened= (soops->treestore==NULL); /* on first view, we open scenes */
+ /* Are we looking for something - we want to tag parents to filter child matches
+ - NOT in datablocks view - searching all datablocks takes way too long to be useful
+ - this variable is static so we only set it once per tree build */
+ searching= (soops->search_string[0]!=0 && soops->outlinevis!=SO_DATABLOCKS);
+
if(soops->tree.first && (soops->storeflag & SO_TREESTORE_REDRAW))
return;
@@ -2665,7 +2693,7 @@ static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te,
te->ys= (float)(*starty);
*starty-= OL_H;
- if((tselem->flag & TSE_CLOSED)==0) {
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
TreeElement *ten;
for(ten= te->subtree.first; ten; ten= ten->next) {
outliner_set_coordinates_element(soops, ten, startx+OL_X, starty);
@@ -2920,7 +2948,8 @@ static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase
}
else tselem->flag |= TSE_CLOSED;
- if(tselem->flag & TSE_CLOSED); else tree_element_show_hierarchy(scene, soops, &te->subtree);
+ if( !(tselem->flag & TSE_CLOSED) || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
+ tree_element_show_hierarchy(scene, soops, &te->subtree);
}
}
@@ -2980,7 +3009,7 @@ void outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *selectin
tselem->flag &= ~TSE_SELECTED;
}
}
- else if ((tselem->flag & TSE_CLOSED)==0) {
+ else if ( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
/* Only try selecting sub-elements if we haven't hit the right element yet
*
* Hack warning:
@@ -3036,7 +3065,7 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb,
}
}
}
- if((tselem->flag & TSE_CLOSED)==0) {
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
set_operation_types(soops, &te->subtree,
scenelevel, objectlevel, idlevel, datalevel);
}
@@ -3135,7 +3164,7 @@ static void outliner_do_libdata_operation(bContext *C, Scene *scene, SpaceOops *
operation_cb(C, scene, te, tsep, tselem);
}
}
- if((tselem->flag & TSE_CLOSED)==0) {
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
outliner_do_libdata_operation(C, scene, soops, &te->subtree, operation_cb);
}
}
@@ -3237,7 +3266,7 @@ static void outliner_do_object_operation(bContext *C, Scene *scene, SpaceOops *s
operation_cb(C, scene, te, NULL, tselem);
}
}
- if((tselem->flag & TSE_CLOSED)==0) {
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
outliner_do_object_operation(C, scene, soops, &te->subtree, operation_cb);
}
}
@@ -3314,7 +3343,7 @@ static void outliner_do_data_operation(SpaceOops *soops, int type, int event, Li
operation_cb(event, te, tselem);
}
}
- if((tselem->flag & TSE_CLOSED)==0) {
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
outliner_do_data_operation(soops, type, event, &te->subtree, operation_cb);
}
}
@@ -3934,7 +3963,7 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, short m
}
/* go over sub-tree */
- if ((tselem->flag & TSE_CLOSED)==0)
+ if ( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
do_outliner_drivers_editop(soops, &te->subtree, mode);
}
}
@@ -4104,7 +4133,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
}
/* go over sub-tree */
- if ((tselem->flag & TSE_CLOSED)==0)
+ if ( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
do_outliner_keyingset_editop(soops, ks, &te->subtree, mode);
}
}
@@ -4513,13 +4542,19 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
if(*starty+2*OL_H >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) {
int xmax= ar->v2d.cur.xmax;
-
+
/* icons can be ui buts, we dont want it to overlap with restrict */
if((soops->flag & SO_HIDE_RESTRICTCOLS)==0)
xmax-= OL_TOGW+ICON_DEFAULT_WIDTH;
glEnable(GL_BLEND);
+ /* start by highlighting search matches */
+ if(searching && (tselem->flag & TSE_SEARCHMATCH) ) {
+ glColor4f(0.0f, 0.8f, 0.0f, 0.3f); /* TODO - add search highlight colour to theme? */
+ glRecti(startx, *starty, xmax, *starty+OL_H);
+ }
+
/* colors for active/selected data */
if(tselem->type==0) {
if(te->idcode==ID_SCE) {
@@ -4592,7 +4627,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
icon_x = startx+5;
// icons a bit higher
- if(tselem->flag & TSE_CLOSED)
+ if( (tselem->flag & TSE_CLOSED) && !(searching && (tselem->flag & TSE_CHILDSEARCH)) )
UI_icon_draw((float)icon_x, (float)*starty+2, ICON_DISCLOSURE_TRI_RIGHT);
else
UI_icon_draw((float)icon_x, (float)*starty+2, ICON_DISCLOSURE_TRI_DOWN);
@@ -4631,7 +4666,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
offsx+= (int)(OL_X + UI_GetStringWidth(te->name));
/* closed item, we draw the icons, not when it's a scene, or master-server list though */
- if(tselem->flag & TSE_CLOSED) {
+ if( (tselem->flag & TSE_CLOSED) && !(searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
if(te->subtree.first) {
if(tselem->type==0 && te->idcode==ID_SCE);
else if(tselem->type!=TSE_R_LAYER) { /* this tree element always has same amount of branches, so d
@@ -4659,7 +4694,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
*starty-= OL_H;
- if((tselem->flag & TSE_CLOSED)==0) {
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
for(ten= te->subtree.first; ten; ten= ten->next) {
outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx+OL_X, starty);
}
@@ -4685,7 +4720,7 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx,
*starty-= OL_H;
- if((tselem->flag & TSE_CLOSED)==0)
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
outliner_draw_hierarchy(soops, &te->subtree, startx+OL_X, starty);
}
@@ -4709,12 +4744,12 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *
tselem= TREESTORE(te);
/* selection status */
- if((tselem->flag & TSE_CLOSED)==0)
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
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) {
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) ) {
outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
if(tselem->type == TSE_RNA_STRUCT)
fdrawline(0, (float)*starty+OL_H-1, ar->v2d.cur.xmax, (float)*starty+OL_H-1);
@@ -4735,7 +4770,8 @@ static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb,
glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+OL_H-1);
}
*starty-= OL_H;
- if((tselem->flag & TSE_CLOSED)==0) outliner_draw_selection(ar, soops, &te->subtree, starty);
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
+ outliner_draw_selection(ar, soops, &te->subtree, starty);
}
}
@@ -5208,7 +5244,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
}
}
- if((tselem->flag & TSE_CLOSED)==0) outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree);
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
+ outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree);
}
}
@@ -5246,7 +5283,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
ptr= &te->rnaptr;
prop= te->directdata;
- if(!(RNA_property_type(prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0))
+ if(!(RNA_property_type(prop) == PROP_POINTER && ((tselem->flag & TSE_CLOSED)==0 || (searching && (
uiDefAutoButR(block, ptr, prop, -1, "", 0, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
}
else if(tselem->type == TSE_RNA_ARRAY_ELEM) {
@@ -5257,7 +5294,8 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
}
}
- if((tselem->flag & TSE_CLOSED)==0) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree);
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
+ outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree);
}
}
@@ -5521,7 +5559,8 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
}
}
- if((tselem->flag & TSE_CLOSED)==0) outliner_draw_keymapbuts(block, ar, soops, &te->subtree);
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
+ outliner_draw_keymapbuts(block, ar, soops, &te->subtree);
}
}
@@ -5562,7 +5601,8 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
}
}
- if((tselem->flag & TSE_CLOSED)==0) outliner_buttons(C, block, ar, soops, &te->subtree);
+ if( (tselem->flag & TSE_CLOSED)==0 || (searching && (tselem->flag & TSE_CHILDSEARCH)) )
+ outliner_buttons(C, block, ar, soops, &te->subtree);
}
}
diff --git a/source/blender/makesdna/DNA_outliner_types.h b/source/blender/makesdna/DNA_outliner_types.h
index d30351b..5526063 100644
--- a/source/blender/makesdna/DNA_outliner_types.h
+++ b/source/blender/makesdna/DNA_outliner_types.h
@@ -47,6 +47,8 @@ typedef struct TreeStore {
#define TSE_CLOSED 1
#define TSE_SELECTED 2
#define TSE_TEXTBUT 4
+#define TSE_CHILDSEARCH 8
+#define TSE_SEARCHMATCH 16
/* TreeStoreElem types in BIF_outliner.h */

File Metadata

Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
3f/d5/52e550154c4849b8c295be191a48

Event Timeline