diff options
author | Julian Eisel <julian@blender.org> | 2020-06-19 20:09:32 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-06-19 21:06:37 +0300 |
commit | 15083d9e1eebe0be0cca427602aa826f113ff997 (patch) | |
tree | 0c0b9a5945194306c22274489c1dfbf2aa8dd116 | |
parent | f4c0ea1d2986f64ed6125a0ca54c9b30a4ecabec (diff) |
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.
-rw-r--r-- | source/blender/editors/space_outliner/outliner_edit.c | 17 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_tree.c | 20 |
3 files changed, 35 insertions, 4 deletions
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 3db75d9288b..67fa18aad86 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -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) { diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 3a928485711..32a67d57d0f 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -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; diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index d6efe683673..7d685be107c 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -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) { |