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 /source/blender/editors | |
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.
Diffstat (limited to 'source/blender/editors')
-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) { |