UI: Avoid rebuilding Outliner tree when opening/collapsing items

In big files, the Outliner would have a noticeable lag when opening or
collapsing items. That was because the entire tree was rebuilt, which isn't
actually needed in most cases. So we avoid it where possible now.
This commit is contained in:
Julian Eisel 2020-06-19 19:09:32 +02:00
parent f4c0ea1d29
commit 15083d9e1e
Notes: blender-bot 2023-02-14 07:31:34 +01:00
Referenced by commit 7d25139eaf, Fix T82960: Inaccurate selection on collapsed outliner rows
3 changed files with 35 additions and 4 deletions

View File

@ -191,7 +191,14 @@ static int outliner_item_openclose_modal(bContext *C, wmOperator *op, const wmEv
/* Only toggle openclose on the same level as the first clicked element */
if (te->xs == data->x_location) {
outliner_item_openclose(te, data->open, false);
ED_region_tag_redraw(region);
/* Avoid rebuild if possible. */
if (outliner_element_needs_rebuild_on_open_change(TREESTORE(te))) {
ED_region_tag_redraw(region);
}
else {
ED_region_tag_redraw_no_rebuild(region);
}
}
}
@ -231,7 +238,13 @@ static int outliner_item_openclose_invoke(bContext *C, wmOperator *op, const wmE
(toggle_all && (outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1)));
outliner_item_openclose(te, open, toggle_all);
ED_region_tag_redraw(region);
/* Avoid rebuild if possible. */
if (outliner_element_needs_rebuild_on_open_change(TREESTORE(te))) {
ED_region_tag_redraw(region);
}
else {
ED_region_tag_redraw_no_rebuild(region);
}
/* Only toggle once for single click toggling */
if (event->type == LEFTMOUSE) {

View File

@ -228,6 +228,8 @@ void outliner_build_tree(struct Main *mainvar,
struct SpaceOutliner *soops,
struct ARegion *region);
bool outliner_element_needs_rebuild_on_open_change(const TreeStoreElem *tselem);
typedef struct IDsSelectedData {
struct ListBase selected_array;
} IDsSelectedData;

View File

@ -235,6 +235,17 @@ static TreeElement *outliner_add_element(
/* -------------------------------------------------------- */
/**
* Check if an element type needs a full rebuild if the open/collapsed state changes.
* These element types don't add children if collapsed.
*
* This current check isn't great really. A per element-type flag would be preferable.
*/
bool outliner_element_needs_rebuild_on_open_change(const TreeStoreElem *tselem)
{
return ELEM(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_KEYMAP);
}
/* special handling of hierarchical non-lib data */
static void outliner_add_bone(
SpaceOutliner *soops, ListBase *lb, ID *id, Bone *curBone, TreeElement *parent, int *a)
@ -786,8 +797,13 @@ static void outliner_add_id_contents(SpaceOutliner *soops,
}
}
// TODO: this function needs to be split up! It's getting a bit too large...
// Note: "ID" is not always a real ID
/**
* TODO: this function needs to be split up! It's getting a bit too large...
*
* \note: "ID" is not always a real ID
* \note: If child items are only added to the tree if the item is open, the TSE_ type _must_ be
* added to #outliner_element_needs_rebuild_on_open_change().
*/
static TreeElement *outliner_add_element(
SpaceOutliner *soops, ListBase *lb, void *idv, TreeElement *parent, short type, short index)
{