forked from bartvdbraak/blender
Patch [#23443] Change outliner filter into search
Shane Ambler (sambler) for this 12-month vintage! From description: One thing with the outliner filter box is it only filters items that are currently visible. To find what you want you need to manually expand a few levels so that what you want to find is visible. This small patch expands items when filtering is done - effectively turning it into a search. Currently this does not alter the datablocks view as expanding all entries takes waaaay tooooo long. I prevent the expansion of RNA entries for userprefs which prevents infinite recursion but the datablocks list is just too big for this approach. I think it would need a custom outliner_build_tree for a full search.
This commit is contained in:
parent
bef9509565
commit
67ea3180d9
@ -97,7 +97,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_OPEN(tselem,soops))
|
||||
outliner_height(soops, &te->subtree, h);
|
||||
(*h) += UI_UNIT_Y;
|
||||
te= te->next;
|
||||
@ -112,7 +112,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_OPEN(tselem,soops)) {
|
||||
if (te->xend > *w)
|
||||
*w = te->xend;
|
||||
}
|
||||
@ -135,7 +135,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_OPEN(tselem,soops))
|
||||
outliner_rna_width(soops, &te->subtree, w, startx+UI_UNIT_X);
|
||||
te= te->next;
|
||||
}
|
||||
@ -519,7 +519,7 @@ 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_OPEN(tselem,soops)) outliner_draw_restrictbuts(block, scene, ar, soops, &te->subtree);
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,7 +560,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_OPEN(tselem,soops))) )
|
||||
uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1);
|
||||
}
|
||||
else if(tselem->type == TSE_RNA_ARRAY_ELEM) {
|
||||
@ -571,7 +571,7 @@ 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_OPEN(tselem,soops)) outliner_draw_rnabuts(block, scene, ar, soops, sizex, &te->subtree);
|
||||
}
|
||||
}
|
||||
|
||||
@ -828,7 +828,7 @@ 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_OPEN(tselem,soops)) outliner_draw_keymapbuts(block, ar, soops, &te->subtree);
|
||||
}
|
||||
}
|
||||
|
||||
@ -871,7 +871,7 @@ 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_OPEN(tselem,soops)) outliner_buttons(C, block, ar, soops, &te->subtree);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1237,6 +1237,18 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
/* start by highlighting search matches
|
||||
* we don't expand items when searching in the datablocks but we
|
||||
* still want to highlight any filter matches.
|
||||
*/
|
||||
if ( (SEARCHING_OUTLINER(soops) || (soops->outlinevis==SO_DATABLOCKS && soops->search_string[0]!=0)) &&
|
||||
(tselem->flag & TSE_SEARCHMATCH))
|
||||
{
|
||||
/* TODO - add search highlight colour to theme? */
|
||||
glColor4f(0.2f, 0.5f, 0.2f, 0.3f);
|
||||
glRecti(startx, *starty+1, ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1);
|
||||
}
|
||||
|
||||
/* colors for active/selected data */
|
||||
if(tselem->type==0) {
|
||||
if(te->idcode==ID_SCE) {
|
||||
@ -1317,10 +1329,10 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
|
||||
icon_x = startx+5*ufac;
|
||||
|
||||
// icons a bit higher
|
||||
if(tselem->flag & TSE_CLOSED)
|
||||
UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT);
|
||||
else
|
||||
if(TSELEM_OPEN(tselem,soops))
|
||||
UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_DOWN);
|
||||
else
|
||||
UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT);
|
||||
}
|
||||
offsx+= UI_UNIT_X;
|
||||
|
||||
@ -1356,7 +1368,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
|
||||
offsx+= (int)(UI_UNIT_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_OPEN(tselem,soops)) {
|
||||
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 dont draw */
|
||||
@ -1382,7 +1394,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
|
||||
te->ys= (float)*starty;
|
||||
te->xend= startx+offsx;
|
||||
|
||||
if((tselem->flag & TSE_CLOSED)==0) {
|
||||
if(TSELEM_OPEN(tselem,soops)) {
|
||||
*starty-= UI_UNIT_Y;
|
||||
|
||||
for(ten= te->subtree.first; ten; ten= ten->next)
|
||||
@ -1415,7 +1427,7 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx,
|
||||
|
||||
*starty-= UI_UNIT_Y;
|
||||
|
||||
if((tselem->flag & TSE_CLOSED)==0)
|
||||
if(TSELEM_OPEN(tselem,soops))
|
||||
outliner_draw_hierarchy(soops, &te->subtree, startx+UI_UNIT_X, starty);
|
||||
}
|
||||
|
||||
@ -1439,12 +1451,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_OPEN(tselem,soops))
|
||||
if(tselem->type == TSE_RNA_STRUCT)
|
||||
glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+UI_UNIT_Y-1);
|
||||
|
||||
*starty-= UI_UNIT_Y;
|
||||
if((tselem->flag & TSE_CLOSED)==0) {
|
||||
if(TSELEM_OPEN(tselem,soops)) {
|
||||
outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
|
||||
if(tselem->type == TSE_RNA_STRUCT)
|
||||
fdrawline(0, (float)*starty+UI_UNIT_Y, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+UI_UNIT_Y);
|
||||
@ -1465,7 +1477,7 @@ static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb,
|
||||
glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1);
|
||||
}
|
||||
*starty-= UI_UNIT_Y;
|
||||
if((tselem->flag & TSE_CLOSED)==0) outliner_draw_selection(ar, soops, &te->subtree, starty);
|
||||
if(TSELEM_OPEN(tselem,soops)) outliner_draw_selection(ar, soops, &te->subtree, starty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -687,7 +687,7 @@ static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te,
|
||||
te->ys= (float)(*starty);
|
||||
*starty-= UI_UNIT_Y;
|
||||
|
||||
if((tselem->flag & TSE_CLOSED)==0) {
|
||||
if(TSELEM_OPEN(tselem,soops)) {
|
||||
TreeElement *ten;
|
||||
for(ten= te->subtree.first; ten; ten= ten->next) {
|
||||
outliner_set_coordinates_element(soops, ten, startx+UI_UNIT_X, starty);
|
||||
@ -910,7 +910,7 @@ 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_OPEN(tselem,soops)) tree_element_show_hierarchy(scene, soops, &te->subtree);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1175,7 +1175,7 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL
|
||||
}
|
||||
|
||||
/* go over sub-tree */
|
||||
if ((tselem->flag & TSE_CLOSED)==0)
|
||||
if (TSELEM_OPEN(tselem,soops))
|
||||
do_outliner_drivers_editop(soops, &te->subtree, reports, mode);
|
||||
}
|
||||
}
|
||||
@ -1343,7 +1343,7 @@ static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBa
|
||||
}
|
||||
|
||||
/* go over sub-tree */
|
||||
if ((tselem->flag & TSE_CLOSED)==0)
|
||||
if (TSELEM_OPEN(tselem,soops))
|
||||
do_outliner_keyingset_editop(soops, ks, &te->subtree, mode);
|
||||
}
|
||||
}
|
||||
|
@ -126,6 +126,27 @@ typedef struct TreeElement {
|
||||
#define OL_RNA_COL_SPACEX (UI_UNIT_X*2.5f)
|
||||
|
||||
|
||||
/* Outliner Searching --
|
||||
|
||||
Are we looking for something in the outliner?
|
||||
If so finding matches in child items makes it more useful
|
||||
|
||||
- We want to flag parents to act as being open to filter child matches
|
||||
- and also flag matches so we can highlight them
|
||||
- Flags are stored in TreeStoreElem->flag
|
||||
- Flag options defined in DNA_outliner_types.h
|
||||
- SO_SEARCH_RECURSIVE defined in DNA_space_types.h
|
||||
|
||||
- NOT in datablocks view - searching all datablocks takes way too long
|
||||
to be useful
|
||||
- not searching into RNA items helps but isn't the complete solution
|
||||
*/
|
||||
|
||||
#define SEARCHING_OUTLINER(sov) (sov->search_flags & SO_SEARCH_RECURSIVE)
|
||||
|
||||
/* is the currrent element open? if so we also show children */
|
||||
#define TSELEM_OPEN(telm,sv) ( (telm->flag & TSE_CLOSED)==0 || (SEARCHING_OUTLINER(sv) && (telm->flag & TSE_CHILDSEARCH)) )
|
||||
|
||||
/* outliner_tree.c ----------------------------------------------- */
|
||||
|
||||
void outliner_free_tree(ListBase *lb);
|
||||
|
@ -134,7 +134,7 @@ static int outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *se
|
||||
change |= 1;
|
||||
}
|
||||
}
|
||||
else if ((tselem->flag & TSE_CLOSED)==0) {
|
||||
else if (TSELEM_OPEN(tselem,soops)) {
|
||||
/* Only try selecting sub-elements if we haven't hit the right element yet
|
||||
*
|
||||
* Hack warning:
|
||||
|
@ -145,7 +145,7 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb,
|
||||
}
|
||||
}
|
||||
}
|
||||
if((tselem->flag & TSE_CLOSED)==0) {
|
||||
if(TSELEM_OPEN(tselem,soops)) {
|
||||
set_operation_types(soops, &te->subtree,
|
||||
scenelevel, objectlevel, idlevel, datalevel);
|
||||
}
|
||||
@ -250,7 +250,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_OPEN(tselem,soops)) {
|
||||
outliner_do_libdata_operation(C, scene, soops, &te->subtree, operation_cb);
|
||||
}
|
||||
}
|
||||
@ -397,7 +397,7 @@ void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soop
|
||||
operation_cb(C, scene_owner ? scene_owner : scene_act, te, NULL, tselem);
|
||||
}
|
||||
}
|
||||
if((tselem->flag & TSE_CLOSED)==0) {
|
||||
if(TSELEM_OPEN(tselem,soops)) {
|
||||
outliner_do_object_operation(C, scene_act, soops, &te->subtree, operation_cb);
|
||||
}
|
||||
}
|
||||
@ -504,7 +504,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_OPEN(tselem,soops)) {
|
||||
outliner_do_data_operation(soops, type, event, &te->subtree, operation_cb);
|
||||
}
|
||||
}
|
||||
@ -857,7 +857,7 @@ static void outliner_do_id_set_operation(SpaceOops *soops, int type, ListBase *l
|
||||
operation_cb(te, tselem, tsep, newid);
|
||||
}
|
||||
}
|
||||
if ((tselem->flag & TSE_CLOSED)==0) {
|
||||
if (TSELEM_OPEN(tselem,soops)) {
|
||||
outliner_do_id_set_operation(soops, type, &te->subtree, newid, operation_cb);
|
||||
}
|
||||
}
|
||||
|
@ -827,6 +827,10 @@ 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 */
|
||||
if(SEARCHING_OUTLINER(soops))
|
||||
tselem->flag |= TSE_CHILDSEARCH;
|
||||
|
||||
te->parent= parent;
|
||||
te->index= index; // for data arays
|
||||
if(ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP));
|
||||
@ -981,6 +985,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_OUTLINER(soops) && BLI_strcasecmp("RNA",te->name)==0) tselem->flag &= ~TSE_CHILDSEARCH;
|
||||
|
||||
iterprop= RNA_struct_iterator_property(ptr->type);
|
||||
tot= RNA_property_collection_length(ptr, iterprop);
|
||||
|
||||
@ -989,7 +996,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_OPEN(tselem,soops)) {
|
||||
for(a=0; a<tot; a++)
|
||||
outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_PROPERTY, a);
|
||||
}
|
||||
@ -1010,11 +1017,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_OUTLINER(soops) && 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_OPEN(tselem,soops))
|
||||
outliner_add_element(soops, &te->subtree, (void*)&pptr, te, TSE_RNA_STRUCT, -1);
|
||||
else
|
||||
te->flag |= TE_LAZY_CLOSED;
|
||||
@ -1023,7 +1033,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_OPEN(tselem,soops)) {
|
||||
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, a);
|
||||
@ -1035,7 +1045,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_OPEN(tselem,soops)) {
|
||||
for(a=0; a<tot; a++)
|
||||
outliner_add_element(soops, &te->subtree, (void*)ptr, te, TSE_RNA_ARRAY_ELEM, a);
|
||||
}
|
||||
@ -1068,7 +1078,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_OPEN(tselem,soops)) {
|
||||
a= 0;
|
||||
|
||||
for (kmi= km->items.first; kmi; kmi= kmi->next, a++) {
|
||||
@ -1368,7 +1378,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_OPEN(tselem,soops)) || outliner_filter_tree(soops, &te->subtree)==0) {
|
||||
outliner_free_tree(&te->subtree);
|
||||
BLI_remlink(lb, te);
|
||||
|
||||
@ -1377,6 +1390,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);
|
||||
}
|
||||
@ -1399,6 +1417,14 @@ 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 only set once per tree build */
|
||||
if(soops->search_string[0]!=0 && soops->outlinevis!=SO_DATABLOCKS)
|
||||
soops->search_flags |= SO_SEARCH_RECURSIVE;
|
||||
else
|
||||
soops->search_flags &= ~SO_SEARCH_RECURSIVE;
|
||||
|
||||
if(soops->tree.first && (soops->storeflag & SO_TREESTORE_REDRAW))
|
||||
return;
|
||||
|
||||
|
@ -51,6 +51,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 */
|
||||
|
||||
|
@ -861,6 +861,7 @@ enum {
|
||||
/* outliner search flags (SpaceOops->search_flags) */
|
||||
#define SO_FIND_CASE_SENSITIVE (1<<0)
|
||||
#define SO_FIND_COMPLETE (1<<1)
|
||||
#define SO_SEARCH_RECURSIVE (1<<2)
|
||||
|
||||
/* headerbuttons: 450-499 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user