From 5f888e65c3e765d5c176d3f54cf7d20d216441fc Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Wed, 24 Apr 2019 11:41:35 +0000 Subject: Outliner: Show parenting hierarchy in view layer view If the "Object Children" filter is enabled, we nest the object children inside the object. If the child itself is not in the collection, it is grayed out, connected by a dash line, and its restriction flags and contents are not shown. If "Object Children" filter is disabled, it works as before. Note: This is not super fast, but at least we traverse the tree only once to get the children of an object. That said, there is a lot of loops going on here. Task T63526. Development notes: I could use the GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR shader, but that would mean I would need to iterate over the tree twice (once for each shader) - or do some bigger refactor. Also I could not get that shader to work. This shader expects float vertices while the current one is using integers, so converting the code would make the dash line drawing to diverge from the regular lines even further. Differential Revision: https://developer.blender.org/D4696 --- .../blender/editors/space_outliner/outliner_draw.c | 67 ++++++++++++++++++---- 1 file changed, 56 insertions(+), 11 deletions(-) (limited to 'source/blender/editors/space_outliner/outliner_draw.c') diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 9dbea3c5b1b..545e31c8b4a 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -627,6 +627,10 @@ static void outliner_draw_restrictbuts(uiBlock *block, UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE); } + else if ((tselem->type == 0 && te->idcode == ID_OB) && + (te->flag & TE_CHILD_NOT_IN_COLLECTION)) { + /* Don't show restrict columns for children that are not directly inside the collection. */ + } else if (tselem->type == 0 && te->idcode == ID_OB) { PointerRNA ptr; Object *ob = (Object *)tselem->id; @@ -2074,7 +2078,10 @@ static void outliner_draw_tree_element(bContext *C, tselem = TREESTORE(te); if (*starty + 2 * UI_UNIT_Y >= ar->v2d.cur.ymin && *starty <= ar->v2d.cur.ymax) { - const float alpha_fac = ((te->flag & TE_DISABLED) || draw_grayed_out) ? 0.5f : 1.0f; + const float alpha_fac = ((te->flag & TE_DISABLED) || (te->flag & TE_CHILD_NOT_IN_COLLECTION) || + draw_grayed_out) ? + 0.5f : + 1.0f; const float alpha = 0.5f * alpha_fac; int xmax = ar->v2d.cur.xmax; @@ -2338,17 +2345,28 @@ static void outliner_draw_hierarchy_lines_recursive(unsigned pos, bool draw_grayed_out, int *starty) { - TreeElement *te, *te_vertical_line_last = NULL; - int y1, y2; + TreeElement *te, *te_vertical_line_last = NULL, *te_vertical_line_last_dashed = NULL; + int y1, y2, y1_dashed, y2_dashed; if (BLI_listbase_is_empty(lb)) { return; } + struct { + int steps_num; + int step_len; + int gap_len; + } dash = { + .steps_num = 4, + }; + + dash.step_len = UI_UNIT_X / dash.steps_num; + dash.gap_len = dash.step_len / 2; + const unsigned char grayed_alpha = col[3] / 2; /* For vertical lines between objects. */ - y1 = y2 = *starty; + y1 = y2 = y1_dashed = y2_dashed = *starty; for (te = lb->first; te; te = te->next) { bool draw_childs_grayed_out = draw_grayed_out || (te->flag & TE_DRAGGING); TreeStoreElem *tselem = TREESTORE(te); @@ -2360,16 +2378,31 @@ static void outliner_draw_hierarchy_lines_recursive(unsigned pos, immUniformColor4ubv(col); } - /* Horizontal Line? */ - if (tselem->type == 0 && (te->idcode == ID_OB || te->idcode == ID_SCE)) { - immRecti(pos, startx, *starty, startx + UI_UNIT_X, *starty - 1); + if ((te->flag & TE_CHILD_NOT_IN_COLLECTION) == 0) { + /* Horizontal Line? */ + if (tselem->type == 0 && (te->idcode == ID_OB || te->idcode == ID_SCE)) { + immRecti(pos, startx, *starty, startx + UI_UNIT_X, *starty - 1); - /* Vertical Line? */ - if (te->idcode == ID_OB) { - te_vertical_line_last = te; - y2 = *starty; + /* Vertical Line? */ + if (te->idcode == ID_OB) { + te_vertical_line_last = te; + y2 = *starty; + } + y1_dashed = *starty - UI_UNIT_Y; } } + else { + BLI_assert(te->idcode == ID_OB); + /* Horizontal line - dashed. */ + int start = startx; + for (int i = 0; i < dash.steps_num; i++) { + immRecti(pos, start, *starty, start + dash.step_len - dash.gap_len, *starty - 1); + start += dash.step_len; + } + + te_vertical_line_last_dashed = te; + y2_dashed = *starty; + } *starty -= UI_UNIT_Y; @@ -2391,6 +2424,18 @@ static void outliner_draw_hierarchy_lines_recursive(unsigned pos, if ((te != NULL) && (te->parent || lb->first != lb->last)) { immRecti(pos, startx, y1 + UI_UNIT_Y, startx + 1, y2); } + + /* Children that are not in the collection are always in the end of the subtree. + * This way we can draw their own dashed vertical lines. */ + te = te_vertical_line_last_dashed; + if ((te != NULL) && (te->parent || lb->first != lb->last)) { + const int steps_num = ((y1_dashed + UI_UNIT_Y) - y2_dashed) / dash.step_len; + int start = y1_dashed + UI_UNIT_Y; + for (int i = 0; i < steps_num; i++) { + immRecti(pos, startx, start, startx + 1, start - dash.step_len + dash.gap_len); + start -= dash.step_len; + } + } } static void outliner_draw_hierarchy_lines(SpaceOutliner *soops, -- cgit v1.2.3