Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-06-19 20:09:32 +0300
committerJulian Eisel <julian@blender.org>2020-06-19 21:06:37 +0300
commit15083d9e1eebe0be0cca427602aa826f113ff997 (patch)
tree0c0b9a5945194306c22274489c1dfbf2aa8dd116
parentf4c0ea1d2986f64ed6125a0ca54c9b30a4ecabec (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.c17
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h2
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c20
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)
{