[Bf-blender-cvs] [213d0d6f706] soc-2019-outliner: Outliner: Add synced selection

Nathan Craddock noreply at git.blender.org
Wed Jun 12 06:30:05 CEST 2019


Commit: 213d0d6f706006a5cc43376b661c6f8a4e273f77
Author: Nathan Craddock
Date:   Tue Jun 11 22:27:34 2019 -0600
Branches: soc-2019-outliner
https://developer.blender.org/rB213d0d6f706006a5cc43376b661c6f8a4e273f77

Outliner: Add synced selection

This implementation is to see how syncing will be done, to be redone
later in a more general way. Right now each operator must explicitly
sync the selection.

===================================================================

M	source/blender/editors/object/object_select.c
M	source/blender/editors/space_outliner/outliner_draw.c
M	source/blender/editors/space_outliner/outliner_intern.h
M	source/blender/editors/space_outliner/outliner_select.c
M	source/blender/editors/space_view3d/view3d_select.c

===================================================================

diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index afdda8d6b7f..c13f3694135 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -94,6 +94,24 @@
  * \note Caller must send a `NC_SCENE | ND_OB_SELECT` notifier
  * (or a `NC_SCENE | ND_OB_VISIBLE` in case of visibility toggling).
  */
+
+static void object_sync_selection_to_outliner(bContext *C)
+{
+  Main *bmain = CTX_data_main(C);
+  for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+    for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+      for (SpaceLink *space = sa->spacedata.first; space; space = space->next) {
+        if (space->spacetype == SPACE_OUTLINER) {
+          SpaceOutliner *soutliner = (SpaceOutliner *)space;
+
+          /* Mark selection state as dirty */
+          soutliner->flag |= SO_IS_DIRTY;
+        }
+      }
+    }
+  }
+}
+
 void ED_object_base_select(Base *base, eObjectSelect_Mode mode)
 {
   if (mode == BA_INVERT) {
@@ -1141,6 +1159,8 @@ static int object_select_all_exec(bContext *C, wmOperator *op)
     DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
     WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
 
+    object_sync_selection_to_outliner(C);
+
     return OPERATOR_FINISHED;
   }
   else if (any_visible == false) {
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 4f32543730e..c905ffa5742 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -3507,6 +3507,12 @@ void draw_outliner(const bContext *C)
 
   outliner_build_tree(mainvar, scene, view_layer, soops, ar);  // always
 
+  /* Get selection state from view layer if dirty */
+  if ((soops->flag & SO_IS_DIRTY) != 0 && (soops->flag & SO_SYNC_SELECTION)) {
+    do_outliner_selection_sync(C, false);
+  }
+  soops->flag &= ~SO_IS_DIRTY;
+
   /* force display to pixel coords */
   v2d->flag |= (V2D_PIXELOFS_X | V2D_PIXELOFS_Y);
   /* set matrix for 2d-view controls */
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index bf51b05c240..a5f079ef490 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -261,6 +261,8 @@ void outliner_object_mode_toggle(struct bContext *C,
                                  ViewLayer *view_layer,
                                  Base *base);
 
+void do_outliner_selection_sync(struct bContext *C, bool to_view_layer);
+
 /* outliner_edit.c ---------------------------------------------- */
 typedef void (*outliner_operation_cb)(struct bContext *C,
                                       struct ReportList *,
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index c17fe1a06da..6032177ecb7 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -1310,6 +1310,74 @@ void outliner_item_do_activate_from_tree_element(
       C, scene, view_layer, soops, te, tselem, extend, recursive);
 }
 
+static void do_outliner_selection_sync_recursive(SpaceOutliner *soops,
+                                                 ViewLayer *view_layer,
+                                                 ListBase *tree,
+                                                 bool to_view_layer)
+{
+  TreeElement *te;
+
+  for (te = tree->first; te; te = te->next) {
+    if (te->idcode == ID_OB) {
+      TreeStoreElem *tselem = TREESTORE(te);
+      Object *ob = (Object *)tselem->id;
+
+      Base *base = (te->directdata) ? (Base *)te->directdata :
+                                      BKE_view_layer_base_find(view_layer, ob);
+
+      if (to_view_layer) {
+        const bool is_selected = (tselem->flag & TSE_SELECTED) != 0;
+
+        if (is_selected) {
+
+          base->flag |= BASE_SELECTED;
+        }
+      }
+      else {
+        const bool is_selected = (base != NULL) && ((base->flag & BASE_SELECTED) != 0);
+
+        if (is_selected) {
+          tselem->flag |= TSE_SELECTED;
+        }
+      }
+    }
+
+    if (&te->subtree) {
+      do_outliner_selection_sync_recursive(soops, view_layer, &te->subtree, to_view_layer);
+    }
+  }
+}
+
+void do_outliner_selection_sync(bContext *C, bool to_view_layer)
+{
+  ViewLayer *view_layer = CTX_data_view_layer(C);
+  SpaceOutliner *soops = CTX_wm_space_outliner(C);
+
+  if (!to_view_layer) {
+    outliner_flag_set(&soops->tree, TSE_SELECTED, false);
+  }
+  do_outliner_selection_sync_recursive(soops, view_layer, &soops->tree, to_view_layer);
+
+  if (to_view_layer) {
+    /* Mark other outliners as dirty */
+    if (to_view_layer) {
+      Main *bmain = CTX_data_main(C);
+      for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+        for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+          for (SpaceLink *space = sa->spacedata.first; space; space = space->next) {
+            if (space->spacetype == SPACE_OUTLINER) {
+              SpaceOutliner *soutliner = (SpaceOutliner *)space;
+
+              /* Mark selection state as dirty */
+              soutliner->flag |= SO_IS_DIRTY;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
 /**
  * Action to run when clicking in the outliner,
  *
@@ -1328,6 +1396,9 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
   float view_mval[2];
   bool changed = false, rebuild_tree = false;
 
+  // Set dirty
+  soops->flag |= SO_IS_DIRTY;
+
   UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &view_mval[0], &view_mval[1]);
 
   if (outliner_is_co_within_restrict_columns(soops, ar, view_mval[0])) {
@@ -1374,6 +1445,11 @@ static int outliner_item_do_activate_from_cursor(bContext *C,
       ED_region_tag_redraw_no_rebuild(ar);
     }
     ED_undo_push(C, "Outliner selection change");
+
+    /* Sync selection */
+    if (soops->flag & SO_SYNC_SELECTION) {
+      do_outliner_selection_sync(C, true);
+    }
   }
 
   return OPERATOR_FINISHED;
@@ -1463,6 +1539,10 @@ static int outliner_box_select_exec(bContext *C, wmOperator *op)
   WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
   ED_region_tag_redraw(ar);
 
+  if ((soops->flag & SO_SYNC_SELECTION) != 0) {
+    do_outliner_selection_sync(C, true);
+  }
+
   return OPERATOR_FINISHED;
 }
 
@@ -1614,7 +1694,6 @@ static void do_outliner_select_walk(SpaceOutliner *soops, TreeElement *active, c
   }
   else if (direction == OUTLINER_SELECT_WALK_RIGHT) {
     if (!TSELEM_OPEN(tselem, soops) && active->subtree.first) {
-      printf("not open\n");
       tselem->flag &= ~TSE_CLOSED;
     }
   }
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 6d741d39aae..31a06f2d049 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -114,6 +114,23 @@ float ED_view3d_select_dist_px(void)
   return 75.0f * U.pixelsize;
 }
 
+static void view3d_sync_selection_to_outliner(bContext *C)
+{
+  Main *bmain = CTX_data_main(C);
+  for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+    for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+      for (SpaceLink *space = sa->spacedata.first; space; space = space->next) {
+        if (space->spacetype == SPACE_OUTLINER) {
+          SpaceOutliner *soutliner = (SpaceOutliner *)space;
+
+          /* Mark selection state as dirty */
+          soutliner->flag |= SO_IS_DIRTY;
+        }
+      }
+    }
+  }
+}
+
 /* TODO: should return whether there is valid context to continue */
 void ED_view3d_viewcontext_init(bContext *C, ViewContext *vc)
 {
@@ -1334,6 +1351,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
     MEM_freeN((void *)mcords);
 
     if (changed_multi) {
+      view3d_sync_selection_to_outliner(C);
       return OPERATOR_FINISHED;
     }
     else {
@@ -2354,6 +2372,10 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
    * */
   if (retval) {
     WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+
+    /* Mark outliners selection state as dirty */
+    view3d_sync_selection_to_outliner(C);
+
     return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED;
   }
   else {
@@ -3202,6 +3224,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
   WM_generic_user_data_free(wm_userdata);
 
   if (changed_multi) {
+    view3d_sync_selection_to_outliner(C);
     return OPERATOR_FINISHED;
   }
   else {
@@ -3951,6 +3974,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
   }
   else if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) {
     if (PE_circle_select(C, sel_op, mval, (float)radius)) {
+      view3d_sync_selection_to_outliner(C);
       return OPERATOR_FINISHED;
     }
     return OPERATOR_CANCELLED;
@@ -3970,6 +3994,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
     WM_generic_user_data_free(wm_userdata);
   }
 
+  view3d_sync_selection_to_outliner(C);
   return OPERATOR_FINISHED;
 }



More information about the Bf-blender-cvs mailing list