[Bf-blender-cvs] [b91332e93d9] temp-soc-2019-outliner-sync: Outliner: Allow select on row icons
Nathan Craddock
noreply at git.blender.org
Fri Aug 9 06:01:56 CEST 2019
Commit: b91332e93d9c23d42ad05d384a6aecc53cdefa15
Author: Nathan Craddock
Date: Thu Aug 8 15:37:32 2019 -0600
Branches: temp-soc-2019-outliner-sync
https://developer.blender.org/rBb91332e93d9c23d42ad05d384a6aecc53cdefa15
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.
===================================================================
M source/blender/editors/space_outliner/outliner_draw.c
M source/blender/editors/space_outliner/outliner_edit.c
M source/blender/editors/space_outliner/outliner_intern.h
M source/blender/editors/space_outliner/outliner_select.c
M source/blender/editors/space_outliner/outliner_tools.c
M source/blender/editors/space_outliner/outliner_utils.c
===================================================================
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index a2fe131198d..a3b1c03a1b8 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -2590,7 +2590,11 @@ static void tselem_draw_icon(uiBlock *block,
return;
}
+ /* Icon is covered by restrict buttons */
if (!is_clickable || x >= xmax) {
+ /* Reduce alpha to match icon buttons */
+ alpha *= 0.8f;
+
/* placement of icons, copied from interface_widgets.c */
float aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
x += 2.0f * aspect;
@@ -2698,7 +2702,6 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
float ufac = UI_UNIT_X / 20.0f;
float icon_color[4], icon_border[4];
outliner_icon_background_colors(icon_color, icon_border);
- icon_color[3] *= alpha_fac;
if (active == OL_DRAWSEL_ACTIVE) {
UI_GetThemeColor4fv(TH_EDITED_OBJECT, icon_color);
icon_border[3] = 0.3f;
@@ -2723,6 +2726,9 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
GPU_blend(true); /* Roundbox disables. */
}
+ if (tselem->flag & TSE_HIGHLIGHTED) {
+ alpha_fac += 0.5;
+ }
tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, alpha_fac, false);
te->xs = *offsx;
te->ys = ys;
@@ -2730,7 +2736,12 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
if (num_elements > 1) {
outliner_draw_iconrow_number(fstyle, *offsx, ys, num_elements);
+ te->flag |= TE_ICONROW_MERGED;
}
+ else {
+ te->flag |= TE_ICONROW;
+ }
+
(*offsx) += UI_UNIT_X;
}
@@ -2740,7 +2751,7 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
* We use a continuum of indices until we get to the object data-blocks
* and we then make room for the object types.
*/
-static int tree_element_id_type_to_index(TreeElement *te)
+int tree_element_id_type_to_index(TreeElement *te)
{
TreeStoreElem *tselem = TREESTORE(te);
@@ -2870,7 +2881,7 @@ static void outliner_set_coord_tree_element(TreeElement *te, int startx, int sta
TreeElement *ten;
/* closed items may be displayed in row of parent, don't change their coordinate! */
- if ((te->flag & TE_ICONROW) == 0) {
+ if ((te->flag & TE_ICONROW) == 0 && (te->flag & TE_ICONROW_MERGED) == 0) {
/* store coord and continue, we need coordinates for elements outside view too */
te->xs = startx;
te->ys = starty;
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 57fea544c77..842502ec82f 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -101,9 +101,15 @@ static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const
ARegion *ar = CTX_wm_region(C);
SpaceOutliner *soops = CTX_wm_space_outliner(C);
- const float my = UI_view2d_region_to_view_y(&ar->v2d, event->mval[1]);
- TreeElement *hovered_te = outliner_find_item_at_y(soops, &soops->tree, my);
+ float view_mval[2];
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
+
+ TreeElement *hovered_te = outliner_find_item_at_y(soops, &soops->tree, view_mval[1]);
+
+ if (hovered_te) {
+ hovered_te = outliner_find_item_at_x_in_row(soops, hovered_te, view_mval[0], NULL);
+ }
bool changed = false;
if (!hovered_te || !(hovered_te->store_elem->flag & TSE_HIGHLIGHTED)) {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index c12fdcc6d1f..72cd8dc6424 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -131,6 +131,9 @@ enum {
TE_DISABLED = (1 << 4),
TE_DRAGGING = (1 << 5),
TE_CHILD_NOT_IN_COLLECTION = (1 << 6),
+ /* Child elements of the same type in the iconrow are drawn merged as one icon.
+ * TE_ICONROW_MERGED is set for an element that is part of these merged child icons. */
+ TE_ICONROW_MERGED = (1 << 7),
};
/* button events */
@@ -223,6 +226,8 @@ void outliner_collection_isolate_flag(struct Scene *scene,
const char *propname,
const bool value);
+int tree_element_id_type_to_index(TreeElement *te);
+
/* outliner_select.c -------------------------------------------- */
eOLDrawState tree_element_type_active(struct bContext *C,
struct Scene *scene,
@@ -255,6 +260,8 @@ void outliner_object_mode_toggle(struct bContext *C,
void outliner_element_activate(struct SpaceOutliner *soops, struct TreeStoreElem *tselem);
+bool outliner_item_is_co_within_close_toggle(TreeElement *te, float view_co_x);
+
/* outliner_edit.c ---------------------------------------------- */
typedef void (*outliner_operation_cb)(struct bContext *C,
struct ReportList *,
@@ -382,6 +389,10 @@ void OUTLINER_OT_orphans_purge(struct wmOperatorType *ot);
/* outliner_tools.c ---------------------------------------------- */
+void merged_element_search_menu_invoke(struct bContext *C,
+ TreeElement *parent_te,
+ TreeElement *activate_te);
+
void OUTLINER_OT_operation(struct wmOperatorType *ot);
void OUTLINER_OT_scene_operation(struct wmOperatorType *ot);
void OUTLINER_OT_object_operation(struct wmOperatorType *ot);
@@ -441,7 +452,8 @@ TreeElement *outliner_find_item_at_y(const SpaceOutliner *soops,
float view_co_y);
TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *soops,
const TreeElement *parent_te,
- float view_co_x);
+ float view_co_x,
+ bool *multiple_objects);
TreeElement *outliner_find_tse(struct SpaceOutliner *soops, const TreeStoreElem *tse);
TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem);
TreeElement *outliner_find_parent_element(ListBase *lb,
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 38dfe439b9c..ddb943d6c66 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -1246,12 +1246,6 @@ static void outliner_item_toggle_closed(TreeElement *te, const bool toggle_child
}
}
-static bool outliner_item_is_co_within_close_toggle(TreeElement *te, float view_co_x)
-{
- return ((te->flag & TE_ICONROW) == 0) && (view_co_x > te->xs) &&
- (view_co_x < te->xs + UI_UNIT_X);
-}
-
static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *soops,
const ARegion *ar,
float view_co_x)
@@ -1313,8 +1307,18 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
else {
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- /* the row may also contain children, if one is hovered we want this instead of current te */
- TreeElement *activate_te = outliner_find_item_at_x_in_row(soops, te, view_mval[0]);
+
+ /* The row may also contain children, if one is hovered we want this instead of current te */
+ bool merged_elements = false;
+ TreeElement *activate_te = outliner_find_item_at_x_in_row(
+ soops, te, view_mval[0], &merged_elements);
+
+ /* If the selected icon was an aggregate of multiple elements, run the search popup */
+ if (merged_elements) {
+ merged_element_search_menu_invoke(C, te, activate_te);
+ return OPERATOR_CANCELLED;
+ }
+
TreeStoreElem *activate_tselem = TREESTORE(activate_te);
outliner_item_select(soops, activate_te, extend, extend);
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index f9905cc4fcd..190e859e189 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -478,6 +478,116 @@ void OUTLINER_OT_scene_operation(wmOperatorType *ot)
}
/* ******************************************** */
+/* Stores the parent and a child element of a merged iconrow icon for
+ * the merged select popup menu. The subtree of the parent is searched and
+ * the child is needed to only show elements of the same type in the popup. */
+typedef struct MergedSearchData {
+ TreeElement *parent_element;
+ TreeElement *select_element;
+} MergedSearchData;
+
+static void merged_element_search_cb_recursive(
+ const ListBase *tree, short tselem_type, short type, const char *str, uiSearchItems *items)
+{
+ char name[64];
+ int iconid;
+
+ for (TreeElement *te = tree->first; te; te = te->next) {
+ if (tree_element_id_type_to_index(te) == type && tselem_type == TREESTORE(te)->type) {
+ if (BLI_strcasestr(te->name, str)) {
+ BLI_strncpy(name, te->name, 64);
+
+ iconid = tree_element_get_icon(TREESTORE(te), te).icon;
+
+ if (!UI_search_item_add(items, name, te, iconid)) {
+ break;
+ }
+ }
+ }
+
+ merged_element_search_cb_recursive(&te->subtree, tselem_type, type, str, items);
+ }
+}
+
+/* Get a list of elements that match the search string */
+static void merged_element_search_cb(const bContext *UNUSED(C),
+ void *data,
+ const char *str,
+ uiSearchItems *items)
+{
+ MergedSearchData *search_data = (MergedSearchData *)data;
+ TreeElement *parent = search_data->parent_element;
+ TreeElement *te = search_data->select_element;
+
+ int type = tree_element_id_type_to_index(te);
+
+ merged_element_search_cb_recursive(&parent->subtree, TREESTORE(te)->type, type, str, items);
+}
+
+/* Activate an element fr
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list