Source/Interface/Outliner

Outliner
The Outliner provides important information and operations to the user about the data and relationships between data for the current file. It is a regular editor in Blender (`SpaceOutliner`, `SPACE_OUTLINER`)

Ongoing Refactor
See T96713: Continued Outliner Code Refactor.


 * Information about the ongoing refactor of the Outliner code.
 * Moving towards an object oriented design in C++, with inheritance for display modes and tree elements.

Tree Building
For more precise information, see `space_outliner\tree\tree_display_"displaymode".cc`
 * Rebuilding the Outliner tree can be expensive in big files. Therefore they are avoided. see `ED_region_tag_redraw` vs. `ED_region_tag_redraw_no_rebuild`
 * Based on received notifiers (TODO link), a decision is made if the tree needs to be rebuilt or if a simple redraw without rebuild is enough. This is a bit finicky & fragile, but a worthwile optimization.
 * Tree building is done individually for each display mode as mentioned in [Drawing section].

Main Data Structures

 * `SpaceOutliner`
 * `TreeElement`
 * `TreeStoreElem`
 * `AbstractTreeElement`
 * `AbstractTreeDisplay`

Operations/Tools
Outliner operations are accessed via context menu, shortcut keys and mouse events. Context menu building is done in `outliner_tools.cc` Operations are registered in `outliner_ops.cc`. They are defined in different file based on their use.
 * Selection operations such as box select are defined in `outliner_select.cc`
 * Drag-drop operations in `outliner_dragdrop.cc`
 * Collection related operations in `outliner_collection.cc`
 * General tree-element related operations in `outliner_tools.cc`

These operations are executed with `exec` callback functions and some with `outliner_operation_fn` callback. Examples:

Refactor Needed!

 * The way Outliner operations are implemented is not great:
 * Performs data management in UI code (sometimes low level). UI should only call other modules to perform data changes, not do them itself.
 * Does not use the regular operator system, works around it even. Problem is getting Outliner context transferred to the operators (e.g. which items are selected, so the operator can act on selection).
 * Enums are used to differentiate the operations and display them in the context menus, this is rather unflexible and makes code paths confusing to keep track of (its quite `switch`-`case` heavy)
 * All of this makes the code quite confusing and difficult to maintain.
 * How this should be refactored:
 * Outliner can expose all relevant data via context, e.g. in a `"selected_objects"` context member (see `outliner_context.cc`)
 * General operators can then simply act on this context. These would be mostly implemented in the corresponding modules (e.g. `OBJECT_OT_do_something`), not in the Outliner.
 * Pain point: This may be tricky to get right for batch operations (operations applied to many selected objects for example).

Display Modes
Some display modes have special requirements and treatment.

View Layer Display Mode

 * This is the default view mode in Blender. It tries to convey a lot of information.
 * This makes the design quite complex, there are a lot of pitfalls to consider.
 * Outliner displays two hierarchies in one:
 * Collections and their contents
 * Object parenting relations
 * Design weakness: Can cause confusion, because objects that are not inside a collection appear inside the collection in the Outliner tree.
 * Restriction toggles are directly mapped to bit-flags inside collections, objects and bases (wrappers to link objects into collections).
 * Hide in viewport toogle is layer level property. Its state is not stored in object, collection, etc. Re-enabling `Exclude from view layer` generates a new layer collection. That said, state of `hide viewport` is set to OFF irresepctive of it's previous state when collection exclude property is re-enabled (#87111)

Scene Display Mode
Almost the same as View Layer one.

Data API Display Mode

 * Recursively built from the RNA hierachy (RNA structs and properties)
 * Attention: The tree needs to be rebuilt as elements get uncollapsed, because the RNA hierarchy can have a very deep level of recursion. So only the visible elements are built.

Blender File Display Mode

 * Displays All datablocks in the current file (`Main` database contents)
 * Datablocks linked from external library files

Orphaned Data Display Mode
This displays data-block which has no user. These data-blocks are deleted on reloading the file (can be prevented with Fake user toggle). To display orphaned data-blocks, function loops through ListBases of all IDs present in Main database, if data-block satifies `ID_REAL_USERS(id) <= 0` then they are appended to tree list.

Library Overrides Display Mode
Override mode displays IDs (and heirarchies) that are overridden. It also displays overridden properties. rna-buttons for properties mode and override toggle in heirachies mode are drawn in `outliner_draw.cc` See:

Selection Behavior
Selection of tree elements is dependant on cursor position. Clicking in outliner space calls `outliner_item_activate_invoke` function, It later selects/activates element based on mouse position.


 * `outliner_item_select`: Handles selection of individual element
 * `do_outliner_range_select`: Handles Selection of range of items
 * `outliner_set_properties_tab`: switches to object properties tab in properties editor when clicked over icon
 * `TSE_SELECTED`: set the flag to select tree element
 * `TSE_ACTIVE`: set the flag to mark tree element active

For more specific information, refer `source\blender\editors\space_outliner\outliner_select.cc`

Selection Syncing
- Keeps selection in the viewport in Sync with the Outliner selection.

Drag & Drop
Outliner Drag operation is executed with LMB drag event. This is initiated with `outliner_item_drag_drop_invoke`. Outliner supports drag & drop operation for various `ID` types and datastacks (for example: modifier). Check `outliner_dropboxes` to know which outliner element supports drop operation.

For more information, see: `source\blender\editors\space_outliner\outliner_dragdrop.cc` `source\blender\windowmanager\intern\wm_dragdrop.cc`

Drawing

 * Outliner space is created in `space_outliner.cc` and its contents i.e. tree elements, icons, restriction toggles, etc. are drawn in `outliner_draw.cc`.
 * Callback functions are defined for buttons/toggles present in the outliner for handling the events.
 * Type of elements to draw in outliner is decided separately for every display mode with `buildtree` function. For example: In `tree_display_view_layer.cc`, buildtree function generates a tree for "view layer" display mode, considering view settings.