From 01006aa45d1afc9f45d2f6a42f6981f5c92af051 Mon Sep 17 00:00:00 2001 From: Nathan Craddock Date: Thu, 8 Aug 2019 15:37:32 -0600 Subject: Outliner: Allow select on row icons Allow selection of subtree elements on a collapsed element's row. Because subtree elements are aggregated by type, a select on an icon that represents multiple subtree elements will invoke a popup menu to select the specific subtree element. Also draws highlights on cursor hover over a row icon. Any child elements that are linked to multiple collections will only be listed in the popup one time, and selection from the popup will select the first instance in the subtree. --- .../editors/space_outliner/outliner_utils.c | 56 ++++++++++++++++------ 1 file changed, 42 insertions(+), 14 deletions(-) (limited to 'source/blender/editors/space_outliner/outliner_utils.c') diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c index 727d9866793..d39a9387a6a 100644 --- a/source/blender/editors/space_outliner/outliner_utils.c +++ b/source/blender/editors/space_outliner/outliner_utils.c @@ -66,6 +66,38 @@ TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops, return NULL; } +static TreeElement *outliner_find_item_at_x_in_row_recursive(const TreeElement *parent_te, + float view_co_x, + bool *r_merged) +{ + TreeElement *child_te = parent_te->subtree.first; + + bool over_element = false; + + while (child_te) { + over_element = (view_co_x > child_te->xs) && (view_co_x < child_te->xend); + if ((child_te->flag & TE_ICONROW) && over_element) { + return child_te; + } + else if ((child_te->flag & TE_ICONROW_MERGED) && over_element) { + if (r_merged) { + *r_merged = true; + } + return child_te; + } + + TreeElement *te = outliner_find_item_at_x_in_row_recursive(child_te, view_co_x, r_merged); + if (te != child_te) { + return te; + } + + child_te = child_te->next; + } + + /* return parent if no child is hovered */ + return (TreeElement *)parent_te; +} + /** * Collapsed items can show their children as click-able icons. This function tries to find * such an icon that represents the child item at x-coordinate \a view_co_x (view-space). @@ -74,24 +106,14 @@ TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops, */ TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *soops, const TreeElement *parent_te, - float view_co_x) + float view_co_x, + bool *r_merged) { - /* if parent_te is opened, it doesn't show childs in row */ + /* if parent_te is opened, it doesn't show children in row */ if (!TSELEM_OPEN(TREESTORE(parent_te), soops)) { - /* no recursion, items can only display their direct children in the row */ - for (TreeElement *child_te = parent_te->subtree.first; - /* don't look further if co_x is smaller than child position*/ - child_te && view_co_x >= child_te->xs; - - child_te = child_te->next) { - if ((child_te->flag & TE_ICONROW) && (view_co_x > child_te->xs) && - (view_co_x < child_te->xend)) { - return child_te; - } - } + return outliner_find_item_at_x_in_row_recursive(parent_te, view_co_x, r_merged); } - /* return parent if no child is hovered */ return (TreeElement *)parent_te; } @@ -305,6 +327,12 @@ float outliner_restrict_columns_width(const SpaceOutliner *soops) return (num_columns * UI_UNIT_X + V2D_SCROLL_WIDTH); } +/* Find if x coordinate is over element disclosure toggle */ +bool outliner_item_is_co_within_close_toggle(TreeElement *te, float view_co_x) +{ + return (view_co_x > te->xs) && (view_co_x < te->xs + UI_UNIT_X); +} + /* Get base of object under cursor. Used for eyedropper tool */ Base *ED_outliner_give_base_under_cursor(bContext *C, const int mval[2]) { -- cgit v1.2.3