Blender  V2.93
outliner_draw.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2004 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "DNA_armature_types.h"
25 #include "DNA_collection_types.h"
26 #include "DNA_constraint_types.h"
28 #include "DNA_gpencil_types.h"
29 #include "DNA_light_types.h"
30 #include "DNA_lightprobe_types.h"
31 #include "DNA_object_force_types.h"
32 #include "DNA_object_types.h"
33 #include "DNA_scene_types.h"
34 #include "DNA_sequence_types.h"
35 
36 #include "BLI_blenlib.h"
37 #include "BLI_math.h"
38 #include "BLI_mempool.h"
39 #include "BLI_string_utils.h"
40 #include "BLI_utildefines.h"
41 
42 #include "BLT_translation.h"
43 
44 #include "BKE_armature.h"
45 #include "BKE_context.h"
46 #include "BKE_deform.h"
47 #include "BKE_gpencil.h"
48 #include "BKE_idtype.h"
49 #include "BKE_layer.h"
50 #include "BKE_lib_id.h"
51 #include "BKE_library.h"
52 #include "BKE_main.h"
53 #include "BKE_modifier.h"
54 #include "BKE_object.h"
55 #include "BKE_particle.h"
56 #include "BKE_report.h"
57 
58 #include "DEG_depsgraph.h"
59 #include "DEG_depsgraph_build.h"
60 
61 #include "ED_armature.h"
62 #include "ED_outliner.h"
63 #include "ED_screen.h"
64 
65 #include "WM_api.h"
66 #include "WM_message.h"
67 #include "WM_types.h"
68 
69 #include "GPU_immediate.h"
70 #include "GPU_state.h"
71 
72 #include "UI_interface.h"
73 #include "UI_interface_icons.h"
74 #include "UI_resources.h"
75 #include "UI_view2d.h"
76 
77 #include "RNA_access.h"
78 
79 #include "outliner_intern.h"
80 
81 /* Disable - this is far too slow - campbell. */
82 /* #define USE_GROUP_SELECT */
83 
84 /* ****************************************************** */
85 /* Tree Size Functions */
86 
87 static void outliner_tree_dimensions_impl(SpaceOutliner *space_outliner,
88  ListBase *lb,
89  int *width,
90  int *height)
91 {
92  LISTBASE_FOREACH (TreeElement *, te, lb) {
93  *width = MAX2(*width, te->xend);
94  if (height != NULL) {
95  *height += UI_UNIT_Y;
96  }
97 
98  TreeStoreElem *tselem = TREESTORE(te);
99  if (TSELEM_OPEN(tselem, space_outliner)) {
100  outliner_tree_dimensions_impl(space_outliner, &te->subtree, width, height);
101  }
102  else {
103  outliner_tree_dimensions_impl(space_outliner, &te->subtree, width, NULL);
104  }
105  }
106 }
107 
108 void outliner_tree_dimensions(SpaceOutliner *space_outliner, int *r_width, int *r_height)
109 {
110  *r_width = 0;
111  *r_height = 0;
112  outliner_tree_dimensions_impl(space_outliner, &space_outliner->tree, r_width, r_height);
113 }
114 
118 static bool is_object_data_in_editmode(const ID *id, const Object *obact)
119 {
120  if (id == NULL) {
121  return false;
122  }
123 
124  const short id_type = GS(id->name);
125 
126  if (id_type == ID_GD && obact && obact->data == id) {
127  bGPdata *gpd = (bGPdata *)id;
128  return GPENCIL_EDIT_MODE(gpd);
129  }
130 
131  return ((obact && (obact->mode & OB_MODE_EDIT)) && (id && OB_DATA_SUPPORT_EDITMODE(id_type)) &&
132  (GS(((ID *)obact->data)->name) == id_type) && BKE_object_data_is_in_editmode(id));
133 }
134 
135 /* ****************************************************** */
136 
138  EditBone *ebone_parent,
139  int flag,
140  bool set_flag)
141 {
142  EditBone *ebone;
143 
144  for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
145  if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
146  if (set_flag) {
147  ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
148  ebone->flag |= flag;
149  }
150  else {
151  ebone->flag &= ~flag;
152  }
153  }
154  }
155 }
156 
157 static void restrictbutton_recursive_bone(Bone *bone_parent, int flag, bool set_flag)
158 {
159  Bone *bone;
160  for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
161  if (set_flag) {
162  bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
163  bone->flag |= flag;
164  }
165  else {
166  bone->flag &= ~flag;
167  }
168  restrictbutton_recursive_bone(bone, flag, set_flag);
169  }
170 }
171 
172 static void restrictbutton_r_lay_fn(bContext *C, void *poin, void *UNUSED(poin2))
173 {
175 }
176 
177 static void restrictbutton_bone_visibility_fn(bContext *C, void *poin, void *UNUSED(poin2))
178 {
179  Bone *bone = (Bone *)poin;
180 
181  if (CTX_wm_window(C)->eventstate->shift) {
183  }
184 }
185 
186 static void restrictbutton_bone_select_fn(bContext *C, void *UNUSED(poin), void *poin2)
187 {
188  Bone *bone = (Bone *)poin2;
189  if (bone->flag & BONE_UNSELECTABLE) {
190  bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
191  }
192 
193  if (CTX_wm_window(C)->eventstate->shift) {
195  }
196 
198 }
199 
200 static void restrictbutton_ebone_select_fn(bContext *C, void *poin, void *poin2)
201 {
202  bArmature *arm = (bArmature *)poin;
203  EditBone *ebone = (EditBone *)poin2;
204 
205  if (ebone->flag & BONE_UNSELECTABLE) {
206  ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
207  }
208 
209  if (CTX_wm_window(C)->eventstate->shift) {
211  arm, ebone, BONE_UNSELECTABLE, (ebone->flag & BONE_UNSELECTABLE) != 0);
212  }
213 
215 }
216 
217 static void restrictbutton_ebone_visibility_fn(bContext *C, void *poin, void *poin2)
218 {
219  bArmature *arm = (bArmature *)poin;
220  EditBone *ebone = (EditBone *)poin2;
221  if (ebone->flag & BONE_HIDDEN_A) {
222  ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
223  }
224 
225  if (CTX_wm_window(C)->eventstate->shift) {
226  restrictbutton_recursive_ebone(arm, ebone, BONE_HIDDEN_A, (ebone->flag & BONE_HIDDEN_A) != 0);
227  }
228 
230 }
231 
232 static void restrictbutton_gp_layer_flag_fn(bContext *C, void *poin, void *UNUSED(poin2))
233 {
234  ID *id = (ID *)poin;
235 
238 }
239 
240 static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void *UNUSED(poin2))
241 {
242  ID *id = (ID *)poin;
243 
244  BLI_assert(id != NULL);
245 
246  if (id->flag & LIB_FAKEUSER) {
247  id_us_plus(id);
248  }
249  else {
250  id_us_min(id);
251  }
252 }
253 
255  Base *base,
256  Object *ob,
257  const char *propname)
258 {
259  Main *bmain = CTX_data_main(C);
260  wmWindow *win = CTX_wm_window(C);
262  ViewLayer *view_layer = CTX_data_view_layer(C);
263  PointerRNA ptr;
264 
265  bool extend = (win->eventstate->shift != 0);
266 
267  if (!extend) {
268  return;
269  }
270 
271  /* Create PointerRNA and PropertyRNA for either Object or Base. */
272  ID *id = ob ? &ob->id : &scene->id;
273  StructRNA *struct_rna = ob ? &RNA_Object : &RNA_ObjectBase;
274  void *data = ob ? (void *)ob : (void *)base;
275 
276  RNA_pointer_create(id, struct_rna, data, &ptr);
277  PropertyRNA *base_or_object_prop = RNA_struct_type_find_property(struct_rna, propname);
278  const bool value = RNA_property_boolean_get(&ptr, base_or_object_prop);
279 
280  Object *ob_parent = ob ? ob : base->object;
281 
282  for (Object *ob_iter = bmain->objects.first; ob_iter; ob_iter = ob_iter->id.next) {
283  if (BKE_object_is_child_recursive(ob_parent, ob_iter)) {
284  if (ob) {
285  RNA_id_pointer_create(&ob_iter->id, &ptr);
287  }
288  else {
289  Base *base_iter = BKE_view_layer_base_find(view_layer, ob_iter);
290  /* Child can be in a collection excluded from viewlayer. */
291  if (base_iter == NULL) {
292  continue;
293  }
294  RNA_pointer_create(&scene->id, &RNA_ObjectBase, base_iter, &ptr);
295  }
296  RNA_property_boolean_set(&ptr, base_or_object_prop, value);
297  }
298  }
299 
300  /* We don't call RNA_property_update() due to performance, so we batch update them. */
301  if (ob) {
304  }
305  else {
306  BKE_layer_collection_sync(scene, view_layer);
308  }
309 }
310 
314 static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
315 {
316  Object *ob = poin;
317  char *propname = poin2;
319 }
320 
324 static void outliner__base_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
325 {
326  Base *base = poin;
327  char *propname = poin2;
328  outliner_object_set_flag_recursive_fn(C, base, NULL, propname);
329 }
330 
333  LayerCollection *layer_collection,
334  Collection *collection,
335  PointerRNA *ptr)
336 {
337  if (collection) {
338  RNA_id_pointer_create(&collection->id, ptr);
339  }
340  else {
341  RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, ptr);
342  }
343 }
344 
347  Scene *scene, ViewLayer *view_layer, Collection *collection, Object *ob, PointerRNA *ptr)
348 {
349  if (collection) {
351  }
352  else {
353  Base *base = BKE_view_layer_base_find(view_layer, ob);
355  }
356 }
357 
358 /* Note: Collection is only valid when we want to change the collection data, otherwise we get it
359  * from layer collection. Layer collection is valid whenever we are looking at a view layer. */
361  ViewLayer *view_layer,
362  LayerCollection *layer_collection,
363  Collection *collection,
364  PropertyRNA *layer_or_collection_prop,
365  PropertyRNA *base_or_object_prop,
366  const bool value)
367 {
368  if (layer_collection && layer_collection->flag & LAYER_COLLECTION_EXCLUDE) {
369  return;
370  }
371  PointerRNA ptr;
372  outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr);
373  RNA_property_boolean_set(&ptr, layer_or_collection_prop, value);
374 
375  /* Set the same flag for the nested objects as well. */
376  if (base_or_object_prop) {
377  /* Note: We can't use BKE_collection_object_cache_get()
378  * otherwise we would not take collection exclusion into account. */
379  LISTBASE_FOREACH (CollectionObject *, cob, &layer_collection->collection->gobject) {
380 
381  outliner_base_or_object_pointer_create(scene, view_layer, collection, cob->ob, &ptr);
382  RNA_property_boolean_set(&ptr, base_or_object_prop, value);
383 
384  if (collection) {
386  }
387  }
388  }
389 
390  /* Keep going recursively. */
391  ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children);
392  LISTBASE_FOREACH (Link *, link, lb) {
393  LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL;
394  Collection *collection_iter = layer_collection ?
395  (collection ? layer_collection_iter->collection : NULL) :
396  ((CollectionChild *)link)->collection;
398  view_layer,
399  layer_collection_iter,
400  collection_iter,
401  layer_or_collection_prop,
402  base_or_object_prop,
403  value);
404  }
405 
406  if (collection) {
408  }
409 }
410 
422  const LayerCollection *layer_collection_cmp,
423  const Collection *collection_cmp,
424  const bool value_cmp,
425  const PropertyRNA *layer_or_collection_prop,
426  LayerCollection *layer_collection,
427  Collection *collection)
428 {
429  PointerRNA ptr;
430  outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr);
431  const bool value = RNA_property_boolean_get(&ptr, (PropertyRNA *)layer_or_collection_prop);
432  Collection *collection_ensure = collection ? collection : layer_collection->collection;
433  const Collection *collection_ensure_cmp = collection_cmp ? collection_cmp :
434  layer_collection_cmp->collection;
435 
436  if (collection_ensure->flag & COLLECTION_IS_MASTER) {
437  }
438  else if (collection_ensure == collection_ensure_cmp) {
439  }
440  else if (BKE_collection_has_collection(collection_ensure, (Collection *)collection_ensure_cmp) ||
441  BKE_collection_has_collection((Collection *)collection_ensure_cmp, collection_ensure)) {
442  /* This collection is either a parent or a child of the collection.
443  * We expect it to be set "visible" already. */
444  if (value != value_cmp) {
445  return false;
446  }
447  }
448  else {
449  /* This collection is neither a parent nor a child of the collection.
450  * We expect it to be "invisible". */
451  if (value == value_cmp) {
452  return false;
453  }
454  }
455 
456  /* Keep going recursively. */
457  ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children);
458  LISTBASE_FOREACH (Link *, link, lb) {
459  LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL;
460  Collection *collection_iter = layer_collection ?
461  (collection ? layer_collection_iter->collection : NULL) :
462  ((CollectionChild *)link)->collection;
463  if (layer_collection_iter && layer_collection_iter->flag & LAYER_COLLECTION_EXCLUDE) {
464  continue;
465  }
467  layer_collection_cmp,
468  collection_cmp,
469  value_cmp,
470  layer_or_collection_prop,
471  layer_collection_iter,
472  collection_iter)) {
473  return false;
474  }
475  }
476 
477  return true;
478 }
479 
481  ViewLayer *view_layer,
482  LayerCollection *layer_collection,
483  Collection *collection,
484  PropertyRNA *layer_or_collection_prop,
485  const char *propname,
486  const bool value)
487 {
488  PointerRNA ptr;
489  const bool is_hide = strstr(propname, "hide_") != NULL;
490 
491  LayerCollection *top_layer_collection = layer_collection ? view_layer->layer_collections.first :
492  NULL;
493  Collection *top_collection = collection ? scene->master_collection : NULL;
494 
495  bool was_isolated = (value == is_hide);
496  was_isolated &= outliner_collection_is_isolated(scene,
497  layer_collection,
498  collection,
499  !is_hide,
500  layer_or_collection_prop,
501  top_layer_collection,
502  top_collection);
503 
504  if (was_isolated) {
505  const bool default_value = RNA_property_boolean_get_default(NULL, layer_or_collection_prop);
506  /* Make every collection go back to its default "visibility" state. */
508  view_layer,
509  top_layer_collection,
510  top_collection,
511  layer_or_collection_prop,
512  NULL,
513  default_value);
514  return;
515  }
516 
517  /* Make every collection "invisible". */
519  view_layer,
520  top_layer_collection,
521  top_collection,
522  layer_or_collection_prop,
523  NULL,
524  is_hide);
525 
526  /* Make this collection and its children collections the only "visible". */
528  scene, view_layer, layer_collection, collection, layer_or_collection_prop, NULL, !is_hide);
529 
530  /* Make this collection direct parents also "visible". */
531  if (layer_collection) {
532  LayerCollection *lc_parent = layer_collection;
533  LISTBASE_FOREACH (LayerCollection *, lc_iter, &top_layer_collection->layer_collections) {
534  if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) {
535  lc_parent = lc_iter;
536  break;
537  }
538  }
539 
540  while (lc_parent != layer_collection) {
542  scene, lc_parent, collection ? lc_parent->collection : NULL, &ptr);
543  RNA_property_boolean_set(&ptr, layer_or_collection_prop, !is_hide);
544 
545  LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_parent->layer_collections) {
546  if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) {
547  lc_parent = lc_iter;
548  break;
549  }
550  }
551  }
552  }
553  else {
554  CollectionParent *parent;
555  Collection *child = collection;
556  while ((parent = child->parents.first)) {
557  if (parent->collection->flag & COLLECTION_IS_MASTER) {
558  break;
559  }
560  RNA_id_pointer_create(&parent->collection->id, &ptr);
561  RNA_property_boolean_set(&ptr, layer_or_collection_prop, !is_hide);
562  child = parent->collection;
563  }
564  }
565 }
566 
568  LayerCollection *layer_collection,
569  Collection *collection,
570  const char *propname)
571 {
572  Main *bmain = CTX_data_main(C);
573  wmWindow *win = CTX_wm_window(C);
575  ViewLayer *view_layer = CTX_data_view_layer(C);
576  PointerRNA ptr;
577 
578  bool do_isolate = (win->eventstate->ctrl != 0);
579  bool extend = (win->eventstate->shift != 0);
580 
581  if (!ELEM(true, do_isolate, extend)) {
582  return;
583  }
584 
585  /* Create PointerRNA and PropertyRNA for either Collection or LayerCollection. */
586  ID *id = collection ? &collection->id : &scene->id;
587  StructRNA *struct_rna = collection ? &RNA_Collection : &RNA_LayerCollection;
588  void *data = collection ? (void *)collection : (void *)layer_collection;
589 
590  RNA_pointer_create(id, struct_rna, data, &ptr);
591  outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr);
592  PropertyRNA *layer_or_collection_prop = RNA_struct_type_find_property(struct_rna, propname);
593  const bool value = RNA_property_boolean_get(&ptr, layer_or_collection_prop);
594 
595  PropertyRNA *base_or_object_prop = NULL;
596  if (layer_collection != NULL) {
597  /* If we are toggling Layer collections we still want to change the properties of the base
598  * or the objects. If we have a matching property, toggle it as well, it can be NULL. */
599  struct_rna = collection ? &RNA_Object : &RNA_ObjectBase;
600  base_or_object_prop = RNA_struct_type_find_property(struct_rna, propname);
601  }
602 
603  if (extend) {
605  view_layer,
606  layer_collection,
607  collection,
608  layer_or_collection_prop,
609  base_or_object_prop,
610  value);
611  }
612  else {
614  view_layer,
615  layer_collection,
616  collection,
617  layer_or_collection_prop,
618  propname,
619  value);
620  }
621 
622  /* We don't call RNA_property_update() due to performance, so we batch update them. */
625 }
626 
632  void *poin,
633  void *poin2)
634 {
635  LayerCollection *layer_collection = poin;
636  char *propname = poin2;
637  outliner_collection_set_flag_recursive_fn(C, layer_collection, NULL, propname);
638 }
639 
644 static void view_layer__collection_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
645 {
646  LayerCollection *layer_collection = poin;
647  char *propname = poin2;
649  C, layer_collection, layer_collection->collection, propname);
650 }
651 
656 static void scenes__collection_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
657 {
658  Collection *collection = poin;
659  char *propname = poin2;
660  outliner_collection_set_flag_recursive_fn(C, NULL, collection, propname);
661 }
662 
663 static void namebutton_fn(bContext *C, void *tsep, char *oldname)
664 {
665  Main *bmain = CTX_data_main(C);
666  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
667  struct wmMsgBus *mbus = CTX_wm_message_bus(C);
668  BLI_mempool *ts = space_outliner->treestore;
669  TreeStoreElem *tselem = tsep;
670 
671  if (ts && tselem) {
672  TreeElement *te = outliner_find_tree_element(&space_outliner->tree, tselem);
673 
674  if (tselem->type == TSE_SOME_ID) {
675  BLI_libblock_ensure_unique_name(bmain, tselem->id->name);
676 
677  WM_msg_publish_rna_prop(mbus, tselem->id, tselem->id, ID, name);
678 
679  switch (GS(tselem->id->name)) {
680  case ID_MA:
682  break;
683  case ID_TE:
685  break;
686  case ID_IM:
688  break;
689  case ID_SCE:
691  break;
692  case ID_OB: {
693  Object *ob = (Object *)tselem->id;
694  if (ob->type == OB_MBALL) {
696  }
698  break;
699  }
700  default:
701  break;
702  }
704 
705  /* Check the library target exists */
706  if (te->idcode == ID_LI) {
707  Library *lib = (Library *)tselem->id;
708  char expanded[FILE_MAX];
709 
710  BKE_library_filepath_set(bmain, lib, lib->filepath);
711 
712  BLI_strncpy(expanded, lib->filepath, sizeof(expanded));
713  BLI_path_abs(expanded, BKE_main_blendfile_path(bmain));
714  if (!BLI_exists(expanded)) {
716  RPT_ERROR,
717  "Library path '%s' does not exist, correct this before saving",
718  expanded);
719  }
720  else if (lib->id.tag & LIB_TAG_MISSING) {
722  RPT_INFO,
723  "Library path '%s' is now valid, please reload the library",
724  expanded);
725  lib->id.tag &= ~LIB_TAG_MISSING;
726  }
727  }
728  }
729  else {
730  switch (tselem->type) {
731  case TSE_DEFGROUP: {
732  Object *ob = (Object *)tselem->id;
733  bDeformGroup *vg = te->directdata;
735  WM_msg_publish_rna_prop(mbus, &ob->id, vg, VertexGroup, name);
736  break;
737  }
738  case TSE_NLA_ACTION: {
739  bAction *act = (bAction *)tselem->id;
741  WM_msg_publish_rna_prop(mbus, &act->id, &act->id, ID, name);
742  break;
743  }
744  case TSE_EBONE: {
745  bArmature *arm = (bArmature *)tselem->id;
746  if (arm->edbo) {
747  EditBone *ebone = te->directdata;
748  char newname[sizeof(ebone->name)];
749 
750  /* restore bone name */
751  BLI_strncpy(newname, ebone->name, sizeof(ebone->name));
752  BLI_strncpy(ebone->name, oldname, sizeof(ebone->name));
753  ED_armature_bone_rename(bmain, arm, oldname, newname);
754  WM_msg_publish_rna_prop(mbus, &arm->id, ebone, EditBone, name);
756  }
757  break;
758  }
759 
760  case TSE_BONE: {
761  TreeViewContext tvc;
763 
764  bArmature *arm = (bArmature *)tselem->id;
765  Bone *bone = te->directdata;
766  char newname[sizeof(bone->name)];
767 
768  /* always make current object active */
769  tree_element_activate(C, &tvc, te, OL_SETSEL_NORMAL, true);
770 
771  /* restore bone name */
772  BLI_strncpy(newname, bone->name, sizeof(bone->name));
773  BLI_strncpy(bone->name, oldname, sizeof(bone->name));
774  ED_armature_bone_rename(bmain, arm, oldname, newname);
775  WM_msg_publish_rna_prop(mbus, &arm->id, bone, Bone, name);
777  break;
778  }
779  case TSE_POSE_CHANNEL: {
780  TreeViewContext tvc;
782 
783  Object *ob = (Object *)tselem->id;
784  bArmature *arm = (bArmature *)ob->data;
785  bPoseChannel *pchan = te->directdata;
786  char newname[sizeof(pchan->name)];
787 
788  /* always make current pose-bone active */
789  tree_element_activate(C, &tvc, te, OL_SETSEL_NORMAL, true);
790 
791  BLI_assert(ob->type == OB_ARMATURE);
792 
793  /* restore bone name */
794  BLI_strncpy(newname, pchan->name, sizeof(pchan->name));
795  BLI_strncpy(pchan->name, oldname, sizeof(pchan->name));
796  ED_armature_bone_rename(bmain, ob->data, oldname, newname);
797  WM_msg_publish_rna_prop(mbus, &arm->id, pchan->bone, Bone, name);
799  break;
800  }
801  case TSE_POSEGRP: {
802  Object *ob = (Object *)tselem->id; /* id = object. */
803  bActionGroup *grp = te->directdata;
804 
806  grp,
808  '.',
809  offsetof(bActionGroup, name),
810  sizeof(grp->name));
811  WM_msg_publish_rna_prop(mbus, &ob->id, grp, ActionGroup, name);
813  break;
814  }
815  case TSE_GP_LAYER: {
816  bGPdata *gpd = (bGPdata *)tselem->id; /* id = GP Datablock */
817  bGPDlayer *gpl = te->directdata;
818 
819  /* always make layer active */
821 
822  /* XXX: name needs translation stuff. */
824  &gpd->layers, gpl, "GP Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
825 
826  WM_msg_publish_rna_prop(mbus, &gpd->id, gpl, GPencilLayer, info);
829  break;
830  }
831  case TSE_R_LAYER: {
832  Scene *scene = (Scene *)tselem->id;
833  ViewLayer *view_layer = te->directdata;
834 
835  /* Restore old name. */
836  char newname[sizeof(view_layer->name)];
837  BLI_strncpy(newname, view_layer->name, sizeof(view_layer->name));
838  BLI_strncpy(view_layer->name, oldname, sizeof(view_layer->name));
839 
840  /* Rename, preserving animation and compositing data. */
841  BKE_view_layer_rename(bmain, scene, view_layer, newname);
842  WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, ViewLayer, name);
844  break;
845  }
846  case TSE_LAYER_COLLECTION: {
847  /* The ID is a #Collection, not a #LayerCollection */
848  Collection *collection = (Collection *)tselem->id;
849  BLI_libblock_ensure_unique_name(bmain, collection->id.name);
850  WM_msg_publish_rna_prop(mbus, &collection->id, &collection->id, ID, name);
852  break;
853  }
854  }
855  }
856  tselem->flag &= ~TSE_TEXTBUT;
857  }
858 }
859 
860 typedef struct RestrictProperties {
862 
872 
873 /* We don't care about the value of the property
874  * but whether the property should be active or grayed out. */
875 typedef struct RestrictPropertiesActive {
892 
894  PointerRNA *collection_ptr, RestrictProperties *props, RestrictPropertiesActive *props_active)
895 {
896  if (props_active->collection_hide_render) {
898  collection_ptr, props->collection_hide_render);
899  if (!props_active->collection_hide_render) {
900  props_active->layer_collection_holdout = false;
901  props_active->layer_collection_indirect_only = false;
902  props_active->object_hide_render = false;
903  props_active->modifier_show_render = false;
904  props_active->constraint_enable = false;
905  }
906  }
907 
908  if (props_active->collection_hide_viewport) {
910  collection_ptr, props->collection_hide_viewport);
911  if (!props_active->collection_hide_viewport) {
912  props_active->collection_hide_select = false;
913  props_active->object_hide_select = false;
914  props_active->layer_collection_hide_viewport = false;
915  props_active->object_hide_viewport = false;
916  props_active->base_hide_viewport = false;
917  props_active->modifier_show_viewport = false;
918  props_active->constraint_enable = false;
919  }
920  }
921 
922  if (props_active->collection_hide_select) {
924  collection_ptr, props->collection_hide_select);
925  if (!props_active->collection_hide_select) {
926  props_active->object_hide_select = false;
927  }
928  }
929 }
930 
932  PointerRNA *layer_collection_ptr,
933  PointerRNA *collection_ptr,
934  RestrictProperties *props,
935  RestrictPropertiesActive *props_active)
936 {
937  outliner_restrict_properties_enable_collection_set(collection_ptr, props, props_active);
938 
939  if (props_active->layer_collection_holdout) {
941  layer_collection_ptr, props->layer_collection_holdout);
942  }
943 
944  if (props_active->layer_collection_indirect_only) {
946  layer_collection_ptr, props->layer_collection_indirect_only);
947  }
948 
949  if (props_active->layer_collection_hide_viewport) {
951  layer_collection_ptr, props->layer_collection_hide_viewport);
952 
953  if (!props_active->layer_collection_hide_viewport) {
954  props_active->base_hide_viewport = false;
955  props_active->collection_hide_select = false;
956  props_active->object_hide_select = false;
957  }
958  }
959 
960  if (props_active->layer_collection_exclude) {
962  layer_collection_ptr, props->layer_collection_exclude);
963 
964  if (!props_active->layer_collection_exclude) {
965  props_active->collection_hide_viewport = false;
966  props_active->collection_hide_select = false;
967  props_active->collection_hide_render = false;
968  props_active->layer_collection_hide_viewport = false;
969  props_active->layer_collection_holdout = false;
970  props_active->layer_collection_indirect_only = false;
971  }
972  }
973 }
974 
976  TreeElement *te,
977  PointerRNA *collection_ptr,
978  PointerRNA *layer_collection_ptr,
979  RestrictProperties *props,
980  RestrictPropertiesActive *props_active)
981 {
982  TreeStoreElem *tselem = TREESTORE(te);
983  LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ? te->directdata :
984  NULL;
986 
987  if (collection->flag & COLLECTION_IS_MASTER) {
988  return false;
989  }
990 
991  /* Create the PointerRNA. */
992  RNA_id_pointer_create(&collection->id, collection_ptr);
993  if (layer_collection != NULL) {
994  RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, layer_collection_ptr);
995  }
996 
997  /* Update the restriction column values for the collection children. */
998  if (layer_collection) {
1000  layer_collection_ptr, collection_ptr, props, props_active);
1001  }
1002  else {
1003  outliner_restrict_properties_enable_collection_set(collection_ptr, props, props_active);
1004  }
1005  return true;
1006 }
1007 
1009  Scene *scene,
1010  ViewLayer *view_layer,
1011  ARegion *region,
1012  SpaceOutliner *space_outliner,
1013  ListBase *lb,
1014  RestrictPropertiesActive props_active_parent)
1015 {
1016  /* Get RNA properties (once for speed). */
1017  static RestrictProperties props = {false};
1018  if (!props.initialized) {
1024  "hide_viewport");
1028  "exclude");
1030  "holdout");
1032  "indirect_only");
1034  "hide_viewport");
1037 
1039 
1041 
1042  props.initialized = true;
1043  }
1044 
1045  struct {
1046  int enable;
1047  int select;
1048  int hide;
1049  int viewport;
1050  int render;
1051  int indirect_only;
1052  int holdout;
1053  } restrict_offsets = {0};
1054  int restrict_column_offset = 0;
1055 
1056  /* This will determine the order of drawing from RIGHT to LEFT. */
1057  if (space_outliner->outlinevis == SO_VIEW_LAYER) {
1058  if (space_outliner->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) {
1059  restrict_offsets.indirect_only = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
1060  }
1061  if (space_outliner->show_restrict_flags & SO_RESTRICT_HOLDOUT) {
1062  restrict_offsets.holdout = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
1063  }
1064  }
1065  if (space_outliner->show_restrict_flags & SO_RESTRICT_RENDER) {
1066  restrict_offsets.render = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
1067  }
1068  if (space_outliner->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
1069  restrict_offsets.viewport = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
1070  }
1071  if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
1072  restrict_offsets.hide = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
1073  }
1074  if (space_outliner->show_restrict_flags & SO_RESTRICT_SELECT) {
1075  restrict_offsets.select = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
1076  }
1077  if (space_outliner->outlinevis == SO_VIEW_LAYER &&
1078  space_outliner->show_restrict_flags & SO_RESTRICT_ENABLE) {
1079  restrict_offsets.enable = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH;
1080  }
1081 
1082  BLI_assert((restrict_column_offset * UI_UNIT_X + V2D_SCROLL_WIDTH) ==
1083  outliner_restrict_columns_width(space_outliner));
1084 
1085  /* Create buttons. */
1086  uiBut *bt;
1087 
1088  LISTBASE_FOREACH (TreeElement *, te, lb) {
1089  TreeStoreElem *tselem = TREESTORE(te);
1090  RestrictPropertiesActive props_active = props_active_parent;
1091 
1092  if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) {
1093  if (tselem->type == TSE_R_LAYER && (space_outliner->outlinevis == SO_SCENES)) {
1094  if (space_outliner->show_restrict_flags & SO_RESTRICT_RENDER) {
1095  /* View layer render toggle. */
1096  ViewLayer *layer = te->directdata;
1097 
1098  bt = uiDefIconButBitS(block,
1101  0,
1102  ICON_RESTRICT_RENDER_OFF,
1103  (int)(region->v2d.cur.xmax - restrict_offsets.render),
1104  te->ys,
1105  UI_UNIT_X,
1106  UI_UNIT_Y,
1107  &layer->flag,
1108  0,
1109  0,
1110  0,
1111  0,
1112  TIP_("Use view layer for rendering"));
1116  }
1117  }
1118  else if (((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) &&
1119  (te->flag & TE_CHILD_NOT_IN_COLLECTION)) {
1120  /* Don't show restrict columns for children that are not directly inside the collection. */
1121  }
1122  else if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
1123  PointerRNA ptr;
1124  Object *ob = (Object *)tselem->id;
1125  RNA_id_pointer_create(&ob->id, &ptr);
1126 
1127  if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
1128  Base *base = (te->directdata) ? (Base *)te->directdata :
1129  BKE_view_layer_base_find(view_layer, ob);
1130  if (base) {
1131  PointerRNA base_ptr;
1132  RNA_pointer_create(&scene->id, &RNA_ObjectBase, base, &base_ptr);
1133  bt = uiDefIconButR_prop(block,
1135  0,
1136  0,
1137  (int)(region->v2d.cur.xmax - restrict_offsets.hide),
1138  te->ys,
1139  UI_UNIT_X,
1140  UI_UNIT_Y,
1141  &base_ptr,
1142  props.base_hide_viewport,
1143  -1,
1144  0,
1145  0,
1146  0,
1147  0,
1148  TIP_("Temporarily hide in viewport\n"
1149  "* Shift to set children"));
1151  bt, outliner__base_set_flag_recursive_fn, base, (void *)"hide_viewport");
1153  if (!props_active.base_hide_viewport) {
1155  }
1156  }
1157  }
1158 
1159  if (space_outliner->show_restrict_flags & SO_RESTRICT_SELECT) {
1160  bt = uiDefIconButR_prop(block,
1162  0,
1163  0,
1164  (int)(region->v2d.cur.xmax - restrict_offsets.select),
1165  te->ys,
1166  UI_UNIT_X,
1167  UI_UNIT_Y,
1168  &ptr,
1169  props.object_hide_select,
1170  -1,
1171  0,
1172  0,
1173  -1,
1174  -1,
1175  TIP_("Disable selection in viewport\n"
1176  "* Shift to set children"));
1177  UI_but_func_set(bt, outliner__object_set_flag_recursive_fn, ob, (char *)"hide_select");
1179  if (!props_active.object_hide_select) {
1181  }
1182  }
1183 
1184  if (space_outliner->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
1185  bt = uiDefIconButR_prop(block,
1187  0,
1188  0,
1189  (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
1190  te->ys,
1191  UI_UNIT_X,
1192  UI_UNIT_Y,
1193  &ptr,
1194  props.object_hide_viewport,
1195  -1,
1196  0,
1197  0,
1198  -1,
1199  -1,
1200  TIP_("Globally disable in viewports\n"
1201  "* Shift to set children"));
1202  UI_but_func_set(bt, outliner__object_set_flag_recursive_fn, ob, (void *)"hide_viewport");
1204  if (!props_active.object_hide_viewport) {
1206  }
1207  }
1208 
1209  if (space_outliner->show_restrict_flags & SO_RESTRICT_RENDER) {
1210  bt = uiDefIconButR_prop(block,
1212  0,
1213  0,
1214  (int)(region->v2d.cur.xmax - restrict_offsets.render),
1215  te->ys,
1216  UI_UNIT_X,
1217  UI_UNIT_Y,
1218  &ptr,
1219  props.object_hide_render,
1220  -1,
1221  0,
1222  0,
1223  -1,
1224  -1,
1225  TIP_("Globally disable in renders\n"
1226  "* Shift to set children"));
1227  UI_but_func_set(bt, outliner__object_set_flag_recursive_fn, ob, (char *)"hide_render");
1229  if (!props_active.object_hide_render) {
1231  }
1232  }
1233  }
1234  else if (tselem->type == TSE_CONSTRAINT) {
1235  bConstraint *con = (bConstraint *)te->directdata;
1236 
1237  PointerRNA ptr;
1238  RNA_pointer_create(tselem->id, &RNA_Constraint, con, &ptr);
1239 
1240  if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
1241  bt = uiDefIconButR_prop(block,
1243  0,
1244  0,
1245  (int)(region->v2d.cur.xmax - restrict_offsets.hide),
1246  te->ys,
1247  UI_UNIT_X,
1248  UI_UNIT_Y,
1249  &ptr,
1250  props.constraint_enable,
1251  -1,
1252  0,
1253  0,
1254  -1,
1255  -1,
1256  NULL);
1258  if (!props_active.constraint_enable) {
1260  }
1261  }
1262  }
1263  else if (tselem->type == TSE_MODIFIER) {
1264  ModifierData *md = (ModifierData *)te->directdata;
1265 
1266  PointerRNA ptr;
1267  RNA_pointer_create(tselem->id, &RNA_Modifier, md, &ptr);
1268 
1269  if (space_outliner->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
1270  bt = uiDefIconButR_prop(block,
1272  0,
1273  0,
1274  (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
1275  te->ys,
1276  UI_UNIT_X,
1277  UI_UNIT_Y,
1278  &ptr,
1279  props.modifier_show_viewport,
1280  -1,
1281  0,
1282  0,
1283  -1,
1284  -1,
1285  NULL);
1287  if (!props_active.modifier_show_viewport) {
1289  }
1290  }
1291 
1292  if (space_outliner->show_restrict_flags & SO_RESTRICT_RENDER) {
1293  bt = uiDefIconButR_prop(block,
1295  0,
1296  0,
1297  (int)(region->v2d.cur.xmax - restrict_offsets.render),
1298  te->ys,
1299  UI_UNIT_X,
1300  UI_UNIT_Y,
1301  &ptr,
1302  props.modifier_show_render,
1303  -1,
1304  0,
1305  0,
1306  -1,
1307  -1,
1308  NULL);
1310  if (!props_active.modifier_show_render) {
1312  }
1313  }
1314  }
1315  else if (tselem->type == TSE_POSE_CHANNEL) {
1316  PointerRNA ptr;
1317  bPoseChannel *pchan = (bPoseChannel *)te->directdata;
1318  Bone *bone = pchan->bone;
1319  Object *ob = (Object *)tselem->id;
1320  bArmature *arm = ob->data;
1321 
1322  RNA_pointer_create(&arm->id, &RNA_Bone, bone, &ptr);
1323 
1324  if (space_outliner->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
1325  bt = uiDefIconButR_prop(block,
1327  0,
1328  0,
1329  (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
1330  te->ys,
1331  UI_UNIT_X,
1332  UI_UNIT_Y,
1333  &ptr,
1334  props.bone_hide_viewport,
1335  -1,
1336  0,
1337  0,
1338  -1,
1339  -1,
1340  TIP_("Restrict visibility in the 3D View\n"
1341  "* Shift to set children"));
1345  }
1346 
1347  if (space_outliner->show_restrict_flags & SO_RESTRICT_SELECT) {
1348  bt = uiDefIconButBitI(block,
1351  0,
1352  ICON_RESTRICT_SELECT_OFF,
1353  (int)(region->v2d.cur.xmax - restrict_offsets.select),
1354  te->ys,
1355  UI_UNIT_X,
1356  UI_UNIT_Y,
1357  &(bone->flag),
1358  0,
1359  0,
1360  0,
1361  0,
1362  TIP_("Restrict selection in the 3D View\n"
1363  "* Shift to set children"));
1364  UI_but_func_set(bt, restrictbutton_bone_select_fn, ob->data, bone);
1367  }
1368  }
1369  else if (tselem->type == TSE_EBONE) {
1370  bArmature *arm = (bArmature *)tselem->id;
1371  EditBone *ebone = (EditBone *)te->directdata;
1372 
1373  if (space_outliner->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
1374  bt = uiDefIconButBitI(block,
1376  BONE_HIDDEN_A,
1377  0,
1378  ICON_RESTRICT_VIEW_OFF,
1379  (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
1380  te->ys,
1381  UI_UNIT_X,
1382  UI_UNIT_Y,
1383  &(ebone->flag),
1384  0,
1385  0,
1386  0,
1387  0,
1388  TIP_("Restrict visibility in the 3D View\n"
1389  "* Shift to set children"));
1393  }
1394 
1395  if (space_outliner->show_restrict_flags & SO_RESTRICT_SELECT) {
1396  bt = uiDefIconButBitI(block,
1399  0,
1400  ICON_RESTRICT_SELECT_OFF,
1401  (int)(region->v2d.cur.xmax - restrict_offsets.select),
1402  te->ys,
1403  UI_UNIT_X,
1404  UI_UNIT_Y,
1405  &(ebone->flag),
1406  0,
1407  0,
1408  0,
1409  0,
1410  TIP_("Restrict selection in the 3D View\n"
1411  "* Shift to set children"));
1415  }
1416  }
1417  else if (tselem->type == TSE_GP_LAYER) {
1418  ID *id = tselem->id;
1419  bGPDlayer *gpl = (bGPDlayer *)te->directdata;
1420 
1421  if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
1422  bt = uiDefIconButBitS(block,
1424  GP_LAYER_HIDE,
1425  0,
1426  ICON_HIDE_OFF,
1427  (int)(region->v2d.cur.xmax - restrict_offsets.hide),
1428  te->ys,
1429  UI_UNIT_X,
1430  UI_UNIT_Y,
1431  &gpl->flag,
1432  0,
1433  0,
1434  0,
1435  0,
1436  TIP_("Restrict visibility in the 3D View"));
1440  }
1441 
1442  if (space_outliner->show_restrict_flags & SO_RESTRICT_SELECT) {
1443  bt = uiDefIconButBitS(block,
1446  0,
1447  ICON_UNLOCKED,
1448  (int)(region->v2d.cur.xmax - restrict_offsets.select),
1449  te->ys,
1450  UI_UNIT_X,
1451  UI_UNIT_Y,
1452  &gpl->flag,
1453  0,
1454  0,
1455  0,
1456  0,
1457  TIP_("Restrict editing of strokes and keyframes in this layer"));
1460  }
1461  }
1462  else if (outliner_is_collection_tree_element(te)) {
1463  PointerRNA collection_ptr;
1464  PointerRNA layer_collection_ptr;
1465 
1467  scene, te, &collection_ptr, &layer_collection_ptr, &props, &props_active)) {
1468 
1469  LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ?
1470  te->directdata :
1471  NULL;
1473 
1474  if (layer_collection != NULL) {
1475  if (space_outliner->show_restrict_flags & SO_RESTRICT_ENABLE) {
1476  bt = uiDefIconButR_prop(block,
1478  0,
1479  0,
1480  (int)(region->v2d.cur.xmax) - restrict_offsets.enable,
1481  te->ys,
1482  UI_UNIT_X,
1483  UI_UNIT_Y,
1484  &layer_collection_ptr,
1486  -1,
1487  0,
1488  0,
1489  0,
1490  0,
1491  NULL);
1493  }
1494 
1495  if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
1496  bt = uiDefIconButR_prop(block,
1498  0,
1499  0,
1500  (int)(region->v2d.cur.xmax - restrict_offsets.hide),
1501  te->ys,
1502  UI_UNIT_X,
1503  UI_UNIT_Y,
1504  &layer_collection_ptr,
1506  -1,
1507  0,
1508  0,
1509  0,
1510  0,
1511  TIP_("Temporarily hide in viewport\n"
1512  "* Ctrl to isolate collection\n"
1513  "* Shift to set inside collections and objects"));
1514  UI_but_func_set(bt,
1516  layer_collection,
1517  (char *)"hide_viewport");
1519  if (!props_active.layer_collection_hide_viewport) {
1521  }
1522  }
1523 
1524  if (space_outliner->show_restrict_flags & SO_RESTRICT_HOLDOUT) {
1525  bt = uiDefIconButR_prop(block,
1527  0,
1528  0,
1529  (int)(region->v2d.cur.xmax - restrict_offsets.holdout),
1530  te->ys,
1531  UI_UNIT_X,
1532  UI_UNIT_Y,
1533  &layer_collection_ptr,
1535  -1,
1536  0,
1537  0,
1538  0,
1539  0,
1540  TIP_("Mask out objects in collection from view layer\n"
1541  "* Ctrl to isolate collection\n"
1542  "* Shift to set inside collections"));
1543  UI_but_func_set(bt,
1545  layer_collection,
1546  (char *)"holdout");
1548  if (!props_active.layer_collection_holdout) {
1550  }
1551  }
1552 
1553  if (space_outliner->show_restrict_flags & SO_RESTRICT_INDIRECT_ONLY) {
1554  bt = uiDefIconButR_prop(
1555  block,
1557  0,
1558  0,
1559  (int)(region->v2d.cur.xmax - restrict_offsets.indirect_only),
1560  te->ys,
1561  UI_UNIT_X,
1562  UI_UNIT_Y,
1563  &layer_collection_ptr,
1565  -1,
1566  0,
1567  0,
1568  0,
1569  0,
1570  TIP_("Objects in collection only contribute indirectly (through shadows and "
1571  "reflections) in the view layer\n"
1572  "* Ctrl to isolate collection\n"
1573  "* Shift to set inside collections"));
1574  UI_but_func_set(bt,
1576  layer_collection,
1577  (char *)"indirect_only");
1579  if (props_active.layer_collection_holdout ||
1580  !props_active.layer_collection_indirect_only) {
1582  }
1583  }
1584  }
1585 
1586  if (space_outliner->show_restrict_flags & SO_RESTRICT_VIEWPORT) {
1587  bt = uiDefIconButR_prop(block,
1589  0,
1590  0,
1591  (int)(region->v2d.cur.xmax - restrict_offsets.viewport),
1592  te->ys,
1593  UI_UNIT_X,
1594  UI_UNIT_Y,
1595  &collection_ptr,
1597  -1,
1598  0,
1599  0,
1600  0,
1601  0,
1602  TIP_("Globally disable in viewports\n"
1603  "* Ctrl to isolate collection\n"
1604  "* Shift to set inside collections and objects"));
1605  if (layer_collection != NULL) {
1606  UI_but_func_set(bt,
1608  layer_collection,
1609  (char *)"hide_viewport");
1610  }
1611  else {
1612  UI_but_func_set(bt,
1614  collection,
1615  (char *)"hide_viewport");
1616  }
1618  if (!props_active.collection_hide_viewport) {
1620  }
1621  }
1622 
1623  if (space_outliner->show_restrict_flags & SO_RESTRICT_RENDER) {
1624  bt = uiDefIconButR_prop(block,
1626  0,
1627  0,
1628  (int)(region->v2d.cur.xmax - restrict_offsets.render),
1629  te->ys,
1630  UI_UNIT_X,
1631  UI_UNIT_Y,
1632  &collection_ptr,
1633  props.collection_hide_render,
1634  -1,
1635  0,
1636  0,
1637  0,
1638  0,
1639  TIP_("Globally disable in renders\n"
1640  "* Ctrl to isolate collection\n"
1641  "* Shift to set inside collections and objects"));
1642  if (layer_collection != NULL) {
1643  UI_but_func_set(bt,
1645  layer_collection,
1646  (char *)"hide_render");
1647  }
1648  else {
1650  bt, scenes__collection_set_flag_recursive_fn, collection, (char *)"hide_render");
1651  }
1653  if (!props_active.collection_hide_render) {
1655  }
1656  }
1657 
1658  if (space_outliner->show_restrict_flags & SO_RESTRICT_SELECT) {
1659  bt = uiDefIconButR_prop(block,
1661  0,
1662  0,
1663  (int)(region->v2d.cur.xmax - restrict_offsets.select),
1664  te->ys,
1665  UI_UNIT_X,
1666  UI_UNIT_Y,
1667  &collection_ptr,
1668  props.collection_hide_select,
1669  -1,
1670  0,
1671  0,
1672  0,
1673  0,
1674  TIP_("Disable selection in viewport\n"
1675  "* Ctrl to isolate collection\n"
1676  "* Shift to set inside collections and objects"));
1677  if (layer_collection != NULL) {
1678  UI_but_func_set(bt,
1680  layer_collection,
1681  (char *)"hide_select");
1682  }
1683  else {
1685  bt, scenes__collection_set_flag_recursive_fn, collection, (char *)"hide_select");
1686  }
1688  if (!props_active.collection_hide_select) {
1690  }
1691  }
1692  }
1693  }
1694  }
1695  else if (outliner_is_collection_tree_element(te)) {
1696  PointerRNA collection_ptr;
1697  PointerRNA layer_collection_ptr;
1699  scene, te, &collection_ptr, &layer_collection_ptr, &props, &props_active);
1700  }
1701 
1702  if (TSELEM_OPEN(tselem, space_outliner)) {
1704  block, scene, view_layer, region, space_outliner, &te->subtree, props_active);
1705  }
1706  }
1707 }
1708 
1709 static void outliner_draw_userbuts(uiBlock *block,
1710  ARegion *region,
1711  SpaceOutliner *space_outliner,
1712  ListBase *lb)
1713 {
1714 
1715  LISTBASE_FOREACH (TreeElement *, te, lb) {
1716  TreeStoreElem *tselem = TREESTORE(te);
1717  if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) {
1718  if (tselem->type == TSE_SOME_ID) {
1719  uiBut *bt;
1720  ID *id = tselem->id;
1721  const char *tip = NULL;
1722  char buf[16] = "";
1723  int but_flag = UI_BUT_DRAG_LOCK;
1724 
1725  if (ID_IS_LINKED(id)) {
1726  but_flag |= UI_BUT_DISABLED;
1727  }
1728 
1730  bt = uiDefBut(block,
1731  UI_BTYPE_BUT,
1732  1,
1733  buf,
1734  (int)(region->v2d.cur.xmax - OL_TOG_USER_BUTS_USERS),
1735  te->ys,
1736  UI_UNIT_X,
1737  UI_UNIT_Y,
1738  NULL,
1739  0.0,
1740  0.0,
1741  0,
1742  0,
1743  TIP_("Number of users of this data-block"));
1744  UI_but_flag_enable(bt, but_flag);
1745 
1746  if (id->flag & LIB_FAKEUSER) {
1747  tip = TIP_("Data-block will be retained using a fake user");
1748  }
1749  else {
1750  tip = TIP_("Data-block has no users and will be deleted");
1751  }
1752  bt = uiDefIconButBitS(block,
1754  LIB_FAKEUSER,
1755  1,
1756  ICON_FAKE_USER_OFF,
1757  (int)(region->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS),
1758  te->ys,
1759  UI_UNIT_X,
1760  UI_UNIT_Y,
1761  &id->flag,
1762  0,
1763  0,
1764  0,
1765  0,
1766  tip);
1768  UI_but_flag_enable(bt, but_flag);
1769  }
1770  }
1771 
1772  if (TSELEM_OPEN(tselem, space_outliner)) {
1773  outliner_draw_userbuts(block, region, space_outliner, &te->subtree);
1774  }
1775  }
1776 }
1777 
1779  ARegion *region,
1780  SpaceOutliner *space_outliner,
1781  ListBase *lb,
1782  const bool is_open)
1783 {
1784  bool any_item_has_warnings = false;
1785 
1786  LISTBASE_FOREACH (TreeElement *, te, lb) {
1787  bool item_has_warnings = false;
1788  const bool do_draw = (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin &&
1789  te->ys <= region->v2d.cur.ymax);
1790  int but_flag = UI_BUT_DRAG_LOCK;
1791  const char *tip = NULL;
1792 
1793  TreeStoreElem *tselem = TREESTORE(te);
1794  switch (tselem->type) {
1796  ID *id = tselem->id;
1797 
1799  item_has_warnings = true;
1800  if (do_draw) {
1801  tip = TIP_(
1802  "This override data-block is not needed anymore, but was detected as user-edited");
1803  }
1804  }
1805  else if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && ID_REAL_USERS(id) == 0) {
1806  item_has_warnings = true;
1807  if (do_draw) {
1808  tip = TIP_("This override data-block is unused");
1809  }
1810  }
1811  break;
1812  }
1813  case TSE_LIBRARY_OVERRIDE: {
1814  const bool is_rna_path_valid = (bool)(POINTER_AS_UINT(te->directdata));
1815  if (!is_rna_path_valid) {
1816  item_has_warnings = true;
1817  if (do_draw) {
1818  tip = TIP_(
1819  "This override property does not exist in current data, it will be removed on "
1820  "next .blend file save");
1821  }
1822  }
1823  break;
1824  }
1825  default:
1826  break;
1827  }
1828 
1829  const bool any_child_has_warnings = outliner_draw_overrides_buts(
1830  block,
1831  region,
1832  space_outliner,
1833  &te->subtree,
1834  is_open && TSELEM_OPEN(tselem, space_outliner));
1835 
1836  if (do_draw &&
1837  (item_has_warnings || (any_child_has_warnings && !TSELEM_OPEN(tselem, space_outliner)))) {
1838  if (tip == NULL) {
1839  tip = TIP_("Some sub-items require attention");
1840  }
1841  uiBut *bt = uiDefIconBut(block,
1842  UI_BTYPE_BUT,
1843  1,
1844  ICON_ERROR,
1845  (int)(region->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS),
1846  te->ys,
1847  UI_UNIT_X,
1848  UI_UNIT_Y,
1849  NULL,
1850  0.0,
1851  0.0,
1852  0.0,
1853  0.0,
1854  tip);
1855  UI_but_flag_enable(bt, but_flag);
1856  }
1857  any_item_has_warnings = any_item_has_warnings || item_has_warnings || any_child_has_warnings;
1858  }
1859 
1860  return any_item_has_warnings;
1861 }
1862 
1863 static void outliner_draw_rnacols(ARegion *region, int sizex)
1864 {
1865  View2D *v2d = &region->v2d;
1866 
1867  float miny = v2d->cur.ymin;
1868  if (miny < v2d->tot.ymin) {
1869  miny = v2d->tot.ymin;
1870  }
1871 
1872  GPU_line_width(1.0f);
1873 
1877 
1879 
1880  immVertex2f(pos, sizex, v2d->cur.ymax);
1881  immVertex2f(pos, sizex, miny);
1882 
1883  immVertex2f(pos, sizex + OL_RNA_COL_SIZEX, v2d->cur.ymax);
1884  immVertex2f(pos, sizex + OL_RNA_COL_SIZEX, miny);
1885 
1886  immEnd();
1887 
1888  immUnbindProgram();
1889 }
1890 
1892  uiBlock *block, ARegion *region, SpaceOutliner *space_outliner, int sizex, ListBase *lb)
1893 {
1894  PointerRNA *ptr;
1895  PropertyRNA *prop;
1896 
1897  LISTBASE_FOREACH (TreeElement *, te, lb) {
1898  TreeStoreElem *tselem = TREESTORE(te);
1899  if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) {
1900  if (tselem->type == TSE_RNA_PROPERTY) {
1901  ptr = &te->rnaptr;
1902  prop = te->directdata;
1903 
1904  if (!TSELEM_OPEN(tselem, space_outliner)) {
1905  if (RNA_property_type(prop) == PROP_POINTER) {
1906  uiBut *but = uiDefAutoButR(block,
1907  ptr,
1908  prop,
1909  -1,
1910  "",
1911  ICON_NONE,
1912  sizex,
1913  te->ys,
1915  UI_UNIT_Y - 1);
1917  }
1918  else if (RNA_property_type(prop) == PROP_ENUM) {
1919  uiDefAutoButR(block,
1920  ptr,
1921  prop,
1922  -1,
1923  NULL,
1924  ICON_NONE,
1925  sizex,
1926  te->ys,
1928  UI_UNIT_Y - 1);
1929  }
1930  else {
1931  uiDefAutoButR(block,
1932  ptr,
1933  prop,
1934  -1,
1935  "",
1936  ICON_NONE,
1937  sizex,
1938  te->ys,
1940  UI_UNIT_Y - 1);
1941  }
1942  }
1943  }
1944  else if (tselem->type == TSE_RNA_ARRAY_ELEM) {
1945  ptr = &te->rnaptr;
1946  prop = te->directdata;
1947 
1948  uiDefAutoButR(block,
1949  ptr,
1950  prop,
1951  te->index,
1952  "",
1953  ICON_NONE,
1954  sizex,
1955  te->ys,
1957  UI_UNIT_Y - 1);
1958  }
1959  }
1960 
1961  if (TSELEM_OPEN(tselem, space_outliner)) {
1962  outliner_draw_rnabuts(block, region, space_outliner, sizex, &te->subtree);
1963  }
1964  }
1965 }
1966 
1967 static void outliner_buttons(const bContext *C,
1968  uiBlock *block,
1969  ARegion *region,
1970  const float restrict_column_width,
1971  TreeElement *te)
1972 {
1973  uiBut *bt;
1974  TreeStoreElem *tselem;
1975  int spx, dx, len;
1976 
1977  tselem = TREESTORE(te);
1978 
1979  BLI_assert(tselem->flag & TSE_TEXTBUT);
1980  /* If we add support to rename Sequence, need change this. */
1981 
1982  if (tselem->type == TSE_EBONE) {
1983  len = sizeof(((EditBone *)0)->name);
1984  }
1985  else if (tselem->type == TSE_MODIFIER) {
1986  len = sizeof(((ModifierData *)0)->name);
1987  }
1988  else if (tselem->id && GS(tselem->id->name) == ID_LI) {
1989  len = sizeof(((Library *)0)->filepath);
1990  }
1991  else {
1992  len = MAX_ID_NAME - 2;
1993  }
1994 
1995  spx = te->xs + 1.8f * UI_UNIT_X;
1996  dx = region->v2d.cur.xmax - (spx + restrict_column_width + 0.2f * UI_UNIT_X);
1997 
1998  bt = uiDefBut(block,
1999  UI_BTYPE_TEXT,
2000  OL_NAMEBUTTON,
2001  "",
2002  spx,
2003  te->ys,
2004  dx,
2005  UI_UNIT_Y - 1,
2006  (void *)te->name,
2007  1.0,
2008  (float)len,
2009  0,
2010  0,
2011  "");
2013 
2014  /* Returns false if button got removed. */
2015  if (false == UI_but_active_only(C, region, block, bt)) {
2016  tselem->flag &= ~TSE_TEXTBUT;
2017 
2018  /* Bad! (notifier within draw) without this, we don't get a refresh. */
2020  }
2021 }
2022 
2023 static void outliner_mode_toggle_fn(bContext *C, void *tselem_poin, void *UNUSED(arg2))
2024 {
2025  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
2026  TreeStoreElem *tselem = (TreeStoreElem *)tselem_poin;
2027  TreeViewContext tvc;
2029 
2030  TreeElement *te = outliner_find_tree_element(&space_outliner->tree, tselem);
2031  if (!te) {
2032  return;
2033  }
2034 
2035  /* Check that the item is actually an object. */
2036  BLI_assert(tselem->id != NULL && GS(tselem->id->name) == ID_OB);
2037 
2038  Object *ob = (Object *)tselem->id;
2039  const bool object_data_shared = (ob->data == tvc.obact->data);
2040 
2041  wmWindow *win = CTX_wm_window(C);
2042  const bool do_extend = win->eventstate->ctrl != 0 && !object_data_shared;
2043  outliner_item_mode_toggle(C, &tvc, te, do_extend);
2044 }
2045 
2046 /* Draw icons for adding and removing objects from the current interaction mode. */
2048  TreeViewContext *tvc,
2049  TreeElement *te,
2050  TreeStoreElem *tselem,
2051  const bool lock_object_modes)
2052 {
2053  if ((tselem->type != TSE_SOME_ID) || (te->idcode != ID_OB)) {
2054  return;
2055  }
2056 
2057  Object *ob = (Object *)tselem->id;
2058  Object *ob_active = tvc->obact;
2059 
2060  /* Not all objects support particle systems. */
2061  if (ob_active->mode == OB_MODE_PARTICLE_EDIT && !psys_get_current(ob)) {
2062  return;
2063  }
2064 
2065  /* Only for objects with the same type. */
2066  if (ob->type != ob_active->type) {
2067  return;
2068  }
2069 
2070  bool draw_active_icon = ob->mode == ob_active->mode;
2071 
2072  /* When not locking object modes, objects can remain in non-object modes. For modes that do not
2073  * allow multi-object editing, these other objects should still show be viewed as not in the
2074  * mode. Otherwise multiple objects show the same mode icon in the outliner even though only
2075  * one object is actually editable in the mode. */
2076  if (!lock_object_modes && ob != ob_active && !(tvc->ob_edit || tvc->ob_pose)) {
2077  draw_active_icon = false;
2078  }
2079 
2080  const bool object_data_shared = (ob->data == ob_active->data);
2081  draw_active_icon = draw_active_icon || object_data_shared;
2082 
2083  int icon;
2084  const char *tip;
2085  if (draw_active_icon) {
2086  icon = UI_icon_from_object_mode(ob_active->mode);
2087  tip = object_data_shared ? TIP_("Change the object in the current mode") :
2088  TIP_("Remove from the current mode");
2089  }
2090  else {
2091  icon = ICON_DOT;
2092  tip = TIP_(
2093  "Change the object in the current mode\n"
2094  "* Ctrl to add to the current mode");
2095  }
2097  uiBut *but = uiDefIconBut(block,
2099  0,
2100  icon,
2101  0,
2102  te->ys,
2103  UI_UNIT_X,
2104  UI_UNIT_Y,
2105  NULL,
2106  0.0,
2107  0.0,
2108  0.0,
2109  0.0,
2110  tip);
2113  /* Mode toggling handles it's own undo state because undo steps need to be grouped. */
2115 
2116  if (ID_IS_LINKED(&ob->id)) {
2117  UI_but_disable(but, TIP_("Can't edit external library data"));
2118  }
2119 }
2120 
2122  uiBlock *block,
2123  TreeViewContext *tvc,
2124  SpaceOutliner *space_outliner,
2125  ListBase *tree)
2126 {
2127  TreeStoreElem *tselem;
2128  const bool lock_object_modes = tvc->scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK;
2129 
2130  LISTBASE_FOREACH (TreeElement *, te, tree) {
2131  tselem = TREESTORE(te);
2132 
2133  if (tvc->obact && tvc->obact->mode != OB_MODE_OBJECT) {
2134  outliner_draw_mode_column_toggle(block, tvc, te, tselem, lock_object_modes);
2135  }
2136 
2137  if (TSELEM_OPEN(tselem, space_outliner)) {
2138  outliner_draw_mode_column(C, block, tvc, space_outliner, &te->subtree);
2139  }
2140  }
2141 }
2142 
2143 /* ****************************************************** */
2144 /* Normal Drawing... */
2145 
2147 {
2148  TreeElementIcon data = {0};
2149 
2150  if (tselem->type != TSE_SOME_ID) {
2151  switch (tselem->type) {
2152  case TSE_ANIM_DATA:
2153  data.icon = ICON_ANIM_DATA; /* XXX */
2154  break;
2155  case TSE_NLA:
2156  data.icon = ICON_NLA;
2157  break;
2158  case TSE_NLA_TRACK:
2159  data.icon = ICON_NLA; /* XXX */
2160  break;
2161  case TSE_NLA_ACTION:
2162  data.icon = ICON_ACTION;
2163  break;
2164  case TSE_DRIVER_BASE:
2165  data.icon = ICON_DRIVER;
2166  break;
2167  case TSE_DEFGROUP_BASE:
2168  data.icon = ICON_GROUP_VERTEX;
2169  break;
2170  case TSE_DEFGROUP:
2171  data.icon = ICON_GROUP_VERTEX;
2172  break;
2173  case TSE_BONE:
2174  case TSE_EBONE:
2175  data.icon = ICON_BONE_DATA;
2176  break;
2177  case TSE_CONSTRAINT_BASE:
2178  data.icon = ICON_CONSTRAINT;
2179  data.drag_id = tselem->id;
2180  break;
2181  case TSE_CONSTRAINT: {
2182  bConstraint *con = te->directdata;
2183  data.drag_id = tselem->id;
2184  switch ((eBConstraint_Types)con->type) {
2186  data.icon = ICON_CON_CAMERASOLVER;
2187  break;
2189  data.icon = ICON_CON_FOLLOWTRACK;
2190  break;
2192  data.icon = ICON_CON_OBJECTSOLVER;
2193  break;
2195  data.icon = ICON_CON_LOCLIKE;
2196  break;
2198  data.icon = ICON_CON_ROTLIKE;
2199  break;
2201  data.icon = ICON_CON_SIZELIKE;
2202  break;
2204  data.icon = ICON_CON_TRANSLIKE;
2205  break;
2207  data.icon = ICON_CON_DISTLIMIT;
2208  break;
2210  data.icon = ICON_CON_LOCLIMIT;
2211  break;
2213  data.icon = ICON_CON_ROTLIMIT;
2214  break;
2216  data.icon = ICON_CON_SIZELIMIT;
2217  break;
2219  data.icon = ICON_CON_SAMEVOL;
2220  break;
2222  data.icon = ICON_CON_TRANSFORM;
2223  break;
2225  data.icon = ICON_CON_TRANSFORM_CACHE;
2226  break;
2228  data.icon = ICON_CON_CLAMPTO;
2229  break;
2231  data.icon = ICON_CON_TRACKTO;
2232  break;
2234  data.icon = ICON_CON_KINEMATIC;
2235  break;
2237  data.icon = ICON_CON_LOCKTRACK;
2238  break;
2240  data.icon = ICON_CON_SPLINEIK;
2241  break;
2243  data.icon = ICON_CON_STRETCHTO;
2244  break;
2246  data.icon = ICON_CON_TRACKTO;
2247  break;
2249  data.icon = ICON_CON_ACTION;
2250  break;
2252  data.icon = ICON_CON_ARMATURE;
2253  break;
2255  data.icon = ICON_CON_CHILDOF;
2256  break;
2258  data.icon = ICON_CON_FLOOR;
2259  break;
2261  data.icon = ICON_CON_FOLLOWPATH;
2262  break;
2263  case CONSTRAINT_TYPE_PIVOT:
2264  data.icon = ICON_CON_PIVOT;
2265  break;
2267  data.icon = ICON_CON_SHRINKWRAP;
2268  break;
2269 
2270  default:
2271  data.icon = ICON_DOT;
2272  break;
2273  }
2274  break;
2275  }
2276  case TSE_MODIFIER_BASE:
2277  data.icon = ICON_MODIFIER_DATA;
2278  data.drag_id = tselem->id;
2279  break;
2281  case TSE_LIBRARY_OVERRIDE:
2282  data.icon = ICON_LIBRARY_DATA_OVERRIDE;
2283  break;
2284  case TSE_LINKED_OB:
2285  data.icon = ICON_OBJECT_DATA;
2286  break;
2287  case TSE_LINKED_PSYS:
2288  data.icon = ICON_PARTICLES;
2289  break;
2290  case TSE_MODIFIER: {
2291  Object *ob = (Object *)tselem->id;
2292  data.drag_id = tselem->id;
2293 
2294  if (ob->type != OB_GPENCIL) {
2295  ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr);
2296  const ModifierTypeInfo *modifier_type = BKE_modifier_get_info(md->type);
2297  if (modifier_type != NULL) {
2298  data.icon = modifier_type->icon;
2299  }
2300  else {
2301  data.icon = ICON_DOT;
2302  }
2303  }
2304  else {
2305  /* grease pencil modifiers */
2307  switch ((GpencilModifierType)md->type) {
2309  data.icon = ICON_MOD_NOISE;
2310  break;
2312  data.icon = ICON_MOD_SUBSURF;
2313  break;
2315  data.icon = ICON_MOD_THICKNESS;
2316  break;
2318  data.icon = ICON_MOD_TINT;
2319  break;
2321  data.icon = ICON_MOD_ARRAY;
2322  break;
2324  data.icon = ICON_MOD_BUILD;
2325  break;
2327  data.icon = ICON_MOD_MASK;
2328  break;
2330  data.icon = ICON_MOD_HUE_SATURATION;
2331  break;
2333  data.icon = ICON_MOD_LATTICE;
2334  break;
2336  data.icon = ICON_MOD_MIRROR;
2337  break;
2339  data.icon = ICON_MOD_SIMPLIFY;
2340  break;
2342  data.icon = ICON_MOD_SMOOTH;
2343  break;
2345  data.icon = ICON_HOOK;
2346  break;
2348  data.icon = ICON_MOD_OFFSET;
2349  break;
2351  data.icon = ICON_MOD_ARMATURE;
2352  break;
2354  data.icon = ICON_GP_MULTIFRAME_EDITING;
2355  break;
2357  data.icon = ICON_MOD_TIME;
2358  break;
2360  data.icon = ICON_TEXTURE;
2361  break;
2362 
2363  /* Default */
2364  default:
2365  data.icon = ICON_DOT;
2366  break;
2367  }
2368  }
2369  break;
2370  }
2371  case TSE_POSE_BASE:
2372  data.icon = ICON_ARMATURE_DATA;
2373  break;
2374  case TSE_POSE_CHANNEL:
2375  data.icon = ICON_BONE_DATA;
2376  break;
2377  case TSE_PROXY:
2378  data.icon = ICON_GHOST_ENABLED;
2379  break;
2380  case TSE_R_LAYER_BASE:
2381  data.icon = ICON_RENDERLAYERS;
2382  break;
2384  data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE;
2385  break;
2386  case TSE_R_LAYER:
2387  data.icon = ICON_RENDER_RESULT;
2388  break;
2389  case TSE_POSEGRP_BASE:
2390  case TSE_POSEGRP:
2391  data.icon = ICON_GROUP_BONE;
2392  break;
2393  case TSE_SEQUENCE:
2394  switch (te->idcode) {
2395  case SEQ_TYPE_SCENE:
2396  data.icon = ICON_SCENE_DATA;
2397  break;
2398  case SEQ_TYPE_MOVIECLIP:
2399  data.icon = ICON_TRACKER;
2400  break;
2401  case SEQ_TYPE_MASK:
2402  data.icon = ICON_MOD_MASK;
2403  break;
2404  case SEQ_TYPE_MOVIE:
2405  data.icon = ICON_FILE_MOVIE;
2406  break;
2407  case SEQ_TYPE_SOUND_RAM:
2408  data.icon = ICON_SOUND;
2409  break;
2410  case SEQ_TYPE_IMAGE:
2411  data.icon = ICON_FILE_IMAGE;
2412  break;
2413  case SEQ_TYPE_COLOR:
2414  case SEQ_TYPE_ADJUSTMENT:
2415  data.icon = ICON_COLOR;
2416  break;
2417  case SEQ_TYPE_TEXT:
2418  data.icon = ICON_FONT_DATA;
2419  break;
2420  case SEQ_TYPE_ADD:
2421  case SEQ_TYPE_SUB:
2422  case SEQ_TYPE_MUL:
2423  case SEQ_TYPE_OVERDROP:
2424  case SEQ_TYPE_ALPHAOVER:
2425  case SEQ_TYPE_ALPHAUNDER:
2426  case SEQ_TYPE_COLORMIX:
2427  case SEQ_TYPE_MULTICAM:
2428  case SEQ_TYPE_TRANSFORM:
2429  case SEQ_TYPE_SPEED:
2430  case SEQ_TYPE_GLOW:
2432  data.icon = ICON_SHADERFX;
2433  break;
2434  case SEQ_TYPE_CROSS:
2435  case SEQ_TYPE_GAMCROSS:
2436  case SEQ_TYPE_WIPE:
2437  data.icon = ICON_ARROW_LEFTRIGHT;
2438  break;
2439  case SEQ_TYPE_META:
2440  data.icon = ICON_SEQ_STRIP_META;
2441  break;
2442  default:
2443  data.icon = ICON_DOT;
2444  break;
2445  }
2446  break;
2447  case TSE_SEQ_STRIP:
2448  data.icon = ICON_LIBRARY_DATA_DIRECT;
2449  break;
2450  case TSE_SEQUENCE_DUP:
2451  data.icon = ICON_SEQ_STRIP_DUPLICATE;
2452  break;
2453  case TSE_RNA_STRUCT:
2454  if (RNA_struct_is_ID(te->rnaptr.type)) {
2455  data.drag_id = (ID *)te->rnaptr.data;
2456  data.icon = RNA_struct_ui_icon(te->rnaptr.type);
2457  }
2458  else {
2459  data.icon = RNA_struct_ui_icon(te->rnaptr.type);
2460  }
2461  break;
2462  case TSE_LAYER_COLLECTION:
2464  case TSE_VIEW_COLLECTION_BASE: {
2466  if (collection && !(collection->flag & COLLECTION_IS_MASTER)) {
2467  data.drag_id = tselem->id;
2468  data.drag_parent = (data.drag_id && te->parent) ? TREESTORE(te->parent)->id : NULL;
2469  }
2470 
2471  data.icon = ICON_OUTLINER_COLLECTION;
2472  break;
2473  }
2474  case TSE_GP_LAYER: {
2475  data.icon = ICON_OUTLINER_DATA_GP_LAYER;
2476  break;
2477  }
2479  case TSE_GPENCIL_EFFECT:
2480  data.drag_id = tselem->id;
2481  data.icon = ICON_SHADERFX;
2482  break;
2483  default:
2484  data.icon = ICON_DOT;
2485  break;
2486  }
2487  }
2488  else if (tselem->id) {
2489  data.drag_id = tselem->id;
2490  data.drag_parent = (data.drag_id && te->parent) ? TREESTORE(te->parent)->id : NULL;
2491 
2492  if (GS(tselem->id->name) == ID_OB) {
2493  Object *ob = (Object *)tselem->id;
2494  switch (ob->type) {
2495  case OB_LAMP:
2496  data.icon = ICON_OUTLINER_OB_LIGHT;
2497  break;
2498  case OB_MESH:
2499  data.icon = ICON_OUTLINER_OB_MESH;
2500  break;
2501  case OB_CAMERA:
2502  data.icon = ICON_OUTLINER_OB_CAMERA;
2503  break;
2504  case OB_CURVE:
2505  data.icon = ICON_OUTLINER_OB_CURVE;
2506  break;
2507  case OB_MBALL:
2508  data.icon = ICON_OUTLINER_OB_META;
2509  break;
2510  case OB_LATTICE:
2511  data.icon = ICON_OUTLINER_OB_LATTICE;
2512  break;
2513  case OB_ARMATURE:
2514  data.icon = ICON_OUTLINER_OB_ARMATURE;
2515  break;
2516  case OB_FONT:
2517  data.icon = ICON_OUTLINER_OB_FONT;
2518  break;
2519  case OB_SURF:
2520  data.icon = ICON_OUTLINER_OB_SURFACE;
2521  break;
2522  case OB_SPEAKER:
2523  data.icon = ICON_OUTLINER_OB_SPEAKER;
2524  break;
2525  case OB_LIGHTPROBE:
2526  data.icon = ICON_OUTLINER_OB_LIGHTPROBE;
2527  break;
2528  case OB_HAIR:
2529  data.icon = ICON_OUTLINER_OB_HAIR;
2530  break;
2531  case OB_POINTCLOUD:
2532  data.icon = ICON_OUTLINER_OB_POINTCLOUD;
2533  break;
2534  case OB_VOLUME:
2535  data.icon = ICON_OUTLINER_OB_VOLUME;
2536  break;
2537  case OB_EMPTY:
2538  if (ob->instance_collection && (ob->transflag & OB_DUPLICOLLECTION)) {
2539  data.icon = ICON_OUTLINER_OB_GROUP_INSTANCE;
2540  }
2541  else if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
2542  data.icon = ICON_OUTLINER_OB_IMAGE;
2543  }
2544  else if (ob->pd && ob->pd->forcefield) {
2545  data.icon = ICON_OUTLINER_OB_FORCE_FIELD;
2546  }
2547  else {
2548  data.icon = ICON_OUTLINER_OB_EMPTY;
2549  }
2550  break;
2551  case OB_GPENCIL:
2552  data.icon = ICON_OUTLINER_OB_GREASEPENCIL;
2553  break;
2554  }
2555  }
2556  else {
2557  /* TODO(sergey): Casting to short here just to handle ID_NLA which is
2558  * NOT inside of IDType enum.
2559  */
2560  switch ((short)GS(tselem->id->name)) {
2561  case ID_SCE:
2562  data.icon = ICON_SCENE_DATA;
2563  break;
2564  case ID_ME:
2565  data.icon = ICON_OUTLINER_DATA_MESH;
2566  break;
2567  case ID_CU:
2568  data.icon = ICON_OUTLINER_DATA_CURVE;
2569  break;
2570  case ID_MB:
2571  data.icon = ICON_OUTLINER_DATA_META;
2572  break;
2573  case ID_LT:
2574  data.icon = ICON_OUTLINER_DATA_LATTICE;
2575  break;
2576  case ID_LA: {
2577  Light *la = (Light *)tselem->id;
2578  switch (la->type) {
2579  case LA_LOCAL:
2580  data.icon = ICON_LIGHT_POINT;
2581  break;
2582  case LA_SUN:
2583  data.icon = ICON_LIGHT_SUN;
2584  break;
2585  case LA_SPOT:
2586  data.icon = ICON_LIGHT_SPOT;
2587  break;
2588  case LA_AREA:
2589  data.icon = ICON_LIGHT_AREA;
2590  break;
2591  default:
2592  data.icon = ICON_OUTLINER_DATA_LIGHT;
2593  break;
2594  }
2595  break;
2596  }
2597  case ID_MA:
2598  data.icon = ICON_MATERIAL_DATA;
2599  break;
2600  case ID_TE:
2601  data.icon = ICON_TEXTURE_DATA;
2602  break;
2603  case ID_IM:
2604  data.icon = ICON_IMAGE_DATA;
2605  break;
2606  case ID_SPK:
2607  case ID_SO:
2608  data.icon = ICON_OUTLINER_DATA_SPEAKER;
2609  break;
2610  case ID_AR:
2611  data.icon = ICON_OUTLINER_DATA_ARMATURE;
2612  break;
2613  case ID_CA:
2614  data.icon = ICON_OUTLINER_DATA_CAMERA;
2615  break;
2616  case ID_KE:
2617  data.icon = ICON_SHAPEKEY_DATA;
2618  break;
2619  case ID_WO:
2620  data.icon = ICON_WORLD_DATA;
2621  break;
2622  case ID_AC:
2623  data.icon = ICON_ACTION;
2624  break;
2625  case ID_NLA:
2626  data.icon = ICON_NLA;
2627  break;
2628  case ID_TXT:
2629  data.icon = ICON_SCRIPT;
2630  break;
2631  case ID_GR:
2632  data.icon = ICON_OUTLINER_COLLECTION;
2633  break;
2634  case ID_HA:
2635  data.icon = ICON_OUTLINER_DATA_HAIR;
2636  break;
2637  case ID_PT:
2638  data.icon = ICON_OUTLINER_DATA_POINTCLOUD;
2639  break;
2640  case ID_VO:
2641  data.icon = ICON_OUTLINER_DATA_VOLUME;
2642  break;
2643  case ID_LI:
2644  if (tselem->id->tag & LIB_TAG_MISSING) {
2645  data.icon = ICON_LIBRARY_DATA_BROKEN;
2646  }
2647  else if (((Library *)tselem->id)->parent) {
2648  data.icon = ICON_LIBRARY_DATA_INDIRECT;
2649  }
2650  else {
2651  data.icon = ICON_LIBRARY_DATA_DIRECT;
2652  }
2653  break;
2654  case ID_LS:
2655  data.icon = ICON_LINE_DATA;
2656  break;
2657  case ID_GD:
2658  data.icon = ICON_OUTLINER_DATA_GREASEPENCIL;
2659  break;
2660  case ID_LP: {
2661  LightProbe *lp = (LightProbe *)tselem->id;
2662  switch (lp->type) {
2663  case LIGHTPROBE_TYPE_CUBE:
2664  data.icon = ICON_LIGHTPROBE_CUBEMAP;
2665  break;
2667  data.icon = ICON_LIGHTPROBE_PLANAR;
2668  break;
2669  case LIGHTPROBE_TYPE_GRID:
2670  data.icon = ICON_LIGHTPROBE_GRID;
2671  break;
2672  default:
2673  data.icon = ICON_LIGHTPROBE_CUBEMAP;
2674  break;
2675  }
2676  break;
2677  }
2678  case ID_BR:
2679  data.icon = ICON_BRUSH_DATA;
2680  break;
2681  case ID_SCR:
2682  case ID_WS:
2683  data.icon = ICON_WORKSPACE;
2684  break;
2685  case ID_MSK:
2686  data.icon = ICON_MOD_MASK;
2687  break;
2688  case ID_MC:
2689  data.icon = ICON_SEQUENCE;
2690  break;
2691  case ID_PC:
2692  data.icon = ICON_CURVE_BEZCURVE;
2693  break;
2694  case ID_SIM:
2695  /* TODO: Use correct icon. */
2696  data.icon = ICON_PHYSICS;
2697  break;
2698  default:
2699  break;
2700  }
2701  }
2702  }
2703 
2704  return data;
2705 }
2706 
2707 static void tselem_draw_icon(uiBlock *block,
2708  int xmax,
2709  float x,
2710  float y,
2711  TreeStoreElem *tselem,
2712  TreeElement *te,
2713  float alpha,
2714  const bool is_clickable)
2715 {
2717  if (data.icon == 0) {
2718  return;
2719  }
2720 
2721  const bool is_collection = outliner_is_collection_tree_element(te);
2722 
2723  /* Collection colors and icons covered by restrict buttons. */
2724  if (!is_clickable || x >= xmax || is_collection) {
2725  /* Placement of icons, copied from interface_widgets.c */
2726  float aspect = (0.8f * UI_UNIT_Y) / ICON_DEFAULT_HEIGHT;
2727  x += 2.0f * aspect;
2728  y += 2.0f * aspect;
2729 
2730  if (is_collection) {
2732  if (collection->color_tag != COLLECTION_COLOR_NONE) {
2733  bTheme *btheme = UI_GetTheme();
2735  y,
2736  data.icon,
2737  U.inv_dpi_fac,
2738  alpha,
2739  0.0f,
2740  btheme->collection_color[collection->color_tag].color,
2741  true);
2742  return;
2743  }
2744  }
2745 
2746  /* Reduce alpha to match icon buttons */
2747  alpha *= 0.8f;
2748 
2749  /* Restrict column clip. it has been coded by simply overdrawing, doesn't work for buttons. */
2750  uchar color[4];
2751  if (UI_icon_get_theme_color(data.icon, color)) {
2752  UI_icon_draw_ex(x, y, data.icon, U.inv_dpi_fac, alpha, 0.0f, color, true);
2753  }
2754  else {
2755  UI_icon_draw_ex(x, y, data.icon, U.inv_dpi_fac, alpha, 0.0f, NULL, false);
2756  }
2757  }
2758  else {
2759  uiDefIconBut(block,
2761  0,
2762  data.icon,
2763  x,
2764  y,
2765  UI_UNIT_X,
2766  UI_UNIT_Y,
2767  NULL,
2768  0.0,
2769  0.0,
2770  1.0,
2771  alpha,
2772  (data.drag_id && ID_IS_LINKED(data.drag_id)) ? data.drag_id->lib->filepath : "");
2773  }
2774 }
2775 
2780 static void outliner_draw_iconrow_number(const uiFontStyle *fstyle,
2781  int offsx,
2782  int ys,
2783  const int num_elements)
2784 {
2785  const float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
2786  float ufac = 0.25f * UI_UNIT_X;
2787  float offset_x = (float)offsx + UI_UNIT_X * 0.35f;
2788 
2791  &(const rctf){
2792  .xmin = offset_x + ufac,
2793  .xmax = offset_x + UI_UNIT_X - ufac,
2794  .ymin = (float)ys - UI_UNIT_Y * 0.2f + ufac,
2795  .ymax = (float)ys - UI_UNIT_Y * 0.2f + UI_UNIT_Y - ufac,
2796  },
2797  true,
2798  (float)UI_UNIT_Y / 2.0f - ufac,
2799  color);
2800 
2801  /* Now the numbers. */
2802  uchar text_col[4];
2803 
2804  UI_GetThemeColor3ubv(TH_TEXT_HI, text_col);
2805  text_col[3] = 255;
2806 
2807  uiFontStyle fstyle_small = *fstyle;
2808  fstyle_small.points *= 0.8f;
2809 
2810  /* We treat +99 as 4 digits to make sure the (eyeballed) alignment looks nice. */
2811  int num_digits = 4;
2812  char number_text[4] = "+99\0";
2813  if (num_elements < 100) {
2814  BLI_snprintf(number_text, sizeof(number_text), "%d", num_elements);
2815  num_digits = num_elements < 10 ? 1 : 2;
2816  }
2817  UI_fontstyle_draw_simple(&fstyle_small,
2818  (offset_x + ufac + UI_UNIT_X * (2 - num_digits) * 0.12f),
2819  (float)ys - UI_UNIT_Y * 0.095f + ufac,
2820  number_text,
2821  text_col);
2822  UI_fontstyle_set(fstyle);
2823  GPU_blend(GPU_BLEND_ALPHA); /* Roundbox and text drawing disables. */
2824 }
2825 
2826 static void outliner_icon_background_colors(float icon_color[4], float icon_border[4])
2827 {
2828  float text[4];
2830 
2831  copy_v3_v3(icon_color, text);
2832  icon_color[3] = 0.4f;
2833  copy_v3_v3(icon_border, text);
2834  icon_border[3] = 0.2f;
2835 }
2836 
2837 /* Draw a rounded rectangle behind icons of active elements. */
2838 static void outliner_draw_active_indicator(const float minx,
2839  const float miny,
2840  const float maxx,
2841  const float maxy,
2842  const float icon_color[4],
2843  const float icon_border[4])
2844 {
2845  const float ufac = UI_UNIT_X / 20.0f;
2846  const float radius = UI_UNIT_Y / 4.0f;
2847 
2850  &(const rctf){
2851  .xmin = minx,
2852  .xmax = maxx,
2853  .ymin = miny + ufac,
2854  .ymax = maxy - ufac,
2855  },
2856  true,
2857  radius,
2858  icon_color);
2860  &(const rctf){
2861  .xmin = minx,
2862  .xmax = maxx,
2863  .ymin = miny + ufac,
2864  .ymax = maxy - ufac,
2865  },
2866  false,
2867  radius,
2868  icon_border);
2869  GPU_blend(GPU_BLEND_ALPHA); /* Roundbox disables. */
2870 }
2871 
2873  TreeElement *te,
2874  const uiFontStyle *fstyle,
2875  int xmax,
2876  int *offsx,
2877  int ys,
2878  float alpha_fac,
2879  const eOLDrawState active,
2880  const int num_elements)
2881 {
2882  TreeStoreElem *tselem = TREESTORE(te);
2883 
2884  if (active != OL_DRAWSEL_NONE) {
2885  float icon_color[4], icon_border[4];
2886  outliner_icon_background_colors(icon_color, icon_border);
2887  if (active == OL_DRAWSEL_ACTIVE) {
2889  icon_border[3] = 0.3f;
2890  }
2891 
2892  outliner_draw_active_indicator((float)*offsx,
2893  (float)ys,
2894  (float)*offsx + UI_UNIT_X,
2895  (float)ys + UI_UNIT_Y,
2896  icon_color,
2897  icon_border);
2898  }
2899 
2900  if (tselem->flag & TSE_HIGHLIGHTED_ICON) {
2901  alpha_fac += 0.5;
2902  }
2903  tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, alpha_fac, false);
2904  te->xs = *offsx;
2905  te->ys = ys;
2906  te->xend = (short)*offsx + UI_UNIT_X;
2907 
2908  if (num_elements > 1) {
2909  outliner_draw_iconrow_number(fstyle, *offsx, ys, num_elements);
2910  te->flag |= TE_ICONROW_MERGED;
2911  }
2912  else {
2913  te->flag |= TE_ICONROW;
2914  }
2915 
2916  (*offsx) += UI_UNIT_X;
2917 }
2918 
2926 {
2927  TreeStoreElem *tselem = TREESTORE(te);
2928 
2929  const int id_index = (tselem->type == TSE_SOME_ID) ? BKE_idtype_idcode_to_index(te->idcode) :
2930  INDEX_ID_GR;
2931  if (id_index < INDEX_ID_OB) {
2932  return id_index;
2933  }
2934  if (id_index == INDEX_ID_OB) {
2935  const Object *ob = (Object *)tselem->id;
2936  return INDEX_ID_OB + ob->type;
2937  }
2938  return id_index + OB_TYPE_MAX;
2939 }
2940 
2941 typedef struct MergedIconRow {
2946 
2948  uiBlock *block,
2949  const uiFontStyle *fstyle,
2950  const TreeViewContext *tvc,
2951  SpaceOutliner *space_outliner,
2952  ListBase *lb,
2953  int level,
2954  int xmax,
2955  int *offsx,
2956  int ys,
2957  float alpha_fac,
2958  MergedIconRow *merged)
2959 {
2961 
2962  LISTBASE_FOREACH (TreeElement *, te, lb) {
2963  TreeStoreElem *tselem = TREESTORE(te);
2964  te->flag &= ~(TE_ICONROW | TE_ICONROW_MERGED);
2965 
2966  /* object hierarchy always, further constrained on level */
2967  if ((level < 1) || ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB))) {
2968  /* active blocks get white circle */
2969  if (tselem->type == TSE_SOME_ID) {
2970  if (te->idcode == ID_OB) {
2971  active = (tvc->obact == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE;
2972  }
2973  else if (is_object_data_in_editmode(tselem->id, tvc->obact)) {
2975  }
2976  else {
2977  active = tree_element_active_state_get(tvc, te, tselem);
2978  }
2979  }
2980  else {
2981  active = tree_element_type_active_state_get(C, tvc, te, tselem);
2982  }
2983 
2984  if (!ELEM(tselem->type,
2985  TSE_ID_BASE,
2986  TSE_SOME_ID,
2988  TSE_R_LAYER,
2989  TSE_GP_LAYER,
2992  TSE_BONE,
2993  TSE_EBONE,
2995  TSE_POSEGRP,
2996  TSE_DEFGROUP)) {
2997  outliner_draw_iconrow_doit(block, te, fstyle, xmax, offsx, ys, alpha_fac, active, 1);
2998  }
2999  else {
3000  const int index = tree_element_id_type_to_index(te);
3001  merged->num_elements[index]++;
3002  if ((merged->tree_element[index] == NULL) || (active > merged->active[index])) {
3003  merged->tree_element[index] = te;
3004  }
3005  merged->active[index] = MAX2(active, merged->active[index]);
3006  }
3007  }
3008 
3009  /* this tree element always has same amount of branches, so don't draw */
3010  if (tselem->type != TSE_R_LAYER) {
3012  block,
3013  fstyle,
3014  tvc,
3015  space_outliner,
3016  &te->subtree,
3017  level + 1,
3018  xmax,
3019  offsx,
3020  ys,
3021  alpha_fac,
3022  merged);
3023  }
3024  }
3025 
3026  if (level == 0) {
3027  for (int i = 0; i < INDEX_ID_MAX; i++) {
3028  const int num_subtypes = (i == INDEX_ID_OB) ? OB_TYPE_MAX : 1;
3029  /* See tree_element_id_type_to_index for the index logic. */
3030  int index_base = i;
3031  if (i > INDEX_ID_OB) {
3032  index_base += OB_TYPE_MAX;
3033  }
3034  for (int j = 0; j < num_subtypes; j++) {
3035  const int index = index_base + j;
3036  if (merged->num_elements[index] != 0) {
3038  merged->tree_element[index],
3039  fstyle,
3040  xmax,
3041  offsx,
3042  ys,
3043  alpha_fac,
3044  merged->active[index],
3045  merged->num_elements[index]);
3046  }
3047  }
3048  }
3049  }
3050 }
3051 
3052 /* closed tree element */
3053 static void outliner_set_coord_tree_element(TreeElement *te, int startx, int starty)
3054 {
3055  /* closed items may be displayed in row of parent, don't change their coordinate! */
3056  if ((te->flag & TE_ICONROW) == 0 && (te->flag & TE_ICONROW_MERGED) == 0) {
3057  te->xs = 0;
3058  te->ys = 0;
3059  te->xend = 0;
3060  }
3061 
3062  LISTBASE_FOREACH (TreeElement *, ten, &te->subtree) {
3063  outliner_set_coord_tree_element(ten, startx + UI_UNIT_X, starty);
3064  }
3065 }
3066 
3068  const TreeElement *te,
3069  const TreeStoreElem *tselem)
3070 {
3071  if (tselem->type == TSE_SOME_ID) {
3072  switch (te->idcode) {
3073  case ID_OB: {
3074  const Object *ob = (const Object *)tselem->id;
3075  /* Lookup in view layer is logically const as it only checks a cache. */
3076  const Base *base = (te->directdata) ? (const Base *)te->directdata :
3078  (ViewLayer *)tvc->view_layer, (Object *)ob);
3079  const bool is_visible = (base != NULL) && (base->flag & BASE_VISIBLE_VIEWLAYER);
3080  if (!is_visible) {
3081  return true;
3082  }
3083  }
3084  }
3085  }
3086  switch (tselem->type) {
3087  case TSE_LAYER_COLLECTION: {
3088  const LayerCollection *layer_collection = (const LayerCollection *)te->directdata;
3089  const bool is_visible = layer_collection->runtime_flag & LAYER_COLLECTION_VISIBLE_VIEW_LAYER;
3090  const bool is_excluded = layer_collection->flag & LAYER_COLLECTION_EXCLUDE;
3091  return !is_visible || is_excluded;
3092  }
3093  }
3094 
3095  if (te->flag & TE_CHILD_NOT_IN_COLLECTION) {
3096  return true;
3097  }
3098 
3099  return false;
3100 }
3101 
3103  uiBlock *block,
3104  const uiFontStyle *fstyle,
3105  const TreeViewContext *tvc,
3106  ARegion *region,
3107  SpaceOutliner *space_outliner,
3108  TreeElement *te,
3109  bool draw_grayed_out,
3110  int startx,
3111  int *starty,
3112  const float restrict_column_width,
3113  TreeElement **te_edit)
3114 {
3115  TreeStoreElem *tselem = TREESTORE(te);
3116  float ufac = UI_UNIT_X / 20.0f;
3117  int offsx = 0;
3119  uchar text_color[4];
3120  UI_GetThemeColor4ubv(TH_TEXT, text_color);
3121  float icon_bgcolor[4], icon_border[4];
3122  outliner_icon_background_colors(icon_bgcolor, icon_border);
3123 
3124  if (*starty + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && *starty <= region->v2d.cur.ymax) {
3125  const float alpha_fac = element_should_draw_faded(tvc, te, tselem) ? 0.5f : 1.0f;
3126  int xmax = region->v2d.cur.xmax;
3127 
3128  if ((tselem->flag & TSE_TEXTBUT) && (*te_edit == NULL)) {
3129  *te_edit = te;
3130  }
3131 
3132  /* Icons can be ui buts, we don't want it to overlap with restrict .*/
3133  if (restrict_column_width > 0) {
3134  xmax -= restrict_column_width + UI_UNIT_X;
3135  }
3136 
3138 
3139  /* Colors for active/selected data. */
3140  if (tselem->type == TSE_SOME_ID) {
3141  if (te->idcode == ID_OB) {
3142  Object *ob = (Object *)tselem->id;
3143  Base *base = (te->directdata) ? (Base *)te->directdata :
3145  const bool is_selected = (base != NULL) && ((base->flag & BASE_SELECTED) != 0);
3146 
3147  if (ob == tvc->obact) {
3149  }
3150 
3151  if (is_selected) {
3152  if (ob == tvc->obact) {
3153  /* Active selected object. */
3155  text_color[3] = 255;
3156  }
3157  else {
3158  /* Other selected objects. */
3160  text_color[3] = 255;
3161  }
3162  }
3163  }
3164  else if (is_object_data_in_editmode(tselem->id, tvc->obact)) {
3165  /* Objects being edited. */
3166  UI_GetThemeColor4fv(TH_EDITED_OBJECT, icon_bgcolor);
3167  icon_border[3] = 0.3f;
3169  }
3170  else {
3171  if (tree_element_active_state_get(tvc, te, tselem)) {
3172  /* Active items like camera or material. */
3173  icon_bgcolor[3] = 0.2f;
3175  }
3176  }
3177  }
3178  else {
3179  active = tree_element_type_active_state_get(C, tvc, te, tselem);
3180  }
3181 
3182  /* Active circle. */
3183  if (active != OL_DRAWSEL_NONE) {
3184  outliner_draw_active_indicator((float)startx + offsx + UI_UNIT_X,
3185  (float)*starty,
3186  (float)startx + offsx + 2.0f * UI_UNIT_X,
3187  (float)*starty + UI_UNIT_Y,
3188  icon_bgcolor,
3189  icon_border);
3190 
3191  te->flag |= TE_ACTIVE; /* For lookup in display hierarchies. */
3192  }
3193 
3194  if (tselem->type == TSE_VIEW_COLLECTION_BASE) {
3195  /* Scene collection in view layer can't expand/collapse. */
3196  }
3197  else if (te->subtree.first || ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_SCE)) ||
3198  (te->flag & TE_LAZY_CLOSED)) {
3199  /* Open/close icon, only when sub-levels, except for scene. */
3200  int icon_x = startx;
3201 
3202  /* Icons a bit higher. */
3203  if (TSELEM_OPEN(tselem, space_outliner)) {
3204  UI_icon_draw_alpha((float)icon_x + 2 * ufac,
3205  (float)*starty + 1 * ufac,
3206  ICON_DISCLOSURE_TRI_DOWN,
3207  alpha_fac);
3208  }
3209  else {
3210  UI_icon_draw_alpha((float)icon_x + 2 * ufac,
3211  (float)*starty + 1 * ufac,
3212  ICON_DISCLOSURE_TRI_RIGHT,
3213  alpha_fac);
3214  }
3215  }
3216  offsx += UI_UNIT_X;
3217 
3218  /* Data-type icon. */
3220  tselem_draw_icon(block,
3221  xmax,
3222  (float)startx + offsx,
3223  (float)*starty,
3224  tselem,
3225  te,
3226  (tselem->flag & TSE_HIGHLIGHTED_ICON) ? alpha_fac + 0.5f : alpha_fac,
3227  true);
3228  offsx += UI_UNIT_X + 4 * ufac;
3229  }
3230  else {
3231  offsx += 2 * ufac;
3232  }
3233 
3234  if (ELEM(tselem->type, TSE_SOME_ID, TSE_LAYER_COLLECTION) ||
3235  ((tselem->type == TSE_RNA_STRUCT) && RNA_struct_is_ID(te->rnaptr.type))) {
3236  const BIFIconID lib_icon = UI_icon_from_library(tselem->id);
3237  if (lib_icon != ICON_NONE) {
3239  (float)startx + offsx + 2 * ufac, (float)*starty + 2 * ufac, lib_icon, alpha_fac);
3240  offsx += UI_UNIT_X + 4 * ufac;
3241  }
3242  }
3244 
3245  /* Name. */
3246  if ((tselem->flag & TSE_TEXTBUT) == 0) {
3247  if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
3248  UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.75f, text_color);
3249  text_color[3] = 255;
3250  }
3251  text_color[3] *= alpha_fac;
3252  UI_fontstyle_draw_simple(fstyle, startx + offsx, *starty + 5 * ufac, te->name, text_color);
3253  }
3254 
3255  offsx += (int)(UI_UNIT_X + UI_fontstyle_string_width(fstyle, te->name));
3256 
3257  /* Closed item, we draw the icons, not when it's a scene, or master-server list though. */
3258  if (!TSELEM_OPEN(tselem, space_outliner)) {
3259  if (te->subtree.first) {
3260  if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_SCE)) {
3261  /* Pass. */
3262  }
3263  /* this tree element always has same amount of branches, so don't draw */
3264  else if (tselem->type != TSE_R_LAYER) {
3265  int tempx = startx + offsx;
3266 
3268 
3269  MergedIconRow merged = {{0}};
3271  block,
3272  fstyle,
3273  tvc,
3274  space_outliner,
3275  &te->subtree,
3276  0,
3277  xmax,
3278  &tempx,
3279  *starty,
3280  alpha_fac,
3281  &merged);
3282 
3284  }
3285  }
3286  }
3287  }
3288  /* Store coord and continue, we need coordinates for elements outside view too. */
3289  te->xs = startx;
3290  te->ys = *starty;
3291  te->xend = startx + offsx;
3292 
3293  if (TSELEM_OPEN(tselem, space_outliner)) {
3294  *starty -= UI_UNIT_Y;
3295 
3296  LISTBASE_FOREACH (TreeElement *, ten, &te->subtree) {
3297  /* Check if element needs to be drawn grayed out, but also gray out
3298  * children of a grayed out parent (pass on draw_grayed_out to children). */
3299  bool draw_children_grayed_out = draw_grayed_out || (ten->flag & TE_DRAGGING);
3301  block,
3302  fstyle,
3303  tvc,
3304  region,
3305  space_outliner,
3306  ten,
3307  draw_children_grayed_out,
3308  startx + UI_UNIT_X,
3309  starty,
3310  restrict_column_width,
3311  te_edit);
3312  }
3313  }
3314  else {
3315  LISTBASE_FOREACH (TreeElement *, ten, &te->subtree) {
3316  outliner_set_coord_tree_element(ten, startx, *starty);
3317  }
3318 
3319  *starty -= UI_UNIT_Y;
3320  }
3321 }
3322 
3324 {
3325  LISTBASE_FOREACH (TreeElement *, te, lb) {
3326  TreeStoreElem *tselem = TREESTORE(te);
3327  if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
3328  return true;
3329  }
3330  }
3331  return false;
3332 }
3333 
3335  const uint pos, const int x, const int y1, const int y2, const bool draw_dashed)
3336 {
3337  /* Small vertical padding. */
3338  const short line_padding = UI_UNIT_Y / 4.0f;
3339 
3340  /* >= is 1.0 for undashed lines. */
3341  immUniform1f("dash_factor", draw_dashed ? 0.5f : 1.0f);
3342 
3344  /* Intentionally draw from top to bottom, so collapsing a child item doesn't make the dashes
3345  * appear to move. */
3346  immVertex2f(pos, x, y2 + line_padding);
3347  immVertex2f(pos, x, y1 - line_padding);
3348  immEnd();
3349 }
3350 
3352  SpaceOutliner *space_outliner,
3353  ListBase *lb,
3354  int startx,
3355  const uchar col[4],
3356  bool draw_grayed_out,
3357  int *starty)
3358 {
3359  bTheme *btheme = UI_GetTheme();
3360  int y = *starty;
3361 
3362  /* Draw vertical lines between collections */
3363  bool draw_hierarchy_line;
3364  bool is_object_line;
3365  LISTBASE_FOREACH (TreeElement *, te, lb) {
3366  TreeStoreElem *tselem = TREESTORE(te);
3367  draw_hierarchy_line = false;
3368  is_object_line = false;
3369  *starty -= UI_UNIT_Y;
3370  short color_tag = COLLECTION_COLOR_NONE;
3371 
3372  /* Only draw hierarchy lines for expanded collections and objects with children. */
3373  if (TSELEM_OPEN(tselem, space_outliner) && !BLI_listbase_is_empty(&te->subtree)) {
3374  if (tselem->type == TSE_LAYER_COLLECTION) {
3375  draw_hierarchy_line = true;
3376 
3378  color_tag = collection->color_tag;
3379 
3380  y = *starty;
3381  }
3382  else if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
3383  if (subtree_contains_object(&te->subtree)) {
3384  draw_hierarchy_line = true;
3385  is_object_line = true;
3386  y = *starty;
3387  }
3388  }
3389 
3391  pos, space_outliner, &te->subtree, startx + UI_UNIT_X, col, draw_grayed_out, starty);
3392  }
3393 
3394  if (draw_hierarchy_line) {
3395  if (color_tag != COLLECTION_COLOR_NONE) {
3396  immUniformColor4ubv(btheme->collection_color[color_tag].color);
3397  }
3398  else {
3400  }
3401 
3402  outliner_draw_hierarchy_line(pos, startx, y, *starty, is_object_line);
3403  }
3404  }
3405 }
3406 
3407 static void outliner_draw_hierarchy_lines(SpaceOutliner *space_outliner,
3408  ListBase *lb,
3409  int startx,
3410  int *starty)
3411 {
3414  uchar col[4];
3415 
3417 
3418  float viewport_size[4];
3419  GPU_viewport_size_get_f(viewport_size);
3420  immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
3421  immUniform1i("colors_len", 0); /* "simple" mode */
3422  immUniform1f("dash_width", 8.0f);
3424  col[3] = 255;
3425 
3426  GPU_line_width(1.0f);
3428  outliner_draw_hierarchy_lines_recursive(pos, space_outliner, lb, startx, col, false, starty);
3430 
3431  immUnbindProgram();
3432 }
3433 
3435  SpaceOutliner *space_outliner,
3436  ListBase *lb,
3437  int *starty)
3438 {
3439  LISTBASE_FOREACH (TreeElement *, te, lb) {
3440  TreeStoreElem *tselem = TREESTORE(te);
3441 
3442  /* Selection status. */
3443  if (TSELEM_OPEN(tselem, space_outliner)) {
3444  if (tselem->type == TSE_RNA_STRUCT) {
3448  immThemeColorShadeAlpha(TH_BACK, -15, -200);
3449  immRecti(pos, 0, *starty + 1, (int)region->v2d.cur.xmax, *starty + UI_UNIT_Y - 1);
3450  immUnbindProgram();
3451  }
3452  }
3453 
3454  *starty -= UI_UNIT_Y;
3455  if (TSELEM_OPEN(tselem, space_outliner)) {
3456  outliner_draw_struct_marks(region, space_outliner, &te->subtree, starty);
3457  if (tselem->type == TSE_RNA_STRUCT) {
3461  immThemeColorShadeAlpha(TH_BACK, -15, -200);
3462 
3464  immVertex2f(pos, 0, (float)*starty + UI_UNIT_Y);
3465  immVertex2f(pos, region->v2d.cur.xmax, (float)*starty + UI_UNIT_Y);
3466  immEnd();
3467 
3468  immUnbindProgram();
3469  }
3470  }
3471  }
3472 }
3473 
3475  const ARegion *region,
3476  const SpaceOutliner *space_outliner,
3477  const ListBase *lb,
3478  const float col_selection[4],
3479  const float col_active[4],
3480  const float col_highlight[4],
3481  const float col_searchmatch[4],
3482  int start_x,
3483  int *io_start_y)
3484 {
3485  const bool is_searching = (SEARCHING_OUTLINER(space_outliner) ||
3486  (space_outliner->outlinevis == SO_DATA_API &&
3487  space_outliner->search_string[0] != 0));
3488 
3489  LISTBASE_FOREACH (TreeElement *, te, lb) {
3490  const TreeStoreElem *tselem = TREESTORE(te);
3491  const int start_y = *io_start_y;
3492 
3493  /* Selection status. */
3494  if ((tselem->flag & TSE_ACTIVE) && (tselem->flag & TSE_SELECTED)) {
3495  immUniformColor4fv(col_active);
3496  immRecti(pos, 0, start_y, (int)region->v2d.cur.xmax, start_y + UI_UNIT_Y);
3497  }
3498  else if (tselem->flag & TSE_SELECTED) {
3499  immUniformColor4fv(col_selection);
3500  immRecti(pos, 0, start_y, (int)region->v2d.cur.xmax, start_y + UI_UNIT_Y);
3501  }
3502 
3503  /* Highlights. */
3504  if (tselem->flag & (TSE_DRAG_ANY | TSE_HIGHLIGHTED | TSE_SEARCHMATCH)) {
3505  const int end_x = (int)region->v2d.cur.xmax;
3506 
3507  if (tselem->flag & TSE_DRAG_ANY) {
3508  /* Drag and drop highlight. */
3509  float col[4];
3511 
3512  if (tselem->flag & TSE_DRAG_BEFORE) {
3514  immRecti(pos,
3515  start_x,
3516  start_y + UI_UNIT_Y - U.pixelsize,
3517  end_x,
3518  start_y + UI_UNIT_Y + U.pixelsize);
3519  }
3520  else if (tselem->flag & TSE_DRAG_AFTER) {
3522  immRecti(pos, start_x, start_y - U.pixelsize, end_x, start_y + U.pixelsize);
3523  }
3524  else {
3525  immUniformColor3fvAlpha(col, col[3] * 0.5f);
3526  immRecti(pos, start_x, start_y, end_x, start_y + UI_UNIT_Y);
3527  }
3528  }
3529  else {
3530  if (is_searching && (tselem->flag & TSE_SEARCHMATCH)) {
3531  /* Search match highlights. We don't expand items when searching in the data-blocks,
3532  * but we still want to highlight any filter matches. */
3533  immUniformColor4fv(col_searchmatch);
3534  immRecti(pos, start_x, start_y, end_x, start_y + UI_UNIT_Y);
3535  }
3536  else if (tselem->flag & TSE_HIGHLIGHTED) {
3537  /* Mouse hover highlight. */
3538  immUniformColor4fv(col_highlight);
3539  immRecti(pos, 0, start_y, end_x, start_y + UI_UNIT_Y);
3540  }
3541  }
3542  }
3543 
3544  *io_start_y -= UI_UNIT_Y;
3545  if (TSELEM_OPEN(tselem, space_outliner)) {
3547  region,
3548  space_outliner,
3549  &te->subtree,
3550  col_selection,
3551  col_active,
3552  col_highlight,
3553  col_searchmatch,
3554  start_x + UI_UNIT_X,
3555  io_start_y);
3556  }
3557  }
3558 }
3559 
3560 static void outliner_draw_highlights(ARegion *region,
3561  SpaceOutliner *space_outliner,
3562  int startx,
3563  int *starty)
3564 {
3565  const float col_highlight[4] = {1.0f, 1.0f, 1.0f, 0.13f};
3566  float col_selection[4], col_active[4], col_searchmatch[4];
3567 
3568  UI_GetThemeColor3fv(TH_SELECT_HIGHLIGHT, col_selection);
3569  col_selection[3] = 1.0f; /* No alpha. */
3571  col_active[3] = 1.0f; /* No alpha. */
3572  UI_GetThemeColor4fv(TH_MATCH, col_searchmatch);
3573  col_searchmatch[3] = 0.5f;
3574 
3580  region,
3581  space_outliner,
3582  &space_outliner->tree,
3583  col_selection,
3584  col_active,
3585  col_highlight,
3586  col_searchmatch,
3587  startx,
3588  starty);
3589  immUnbindProgram();
3591 }
3592 
3594  uiBlock *block,
3595  const TreeViewContext *tvc,
3596  ARegion *region,
3597  SpaceOutliner *space_outliner,
3598  const float restrict_column_width,
3599  const bool use_mode_column,
3600  TreeElement **te_edit)
3601 {
3602  const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
3603  int starty, startx;
3604 
3605  /* Move the tree a unit left in view layer mode */
3606  short mode_column_offset = (use_mode_column && (space_outliner->outlinevis == SO_SCENES)) ?
3607  UI_UNIT_X :
3608  0;
3609  if (!use_mode_column && (space_outliner->outlinevis == SO_VIEW_LAYER)) {
3610  mode_column_offset -= UI_UNIT_X;
3611  }
3612 
3613  GPU_blend(GPU_BLEND_ALPHA); /* Only once. */
3614 
3615  if (space_outliner->outlinevis == SO_DATA_API) {
3616  /* struct marks */
3617  starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
3618  outliner_draw_struct_marks(region, space_outliner, &space_outliner->tree, &starty);
3619  }
3620 
3621  /* Draw highlights before hierarchy. */
3622  starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
3623  startx = 0;
3624  outliner_draw_highlights(region, space_outliner, startx, &starty);
3625 
3626  /* Set scissor so tree elements or lines can't overlap restriction icons. */
3627  int scissor[4] = {0};
3628  if (restrict_column_width > 0.0f) {
3629  int mask_x = BLI_rcti_size_x(&region->v2d.mask) - (int)restrict_column_width + 1;
3630  CLAMP_MIN(mask_x, 0);
3631 
3632  GPU_scissor_get(scissor);
3633  GPU_scissor(0, 0, mask_x, region->winy);
3634  }
3635 
3636  /* Draw hierarchy lines for collections and object children. */
3637  starty = (int)region->v2d.tot.ymax - OL_Y_OFFSET;
3638  startx = mode_column_offset + UI_UNIT_X / 2 - (U.pixelsize + 1) / 2;
3639  outliner_draw_hierarchy_lines(space_outliner, &space_outliner->tree, startx, &starty);
3640 
3641  /* Items themselves. */
3642  starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET;
3643  startx = mode_column_offset;
3644  LISTBASE_FOREACH (TreeElement *, te, &space_outliner->tree) {
3646  block,
3647  fstyle,
3648  tvc,
3649  region,
3650  space_outliner,
3651  te,
3652  (te->flag & TE_DRAGGING) != 0,
3653  startx,
3654  &starty,
3655  restrict_column_width,
3656  te_edit);
3657  }
3658 
3659  if (restrict_column_width > 0.0f) {
3660  /* Reset scissor. */
3661  GPU_scissor(UNPACK4(scissor));
3662  }
3663 }
3664 
3665 static void outliner_back(ARegion *region)
3666 {
3667  int ystart;
3668 
3669  ystart = (int)region->v2d.tot.ymax;
3670  ystart = UI_UNIT_Y * (ystart / (UI_UNIT_Y)) - OL_Y_OFFSET;
3671 
3674 
3676 
3677  float col_alternating[4];
3678  UI_GetThemeColor4fv(TH_ROW_ALTERNATE, col_alternating);
3679  immUniformThemeColorBlend(TH_BACK, TH_ROW_ALTERNATE, col_alternating[3]);
3680 
3681  const float x1 = 0.0f, x2 = region->v2d.cur.xmax;
3682  float y1 = ystart, y2;
3683  int tot = (int)floor(ystart - region->v2d.cur.ymin + 2 * UI_UNIT_Y) / (2 * UI_UNIT_Y);
3684 
3685  if (tot > 0) {
3686  immBegin(GPU_PRIM_TRIS, 6 * tot);
3687  while (tot--) {
3688  y1 -= 2 * UI_UNIT_Y;
3689  y2 = y1 + UI_UNIT_Y;
3690  immVertex2f(pos, x1, y1);
3691  immVertex2f(pos, x2, y1);
3692  immVertex2f(pos, x2, y2);
3693 
3694  immVertex2f(pos, x1, y1);
3695  immVertex2f(pos, x2, y2);
3696  immVertex2f(pos, x1, y2);
3697  }
3698  immEnd();
3699  }
3700  immUnbindProgram();
3701 }
3702 
3703 static int outliner_data_api_buttons_start_x(int max_tree_width)
3704 {
3705  return max_ii(OL_RNA_COLX, max_tree_width + OL_RNA_COL_SPACEX);
3706 }
3707 
3708 static int outliner_width(SpaceOutliner *space_outliner,
3709  int max_tree_width,
3710  float restrict_column_width)
3711 {
3712  if (space_outliner->outlinevis == SO_DATA_API) {
3713  return outliner_data_api_buttons_start_x(max_tree_width) + OL_RNA_COL_SIZEX + 10 * UI_DPI_FAC;
3714  }
3715  return max_tree_width + restrict_column_width;
3716 }
3717 
3719  SpaceOutliner *space_outliner,
3720  int tree_width,
3721  int tree_height,
3722  float restrict_column_width)
3723 {
3724  int sizex = outliner_width(space_outliner, tree_width, restrict_column_width);
3725  int sizey = tree_height;
3726 
3727  /* Extend size to allow for horizontal scrollbar and extra offset. */
3728  sizey += V2D_SCROLL_HEIGHT + OL_Y_OFFSET;
3729 
3730  UI_view2d_totRect_set(&region->v2d, sizex, sizey);
3731 }
3732 
3733 /* ****************************************************** */
3734 /* Main Entrypoint - Draw contents of Outliner editor */
3735 
3737 {
3738  Main *mainvar = CTX_data_main(C);
3739  ARegion *region = CTX_wm_region(C);
3740  View2D *v2d = &region->v2d;
3741  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
3742  uiBlock *block;
3743  TreeElement *te_edit = NULL;
3744 
3745  TreeViewContext tvc;
3747 
3748  outliner_build_tree(mainvar, tvc.scene, tvc.view_layer, space_outliner, region); /* Always. */
3749 
3750  /* If global sync select is dirty, flag other outliners. */
3753  }
3754 
3755  /* Sync selection state from view layer. */
3756  if (!ELEM(space_outliner->outlinevis,
3757  SO_LIBRARIES,
3759  SO_DATA_API,
3760  SO_ID_ORPHANS) &&
3761  space_outliner->flag & SO_SYNC_SELECT) {
3762  outliner_sync_selection(C, space_outliner);
3763  }
3764 
3765  /* Force display to pixel coords. */
3766  v2d->flag |= (V2D_PIXELOFS_X | V2D_PIXELOFS_Y);
3767  /* Set matrix for 2D-view controls. */
3768  UI_view2d_view_ortho(v2d);
3769 
3770  /* Only show mode column in View Layers and Scenes view. */
3771  const bool use_mode_column = (space_outliner->flag & SO_MODE_COLUMN) &&
3772  (ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES));
3773 
3774  /* Draw outliner stuff (background, hierarchy lines and names). */
3775  const float restrict_column_width = outliner_restrict_columns_width(space_outliner);
3776  outliner_back(region);
3777  block = UI_block_begin(C, region, __func__, UI_EMBOSS);
3779  block,
3780  &tvc,
3781  region,
3782  space_outliner,
3783  restrict_column_width,
3784  use_mode_column,
3785  &te_edit);
3786 
3787  /* Compute outliner dimensions after it has been drawn. */
3788  int tree_width, tree_height;
3789  outliner_tree_dimensions(space_outliner, &tree_width, &tree_height);
3790 
3791  /* Default to no emboss for outliner UI. */
3793 
3794  if (space_outliner->outlinevis == SO_DATA_API) {
3795  int buttons_start_x = outliner_data_api_buttons_start_x(tree_width);
3796  /* draw rna buttons */
3797  outliner_draw_rnacols(region, buttons_start_x);
3798 
3800  outliner_draw_rnabuts(block, region, space_outliner, buttons_start_x, &space_outliner->tree);
3802  }
3803  else if (space_outliner->outlinevis == SO_ID_ORPHANS) {
3804  /* draw user toggle columns */
3805  outliner_draw_userbuts(block, region, space_outliner, &space_outliner->tree);
3806  }
3807  else if (space_outliner->outlinevis == SO_OVERRIDES_LIBRARY) {
3808  /* Draw overrides status columns. */
3809  outliner_draw_overrides_buts(block, region, space_outliner, &space_outliner->tree, true);
3810  }
3811  else if (restrict_column_width > 0.0f) {
3812  /* draw restriction columns */
3813  RestrictPropertiesActive props_active;
3814  memset(&props_active, 1, sizeof(RestrictPropertiesActive));
3816  tvc.scene,
3817  tvc.view_layer,
3818  region,
3819  space_outliner,
3820  &space_outliner->tree,
3821  props_active);
3822  }
3823 
3824  /* Draw mode icons */
3825  if (use_mode_column) {
3826  outliner_draw_mode_column(C, block, &tvc, space_outliner, &space_outliner->tree);
3827  }
3828 
3830 
3831  /* Draw edit buttons if necessary. */
3832  if (te_edit) {
3833  outliner_buttons(C, block, region, restrict_column_width, te_edit);
3834  }
3835 
3836  UI_block_end(C, block);
3837  UI_block_draw(C, block);
3838 
3839  /* Update total viewable region. */
3841  region, space_outliner, tree_width, tree_height, restrict_column_width);
3842 }
typedef float(TangentPoint)[2]
bool BKE_collection_has_collection(struct Collection *parent, struct Collection *collection)
Definition: collection.c:1545
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct SpaceOutliner * CTX_wm_space_outliner(const bContext *C)
Definition: context.c:836
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct ReportList * CTX_wm_reports(const bContext *C)
Definition: context.c:751
struct wmMsgBus * CTX_wm_message_bus(const bContext *C)
Definition: context.c:746
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
support for deformation groups and hooks.
void BKE_object_defgroup_unique_name(struct bDeformGroup *dg, struct Object *ob)
Definition: deform.c:620
void BKE_gpencil_layer_active_set(struct bGPdata *gpd, struct bGPDlayer *active)
Definition: gpencil.c:1698
int BKE_idtype_idcode_to_index(const short idcode)
Definition: idtype.c:345
void BKE_view_layer_rename(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, const char *name)
Definition: layer.c:522
bool BKE_layer_collection_has_layer_collection(struct LayerCollection *lc_parent, struct LayerCollection *lc_child)
Definition: layer.c:1092
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
Definition: layer.c:394
void BKE_layer_collection_sync(const struct Scene *scene, struct ViewLayer *view_layer)
void BKE_main_collection_sync_remap(const struct Main *bmain)
void id_us_min(struct ID *id)
Definition: lib_id.c:297
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
void BLI_libblock_ensure_unique_name(struct Main *bmain, const char *name) ATTR_NONNULL()
Definition: lib_id.c:2165
void BKE_library_filepath_set(struct Main *bmain, struct Library *lib, const char *filepath)
Definition: library.c:92
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
General operations, lookup, etc. for blender objects.
bool BKE_object_data_is_in_editmode(const struct ID *id)
bool BKE_object_is_child_recursive(const struct Object *ob_parent, const struct Object *ob_child)
struct ParticleSystem * psys_get_current(struct Object *ob)
Definition: particle.c:645
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition: BLI_assert.h:58
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:349
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define FILE_MAX
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:1016
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL()
Definition: string.c:1170
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t len)
Definition: string_utils.c:381
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNPACK4(a)
#define POINTER_AS_UINT(i)
#define UNUSED(x)
#define MAX2(a, b)
#define ELEM(...)
#define CLAMP_MIN(a, b)
#define BLT_I18NCONTEXT_ID_ACTION
#define TIP_(msgid)
#define CTX_DATA_(context, msgid)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ ID_RECALC_BASE_FLAGS
Definition: DNA_ID.h:641
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
Definition: DNA_ID.h:438
@ LIB_TAG_MISSING
Definition: DNA_ID.h:537
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
#define MAX_ID_NAME
Definition: DNA_ID.h:269
@ LIB_LIB_OVERRIDE_RESYNC_LEFTOVER
Definition: DNA_ID.h:498
@ LIB_FAKEUSER
Definition: DNA_ID.h:477
#define ID_REAL_USERS(id)
Definition: DNA_ID.h:413
@ INDEX_ID_GR
Definition: DNA_ID.h:841
@ INDEX_ID_OB
Definition: DNA_ID.h:840
@ INDEX_ID_MAX
Definition: DNA_ID.h:859
@ ID_CA
Definition: DNA_ID_enums.h:68
@ ID_AR
Definition: DNA_ID_enums.h:78
@ ID_MC
Definition: DNA_ID_enums.h:85
@ ID_LI
Definition: DNA_ID_enums.h:58
@ ID_TE
Definition: DNA_ID_enums.h:64
@ ID_IM
Definition: DNA_ID_enums.h:65
@ ID_VO
Definition: DNA_ID_enums.h:95
@ ID_WS
Definition: DNA_ID_enums.h:91
@ ID_LA
Definition: DNA_ID_enums.h:67
@ ID_KE
Definition: DNA_ID_enums.h:70
@ ID_TXT
Definition: DNA_ID_enums.h:74
@ ID_SO
Definition: DNA_ID_enums.h:76
@ ID_SCE
Definition: DNA_ID_enums.h:57
@ ID_LS
Definition: DNA_ID_enums.h:87
@ ID_MSK
Definition: DNA_ID_enums.h:86
@ ID_GD
Definition: DNA_ID_enums.h:83
@ ID_BR
Definition: DNA_ID_enums.h:81
@ ID_LP
Definition: DNA_ID_enums.h:92
@ ID_HA
Definition: DNA_ID_enums.h:93
@ ID_WO
Definition: DNA_ID_enums.h:71
@ ID_SIM
Definition: DNA_ID_enums.h:96
@ ID_MA
Definition: DNA_ID_enums.h:63
@ ID_AC
Definition: DNA_ID_enums.h:79
@ ID_SCR
Definition: DNA_ID_enums.h:72
@ ID_ME
Definition: DNA_ID_enums.h:60
@ ID_GR
Definition: DNA_ID_enums.h:77
@ ID_SPK
Definition: DNA_ID_enums.h:75
@ ID_MB
Definition: DNA_ID_enums.h:62
@ ID_LT
Definition: DNA_ID_enums.h:66
@ ID_OB
Definition: DNA_ID_enums.h:59
@ ID_PT
Definition: DNA_ID_enums.h:94
@ ID_CU
Definition: DNA_ID_enums.h:61
@ ID_PC
Definition: DNA_ID_enums.h:89
#define ID_NLA
Definition: DNA_ID_enums.h:112
@ BONE_ROOTSEL
@ BONE_SELECTED
@ BONE_UNSELECTABLE
@ BONE_HIDDEN_A
@ BONE_HIDDEN_P
@ BONE_TIPSEL
Object groups, one object can be in many groups at once.
@ COLLECTION_COLOR_NONE
@ COLLECTION_IS_MASTER
eBConstraint_Types
@ CONSTRAINT_TYPE_TRACKTO
@ CONSTRAINT_TYPE_PIVOT
@ CONSTRAINT_TYPE_CHILDOF
@ CONSTRAINT_TYPE_TRANSFORM
@ CONSTRAINT_TYPE_FOLLOWTRACK
@ CONSTRAINT_TYPE_OBJECTSOLVER
@ CONSTRAINT_TYPE_ARMATURE
@ CONSTRAINT_TYPE_LOCLIKE
@ CONSTRAINT_TYPE_SHRINKWRAP
@ CONSTRAINT_TYPE_MINMAX
@ CONSTRAINT_TYPE_ROTLIMIT
@ CONSTRAINT_TYPE_CAMERASOLVER
@ CONSTRAINT_TYPE_ROTLIKE
@ CONSTRAINT_TYPE_SPLINEIK
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_TYPE_DISTLIMIT
@ CONSTRAINT_TYPE_TRANSLIKE
@ CONSTRAINT_TYPE_LOCLIMIT
@ CONSTRAINT_TYPE_CLAMPTO
@ CONSTRAINT_TYPE_LOCKTRACK
@ CONSTRAINT_TYPE_SIZELIMIT
@ CONSTRAINT_TYPE_ACTION
@ CONSTRAINT_TYPE_FOLLOWPATH
@ CONSTRAINT_TYPE_STRETCHTO
@ CONSTRAINT_TYPE_SIZELIKE
@ CONSTRAINT_TYPE_SAMEVOL
@ CONSTRAINT_TYPE_DAMPTRACK
@ CONSTRAINT_TYPE_TRANSFORM_CACHE
@ eGpencilModifierType_Array
@ eGpencilModifierType_Noise
@ eGpencilModifierType_Mirror
@ eGpencilModifierType_Color
@ eGpencilModifierType_Multiply
@ eGpencilModifierType_Texture
@ eGpencilModifierType_Subdiv
@ eGpencilModifierType_Lattice
@ eGpencilModifierType_Opacity
@ eGpencilModifierType_Hook
@ eGpencilModifierType_Simplify
@ eGpencilModifierType_Armature
@ eGpencilModifierType_Smooth
@ eGpencilModifierType_Tint
@ eGpencilModifierType_Time
@ eGpencilModifierType_Thick
@ eGpencilModifierType_Build
@ eGpencilModifierType_Offset
#define GPENCIL_EDIT_MODE(gpd)
@ GP_LAYER_LOCKED
@ GP_LAYER_HIDE
@ LAYER_COLLECTION_EXCLUDE
@ BASE_VISIBLE_VIEWLAYER
@ BASE_SELECTED
@ LAYER_COLLECTION_VISIBLE_VIEW_LAYER
@ VIEW_LAYER_RENDER
#define LA_AREA
#define LA_SPOT
#define LA_SUN
#define LA_LOCAL
@ LIGHTPROBE_TYPE_CUBE
@ LIGHTPROBE_TYPE_PLANAR
@ LIGHTPROBE_TYPE_GRID
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_EDIT
@ OB_MODE_OBJECT
Object is a sort of wrapper for general info.
@ OB_DUPLICOLLECTION
@ OB_EMPTY_IMAGE
#define OB_DATA_SUPPORT_EDITMODE(_type)
@ OB_SPEAKER
@ OB_LATTICE
@ OB_MBALL
@ OB_EMPTY
@ OB_SURF
@ OB_CAMERA
@ OB_FONT
@ OB_TYPE_MAX
@ OB_ARMATURE
@ OB_LAMP
@ OB_MESH
@ OB_POINTCLOUD
@ OB_HAIR
@ OB_VOLUME
@ OB_CURVE
@ OB_GPENCIL
@ OB_LIGHTPROBE
@ TSE_PROXY
@ TSE_POSE_CHANNEL
@ TSE_CONSTRAINT_BASE
@ TSE_MODIFIER_BASE
@ TSE_GP_LAYER
@ TSE_SEQUENCE_DUP
@ TSE_RNA_ARRAY_ELEM
@ TSE_SEQUENCE
@ TSE_GPENCIL_EFFECT
@ TSE_POSEGRP_BASE
@ TSE_VIEW_COLLECTION_BASE
@ TSE_ANIM_DATA
@ TSE_LIBRARY_OVERRIDE
@ TSE_RNA_PROPERTY
@ TSE_LIBRARY_OVERRIDE_BASE
@ TSE_EBONE
@ TSE_NLA_TRACK
@ TSE_BONE
@ TSE_LINKED_PSYS
@ TSE_DEFGROUP_BASE
@ TSE_CONSTRAINT
@ TSE_SCENE_COLLECTION_BASE
@ TSE_SCENE_OBJECTS_BASE
@ TSE_R_LAYER_BASE
@ TSE_LAYER_COLLECTION
@ TSE_SEQ_STRIP
@ TSE_GPENCIL_EFFECT_BASE
@ TSE_LINKED_OB
@ TSE_NLA
@ TSE_ID_BASE
@ TSE_SOME_ID
@ TSE_DRIVER_BASE
@ TSE_NLA_ACTION
@ TSE_MODIFIER
@ TSE_POSEGRP
@ TSE_R_LAYER
@ TSE_RNA_STRUCT
@ TSE_POSE_BASE
@ TSE_DEFGROUP
@ TSE_DRAG_AFTER
@ TSE_SELECTED
@ TSE_HIGHLIGHTED_ICON
@ TSE_HIGHLIGHTED
@ TSE_SEARCHMATCH
@ TSE_DRAG_BEFORE
@ TSE_DRAG_ANY
@ TSE_ACTIVE
@ TSE_TEXTBUT
@ SCE_OBJECT_MODE_LOCK
@ SEQ_TYPE_TRANSFORM
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_CROSS
@ SEQ_TYPE_GLOW
@ SEQ_TYPE_COLORMIX
@ SEQ_TYPE_WIPE
@ SEQ_TYPE_META
@ SEQ_TYPE_OVERDROP
@ SEQ_TYPE_ALPHAUNDER
@ SEQ_TYPE_SCENE
@ SEQ_TYPE_GAMCROSS
@ SEQ_TYPE_MULTICAM
@ SEQ_TYPE_MOVIECLIP
@ SEQ_TYPE_MUL
@ SEQ_TYPE_GAUSSIAN_BLUR
@ SEQ_TYPE_ADD
@ SEQ_TYPE_ALPHAOVER
@ SEQ_TYPE_TEXT
@ SEQ_TYPE_IMAGE
@ SEQ_TYPE_SUB
@ SEQ_TYPE_SPEED
@ SEQ_TYPE_COLOR
@ SEQ_TYPE_MOVIE
@ SEQ_TYPE_MASK
@ SEQ_TYPE_ADJUSTMENT
@ SO_RESTRICT_HIDE
@ SO_RESTRICT_RENDER
@ SO_RESTRICT_INDIRECT_ONLY
@ SO_RESTRICT_VIEWPORT
@ SO_RESTRICT_ENABLE
@ SO_RESTRICT_HOLDOUT
@ SO_RESTRICT_SELECT
@ SO_SYNC_SELECT
@ SO_MODE_COLUMN
@ SO_OVERRIDES_LIBRARY
@ SO_DATA_API
@ SO_LIBRARIES
@ SO_VIEW_LAYER
@ SO_SCENES
@ SO_ID_ORPHANS
@ V2D_PIXELOFS_X
@ V2D_PIXELOFS_Y
void ED_outliner_select_sync_flag_outliners(const struct bContext *C)
bool ED_outliner_select_sync_is_dirty(const struct bContext *C)
void immUniformColor4ubv(const unsigned char rgba[4])
void immThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset)
void immUniform2f(const char *name, float x, float y)
void immUniformThemeColorShadeAlpha(int color_id, int color_offset, int alpha_offset)
void immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immUniform1i(const char *name, int x)
void immUniform1f(const char *name, float x)
void immUniformColor4fv(const float rgba[4])
void immUniformThemeColorBlend(int color_id1, int color_id2, float fac)
GPUVertFormat * immVertexFormat(void)
void immBegin(GPUPrimType, uint vertex_len)
void immUniformColor3fvAlpha(const float rgb[3], float a)
void immEnd(void)
void immRecti(uint pos, int x1, int y1, int x2, int y2)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble y1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:36
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:37
@ GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:365
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:171
@ GPU_BLEND_NONE
Definition: GPU_state.h:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
void GPU_line_width(float width)
Definition: gpu_state.cc:173
void GPU_scissor(int x, int y, int width, int height)
Definition: gpu_state.cc:204
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:279
void GPU_scissor_get(int coords[4])
Definition: gpu_state.cc:274
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ GPU_COMP_I32
StructRNA RNA_Bone
StructRNA RNA_Collection
StructRNA RNA_ObjectBase
StructRNA RNA_Modifier
StructRNA RNA_Constraint
StructRNA RNA_LayerCollection
StructRNA RNA_Object
@ PROP_ENUM
Definition: RNA_types.h:77
@ PROP_POINTER
Definition: RNA_types.h:78
#define C
Definition: RandGen.cpp:39
void UI_but_flag_disable(uiBut *but, int flag)
Definition: interface.c:6082
void UI_but_disable(uiBut *but, const char *disabled_hint)
Definition: interface.c:6102
#define UI_UNIT_Y
@ UI_BUT_ICON_REVERSE
Definition: UI_interface.h:298
@ UI_EMBOSS
Definition: UI_interface.h:107
@ UI_EMBOSS_NONE_OR_STATUS
Definition: UI_interface.h:115
void UI_fontstyle_set(const struct uiFontStyle *fs)
uiBut * uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5223
@ UI_BUT_DRAG_LOCK
Definition: UI_interface.h:197
@ UI_BUT_UNDO
Definition: UI_interface.h:208
@ UI_BUT_DISABLED
Definition: UI_interface.h:199
@ UI_BUT_INACTIVE
Definition: UI_interface.h:206
@ UI_CNR_ALL
uiBut * uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:4687
uiBut * uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, const char *name, int icon, int x, int y, int width, int height)
uiBut * uiDefIconButR_prop(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5549
void UI_fontstyle_draw_simple(const struct uiFontStyle *fs, float x, float y, const char *str, const uchar col[4])
void UI_but_drawflag_enable(uiBut *but, int flag)
Definition: interface.c:6092
void UI_draw_roundbox_corner_set(int type)
uiBut * uiDefIconButBitS(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, short *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5433
void UI_block_end(const struct bContext *C, uiBlock *block)
void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss)
Definition: interface.c:3542
void UI_block_draw(const struct bContext *C, struct uiBlock *block)
bool UI_but_active_only(const struct bContext *C, struct ARegion *region, uiBlock *block, uiBut *but)
void UI_but_func_rename_set(uiBut *but, uiButHandleRenameFunc func, void *arg1)
Definition: interface.c:6277
#define UI_DPI_FAC
Definition: UI_interface.h:309
void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
Definition: interface.c:6294
int UI_fontstyle_string_width(const struct uiFontStyle *fs, const char *str)
void UI_draw_roundbox_aa(const struct rctf *rect, bool filled, float rad, const float color[4])
uiBlock * UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, eUIEmbossType emboss)
#define UI_FSTYLE_WIDGET
#define UI_UNIT_X
uiBut * uiDefIconButBitI(uiBlock *block, int type, int bit, int retval, int icon, int x, int y, short width, short height, int *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5371
@ UI_BTYPE_BUT
Definition: UI_interface.h:334
@ UI_BTYPE_TEXT
Definition: UI_interface.h:336
@ UI_BTYPE_LABEL
Definition: UI_interface.h:358
@ UI_BTYPE_ICON_TOGGLE_N
Definition: UI_interface.h:347
@ UI_BTYPE_ICON_TOGGLE
Definition: UI_interface.h:346
void UI_but_flag_enable(uiBut *but, int flag)
Definition: interface.c:6077
int UI_icon_from_object_mode(const int mode)
#define ICON_DEFAULT_HEIGHT
bool UI_icon_get_theme_color(int icon_id, unsigned char color[4])
void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha)
int UI_icon_from_library(const struct ID *id)
void UI_icon_draw_ex(float x, float y, int icon_id, float aspect, float alpha, float desaturate, const uchar mono_color[4], const bool mono_border)
void UI_GetThemeColor3fv(int colorid, float col[3])
Definition: resources.c:1191
void UI_GetThemeColorBlend3ubv(int colorid1, int colorid2, float fac, unsigned char col[3])
Definition: resources.c:1122
BIFIconID
Definition: UI_resources.h:34
@ TH_SELECT_ACTIVE
Definition: UI_resources.h:274
@ TH_ROW_ALTERNATE
Definition: UI_resources.h:278
@ TH_SELECT_HIGHLIGHT
Definition: UI_resources.h:273
@ TH_ACTIVE_OBJECT
Definition: UI_resources.h:276
@ TH_BACK
Definition: UI_resources.h:55
@ TH_EDITED_OBJECT
Definition: UI_resources.h:277
@ TH_SELECTED_OBJECT
Definition: UI_resources.h:275
@ TH_MATCH
Definition: UI_resources.h:272
@ TH_TEXT
Definition: UI_resources.h:58
@ TH_TEXT_HI
Definition: UI_resources.h:59
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
Definition: resources.c:1350
struct bTheme * UI_GetTheme(void)
Definition: resources.c:1086
void UI_GetThemeColor4fv(int colorid, float col[4])
Definition: resources.c:1199
void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4])
Definition: resources.c:1359
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
Definition: resources.c:1381
#define V2D_SCROLL_HEIGHT
Definition: UI_view2d.h:67
void UI_view2d_totRect_set(struct View2D *v2d, int width, int height)
Definition: view2d.c:1052
#define V2D_SCROLL_WIDTH
Definition: UI_view2d.h:68
void UI_view2d_view_ortho(const struct View2D *v2d)
#define NC_ID
Definition: WM_types.h:296
#define ND_DATA
Definition: WM_types.h:408
#define ND_RENDER_OPTIONS
Definition: WM_types.h:335
#define NC_SCENE
Definition: WM_types.h:279
#define ND_POSE
Definition: WM_types.h:359
#define NA_EDITED
Definition: WM_types.h:462
#define NC_MATERIAL
Definition: WM_types.h:281
#define NC_IMAGE
Definition: WM_types.h:285
#define NC_GPENCIL
Definition: WM_types.h:300
#define NC_TEXTURE
Definition: WM_types.h:282
#define NA_RENAME
Definition: WM_types.h:466
#define NC_OBJECT
Definition: WM_types.h:280
#define NC_SPACE
Definition: WM_types.h:293
#define NA_SELECTED
Definition: WM_types.h:467
#define ND_SPACE_OUTLINER
Definition: WM_types.h:422
void ED_armature_bone_rename(Main *bmain, bArmature *arm, const char *oldnamep, const char *newnamep)
bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child)
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
static CCL_NAMESPACE_BEGIN const double alpha
void * tree
DRWShaderLibrary * lib
uint pos
uint col
#define GS(x)
Definition: iris.c:241
format
Definition: logImageCore.h:47
bool active
all scheduled work for the GPU.
Collection * outliner_collection_from_tree_element(const TreeElement *te)
bool outliner_is_collection_tree_element(const TreeElement *te)
static void scenes__collection_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
static void outliner_draw_hierarchy_lines_recursive(uint pos, SpaceOutliner *space_outliner, ListBase *lb, int startx, const uchar col[4], bool draw_grayed_out, int *starty)
static void outliner_draw_mode_column(const bContext *C, uiBlock *block, TreeViewContext *tvc, SpaceOutliner *space_outliner, ListBase *tree)
static void outliner_draw_rnabuts(uiBlock *block, ARegion *region, SpaceOutliner *space_outliner, int sizex, ListBase *lb)
static void outliner_draw_highlights_recursive(uint pos, const ARegion *region, const SpaceOutliner *space_outliner, const ListBase *lb, const float col_selection[4], const float col_active[4], const float col_highlight[4], const float col_searchmatch[4], int start_x, int *io_start_y)
static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ViewLayer *view_layer, ARegion *region, SpaceOutliner *space_outliner, ListBase *lb, RestrictPropertiesActive props_active_parent)
static void outliner_draw_mode_column_toggle(uiBlock *block, TreeViewContext *tvc, TreeElement *te, TreeStoreElem *tselem, const bool lock_object_modes)
static void outliner_restrict_properties_enable_collection_set(PointerRNA *collection_ptr, RestrictProperties *props, RestrictPropertiesActive *props_active)
static void outliner_icon_background_colors(float icon_color[4], float icon_border[4])
static void outliner_draw_iconrow(bContext *C, uiBlock *block, const uiFontStyle *fstyle, const TreeViewContext *tvc, SpaceOutliner *space_outliner, ListBase *lb, int level, int xmax, int *offsx, int ys, float alpha_fac, MergedIconRow *merged)
static void outliner_draw_active_indicator(const float minx, const float miny, const float maxx, const float maxy, const float icon_color[4], const float icon_border[4])
static void outliner_back(ARegion *region)
static void restrictbutton_ebone_select_fn(bContext *C, void *poin, void *poin2)
static int outliner_data_api_buttons_start_x(int max_tree_width)
static void outliner_update_viewable_area(ARegion *region, SpaceOutliner *space_outliner, int tree_width, int tree_height, float restrict_column_width)
static bool element_should_draw_faded(const TreeViewContext *tvc, const TreeElement *te, const TreeStoreElem *tselem)
struct MergedIconRow MergedIconRow
static void outliner_collection_set_flag_recursive_fn(bContext *C, LayerCollection *layer_collection, Collection *collection, const char *propname)
static void outliner__base_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
static void outliner_draw_tree_element(bContext *C, uiBlock *block, const uiFontStyle *fstyle, const TreeViewContext *tvc, ARegion *region, SpaceOutliner *space_outliner, TreeElement *te, bool draw_grayed_out, int startx, int *starty, const float restrict_column_width, TreeElement **te_edit)
static bool subtree_contains_object(ListBase *lb)
static void outliner_draw_struct_marks(ARegion *region, SpaceOutliner *space_outliner, ListBase *lb, int *starty)
static void outliner_draw_hierarchy_line(const uint pos, const int x, const int y1, const int y2, const bool draw_dashed)
static void outliner_draw_iconrow_number(const uiFontStyle *fstyle, int offsx, int ys, const int num_elements)
int tree_element_id_type_to_index(TreeElement *te)
static void outliner_restrict_properties_enable_layer_collection_set(PointerRNA *layer_collection_ptr, PointerRNA *collection_ptr, RestrictProperties *props, RestrictPropertiesActive *props_active)
static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, float alpha, const bool is_clickable)
static bool outliner_restrict_properties_collection_set(Scene *scene, TreeElement *te, PointerRNA *collection_ptr, PointerRNA *layer_collection_ptr, RestrictProperties *props, RestrictPropertiesActive *props_active)
static void outliner_base_or_object_pointer_create(Scene *scene, ViewLayer *view_layer, Collection *collection, Object *ob, PointerRNA *ptr)
static void outliner_draw_tree(bContext *C, uiBlock *block, const TreeViewContext *tvc, ARegion *region, SpaceOutliner *space_outliner, const float restrict_column_width, const bool use_mode_column, TreeElement **te_edit)
static void restrictbutton_recursive_ebone(bArmature *arm, EditBone *ebone_parent, int flag, bool set_flag)
static void outliner_tree_dimensions_impl(SpaceOutliner *space_outliner, ListBase *lb, int *width, int *height)
Definition: outliner_draw.c:87
static void outliner_object_set_flag_recursive_fn(bContext *C, Base *base, Object *ob, const char *propname)
struct RestrictPropertiesActive RestrictPropertiesActive
static bool outliner_collection_is_isolated(Scene *scene, const LayerCollection *layer_collection_cmp, const Collection *collection_cmp, const bool value_cmp, const PropertyRNA *layer_or_collection_prop, LayerCollection *layer_collection, Collection *collection)
void outliner_tree_dimensions(SpaceOutliner *space_outliner, int *r_width, int *r_height)
static void restrictbutton_gp_layer_flag_fn(bContext *C, void *poin, void *UNUSED(poin2))
static int outliner_width(SpaceOutliner *space_outliner, int max_tree_width, float restrict_column_width)
static void outliner_collection_set_flag_recursive(Scene *scene, ViewLayer *view_layer, LayerCollection *layer_collection, Collection *collection, PropertyRNA *layer_or_collection_prop, PropertyRNA *base_or_object_prop, const bool value)
static void outliner_mode_toggle_fn(bContext *C, void *tselem_poin, void *UNUSED(arg2))
static void restrictbutton_ebone_visibility_fn(bContext *C, void *poin, void *poin2)
static void outliner_set_coord_tree_element(TreeElement *te, int startx, int starty)
static void outliner_draw_hierarchy_lines(SpaceOutliner *space_outliner, ListBase *lb, int startx, int *starty)
TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
static void view_layer__layer_collection_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
static void restrictbutton_bone_visibility_fn(bContext *C, void *poin, void *UNUSED(poin2))
static void restrictbutton_r_lay_fn(bContext *C, void *poin, void *UNUSED(poin2))
static void outliner_draw_rnacols(ARegion *region, int sizex)
static void outliner_layer_or_collection_pointer_create(Scene *scene, LayerCollection *layer_collection, Collection *collection, PointerRNA *ptr)
static void outliner_draw_userbuts(uiBlock *block, ARegion *region, SpaceOutliner *space_outliner, ListBase *lb)
static void view_layer__collection_set_flag_recursive_fn(bContext *C, void *poin, void *poin2)
void outliner_collection_isolate_flag(Scene *scene, ViewLayer *view_layer, LayerCollection *layer_collection, Collection *collection, PropertyRNA *layer_or_collection_prop, const char *propname, const bool value)
void draw_outliner(const bContext *C)
static void restrictbutton_bone_select_fn(bContext *C, void *UNUSED(poin), void *poin2)
struct RestrictProperties RestrictProperties
static void restrictbutton_id_user_toggle(bContext *UNUSED(C), void *poin, void *UNUSED(poin2))
static void outliner_draw_highlights(ARegion *region, SpaceOutliner *space_outliner, int startx, int *starty)
static bool is_object_data_in_editmode(const ID *id, const Object *obact)
static void namebutton_fn(bContext *C, void *tsep, char *oldname)
static void outliner_draw_iconrow_doit(uiBlock *block, TreeElement *te, const uiFontStyle *fstyle, int xmax, int *offsx, int ys, float alpha_fac, const eOLDrawState active, const int num_elements)
static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *region, const float restrict_column_width, TreeElement *te)
static void restrictbutton_recursive_bone(Bone *bone_parent, int flag, bool set_flag)
static bool outliner_draw_overrides_buts(uiBlock *block, ARegion *region, SpaceOutliner *space_outliner, ListBase *lb, const bool is_open)
#define SEARCHING_OUTLINER(sov)
#define OL_RNA_COL_SPACEX
void outliner_viewcontext_init(const struct bContext *C, TreeViewContext *tvc)
@ TE_CHILD_NOT_IN_COLLECTION
@ TE_ICONROW_MERGED
@ TE_ICONROW
@ TE_ACTIVE
@ TE_LAZY_CLOSED
@ TE_DRAGGING
eOLDrawState tree_element_active_state_get(const TreeViewContext *tvc, const TreeElement *te, const TreeStoreElem *tselem)
#define OL_RNA_COLX
#define OL_Y_OFFSET
@ OL_SETSEL_NORMAL
TreeElement * outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem)
void outliner_sync_selection(const struct bContext *C, struct SpaceOutliner *space_outliner)
void outliner_build_tree(struct Main *mainvar, struct Scene *scene, struct ViewLayer *view_layer, struct SpaceOutliner *space_outliner, struct ARegion *region)
eOLDrawState
@ OL_DRAWSEL_ACTIVE
@ OL_DRAWSEL_NORMAL
@ OL_DRAWSEL_NONE
#define OL_NAMEBUTTON
void outliner_item_mode_toggle(struct bContext *C, TreeViewContext *tvc, TreeElement *te, const bool do_extend)
float outliner_restrict_columns_width(const struct SpaceOutliner *space_outliner)
#define TREESTORE(a)
#define OL_RNA_COL_SIZEX
void tree_element_activate(struct bContext *C, const TreeViewContext *tvc, TreeElement *te, const eOLSetState set, const bool handle_all_types)
#define OL_TOG_USER_BUTS_STATUS
#define OL_TOG_USER_BUTS_USERS
#define TSELEM_OPEN(telm, sv)
eOLDrawState tree_element_type_active_state_get(const struct bContext *C, const struct TreeViewContext *tvc, const TreeElement *te, const TreeStoreElem *tselem)
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
bool RNA_struct_is_ID(const StructRNA *type)
Definition: rna_access.c:797
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1155
bool RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
Definition: rna_access.c:2557
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2331
PropertyRNA * RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
Definition: rna_access.c:953
int RNA_struct_ui_icon(const StructRNA *type)
Definition: rna_access.c:738
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2358
struct Object * object
struct Bone * next
ListBase childbase
struct Collection * collection
char name[64]
Definition: BKE_armature.h:57
struct EditBone * next
Definition: BKE_armature.h:49
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
int us
Definition: DNA_ID.h:293
short flag
Definition: DNA_ID.h:288
char name[66]
Definition: DNA_ID.h:283
ListBase layer_collections
struct Collection * collection
short type
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase objects
Definition: BKE_main.h:148
TreeElement * tree_element[INDEX_ID_MAX+OB_TYPE_MAX]
int num_elements[INDEX_ID_MAX+OB_TYPE_MAX]
eOLDrawState active[INDEX_ID_MAX+OB_TYPE_MAX]
short transflag
struct Collection * instance_collection
struct bPose * pose
ListBase modifiers
ListBase greasepencil_modifiers
struct PartDeflect * pd
char empty_drawtype
void * data
struct StructRNA * type
Definition: RNA_types.h:51
void * data
Definition: RNA_types.h:52
PropertyRNA * layer_collection_holdout
PropertyRNA * object_hide_viewport
PropertyRNA * modifier_show_viewport
PropertyRNA * collection_hide_viewport
PropertyRNA * layer_collection_hide_viewport
PropertyRNA * bone_hide_viewport
PropertyRNA * modifier_show_render
PropertyRNA * layer_collection_exclude
PropertyRNA * base_hide_viewport
PropertyRNA * object_hide_render
PropertyRNA * object_hide_select
PropertyRNA * constraint_enable
PropertyRNA * collection_hide_select
PropertyRNA * collection_hide_render
PropertyRNA * layer_collection_indirect_only
struct Collection * master_collection
struct ToolSettings * toolsettings
char search_string[64]
struct BLI_mempool * treestore
unsigned char color[4]
struct TreeElement * parent
ListBase subtree
void * directdata
PointerRNA rnaptr
const char * name
struct Scene * scene
struct ViewLayer * view_layer
short flag
ListBase layer_collections
ListBase * edbo
ListBase layers
struct Bone * bone
ListBase agroups
ThemeCollectionColor collection_color[8]
float xmax
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
short shift
Definition: WM_types.h:618
short ctrl
Definition: WM_types.h:618
struct wmEvent * eventstate
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: util_avxb.h:167
ccl_device_inline float2 floor(const float2 &a)
uint len
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition: wm_files.c:3157
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)