2011-07-11 10:59:53 +00:00
|
|
|
/*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2018-06-01 18:19:39 +02:00
|
|
|
* of the License, or (at your option) any later version.
|
2011-07-11 10:59:53 +00:00
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2004 Blender Foundation.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup spoutliner
|
2011-07-11 10:59:53 +00:00
|
|
|
*/
|
|
|
|
|
|
2012-04-26 17:01:04 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
2019-04-16 15:35:08 -03:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
#include "DNA_armature_types.h"
|
2018-08-29 15:32:50 +02:00
|
|
|
#include "DNA_collection_types.h"
|
2020-10-28 11:43:10 -06:00
|
|
|
#include "DNA_constraint_types.h"
|
|
|
|
|
#include "DNA_gpencil_modifier_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_gpencil_types.h"
|
2019-02-27 12:34:56 +11:00
|
|
|
#include "DNA_light_types.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
#include "DNA_material_types.h"
|
2020-10-28 11:43:10 -06:00
|
|
|
#include "DNA_modifier_types.h"
|
2012-04-26 05:17:54 +00:00
|
|
|
#include "DNA_object_types.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
#include "DNA_sequence_types.h"
|
2020-10-28 11:43:10 -06:00
|
|
|
#include "DNA_shader_fx_types.h"
|
2012-04-26 05:17:54 +00:00
|
|
|
#include "DNA_world_types.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
|
2012-05-29 05:45:06 +00:00
|
|
|
#include "BLI_listbase.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_utildefines.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
|
2018-04-24 15:20:17 +02:00
|
|
|
#include "BKE_armature.h"
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#include "BKE_collection.h"
|
2020-10-28 11:43:10 -06:00
|
|
|
#include "BKE_constraint.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
#include "BKE_context.h"
|
2018-07-31 10:22:19 +02:00
|
|
|
#include "BKE_gpencil.h"
|
2020-10-28 11:43:10 -06:00
|
|
|
#include "BKE_gpencil_modifier.h"
|
Render Layers and Collections (merge from render-layers)
Design Documents
----------------
* https://wiki.blender.org/index.php/Dev:2.8/Source/Layers
* https://wiki.blender.org/index.php/Dev:2.8/Source/DataDesignRevised
User Commit Log
---------------
* New Layer and Collection system to replace render layers and viewport layers.
* A layer is a set of collections of objects (and their drawing options) required for specific tasks.
* A collection is a set of objects, equivalent of the old layers in Blender. A collection can be shared across multiple layers.
* All Scenes have a master collection that all other collections are children of.
* New collection "context" tab (in Properties Editor)
* New temporary viewport "collections" panel to control per-collection
visibility
Missing User Features
---------------------
* Collection "Filter"
Option to add objects based on their names
* Collection Manager operators
The existing buttons are placeholders
* Collection Manager drawing
The editor main region is empty
* Collection Override
* Per-Collection engine settings
This will come as a separate commit, as part of the clay-engine branch
Dev Commit Log
--------------
* New DNA file (DNA_layer_types.h) with the new structs
We are replacing Base by a new extended Base while keeping it backward
compatible with some legacy settings (i.e., lay, flag_legacy).
Renamed all Base to BaseLegacy to make it clear the areas of code that
still need to be converted
Note: manual changes were required on - deg_builder_nodes.h, rna_object.c, KX_Light.cpp
* Unittesting for main syncronization requirements
- read, write, add/copy/remove objects, copy scene, collection
link/unlinking, context)
* New Editor: Collection Manager
Based on patch by Julian Eisel
This is extracted from the layer-manager branch. With the following changes:
- Renamed references of layer manager to collections manager
- I doesn't include the editors/space_collections/ draw and util files
- The drawing code itself will be implemented separately by Julian
* Base / Object:
A little note about them. Original Blender code would try to keep them
in sync through the code, juggling flags back and forth. This will now
be handled by Depsgraph, keeping Object and Bases more separated
throughout the non-rendering code.
Scene.base is being cleared in doversion, and the old viewport drawing
code was poorly converted to use the new bases while the new viewport
code doesn't get merged and replace the old one.
Python API Changes
------------------
```
- scene.layers
+ # no longer exists
- scene.objects
+ scene.scene_layers.active.objects
- scene.objects.active
+ scene.render_layers.active.objects.active
- bpy.context.scene.objects.link()
+ bpy.context.scene_collection.objects.link()
- bpy_extras.object_utils.object_data_add(context, obdata, operator=None, use_active_layer=True, name=None)
+ bpy_extras.object_utils.object_data_add(context, obdata, operator=None, name=None)
- bpy.context.object.select
+ bpy.context.object.select = True
+ bpy.context.object.select = False
+ bpy.context.object.select_get()
+ bpy.context.object.select_set(action='SELECT')
+ bpy.context.object.select_set(action='DESELECT')
-AddObjectHelper.layers
+ # no longer exists
```
2017-02-07 10:18:38 +01:00
|
|
|
#include "BKE_layer.h"
|
2018-06-06 16:25:28 +02:00
|
|
|
#include "BKE_main.h"
|
2020-10-28 11:43:10 -06:00
|
|
|
#include "BKE_modifier.h"
|
2018-04-24 15:20:17 +02:00
|
|
|
#include "BKE_object.h"
|
2018-07-31 10:22:19 +02:00
|
|
|
#include "BKE_paint.h"
|
2020-10-28 11:43:10 -06:00
|
|
|
#include "BKE_particle.h"
|
2020-08-27 16:40:56 +02:00
|
|
|
#include "BKE_report.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
#include "BKE_scene.h"
|
2020-10-28 11:43:10 -06:00
|
|
|
#include "BKE_shader_fx.h"
|
2018-04-24 15:20:17 +02:00
|
|
|
#include "BKE_workspace.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
|
2017-06-08 10:14:53 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
2019-08-09 13:47:53 -06:00
|
|
|
#include "DEG_depsgraph_build.h"
|
2017-06-08 10:14:53 +02:00
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
#include "ED_armature.h"
|
2020-10-28 11:43:10 -06:00
|
|
|
#include "ED_buttons.h"
|
2019-08-09 14:12:29 -06:00
|
|
|
#include "ED_gpencil.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
#include "ED_object.h"
|
2019-08-07 22:27:07 -06:00
|
|
|
#include "ED_outliner.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
#include "ED_screen.h"
|
2019-02-15 15:48:11 -02:00
|
|
|
#include "ED_select_utils.h"
|
2012-05-29 05:45:06 +00:00
|
|
|
#include "ED_sequencer.h"
|
2018-04-02 15:02:08 +02:00
|
|
|
#include "ED_undo.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
|
2020-12-19 06:44:57 +01:00
|
|
|
#include "SEQ_select.h"
|
2020-11-01 21:03:31 +01:00
|
|
|
#include "SEQ_sequencer.h"
|
|
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
#include "WM_api.h"
|
2020-09-10 08:35:58 -06:00
|
|
|
#include "WM_toolsystem.h"
|
2011-07-11 10:59:53 +00:00
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
|
|
|
|
#include "UI_interface.h"
|
|
|
|
|
#include "UI_view2d.h"
|
|
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
|
#include "RNA_define.h"
|
|
|
|
|
|
|
|
|
|
#include "outliner_intern.h"
|
|
|
|
|
|
2020-10-30 20:24:06 +11:00
|
|
|
/**
|
|
|
|
|
* \note changes to selection are by convention and not essential.
|
2020-10-30 20:24:18 +11:00
|
|
|
*
|
|
|
|
|
* \note Handles own undo push.
|
2020-10-30 20:24:06 +11:00
|
|
|
*/
|
2020-09-10 08:35:58 -06:00
|
|
|
static void do_outliner_item_editmode_toggle(bContext *C, Scene *scene, Base *base)
|
2019-02-15 15:48:11 -02:00
|
|
|
{
|
2020-09-10 08:35:58 -06:00
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
|
Object *ob = base->object;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-30 20:24:06 +11:00
|
|
|
bool changed = false;
|
2020-09-10 08:35:58 -06:00
|
|
|
if (BKE_object_is_in_editmode(ob)) {
|
2020-10-30 20:24:06 +11:00
|
|
|
changed = ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
|
|
|
|
|
if (changed) {
|
|
|
|
|
ED_object_base_select(base, BA_DESELECT);
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
|
|
|
|
|
}
|
2019-02-15 15:48:11 -02:00
|
|
|
}
|
|
|
|
|
else {
|
2020-10-30 20:24:06 +11:00
|
|
|
changed = ED_object_editmode_enter_ex(CTX_data_main(C), scene, ob, EM_NO_CONTEXT);
|
|
|
|
|
if (changed) {
|
|
|
|
|
ED_object_base_select(base, BA_SELECT);
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_MODE, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (changed) {
|
|
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
|
|
|
|
ED_outliner_select_sync_from_object_tag(C);
|
2020-10-30 20:24:18 +11:00
|
|
|
ED_undo_push(C, "Outliner Edit Mode Toggle");
|
2019-02-15 15:48:11 -02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-30 20:24:06 +11:00
|
|
|
/**
|
|
|
|
|
* \note changes to selection are by convention and not essential.
|
2020-10-30 20:24:18 +11:00
|
|
|
*
|
|
|
|
|
* \note Handles own undo push.
|
2020-10-30 20:24:06 +11:00
|
|
|
*/
|
|
|
|
|
static void do_outliner_item_posemode_toggle(bContext *C, Scene *scene, Base *base)
|
2018-05-30 10:19:09 +02:00
|
|
|
{
|
2018-06-06 16:25:28 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2019-02-15 15:48:11 -02:00
|
|
|
Object *ob = base->object;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-10 08:35:58 -06:00
|
|
|
if (ID_IS_LINKED(ob)) {
|
|
|
|
|
BKE_report(CTX_wm_reports(C), RPT_WARNING, "Cannot pose libdata");
|
2020-10-30 20:24:06 +11:00
|
|
|
return;
|
2018-05-30 10:19:09 +02:00
|
|
|
}
|
2020-10-30 20:24:06 +11:00
|
|
|
|
|
|
|
|
bool changed = false;
|
|
|
|
|
if (ob->mode & OB_MODE_POSE) {
|
|
|
|
|
changed = ED_object_posemode_exit_ex(bmain, ob);
|
|
|
|
|
if (changed) {
|
|
|
|
|
ED_object_base_select(base, BA_DESELECT);
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
|
|
|
|
|
}
|
2018-05-30 10:19:09 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2020-10-30 20:24:06 +11:00
|
|
|
changed = ED_object_posemode_enter_ex(bmain, ob);
|
|
|
|
|
if (changed) {
|
|
|
|
|
ED_object_base_select(base, BA_SELECT);
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (changed) {
|
|
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
|
|
|
|
ED_outliner_select_sync_from_object_tag(C);
|
2020-10-30 20:24:18 +11:00
|
|
|
ED_undo_push(C, "Outliner Pose Mode Toggle");
|
2018-05-30 10:19:09 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-30 20:24:06 +11:00
|
|
|
/**
|
|
|
|
|
* Swap the current active object from the interaction mode with the given base.
|
|
|
|
|
*
|
|
|
|
|
* \note Changes to selection _are_ needed in this case,
|
|
|
|
|
* since entering the object mode uses the selection.
|
|
|
|
|
*
|
|
|
|
|
* If we didn't want to touch selection we could add an option to the operators
|
|
|
|
|
* not to do multi-object editing.
|
2020-10-30 20:24:18 +11:00
|
|
|
*
|
|
|
|
|
* \note Handles own undo push.
|
2020-10-30 20:24:06 +11:00
|
|
|
*/
|
2020-09-10 08:35:58 -06:00
|
|
|
static void do_outliner_item_mode_toggle_generic(bContext *C, TreeViewContext *tvc, Base *base)
|
2018-05-30 10:19:09 +02:00
|
|
|
{
|
2020-09-10 08:35:58 -06:00
|
|
|
const int active_mode = tvc->obact->mode;
|
2020-10-30 20:24:18 +11:00
|
|
|
ED_undo_group_begin(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-10-30 20:24:06 +11:00
|
|
|
if (ED_object_mode_set(C, OB_MODE_OBJECT)) {
|
|
|
|
|
Base *base_active = BKE_view_layer_base_find(tvc->view_layer, tvc->obact);
|
|
|
|
|
if (base_active != base) {
|
|
|
|
|
BKE_view_layer_base_deselect_all(tvc->view_layer);
|
|
|
|
|
BKE_view_layer_base_select_and_set_active(tvc->view_layer, base);
|
|
|
|
|
DEG_id_tag_update(&tvc->scene->id, ID_RECALC_SELECT);
|
2020-10-30 20:24:18 +11:00
|
|
|
ED_undo_push(C, "Change Active");
|
2020-10-30 20:24:06 +11:00
|
|
|
|
2020-10-30 20:24:18 +11:00
|
|
|
/* Operator call does undo push. */
|
2020-10-30 20:24:06 +11:00
|
|
|
ED_object_mode_set(C, active_mode);
|
|
|
|
|
ED_outliner_select_sync_from_object_tag(C);
|
|
|
|
|
}
|
2018-05-30 10:19:09 +02:00
|
|
|
}
|
2020-10-30 20:24:18 +11:00
|
|
|
ED_undo_group_end(C);
|
2018-05-30 10:19:09 +02:00
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
|
2020-06-19 12:35:09 -06:00
|
|
|
/* Toggle the item's interaction mode if supported */
|
2020-09-10 08:35:58 -06:00
|
|
|
void outliner_item_mode_toggle(bContext *C,
|
|
|
|
|
TreeViewContext *tvc,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
const bool do_extend)
|
2020-06-19 12:35:09 -06:00
|
|
|
{
|
|
|
|
|
TreeStoreElem *tselem = TREESTORE(te);
|
|
|
|
|
|
2020-09-10 08:35:58 -06:00
|
|
|
if (tselem->type == 0 && te->idcode == ID_OB) {
|
2020-06-19 12:35:09 -06:00
|
|
|
Object *ob = (Object *)tselem->id;
|
|
|
|
|
Base *base = BKE_view_layer_base_find(tvc->view_layer, ob);
|
2020-09-10 08:35:58 -06:00
|
|
|
|
|
|
|
|
/* Hidden objects can be removed from the mode. */
|
|
|
|
|
if (!base || (!(base->flag & BASE_VISIBLE_DEPSGRAPH) && (ob->mode != tvc->obact->mode))) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!do_extend) {
|
|
|
|
|
do_outliner_item_mode_toggle_generic(C, tvc, base);
|
|
|
|
|
}
|
|
|
|
|
else if (tvc->ob_edit && OB_TYPE_SUPPORT_EDITMODE(ob->type)) {
|
|
|
|
|
do_outliner_item_editmode_toggle(C, tvc->scene, base);
|
|
|
|
|
}
|
|
|
|
|
else if (tvc->ob_pose && ob->type == OB_ARMATURE) {
|
2020-10-30 20:24:06 +11:00
|
|
|
do_outliner_item_posemode_toggle(C, tvc->scene, base);
|
2020-06-19 12:35:09 -06:00
|
|
|
}
|
2018-06-20 10:04:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
/* ****************************************************** */
|
|
|
|
|
/* Outliner Element Selection/Activation on Click */
|
|
|
|
|
|
2018-04-24 15:20:17 +02:00
|
|
|
static eOLDrawState active_viewlayer(bContext *C,
|
2018-07-04 13:00:46 +02:00
|
|
|
Scene *UNUSED(scene),
|
|
|
|
|
ViewLayer *UNUSED(sl),
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
|
|
|
|
/* paranoia check */
|
2019-03-26 21:16:47 +11:00
|
|
|
if (te->idcode != ID_SCE) {
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-04-24 15:20:17 +02:00
|
|
|
ViewLayer *view_layer = te->directdata;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2018-07-04 13:00:46 +02:00
|
|
|
wmWindow *win = CTX_wm_window(C);
|
|
|
|
|
Scene *scene = WM_window_get_active_scene(win);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-04 13:00:46 +02:00
|
|
|
if (BLI_findindex(&scene->view_layers, view_layer) != -1) {
|
|
|
|
|
WM_window_set_active_view_layer(win, view_layer);
|
|
|
|
|
WM_event_add_notifier(C, NC_SCREEN | ND_LAYER, NULL);
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2018-07-04 13:00:46 +02:00
|
|
|
return CTX_data_view_layer(C) == view_layer;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-09 15:51:36 +00:00
|
|
|
/**
|
2019-08-09 14:12:29 -06:00
|
|
|
* Select object tree
|
2013-03-09 15:51:36 +00:00
|
|
|
*/
|
2017-11-23 13:51:49 -02:00
|
|
|
static void do_outliner_object_select_recursive(ViewLayer *view_layer,
|
|
|
|
|
Object *ob_parent,
|
|
|
|
|
bool select)
|
2013-03-09 13:13:04 +00:00
|
|
|
{
|
2017-04-19 11:31:33 +02:00
|
|
|
Base *base;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-11-23 13:51:49 -02:00
|
|
|
for (base = FIRSTBASE(view_layer); base; base = base->next) {
|
2013-03-09 15:51:36 +00:00
|
|
|
Object *ob = base->object;
|
2019-10-10 10:25:46 +11:00
|
|
|
if ((((base->flag & BASE_VISIBLE_DEPSGRAPH) != 0) &&
|
|
|
|
|
BKE_object_is_child_recursive(ob_parent, ob))) {
|
2017-04-19 11:31:33 +02:00
|
|
|
ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
|
2013-03-09 13:13:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-11 16:23:33 +00:00
|
|
|
static void do_outliner_bone_select_recursive(bArmature *arm, Bone *bone_parent, bool select)
|
2013-03-11 16:02:16 +00:00
|
|
|
{
|
|
|
|
|
Bone *bone;
|
|
|
|
|
for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
|
2019-03-26 21:16:47 +11:00
|
|
|
if (select && PBONE_SELECTABLE(arm, bone)) {
|
2013-03-11 16:02:16 +00:00
|
|
|
bone->flag |= BONE_SELECTED;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2013-03-12 13:03:58 +00:00
|
|
|
bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2013-03-11 16:23:33 +00:00
|
|
|
do_outliner_bone_select_recursive(arm, bone, select);
|
2013-03-11 16:02:16 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-11 16:23:33 +00:00
|
|
|
static void do_outliner_ebone_select_recursive(bArmature *arm, EditBone *ebone_parent, bool select)
|
2013-03-11 16:02:16 +00:00
|
|
|
{
|
|
|
|
|
EditBone *ebone;
|
2013-03-11 16:23:33 +00:00
|
|
|
for (ebone = ebone_parent->next; ebone; ebone = ebone->next) {
|
|
|
|
|
if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
|
2019-03-26 21:16:47 +11:00
|
|
|
if (select && EBONE_SELECTABLE(arm, ebone)) {
|
2013-03-12 13:03:58 +00:00
|
|
|
ebone->flag |= BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2013-03-12 13:03:58 +00:00
|
|
|
ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2013-03-11 16:02:16 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_set_active_object(bContext *C,
|
2019-02-16 09:47:19 +11:00
|
|
|
Scene *scene,
|
|
|
|
|
ViewLayer *view_layer,
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *UNUSED(space_outliner),
|
2014-01-16 20:22:45 +11:00
|
|
|
TreeElement *te,
|
|
|
|
|
const eOLSetState set,
|
|
|
|
|
bool recursive)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2012-05-07 17:56:30 +00:00
|
|
|
TreeStoreElem *tselem = TREESTORE(te);
|
2020-04-10 11:21:55 -03:00
|
|
|
TreeStoreElem *parent_tselem = NULL;
|
2020-06-17 20:15:21 -06:00
|
|
|
TreeElement *parent_te = NULL;
|
2011-07-11 10:59:53 +00:00
|
|
|
Scene *sce;
|
2017-02-09 17:51:25 +01:00
|
|
|
Base *base;
|
2012-05-07 17:56:30 +00:00
|
|
|
Object *ob = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
/* if id is not object, we search back */
|
2020-06-17 20:15:21 -06:00
|
|
|
if (tselem->type == 0 && te->idcode == ID_OB) {
|
2013-03-09 03:46:30 +00:00
|
|
|
ob = (Object *)tselem->id;
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
else {
|
2020-06-17 20:15:21 -06:00
|
|
|
parent_te = outliner_search_back_te(te, ID_OB);
|
|
|
|
|
if (parent_te) {
|
|
|
|
|
parent_tselem = TREESTORE(parent_te);
|
|
|
|
|
ob = (Object *)parent_tselem->id;
|
|
|
|
|
|
|
|
|
|
/* Don't return when activating children of the previous active object. */
|
|
|
|
|
if (ob == OBACT(view_layer) && set == OL_SETSEL_NONE) {
|
|
|
|
|
return OL_DRAWSEL_NONE;
|
|
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ob == NULL) {
|
|
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-07 11:19:39 -07:00
|
|
|
sce = (Scene *)outliner_search_back(te, ID_SCE);
|
2012-03-24 06:38:07 +00:00
|
|
|
if (sce && scene != sce) {
|
2018-07-03 15:34:26 +02:00
|
|
|
WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
|
2013-04-06 21:48:39 +00:00
|
|
|
scene = sce;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
/* find associated base in current scene */
|
2017-11-23 13:51:49 -02:00
|
|
|
base = BKE_view_layer_base_find(view_layer, ob);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-06-18 20:40:41 +02:00
|
|
|
if (scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) {
|
|
|
|
|
if (base != NULL) {
|
|
|
|
|
Object *obact = OBACT(view_layer);
|
|
|
|
|
const eObjectMode object_mode = obact ? obact->mode : OB_MODE_OBJECT;
|
|
|
|
|
if (base && !BKE_object_is_mode_compat(base->object, object_mode)) {
|
|
|
|
|
if (object_mode == OB_MODE_OBJECT) {
|
|
|
|
|
struct Main *bmain = CTX_data_main(C);
|
2019-07-25 16:36:22 +02:00
|
|
|
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
2018-06-18 20:40:41 +02:00
|
|
|
ED_object_mode_generic_exit(bmain, depsgraph, scene, base->object);
|
|
|
|
|
}
|
|
|
|
|
if (!BKE_object_is_mode_compat(base->object, object_mode)) {
|
|
|
|
|
base = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-18 20:40:41 +02:00
|
|
|
}
|
2018-05-30 15:24:45 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-05-01 12:52:32 -06:00
|
|
|
if (base) {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set == OL_SETSEL_EXTEND) {
|
2011-07-11 10:59:53 +00:00
|
|
|
/* swap select */
|
2019-03-26 21:16:47 +11:00
|
|
|
if (base->flag & BASE_SELECTED) {
|
2017-02-09 17:51:25 +01:00
|
|
|
ED_object_base_select(base, BA_DESELECT);
|
2020-05-01 12:52:32 -06:00
|
|
|
if (parent_tselem) {
|
|
|
|
|
parent_tselem->flag &= ~TSE_SELECTED;
|
|
|
|
|
}
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2017-02-09 17:51:25 +01:00
|
|
|
ED_object_base_select(base, BA_SELECT);
|
2020-05-01 12:52:32 -06:00
|
|
|
if (parent_tselem) {
|
|
|
|
|
parent_tselem->flag |= TSE_SELECTED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
else {
|
|
|
|
|
/* deleselect all */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-30 15:50:52 +02:00
|
|
|
/* Only in object mode so we can switch the active object,
|
|
|
|
|
* keeping all objects in the current 'mode' selected, useful for multi-pose/edit mode.
|
2019-01-15 23:24:20 +11:00
|
|
|
* This keeps the convention that all objects in the current mode are also selected.
|
|
|
|
|
* see T55246. */
|
2018-06-18 20:40:41 +02:00
|
|
|
if ((scene->toolsettings->object_flag & SCE_OBJECT_MODE_LOCK) ?
|
|
|
|
|
(ob->mode == OB_MODE_OBJECT) :
|
|
|
|
|
true) {
|
2018-05-30 15:50:52 +02:00
|
|
|
BKE_view_layer_base_deselect_all(view_layer);
|
|
|
|
|
}
|
2017-02-09 17:51:25 +01:00
|
|
|
ED_object_base_select(base, BA_SELECT);
|
2020-05-01 12:52:32 -06:00
|
|
|
if (parent_tselem) {
|
|
|
|
|
parent_tselem->flag |= TSE_SELECTED;
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-09 15:51:36 +00:00
|
|
|
if (recursive) {
|
2013-03-12 13:03:58 +00:00
|
|
|
/* Recursive select/deselect for Object hierarchies */
|
2017-12-13 16:23:56 -02:00
|
|
|
do_outliner_object_select_recursive(view_layer, ob, (base->flag & BASE_SELECTED) != 0);
|
2013-03-09 15:51:36 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-28 14:06:04 +01:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2017-02-09 17:51:25 +01:00
|
|
|
ED_object_base_activate(C, base); /* adds notifier */
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
2013-04-06 21:48:39 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-30 15:24:45 +02:00
|
|
|
if (ob != OBEDIT_FROM_VIEW_LAYER(view_layer)) {
|
2019-01-10 13:02:07 +11:00
|
|
|
ED_object_editmode_exit(C, EM_FREEDATA);
|
2018-05-30 15:24:45 +02:00
|
|
|
}
|
2018-05-15 10:25:49 +02:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NORMAL;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_material(bContext *C,
|
2019-02-16 09:47:19 +11:00
|
|
|
Scene *UNUSED(scene),
|
|
|
|
|
ViewLayer *view_layer,
|
2014-01-16 20:22:45 +11:00
|
|
|
TreeElement *te,
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
|
|
|
|
TreeElement *tes;
|
|
|
|
|
Object *ob;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
/* we search for the object parent */
|
2020-03-07 11:19:39 -07:00
|
|
|
ob = (Object *)outliner_search_back(te, ID_OB);
|
2020-07-03 13:31:42 -06:00
|
|
|
/* Note : ob->matbits can be NULL when a local object points to a library mesh. */
|
2017-11-23 13:51:49 -02:00
|
|
|
if (ob == NULL || ob != OBACT(view_layer) || ob->matbits == NULL) {
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE; /* just paranoia */
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
/* searching in ob mat array? */
|
2012-05-07 17:56:30 +00:00
|
|
|
tes = te->parent;
|
|
|
|
|
if (tes->idcode == ID_OB) {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2012-05-07 17:56:30 +00:00
|
|
|
ob->actcol = te->index + 1;
|
2020-07-03 13:31:42 -06:00
|
|
|
ob->matbits[te->index] = 1; /* Make ob material active too. */
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (ob->actcol == te->index + 1) {
|
|
|
|
|
if (ob->matbits[te->index]) {
|
|
|
|
|
return OL_DRAWSEL_NORMAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* or we search for obdata material */
|
|
|
|
|
else {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2012-05-07 17:56:30 +00:00
|
|
|
ob->actcol = te->index + 1;
|
2020-07-03 13:31:42 -06:00
|
|
|
ob->matbits[te->index] = 0; /* Make obdata material active too. */
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (ob->actcol == te->index + 1) {
|
|
|
|
|
if (ob->matbits[te->index] == 0) {
|
|
|
|
|
return OL_DRAWSEL_NORMAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2014-12-21 12:40:02 +01:00
|
|
|
/* Tagging object for update seems a bit stupid here, but looks like we have to do it
|
|
|
|
|
* for render views to update. See T42973.
|
|
|
|
|
* Note that RNA material update does it too, see e.g. rna_MaterialSlot_update(). */
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update((ID *)ob, ID_RECALC_TRANSFORM);
|
2012-11-26 08:52:07 +00:00
|
|
|
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, NULL);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2019-08-09 13:47:53 -06:00
|
|
|
static eOLDrawState tree_element_active_camera(bContext *C,
|
2019-02-16 09:47:19 +11:00
|
|
|
Scene *scene,
|
2019-08-09 13:47:53 -06:00
|
|
|
ViewLayer *UNUSED(view_layer),
|
2014-01-16 20:22:45 +11:00
|
|
|
TreeElement *te,
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2020-03-07 11:19:39 -07:00
|
|
|
Object *ob = (Object *)outliner_search_back(te, ID_OB);
|
2011-07-11 10:59:53 +00:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2019-08-09 13:47:53 -06:00
|
|
|
scene->camera = ob;
|
|
|
|
|
|
|
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
|
wmWindowManager *wm = bmain->wm.first;
|
|
|
|
|
|
|
|
|
|
WM_windows_scene_data_sync(&wm->windows, scene);
|
|
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
|
|
|
|
|
DEG_relations_tag_update(bmain);
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, NULL);
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
|
|
|
|
}
|
2020-07-03 17:20:22 +02:00
|
|
|
return scene->camera == ob;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_world(bContext *C,
|
2019-02-16 09:47:19 +11:00
|
|
|
Scene *scene,
|
|
|
|
|
ViewLayer *UNUSED(sl),
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *UNUSED(space_outliner),
|
2014-01-16 20:22:45 +11:00
|
|
|
TreeElement *te,
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
|
|
|
|
TreeElement *tep;
|
2012-05-07 17:56:30 +00:00
|
|
|
TreeStoreElem *tselem = NULL;
|
|
|
|
|
Scene *sce = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-07 17:56:30 +00:00
|
|
|
tep = te->parent;
|
2012-03-24 06:38:07 +00:00
|
|
|
if (tep) {
|
2012-05-07 17:56:30 +00:00
|
|
|
tselem = TREESTORE(tep);
|
2019-03-26 21:16:47 +11:00
|
|
|
if (tselem->type == 0) {
|
2012-12-22 15:10:04 +00:00
|
|
|
sce = (Scene *)tselem->id;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
|
|
|
|
/* make new scene active */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (sce && scene != sce) {
|
2018-07-03 15:34:26 +02:00
|
|
|
WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), sce);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-07 17:56:30 +00:00
|
|
|
if (tep == NULL || tselem->id == (ID *)scene) {
|
2020-07-03 12:48:00 -06:00
|
|
|
if (set == OL_SETSEL_NONE) {
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NORMAL;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_defgroup(bContext *C,
|
2017-11-23 13:51:49 -02:00
|
|
|
ViewLayer *view_layer,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
|
|
|
|
Object *ob;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
/* id in tselem is object */
|
2012-05-07 17:56:30 +00:00
|
|
|
ob = (Object *)tselem->id;
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2012-05-07 17:56:30 +00:00
|
|
|
BLI_assert(te->index + 1 >= 0);
|
|
|
|
|
ob->actdef = te->index + 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
2012-05-07 17:56:30 +00:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2019-04-22 09:19:45 +10:00
|
|
|
if (ob == OBACT(view_layer)) {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (ob->actdef == te->index + 1) {
|
|
|
|
|
return OL_DRAWSEL_NORMAL;
|
|
|
|
|
}
|
2019-04-22 09:19:45 +10:00
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2019-03-15 14:38:40 +01:00
|
|
|
static eOLDrawState tree_element_active_gplayer(bContext *C,
|
2018-07-31 10:22:19 +02:00
|
|
|
Scene *UNUSED(scene),
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set)
|
|
|
|
|
{
|
|
|
|
|
bGPdata *gpd = (bGPdata *)tselem->id;
|
|
|
|
|
bGPDlayer *gpl = te->directdata;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
/* We can only have a single "active" layer at a time
|
|
|
|
|
* and there must always be an active layer...
|
|
|
|
|
*/
|
|
|
|
|
if (set != OL_SETSEL_NONE) {
|
|
|
|
|
if (gpl) {
|
2020-03-09 16:27:24 +01:00
|
|
|
BKE_gpencil_layer_active_set(gpd, gpl);
|
2019-12-05 10:19:49 +01:00
|
|
|
DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY);
|
2018-07-31 10:22:19 +02:00
|
|
|
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, gpd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return OL_DRAWSEL_NORMAL;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-31 10:22:19 +02:00
|
|
|
return OL_DRAWSEL_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_posegroup(bContext *C,
|
2017-11-23 13:51:49 -02:00
|
|
|
Scene *UNUSED(scene),
|
|
|
|
|
ViewLayer *view_layer,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2012-05-07 17:56:30 +00:00
|
|
|
Object *ob = (Object *)tselem->id;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2011-07-11 10:59:53 +00:00
|
|
|
if (ob->pose) {
|
2012-05-07 17:56:30 +00:00
|
|
|
ob->pose->active_group = te->index + 1;
|
|
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2017-11-23 13:51:49 -02:00
|
|
|
if (ob == OBACT(view_layer) && ob->pose) {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (ob->pose->active_group == te->index + 1) {
|
|
|
|
|
return OL_DRAWSEL_NORMAL;
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_posechannel(bContext *C,
|
2017-11-23 13:51:49 -02:00
|
|
|
Scene *UNUSED(scene),
|
|
|
|
|
ViewLayer *view_layer,
|
2019-11-02 03:11:56 +11:00
|
|
|
Object *ob_pose,
|
2017-11-23 13:51:49 -02:00
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set,
|
|
|
|
|
bool recursive)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2012-05-07 17:56:30 +00:00
|
|
|
Object *ob = (Object *)tselem->id;
|
|
|
|
|
bArmature *arm = ob->data;
|
|
|
|
|
bPoseChannel *pchan = te->directdata;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!(pchan->bone->flag & BONE_HIDDEN_P)) {
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_EXTEND) {
|
2019-04-16 16:09:59 -03:00
|
|
|
/* Single select forces all other bones to get unselected. */
|
|
|
|
|
uint objects_len = 0;
|
2019-10-25 00:40:21 +11:00
|
|
|
Object **objects = BKE_object_pose_array_get_unique(view_layer, NULL, &objects_len);
|
|
|
|
|
|
2019-04-16 16:09:59 -03:00
|
|
|
for (uint object_index = 0; object_index < objects_len; object_index++) {
|
|
|
|
|
Object *ob_iter = BKE_object_pose_armature_get(objects[object_index]);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-16 16:09:59 -03:00
|
|
|
/* Sanity checks. */
|
|
|
|
|
if (ELEM(NULL, ob_iter, ob_iter->pose, ob_iter->data)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-16 16:09:59 -03:00
|
|
|
bPoseChannel *pchannel;
|
|
|
|
|
for (pchannel = ob_iter->pose->chanbase.first; pchannel; pchannel = pchannel->next) {
|
|
|
|
|
pchannel->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-16 16:09:59 -03:00
|
|
|
if (ob != ob_iter) {
|
|
|
|
|
DEG_id_tag_update(ob_iter->data, ID_RECALC_SELECT);
|
|
|
|
|
}
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2019-04-16 16:09:59 -03:00
|
|
|
MEM_freeN(objects);
|
2013-03-13 12:52:44 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if ((set == OL_SETSEL_EXTEND) && (pchan->bone->flag & BONE_SELECTED)) {
|
2011-07-11 10:59:53 +00:00
|
|
|
pchan->bone->flag &= ~BONE_SELECTED;
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2011-07-11 10:59:53 +00:00
|
|
|
pchan->bone->flag |= BONE_SELECTED;
|
2012-05-07 17:56:30 +00:00
|
|
|
arm->act_bone = pchan->bone;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-12 13:03:58 +00:00
|
|
|
if (recursive) {
|
|
|
|
|
/* Recursive select/deselect */
|
|
|
|
|
do_outliner_bone_select_recursive(
|
|
|
|
|
arm, pchan->bone, (pchan->bone->flag & BONE_SELECTED) != 0);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-07 17:56:30 +00:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
|
2019-01-22 20:24:33 +01:00
|
|
|
DEG_id_tag_update(&arm->id, ID_RECALC_SELECT);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2019-11-02 03:11:56 +11:00
|
|
|
if (ob == ob_pose && ob->pose) {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (pchan->bone->flag & BONE_SELECTED) {
|
|
|
|
|
return OL_DRAWSEL_NORMAL;
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_bone(bContext *C,
|
2017-11-23 13:51:49 -02:00
|
|
|
ViewLayer *view_layer,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set,
|
|
|
|
|
bool recursive)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2012-05-07 17:56:30 +00:00
|
|
|
bArmature *arm = (bArmature *)tselem->id;
|
|
|
|
|
Bone *bone = te->directdata;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!(bone->flag & BONE_HIDDEN_P)) {
|
2017-11-23 13:51:49 -02:00
|
|
|
Object *ob = OBACT(view_layer);
|
2012-09-15 06:29:32 +00:00
|
|
|
if (ob) {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_EXTEND) {
|
2013-03-13 12:52:44 +00:00
|
|
|
/* single select forces all other bones to get unselected */
|
2015-11-23 15:44:15 +11:00
|
|
|
for (Bone *bone_iter = arm->bonebase.first; bone_iter != NULL;
|
|
|
|
|
bone_iter = bone_iter->next) {
|
|
|
|
|
bone_iter->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
|
|
|
|
|
do_outliner_bone_select_recursive(arm, bone_iter, false);
|
2013-03-13 12:52:44 +00:00
|
|
|
}
|
2012-09-15 06:29:32 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set == OL_SETSEL_EXTEND && (bone->flag & BONE_SELECTED)) {
|
2011-07-11 10:59:53 +00:00
|
|
|
bone->flag &= ~BONE_SELECTED;
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2011-07-11 10:59:53 +00:00
|
|
|
bone->flag |= BONE_SELECTED;
|
2012-05-07 17:56:30 +00:00
|
|
|
arm->act_bone = bone;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-11 16:02:16 +00:00
|
|
|
if (recursive) {
|
|
|
|
|
/* Recursive select/deselect */
|
2013-03-11 16:23:33 +00:00
|
|
|
do_outliner_bone_select_recursive(arm, bone, (bone->flag & BONE_SELECTED) != 0);
|
2013-03-11 16:02:16 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-09-15 06:29:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2017-11-23 13:51:49 -02:00
|
|
|
Object *ob = OBACT(view_layer);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-07 17:56:30 +00:00
|
|
|
if (ob && ob->data == arm) {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (bone->flag & BONE_SELECTED) {
|
|
|
|
|
return OL_DRAWSEL_NORMAL;
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ebones only draw in editmode armature */
|
2019-04-16 15:35:08 -03:00
|
|
|
static void tree_element_active_ebone__sel(bContext *C, bArmature *arm, EditBone *ebone, short sel)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2012-03-24 06:38:07 +00:00
|
|
|
if (sel) {
|
2012-05-07 17:56:30 +00:00
|
|
|
arm->act_edbone = ebone;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2020-11-05 14:11:01 +01:00
|
|
|
ED_armature_ebone_select_set(ebone, sel);
|
2019-04-16 15:35:08 -03:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, CTX_data_edit_object(C));
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_ebone(bContext *C,
|
2019-04-16 15:35:08 -03:00
|
|
|
ViewLayer *view_layer,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set,
|
|
|
|
|
bool recursive)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2019-04-16 15:35:08 -03:00
|
|
|
bArmature *arm = (bArmature *)tselem->id;
|
2012-05-07 17:56:30 +00:00
|
|
|
EditBone *ebone = te->directdata;
|
2014-01-16 20:22:45 +11:00
|
|
|
eOLDrawState status = OL_DRAWSEL_NONE;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
|
|
|
|
if (set == OL_SETSEL_NORMAL) {
|
2013-03-11 16:02:16 +00:00
|
|
|
if (!(ebone->flag & BONE_HIDDEN_A)) {
|
2019-04-16 15:35:08 -03:00
|
|
|
uint bases_len = 0;
|
|
|
|
|
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(
|
|
|
|
|
view_layer, NULL, &bases_len);
|
|
|
|
|
ED_armature_edit_deselect_all_multi_ex(bases, bases_len);
|
|
|
|
|
MEM_freeN(bases);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-16 15:35:08 -03:00
|
|
|
tree_element_active_ebone__sel(C, arm, ebone, true);
|
2014-01-16 20:22:45 +11:00
|
|
|
status = OL_DRAWSEL_NORMAL;
|
2013-03-11 16:02:16 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
else if (set == OL_SETSEL_EXTEND) {
|
2013-03-11 16:02:16 +00:00
|
|
|
if (!(ebone->flag & BONE_HIDDEN_A)) {
|
|
|
|
|
if (!(ebone->flag & BONE_SELECTED)) {
|
2019-04-16 15:35:08 -03:00
|
|
|
tree_element_active_ebone__sel(C, arm, ebone, true);
|
2014-01-16 20:22:45 +11:00
|
|
|
status = OL_DRAWSEL_NORMAL;
|
2013-03-11 16:02:16 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* entirely selected, so de-select */
|
2019-04-16 15:35:08 -03:00
|
|
|
tree_element_active_ebone__sel(C, arm, ebone, false);
|
2014-01-16 20:22:45 +11:00
|
|
|
status = OL_DRAWSEL_NONE;
|
2013-03-11 16:02:16 +00:00
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-11 16:02:16 +00:00
|
|
|
if (recursive) {
|
|
|
|
|
/* Recursive select/deselect */
|
2013-03-11 16:23:33 +00:00
|
|
|
do_outliner_ebone_select_recursive(arm, ebone, (ebone->flag & BONE_SELECTED) != 0);
|
2013-03-11 16:02:16 +00:00
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
else if (ebone->flag & BONE_SELECTED) {
|
2014-01-16 20:22:45 +11:00
|
|
|
status = OL_DRAWSEL_NORMAL;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-11 16:02:16 +00:00
|
|
|
return status;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_modifier(bContext *C,
|
2017-11-22 10:52:39 -02:00
|
|
|
Scene *UNUSED(scene),
|
|
|
|
|
ViewLayer *UNUSED(sl),
|
|
|
|
|
TreeElement *UNUSED(te),
|
|
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2012-05-07 17:56:30 +00:00
|
|
|
Object *ob = (Object *)tselem->id;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-05-07 17:56:30 +00:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
static eOLDrawState tree_element_active_psys(bContext *C,
|
|
|
|
|
Scene *UNUSED(scene),
|
|
|
|
|
TreeElement *UNUSED(te),
|
|
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set)
|
|
|
|
|
{
|
|
|
|
|
if (set != OL_SETSEL_NONE) {
|
|
|
|
|
Object *ob = (Object *)tselem->id;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_PARTICLE | NA_EDITED, ob);
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
return OL_DRAWSEL_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static int tree_element_active_constraint(bContext *C,
|
2020-10-28 11:43:10 -06:00
|
|
|
Scene *scene,
|
|
|
|
|
ViewLayer *view_layer,
|
|
|
|
|
TreeElement *te,
|
2017-11-22 10:52:39 -02:00
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2012-05-07 17:56:30 +00:00
|
|
|
Object *ob = (Object *)tselem->id;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-10-28 11:43:10 -06:00
|
|
|
/* Activate the parent bone if this is a bone constraint. */
|
|
|
|
|
te = te->parent;
|
|
|
|
|
while (te) {
|
|
|
|
|
tselem = TREESTORE(te);
|
|
|
|
|
if (tselem->type == TSE_POSE_CHANNEL) {
|
|
|
|
|
tree_element_active_posechannel(C, scene, view_layer, ob, te, tselem, set, false);
|
|
|
|
|
return OL_DRAWSEL_NONE;
|
|
|
|
|
}
|
|
|
|
|
te = te->parent;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-07 17:56:30 +00:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-19 12:35:09 -06:00
|
|
|
static eOLDrawState tree_element_active_pose(bContext *UNUSED(C),
|
|
|
|
|
Scene *UNUSED(scene),
|
2019-02-15 15:48:11 -02:00
|
|
|
ViewLayer *view_layer,
|
|
|
|
|
TreeElement *UNUSED(te),
|
|
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2012-05-07 17:56:30 +00:00
|
|
|
Object *ob = (Object *)tselem->id;
|
2017-11-23 13:51:49 -02:00
|
|
|
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-06-29 10:09:17 +02:00
|
|
|
if (base == NULL) {
|
|
|
|
|
/* Armature not instantiated in current scene (e.g. inside an appended group...). */
|
|
|
|
|
return OL_DRAWSEL_NONE;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2018-04-05 18:20:27 +02:00
|
|
|
if (ob->mode & OB_MODE_POSE) {
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NORMAL;
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_sequence(bContext *C,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *UNUSED(tselem),
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2012-05-07 17:56:30 +00:00
|
|
|
Sequence *seq = (Sequence *)te->directdata;
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2012-05-29 05:45:06 +00:00
|
|
|
/* only check on setting */
|
|
|
|
|
if (BLI_findindex(ed->seqbasep, seq) != -1) {
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set == OL_SETSEL_EXTEND) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_select_active_set(scene, NULL);
|
2012-05-29 05:45:06 +00:00
|
|
|
}
|
|
|
|
|
ED_sequencer_deselect_all(scene);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if ((set == OL_SETSEL_EXTEND) && seq->flag & SELECT) {
|
2012-05-29 05:45:06 +00:00
|
|
|
seq->flag &= ~SELECT;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
seq->flag |= SELECT;
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_select_active_set(scene, seq);
|
2012-05-29 05:45:06 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-29 05:45:06 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-05-29 05:45:06 +00:00
|
|
|
if (ed->act_seq == seq && seq->flag & SELECT) {
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NORMAL;
|
2012-05-29 05:45:06 +00:00
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_sequence_dup(Scene *scene,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *UNUSED(tselem),
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
|
|
|
|
Sequence *seq, *p;
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-07 17:56:30 +00:00
|
|
|
seq = (Sequence *)te->directdata;
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set == OL_SETSEL_NONE) {
|
2019-03-26 21:16:47 +11:00
|
|
|
if (seq->flag & SELECT) {
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NORMAL;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-07-03 13:31:42 -06:00
|
|
|
/* XXX select_single_seq(seq, 1); */
|
2012-05-07 17:56:30 +00:00
|
|
|
p = ed->seqbasep->first;
|
2012-03-24 07:52:14 +00:00
|
|
|
while (p) {
|
2013-07-16 11:42:07 +00:00
|
|
|
if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) {
|
2012-05-07 17:56:30 +00:00
|
|
|
p = p->next;
|
2011-07-11 10:59:53 +00:00
|
|
|
continue;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-07-03 13:31:42 -06:00
|
|
|
/* XXX: if (STREQ(p->strip->stripdata->name, seq->strip->stripdata->name)) select_single_seq(p,
|
|
|
|
|
* 0); */
|
2012-05-07 17:56:30 +00:00
|
|
|
p = p->next;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
static eOLDrawState tree_element_active_keymap_item(bContext *UNUSED(C),
|
2017-11-22 10:52:39 -02:00
|
|
|
Scene *UNUSED(scene),
|
|
|
|
|
ViewLayer *UNUSED(sl),
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *UNUSED(tselem),
|
|
|
|
|
const eOLSetState set)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2012-03-24 02:51:46 +00:00
|
|
|
wmKeyMapItem *kmi = te->directdata;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set == OL_SETSEL_NONE) {
|
|
|
|
|
if (kmi->flag & KMI_INACTIVE) {
|
|
|
|
|
return OL_DRAWSEL_NONE;
|
|
|
|
|
}
|
|
|
|
|
return OL_DRAWSEL_NORMAL;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2020-07-03 17:20:22 +02:00
|
|
|
kmi->flag ^= KMI_INACTIVE;
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
static eOLDrawState tree_element_active_master_collection(bContext *C,
|
|
|
|
|
TreeElement *UNUSED(te),
|
|
|
|
|
const eOLSetState set)
|
2017-02-09 20:25:56 +01:00
|
|
|
{
|
2017-02-28 14:06:04 +01:00
|
|
|
if (set == OL_SETSEL_NONE) {
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
2017-02-28 21:58:07 +01:00
|
|
|
LayerCollection *active = CTX_data_layer_collection(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
if (active == view_layer->layer_collections.first) {
|
2017-02-28 14:06:04 +01:00
|
|
|
return OL_DRAWSEL_NORMAL;
|
|
|
|
|
}
|
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
else {
|
|
|
|
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
|
|
|
|
LayerCollection *layer_collection = view_layer->layer_collections.first;
|
|
|
|
|
BKE_layer_collection_activate(view_layer, layer_collection);
|
2020-08-20 20:17:00 +02:00
|
|
|
/* A very precise notifier - ND_LAYER alone is quite vague, we want to avoid unnecessary work
|
|
|
|
|
* when only the active collection changes. */
|
|
|
|
|
WM_main_add_notifier(NC_SCENE | ND_LAYER | NS_LAYER_COLLECTION | NA_ACTIVATED, NULL);
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
return OL_DRAWSEL_NONE;
|
|
|
|
|
}
|
2017-11-30 18:38:07 -02:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
static eOLDrawState tree_element_active_layer_collection(bContext *C,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
const eOLSetState set)
|
|
|
|
|
{
|
|
|
|
|
if (set == OL_SETSEL_NONE) {
|
|
|
|
|
LayerCollection *active = CTX_data_layer_collection(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
if (active == te->directdata) {
|
|
|
|
|
return OL_DRAWSEL_NORMAL;
|
2017-12-01 11:24:21 -02:00
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
LayerCollection *layer_collection = te->directdata;
|
|
|
|
|
ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection);
|
|
|
|
|
BKE_layer_collection_activate(view_layer, layer_collection);
|
2020-08-20 20:17:00 +02:00
|
|
|
/* A very precise notifier - ND_LAYER alone is quite vague, we want to avoid unnecessary work
|
|
|
|
|
* when only the active collection changes. */
|
|
|
|
|
WM_main_add_notifier(NC_SCENE | ND_LAYER | NS_LAYER_COLLECTION | NA_ACTIVATED, NULL);
|
2017-02-09 20:25:56 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-09 20:25:56 +01:00
|
|
|
return OL_DRAWSEL_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
/* ---------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/* generic call for ID data check or make/check active in UI */
|
2019-02-16 09:47:19 +11:00
|
|
|
eOLDrawState tree_element_active(bContext *C,
|
2019-11-02 03:11:56 +11:00
|
|
|
const TreeViewContext *tvc,
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *space_outliner,
|
2019-02-16 09:47:19 +11:00
|
|
|
TreeElement *te,
|
2014-03-24 13:08:29 +01:00
|
|
|
const eOLSetState set,
|
|
|
|
|
const bool handle_all_types)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2012-04-28 06:31:57 +00:00
|
|
|
switch (te->idcode) {
|
2019-04-22 00:18:34 +10:00
|
|
|
/** \note #ID_OB only if handle_all_type is true,
|
|
|
|
|
* else objects are handled specially to allow multiple selection.
|
|
|
|
|
* See #do_outliner_item_activate. */
|
2014-03-24 13:08:29 +01:00
|
|
|
case ID_OB:
|
|
|
|
|
if (handle_all_types) {
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_set_active_object(
|
2020-08-07 11:47:23 -06:00
|
|
|
C, tvc->scene, tvc->view_layer, space_outliner, te, set, false);
|
2014-03-24 13:08:29 +01:00
|
|
|
}
|
|
|
|
|
break;
|
2011-07-11 10:59:53 +00:00
|
|
|
case ID_MA:
|
2020-03-07 11:19:39 -07:00
|
|
|
return tree_element_active_material(C, tvc->scene, tvc->view_layer, te, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case ID_WO:
|
2020-08-07 11:47:23 -06:00
|
|
|
return tree_element_active_world(C, tvc->scene, tvc->view_layer, space_outliner, te, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case ID_CA:
|
2020-03-07 11:19:39 -07:00
|
|
|
return tree_element_active_camera(C, tvc->scene, tvc->view_layer, te, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2014-01-16 20:22:45 +11:00
|
|
|
/**
|
|
|
|
|
* Generic call for non-id data to make/check active in UI
|
|
|
|
|
*/
|
|
|
|
|
eOLDrawState tree_element_type_active(bContext *C,
|
2019-11-02 03:11:56 +11:00
|
|
|
const TreeViewContext *tvc,
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *space_outliner,
|
2014-01-16 20:22:45 +11:00
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *tselem,
|
|
|
|
|
const eOLSetState set,
|
|
|
|
|
bool recursive)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2012-04-28 06:31:57 +00:00
|
|
|
switch (tselem->type) {
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_DEFGROUP:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_defgroup(C, tvc->view_layer, te, tselem, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_BONE:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_bone(C, tvc->view_layer, te, tselem, set, recursive);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_EBONE:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_ebone(C, tvc->view_layer, te, tselem, set, recursive);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_MODIFIER:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_modifier(C, tvc->scene, tvc->view_layer, te, tselem, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_LINKED_OB:
|
2014-01-16 20:22:45 +11:00
|
|
|
if (set != OL_SETSEL_NONE) {
|
2020-08-07 11:47:23 -06:00
|
|
|
tree_element_set_active_object(
|
|
|
|
|
C, tvc->scene, tvc->view_layer, space_outliner, te, set, false);
|
2014-01-16 20:22:45 +11:00
|
|
|
}
|
2019-11-02 03:11:56 +11:00
|
|
|
else if (tselem->id == (ID *)tvc->obact) {
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NORMAL;
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
break;
|
2016-12-28 17:30:58 +01:00
|
|
|
case TSE_LINKED_PSYS:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_psys(C, tvc->scene, te, tselem, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_POSE_BASE:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_pose(C, tvc->scene, tvc->view_layer, te, tselem, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_POSE_CHANNEL:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_posechannel(
|
|
|
|
|
C, tvc->scene, tvc->view_layer, tvc->ob_pose, te, tselem, set, recursive);
|
2020-10-28 11:43:10 -06:00
|
|
|
case TSE_CONSTRAINT_BASE:
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_CONSTRAINT:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_constraint(C, tvc->scene, tvc->view_layer, te, tselem, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_R_LAYER:
|
2019-11-02 03:11:56 +11:00
|
|
|
return active_viewlayer(C, tvc->scene, tvc->view_layer, te, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_POSEGRP:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_posegroup(C, tvc->scene, tvc->view_layer, te, tselem, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_SEQUENCE:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_sequence(C, tvc->scene, te, tselem, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_SEQUENCE_DUP:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_sequence_dup(tvc->scene, te, tselem, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
case TSE_KEYMAP_ITEM:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_keymap_item(C, tvc->scene, tvc->view_layer, te, tselem, set);
|
2015-02-07 12:50:22 +13:00
|
|
|
case TSE_GP_LAYER:
|
2019-11-02 03:11:56 +11:00
|
|
|
return tree_element_active_gplayer(C, tvc->scene, te, tselem, set);
|
2015-02-07 12:50:22 +13:00
|
|
|
break;
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
case TSE_VIEW_COLLECTION_BASE:
|
|
|
|
|
return tree_element_active_master_collection(C, te, set);
|
2017-02-27 22:17:19 +01:00
|
|
|
case TSE_LAYER_COLLECTION:
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
return tree_element_active_layer_collection(C, te, set);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
return OL_DRAWSEL_NONE;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
2020-09-15 15:23:08 -06:00
|
|
|
bPoseChannel *outliner_find_parent_bone(TreeElement *te, TreeElement **r_bone_te)
|
|
|
|
|
{
|
|
|
|
|
TreeStoreElem *tselem;
|
|
|
|
|
|
|
|
|
|
te = te->parent;
|
|
|
|
|
while (te) {
|
|
|
|
|
tselem = TREESTORE(te);
|
|
|
|
|
if (tselem->type == TSE_POSE_CHANNEL) {
|
|
|
|
|
*r_bone_te = te;
|
|
|
|
|
return (bPoseChannel *)te->directdata;
|
|
|
|
|
}
|
|
|
|
|
te = te->parent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-21 14:27:09 -07:00
|
|
|
static void outliner_sync_to_properties_editors(const bContext *C,
|
|
|
|
|
PointerRNA *ptr,
|
|
|
|
|
const int context)
|
|
|
|
|
{
|
|
|
|
|
bScreen *screen = CTX_wm_screen(C);
|
|
|
|
|
|
|
|
|
|
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
|
|
|
|
if (area->spacetype != SPACE_PROPERTIES) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SpaceProperties *sbuts = (SpaceProperties *)area->spacedata.first;
|
|
|
|
|
if (ED_buttons_should_sync_with_outliner(C, sbuts, area)) {
|
|
|
|
|
ED_buttons_set_context(C, sbuts, ptr, context);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-28 11:43:10 -06:00
|
|
|
static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreElem *tselem)
|
|
|
|
|
{
|
|
|
|
|
PointerRNA ptr = {0};
|
|
|
|
|
int context = 0;
|
|
|
|
|
|
|
|
|
|
/* ID Types */
|
|
|
|
|
if (tselem->type == 0) {
|
|
|
|
|
RNA_id_pointer_create(tselem->id, &ptr);
|
|
|
|
|
|
|
|
|
|
switch (te->idcode) {
|
|
|
|
|
case ID_SCE:
|
|
|
|
|
context = BCONTEXT_SCENE;
|
|
|
|
|
break;
|
|
|
|
|
case ID_OB:
|
|
|
|
|
context = BCONTEXT_OBJECT;
|
|
|
|
|
break;
|
|
|
|
|
case ID_ME:
|
|
|
|
|
case ID_CU:
|
|
|
|
|
case ID_MB:
|
|
|
|
|
case ID_IM:
|
|
|
|
|
case ID_LT:
|
|
|
|
|
case ID_LA:
|
|
|
|
|
case ID_CA:
|
|
|
|
|
case ID_KE:
|
|
|
|
|
case ID_SPK:
|
|
|
|
|
case ID_AR:
|
|
|
|
|
case ID_GD:
|
|
|
|
|
case ID_LP:
|
|
|
|
|
case ID_HA:
|
|
|
|
|
case ID_PT:
|
|
|
|
|
case ID_VO:
|
|
|
|
|
context = BCONTEXT_DATA;
|
|
|
|
|
break;
|
|
|
|
|
case ID_MA:
|
|
|
|
|
context = BCONTEXT_MATERIAL;
|
|
|
|
|
break;
|
|
|
|
|
case ID_WO:
|
|
|
|
|
context = BCONTEXT_WORLD;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
switch (tselem->type) {
|
|
|
|
|
case TSE_DEFGROUP_BASE:
|
|
|
|
|
case TSE_DEFGROUP:
|
|
|
|
|
RNA_id_pointer_create(tselem->id, &ptr);
|
|
|
|
|
context = BCONTEXT_DATA;
|
|
|
|
|
break;
|
|
|
|
|
case TSE_CONSTRAINT_BASE:
|
|
|
|
|
case TSE_CONSTRAINT: {
|
|
|
|
|
TreeElement *bone_te = NULL;
|
|
|
|
|
bPoseChannel *pchan = outliner_find_parent_bone(te, &bone_te);
|
|
|
|
|
|
|
|
|
|
if (pchan) {
|
|
|
|
|
RNA_pointer_create(TREESTORE(bone_te)->id, &RNA_PoseBone, pchan, &ptr);
|
|
|
|
|
context = BCONTEXT_BONE_CONSTRAINT;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
RNA_id_pointer_create(tselem->id, &ptr);
|
|
|
|
|
context = BCONTEXT_CONSTRAINT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Expand the selected constraint in the properties editor. */
|
|
|
|
|
if (tselem->type != TSE_CONSTRAINT_BASE) {
|
|
|
|
|
BKE_constraint_panel_expand(te->directdata);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case TSE_MODIFIER_BASE:
|
|
|
|
|
case TSE_MODIFIER:
|
|
|
|
|
RNA_id_pointer_create(tselem->id, &ptr);
|
|
|
|
|
context = BCONTEXT_MODIFIER;
|
|
|
|
|
|
|
|
|
|
if (tselem->type != TSE_MODIFIER_BASE) {
|
|
|
|
|
Object *ob = (Object *)tselem->id;
|
|
|
|
|
|
|
|
|
|
if (ob->type == OB_GPENCIL) {
|
|
|
|
|
BKE_gpencil_modifier_panel_expand(te->directdata);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-11-12 16:59:30 -05:00
|
|
|
ModifierData *md = (ModifierData *)te->directdata;
|
2020-12-17 23:35:05 -06:00
|
|
|
BKE_object_modifier_set_active(ob, md);
|
2020-11-12 16:59:30 -05:00
|
|
|
|
|
|
|
|
switch ((ModifierType)md->type) {
|
|
|
|
|
case eModifierType_ParticleSystem:
|
|
|
|
|
context = BCONTEXT_PARTICLE;
|
|
|
|
|
break;
|
|
|
|
|
case eModifierType_Cloth:
|
|
|
|
|
case eModifierType_Softbody:
|
|
|
|
|
case eModifierType_Collision:
|
|
|
|
|
case eModifierType_Fluidsim:
|
|
|
|
|
case eModifierType_DynamicPaint:
|
|
|
|
|
case eModifierType_Fluid:
|
|
|
|
|
context = BCONTEXT_PHYSICS;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (context == BCONTEXT_MODIFIER) {
|
|
|
|
|
BKE_modifier_panel_expand(md);
|
|
|
|
|
}
|
2020-10-28 11:43:10 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case TSE_GPENCIL_EFFECT_BASE:
|
|
|
|
|
case TSE_GPENCIL_EFFECT:
|
|
|
|
|
RNA_id_pointer_create(tselem->id, &ptr);
|
|
|
|
|
context = BCONTEXT_SHADERFX;
|
|
|
|
|
|
|
|
|
|
if (tselem->type != TSE_GPENCIL_EFFECT_BASE) {
|
|
|
|
|
BKE_shaderfx_panel_expand(te->directdata);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case TSE_BONE: {
|
|
|
|
|
bArmature *arm = (bArmature *)tselem->id;
|
|
|
|
|
Bone *bone = te->directdata;
|
|
|
|
|
|
|
|
|
|
RNA_pointer_create(&arm->id, &RNA_Bone, bone, &ptr);
|
|
|
|
|
context = BCONTEXT_BONE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case TSE_EBONE: {
|
|
|
|
|
bArmature *arm = (bArmature *)tselem->id;
|
|
|
|
|
EditBone *ebone = te->directdata;
|
|
|
|
|
|
|
|
|
|
RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &ptr);
|
|
|
|
|
context = BCONTEXT_BONE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case TSE_POSE_CHANNEL: {
|
|
|
|
|
Object *ob = (Object *)tselem->id;
|
|
|
|
|
bArmature *arm = ob->data;
|
|
|
|
|
bPoseChannel *pchan = te->directdata;
|
|
|
|
|
|
|
|
|
|
RNA_pointer_create(&arm->id, &RNA_PoseBone, pchan, &ptr);
|
|
|
|
|
context = BCONTEXT_BONE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case TSE_POSE_BASE: {
|
|
|
|
|
Object *ob = (Object *)tselem->id;
|
|
|
|
|
bArmature *arm = ob->data;
|
|
|
|
|
|
|
|
|
|
RNA_pointer_create(&arm->id, &RNA_Armature, arm, &ptr);
|
|
|
|
|
context = BCONTEXT_DATA;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case TSE_R_LAYER_BASE:
|
|
|
|
|
case TSE_R_LAYER: {
|
|
|
|
|
ViewLayer *view_layer = te->directdata;
|
|
|
|
|
|
|
|
|
|
RNA_pointer_create(tselem->id, &RNA_ViewLayer, view_layer, &ptr);
|
|
|
|
|
context = BCONTEXT_VIEW_LAYER;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case TSE_POSEGRP_BASE:
|
|
|
|
|
case TSE_POSEGRP: {
|
|
|
|
|
Object *ob = (Object *)tselem->id;
|
|
|
|
|
bArmature *arm = ob->data;
|
|
|
|
|
|
|
|
|
|
RNA_pointer_create(&arm->id, &RNA_Armature, arm, &ptr);
|
|
|
|
|
context = BCONTEXT_DATA;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case TSE_LINKED_PSYS: {
|
|
|
|
|
Object *ob = (Object *)tselem->id;
|
|
|
|
|
ParticleSystem *psys = psys_get_current(ob);
|
|
|
|
|
|
|
|
|
|
RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &ptr);
|
|
|
|
|
context = BCONTEXT_PARTICLE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case TSE_GP_LAYER:
|
|
|
|
|
RNA_id_pointer_create(tselem->id, &ptr);
|
|
|
|
|
context = BCONTEXT_DATA;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ptr.data) {
|
2020-12-21 14:27:09 -07:00
|
|
|
outliner_sync_to_properties_editors(C, &ptr, context);
|
2020-10-28 11:43:10 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
/* ================================================ */
|
|
|
|
|
|
2017-11-20 16:01:04 +11:00
|
|
|
/**
|
|
|
|
|
* Action when clicking to activate an item (typically under the mouse cursor),
|
|
|
|
|
* but don't do any cursor intersection checks.
|
|
|
|
|
*
|
|
|
|
|
* Needed to run from operators accessed from a menu.
|
|
|
|
|
*/
|
|
|
|
|
static void do_outliner_item_activate_tree_element(bContext *C,
|
2019-11-02 03:11:56 +11:00
|
|
|
const TreeViewContext *tvc,
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *space_outliner,
|
2017-11-20 16:01:04 +11:00
|
|
|
TreeElement *te,
|
|
|
|
|
TreeStoreElem *tselem,
|
2016-10-16 02:53:11 +02:00
|
|
|
const bool extend,
|
2019-11-01 06:18:08 +11:00
|
|
|
const bool recursive,
|
2020-06-19 12:35:09 -06:00
|
|
|
const bool do_activate_data)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2018-05-30 10:19:09 +02:00
|
|
|
/* Always makes active object, except for some specific types. */
|
|
|
|
|
if (ELEM(tselem->type,
|
|
|
|
|
TSE_SEQUENCE,
|
|
|
|
|
TSE_SEQ_STRIP,
|
|
|
|
|
TSE_SEQUENCE_DUP,
|
|
|
|
|
TSE_EBONE,
|
|
|
|
|
TSE_LAYER_COLLECTION)) {
|
2020-10-28 11:43:10 -06:00
|
|
|
/* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several
|
|
|
|
|
* objects, we do not want to switch out of edit mode (see T48328 for details). */
|
2018-05-30 10:19:09 +02:00
|
|
|
}
|
2019-11-01 06:18:08 +11:00
|
|
|
else if (do_activate_data) {
|
2017-11-20 16:01:04 +11:00
|
|
|
tree_element_set_active_object(C,
|
2019-11-02 03:11:56 +11:00
|
|
|
tvc->scene,
|
|
|
|
|
tvc->view_layer,
|
2020-08-07 11:47:23 -06:00
|
|
|
space_outliner,
|
2017-11-23 13:51:49 -02:00
|
|
|
te,
|
2017-11-20 16:01:04 +11:00
|
|
|
(extend && tselem->type == 0) ? OL_SETSEL_EXTEND :
|
|
|
|
|
OL_SETSEL_NORMAL,
|
|
|
|
|
recursive && tselem->type == 0);
|
2016-10-16 02:53:11 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-07-03 13:31:42 -06:00
|
|
|
if (tselem->type == 0) { /* The lib blocks. */
|
2019-11-01 06:18:08 +11:00
|
|
|
if (do_activate_data == false) {
|
|
|
|
|
/* Only select in outliner. */
|
|
|
|
|
}
|
|
|
|
|
else if (te->idcode == ID_SCE) {
|
2019-11-02 03:11:56 +11:00
|
|
|
if (tvc->scene != (Scene *)tselem->id) {
|
2018-07-03 15:34:26 +02:00
|
|
|
WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), (Scene *)tselem->id);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2020-08-07 11:47:23 -06:00
|
|
|
else if ((te->idcode == ID_GR) && (space_outliner->outlinevis != SO_VIEW_LAYER)) {
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
Collection *gr = (Collection *)tselem->id;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-10-16 02:53:11 +02:00
|
|
|
if (extend) {
|
|
|
|
|
int sel = BA_SELECT;
|
2018-06-11 11:40:26 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (gr, object) {
|
2019-11-02 03:11:56 +11:00
|
|
|
Base *base = BKE_view_layer_base_find(tvc->view_layer, object);
|
2018-06-11 11:40:26 +02:00
|
|
|
if (base && (base->flag & BASE_SELECTED)) {
|
2016-10-16 02:53:11 +02:00
|
|
|
sel = BA_DESELECT;
|
|
|
|
|
break;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-06-11 11:40:26 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (gr, object) {
|
2019-11-02 03:11:56 +11:00
|
|
|
Base *base = BKE_view_layer_base_find(tvc->view_layer, object);
|
2018-06-11 11:40:26 +02:00
|
|
|
if (base) {
|
|
|
|
|
ED_object_base_select(base, sel);
|
2016-10-16 02:53:11 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2013-03-09 03:46:30 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2019-11-02 03:11:56 +11:00
|
|
|
BKE_view_layer_base_deselect_all(tvc->view_layer);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (gr, object) {
|
2019-11-02 03:11:56 +11:00
|
|
|
Base *base = BKE_view_layer_base_find(tvc->view_layer, object);
|
2017-06-29 12:04:43 +10:00
|
|
|
/* Object may not be in this scene */
|
|
|
|
|
if (base != NULL) {
|
|
|
|
|
if ((base->flag & BASE_SELECTED) == 0) {
|
|
|
|
|
ED_object_base_select(base, BA_SELECT);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-02-09 17:51:25 +01:00
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-11-02 03:11:56 +11:00
|
|
|
DEG_id_tag_update(&tvc->scene->id, ID_RECALC_SELECT);
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, tvc->scene);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2020-07-03 13:31:42 -06:00
|
|
|
else { /* Rest of types. */
|
2020-08-07 11:47:23 -06:00
|
|
|
tree_element_active(C, tvc, space_outliner, te, OL_SETSEL_NORMAL, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-01-16 20:22:45 +11:00
|
|
|
}
|
2019-11-01 06:18:08 +11:00
|
|
|
else if (do_activate_data) {
|
2020-08-07 11:47:23 -06:00
|
|
|
tree_element_type_active(C,
|
|
|
|
|
tvc,
|
|
|
|
|
space_outliner,
|
|
|
|
|
te,
|
|
|
|
|
tselem,
|
|
|
|
|
extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
|
|
|
|
|
recursive);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-19 12:35:09 -06:00
|
|
|
/* Select the item using the set flags */
|
|
|
|
|
void outliner_item_select(bContext *C,
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *space_outliner,
|
2020-06-19 12:35:09 -06:00
|
|
|
TreeElement *te,
|
|
|
|
|
const short select_flag)
|
2016-10-16 02:53:11 +02:00
|
|
|
{
|
|
|
|
|
TreeStoreElem *tselem = TREESTORE(te);
|
2020-06-19 12:35:09 -06:00
|
|
|
const bool activate = select_flag & OL_ITEM_ACTIVATE;
|
|
|
|
|
const bool extend = select_flag & OL_ITEM_EXTEND;
|
|
|
|
|
const bool activate_data = select_flag & OL_ITEM_SELECT_DATA;
|
2016-10-16 02:53:11 +02:00
|
|
|
|
2020-06-19 12:35:09 -06:00
|
|
|
/* Clear previous active when activating and clear selection when not extending selection */
|
|
|
|
|
const short clear_flag = (activate ? TSE_ACTIVE : 0) | (extend ? 0 : TSE_SELECTED);
|
|
|
|
|
if (clear_flag) {
|
2020-08-07 11:47:23 -06:00
|
|
|
outliner_flag_set(&space_outliner->tree, clear_flag, false);
|
2020-06-19 12:35:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (select_flag & OL_ITEM_SELECT) {
|
|
|
|
|
tselem->flag |= TSE_SELECTED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
tselem->flag &= ~TSE_SELECTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (activate) {
|
|
|
|
|
TreeViewContext tvc;
|
|
|
|
|
outliner_viewcontext_init(C, &tvc);
|
|
|
|
|
|
|
|
|
|
tselem->flag |= TSE_ACTIVE;
|
|
|
|
|
do_outliner_item_activate_tree_element(C,
|
|
|
|
|
&tvc,
|
2020-08-07 11:47:23 -06:00
|
|
|
space_outliner,
|
2020-06-19 12:35:09 -06:00
|
|
|
te,
|
|
|
|
|
tselem,
|
|
|
|
|
extend,
|
|
|
|
|
select_flag & OL_ITEM_RECURSIVE,
|
2020-08-07 11:47:23 -06:00
|
|
|
activate_data || space_outliner->flag & SO_SYNC_SELECT);
|
2016-10-16 02:53:11 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-19 17:04:30 -06:00
|
|
|
static bool do_outliner_range_select_recursive(ListBase *lb,
|
2019-08-09 14:12:29 -06:00
|
|
|
TreeElement *active,
|
|
|
|
|
TreeElement *cursor,
|
2019-08-19 17:04:30 -06:00
|
|
|
bool selecting)
|
2019-08-09 14:12:29 -06:00
|
|
|
{
|
2020-04-03 19:15:01 +02:00
|
|
|
LISTBASE_FOREACH (TreeElement *, te, lb) {
|
2019-08-19 17:04:30 -06:00
|
|
|
TreeStoreElem *tselem = TREESTORE(te);
|
|
|
|
|
|
|
|
|
|
if (selecting) {
|
|
|
|
|
tselem->flag |= TSE_SELECTED;
|
2019-08-09 14:12:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set state for selection */
|
2020-11-06 12:30:59 +11:00
|
|
|
if (ELEM(te, active, cursor)) {
|
2019-08-19 17:04:30 -06:00
|
|
|
selecting = !selecting;
|
2019-08-09 14:12:29 -06:00
|
|
|
}
|
|
|
|
|
|
2019-08-19 17:04:30 -06:00
|
|
|
if (selecting) {
|
|
|
|
|
tselem->flag |= TSE_SELECTED;
|
2019-08-09 14:12:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Don't look inside closed elements */
|
2019-08-19 17:04:30 -06:00
|
|
|
if (!(tselem->flag & TSE_CLOSED)) {
|
|
|
|
|
selecting = do_outliner_range_select_recursive(&te->subtree, active, cursor, selecting);
|
2019-08-09 14:12:29 -06:00
|
|
|
}
|
|
|
|
|
}
|
2019-08-19 17:04:30 -06:00
|
|
|
|
|
|
|
|
return selecting;
|
2019-08-09 14:12:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Select a range of items between cursor and active element */
|
2019-08-17 17:06:02 -06:00
|
|
|
static void do_outliner_range_select(bContext *C,
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *space_outliner,
|
2019-08-17 17:06:02 -06:00
|
|
|
TreeElement *cursor,
|
|
|
|
|
const bool extend)
|
2019-08-09 14:12:29 -06:00
|
|
|
{
|
2020-08-07 11:47:23 -06:00
|
|
|
TreeElement *active = outliner_find_element_with_flag(&space_outliner->tree, TSE_ACTIVE);
|
2019-08-09 14:12:29 -06:00
|
|
|
|
2019-08-19 17:04:30 -06:00
|
|
|
/* If no active element exists, activate the element under the cursor */
|
2019-08-09 14:12:29 -06:00
|
|
|
if (!active) {
|
2020-08-07 11:47:23 -06:00
|
|
|
outliner_item_select(C, space_outliner, cursor, OL_ITEM_SELECT | OL_ITEM_ACTIVATE);
|
2019-08-09 14:12:29 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TreeStoreElem *tselem = TREESTORE(active);
|
|
|
|
|
const bool active_selected = (tselem->flag & TSE_SELECTED);
|
|
|
|
|
|
2019-08-17 17:06:02 -06:00
|
|
|
if (!extend) {
|
2020-08-07 11:47:23 -06:00
|
|
|
outliner_flag_set(&space_outliner->tree, TSE_SELECTED, false);
|
2019-08-17 17:06:02 -06:00
|
|
|
}
|
2019-08-09 14:12:29 -06:00
|
|
|
|
|
|
|
|
/* Select active if under cursor */
|
|
|
|
|
if (active == cursor) {
|
2020-08-07 11:47:23 -06:00
|
|
|
outliner_item_select(C, space_outliner, cursor, OL_ITEM_SELECT);
|
2019-08-09 14:12:29 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-19 12:35:09 -06:00
|
|
|
/* If active is not selected or visible, select and activate the element under the cursor */
|
2019-08-09 14:12:29 -06:00
|
|
|
if (!active_selected || !outliner_is_element_visible(active)) {
|
2020-08-07 11:47:23 -06:00
|
|
|
outliner_item_select(C, space_outliner, cursor, OL_ITEM_SELECT | OL_ITEM_ACTIVATE);
|
2019-08-09 14:12:29 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
do_outliner_range_select_recursive(&space_outliner->tree, active, cursor, false);
|
2019-08-09 14:12:29 -06:00
|
|
|
}
|
|
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
static bool outliner_is_co_within_restrict_columns(const SpaceOutliner *space_outliner,
|
2020-03-06 16:56:42 +01:00
|
|
|
const ARegion *region,
|
2019-02-16 09:47:19 +11:00
|
|
|
float view_co_x)
|
2016-10-16 02:53:11 +02:00
|
|
|
{
|
2020-08-07 11:47:23 -06:00
|
|
|
return (view_co_x > region->v2d.cur.xmax - outliner_restrict_columns_width(space_outliner));
|
2016-10-16 02:53:11 +02:00
|
|
|
}
|
|
|
|
|
|
2020-09-10 08:35:58 -06:00
|
|
|
bool outliner_is_co_within_mode_column(SpaceOutliner *space_outliner, const float view_mval[2])
|
|
|
|
|
{
|
|
|
|
|
/* Mode toggles only show in View Layer and Scenes modes. */
|
|
|
|
|
if (!ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return space_outliner->flag & SO_MODE_COLUMN && view_mval[0] < UI_UNIT_X;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-10 17:21:11 -07:00
|
|
|
static bool outliner_is_co_within_active_mode_column(bContext *C,
|
|
|
|
|
SpaceOutliner *space_outliner,
|
|
|
|
|
const float view_mval[2])
|
|
|
|
|
{
|
|
|
|
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
|
|
|
|
Object *obact = OBACT(view_layer);
|
|
|
|
|
|
|
|
|
|
return outliner_is_co_within_mode_column(space_outliner, view_mval) && obact &&
|
|
|
|
|
obact->mode != OB_MODE_OBJECT;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-20 16:01:04 +11:00
|
|
|
/**
|
|
|
|
|
* Action to run when clicking in the outliner,
|
|
|
|
|
*
|
|
|
|
|
* May expend/collapse branches or activate items.
|
|
|
|
|
* */
|
2019-04-29 14:49:25 +02:00
|
|
|
static int outliner_item_do_activate_from_cursor(bContext *C,
|
|
|
|
|
const int mval[2],
|
2019-04-29 15:09:31 +02:00
|
|
|
const bool extend,
|
2019-08-09 14:12:29 -06:00
|
|
|
const bool use_range,
|
2019-04-29 15:09:31 +02:00
|
|
|
const bool deselect_all)
|
2011-07-11 10:59:53 +00:00
|
|
|
{
|
2020-03-06 16:56:42 +01:00
|
|
|
ARegion *region = CTX_wm_region(C);
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
|
2011-07-11 10:59:53 +00:00
|
|
|
TreeElement *te;
|
2016-10-16 02:53:11 +02:00
|
|
|
float view_mval[2];
|
2016-10-16 21:41:10 +02:00
|
|
|
bool changed = false, rebuild_tree = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
UI_view2d_region_to_view(®ion->v2d, mval[0], mval[1], &view_mval[0], &view_mval[1]);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
if (outliner_is_co_within_restrict_columns(space_outliner, region, view_mval[0])) {
|
2011-07-11 10:59:53 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2011-12-22 00:03:20 +00:00
|
|
|
}
|
2020-11-10 17:21:11 -07:00
|
|
|
if (outliner_is_co_within_active_mode_column(C, space_outliner, view_mval)) {
|
2020-09-10 08:35:58 -06:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
if (!(te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_mval[1]))) {
|
2019-04-29 15:09:31 +02:00
|
|
|
if (deselect_all) {
|
2020-08-07 11:47:23 -06:00
|
|
|
outliner_flag_set(&space_outliner->tree, TSE_SELECTED, false);
|
2019-04-29 15:09:31 +02:00
|
|
|
changed = true;
|
|
|
|
|
}
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-08-09 14:12:29 -06:00
|
|
|
/* Don't allow toggle on scene collection */
|
2019-08-08 22:00:57 -06:00
|
|
|
else if ((TREESTORE(te)->type != TSE_VIEW_COLLECTION_BASE) &&
|
|
|
|
|
outliner_item_is_co_within_close_toggle(te, view_mval[0])) {
|
|
|
|
|
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2020-07-03 13:31:42 -06:00
|
|
|
/* The row may also contain children, if one is hovered we want this instead of current te. */
|
2019-08-08 15:37:32 -06:00
|
|
|
bool merged_elements = false;
|
2020-11-26 13:30:31 -07:00
|
|
|
bool is_over_icon = false;
|
2019-08-08 15:37:32 -06:00
|
|
|
TreeElement *activate_te = outliner_find_item_at_x_in_row(
|
2020-11-26 13:30:31 -07:00
|
|
|
space_outliner, te, view_mval[0], &merged_elements, &is_over_icon);
|
2020-11-23 15:58:56 -07:00
|
|
|
|
2019-08-08 15:37:32 -06:00
|
|
|
/* If the selected icon was an aggregate of multiple elements, run the search popup */
|
|
|
|
|
if (merged_elements) {
|
|
|
|
|
merged_element_search_menu_invoke(C, te, activate_te);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-20 20:45:03 +11:00
|
|
|
TreeStoreElem *activate_tselem = TREESTORE(activate_te);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-08-09 14:12:29 -06:00
|
|
|
if (use_range) {
|
2020-08-07 11:47:23 -06:00
|
|
|
do_outliner_range_select(C, space_outliner, activate_te, extend);
|
2019-08-09 14:12:29 -06:00
|
|
|
}
|
|
|
|
|
else {
|
2019-11-01 06:18:08 +11:00
|
|
|
const bool is_over_name_icons = outliner_item_is_co_over_name_icons(activate_te,
|
|
|
|
|
view_mval[0]);
|
2020-06-19 12:35:09 -06:00
|
|
|
/* Always select unless already active and selected */
|
|
|
|
|
const bool select = !extend || !(activate_tselem->flag & TSE_ACTIVE &&
|
|
|
|
|
activate_tselem->flag & TSE_SELECTED);
|
|
|
|
|
|
|
|
|
|
const short select_flag = OL_ITEM_ACTIVATE | (select ? OL_ITEM_SELECT : OL_ITEM_DESELECT) |
|
|
|
|
|
(is_over_name_icons ? OL_ITEM_SELECT_DATA : 0) |
|
2020-09-10 08:35:58 -06:00
|
|
|
(extend ? OL_ITEM_EXTEND : 0);
|
2020-06-19 12:35:09 -06:00
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
outliner_item_select(C, space_outliner, activate_te, select_flag);
|
2020-11-23 15:58:56 -07:00
|
|
|
|
|
|
|
|
/* Only switch properties editor tabs when icons are selected. */
|
2020-11-26 13:30:31 -07:00
|
|
|
if (is_over_icon) {
|
2020-11-23 15:58:56 -07:00
|
|
|
outliner_set_properties_tab(C, activate_te, activate_tselem);
|
|
|
|
|
}
|
2019-08-09 14:12:29 -06:00
|
|
|
}
|
|
|
|
|
|
2016-10-16 02:53:11 +02:00
|
|
|
changed = true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-10-16 02:53:11 +02:00
|
|
|
if (changed) {
|
2018-05-15 12:49:38 +02:00
|
|
|
if (rebuild_tree) {
|
2020-03-06 16:56:42 +01:00
|
|
|
ED_region_tag_redraw(region);
|
2018-05-15 12:49:38 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2020-03-06 16:56:42 +01:00
|
|
|
ED_region_tag_redraw_no_rebuild(region);
|
2016-10-16 21:41:10 +02:00
|
|
|
}
|
2019-08-07 22:27:07 -06:00
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
ED_outliner_select_sync_from_outliner(C, space_outliner);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-10 17:19:03 +00:00
|
|
|
/* event can enterkey, then it opens/closes */
|
2016-10-16 02:53:11 +02:00
|
|
|
static int outliner_item_activate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2013-03-10 17:19:03 +00:00
|
|
|
{
|
2019-04-29 15:09:31 +02:00
|
|
|
const bool extend = RNA_boolean_get(op->ptr, "extend");
|
2019-08-09 14:12:29 -06:00
|
|
|
const bool use_range = RNA_boolean_get(op->ptr, "extend_range");
|
2019-04-29 15:09:31 +02:00
|
|
|
const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
|
2019-08-09 14:12:29 -06:00
|
|
|
return outliner_item_do_activate_from_cursor(C, event->mval, extend, use_range, deselect_all);
|
2013-03-10 17:19:03 +00:00
|
|
|
}
|
|
|
|
|
|
2011-07-11 10:59:53 +00:00
|
|
|
void OUTLINER_OT_item_activate(wmOperatorType *ot)
|
|
|
|
|
{
|
2018-06-27 17:07:02 +02:00
|
|
|
ot->name = "Select";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "OUTLINER_OT_item_activate";
|
2018-06-27 17:07:02 +02:00
|
|
|
ot->description = "Handle mouse clicks to select and activate items";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-10-16 02:53:11 +02:00
|
|
|
ot->invoke = outliner_item_activate_invoke;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = ED_operator_outliner_active;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-08-19 08:58:13 -06:00
|
|
|
ot->flag |= OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
|
|
2019-04-29 17:01:05 +02:00
|
|
|
PropertyRNA *prop;
|
2013-03-09 15:51:36 +00:00
|
|
|
RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection for activation");
|
2019-08-09 14:12:29 -06:00
|
|
|
prop = RNA_def_boolean(
|
|
|
|
|
ot->srna, "extend_range", false, "Extend Range", "Select a range from active element");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
|
|
2019-04-29 17:01:05 +02:00
|
|
|
prop = RNA_def_boolean(ot->srna,
|
|
|
|
|
"deselect_all",
|
|
|
|
|
false,
|
|
|
|
|
"Deselect On Nothing",
|
|
|
|
|
"Deselect all when nothing under the cursor");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2011-07-11 10:59:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ****************************************************** */
|
2012-01-18 21:12:51 +00:00
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
/* **************** Box Select Tool ****************** */
|
2020-08-07 11:47:23 -06:00
|
|
|
static void outliner_item_box_select(bContext *C,
|
|
|
|
|
SpaceOutliner *space_outliner,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
rctf *rectf,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
bool select)
|
2012-01-18 21:12:51 +00:00
|
|
|
{
|
2012-05-07 17:56:30 +00:00
|
|
|
TreeStoreElem *tselem = TREESTORE(te);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-01-18 21:12:51 +00:00
|
|
|
if (te->ys <= rectf->ymax && te->ys + UI_UNIT_Y >= rectf->ymin) {
|
2020-06-19 12:35:09 -06:00
|
|
|
outliner_item_select(
|
2020-08-07 11:47:23 -06:00
|
|
|
C, space_outliner, te, (select ? OL_ITEM_SELECT : OL_ITEM_DESELECT) | OL_ITEM_EXTEND);
|
2012-01-18 21:12:51 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-01-18 21:12:51 +00:00
|
|
|
/* Look at its children. */
|
2020-08-07 11:47:23 -06:00
|
|
|
if (TSELEM_OPEN(tselem, space_outliner)) {
|
2020-09-29 17:08:32 -05:00
|
|
|
LISTBASE_FOREACH (TreeElement *, te_sub, &te->subtree) {
|
|
|
|
|
outliner_item_box_select(C, space_outliner, scene, rectf, te_sub, select);
|
2012-01-18 21:12:51 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
static int outliner_box_select_exec(bContext *C, wmOperator *op)
|
2012-01-18 21:12:51 +00:00
|
|
|
{
|
2012-05-07 17:56:30 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
|
2020-03-06 16:56:42 +01:00
|
|
|
ARegion *region = CTX_wm_region(C);
|
2012-01-18 21:12:51 +00:00
|
|
|
rctf rectf;
|
2019-03-07 20:33:57 +11:00
|
|
|
|
|
|
|
|
const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
|
|
|
|
|
const bool select = (sel_op != SEL_OP_SUB);
|
|
|
|
|
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
|
2020-08-07 11:47:23 -06:00
|
|
|
outliner_flag_set(&space_outliner->tree, TSE_SELECTED, 0);
|
2019-03-07 20:33:57 +11:00
|
|
|
}
|
2012-01-18 21:12:51 +00:00
|
|
|
|
2014-04-21 16:47:16 +10:00
|
|
|
WM_operator_properties_border_to_rctf(op, &rectf);
|
2020-03-06 16:56:42 +01:00
|
|
|
UI_view2d_region_to_view_rctf(®ion->v2d, &rectf, &rectf);
|
2012-01-18 21:12:51 +00:00
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
LISTBASE_FOREACH (TreeElement *, te, &space_outliner->tree) {
|
|
|
|
|
outliner_item_box_select(C, space_outliner, scene, &rectf, te, select);
|
2012-01-18 21:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
2012-05-07 17:56:30 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
|
2020-08-20 20:17:00 +02:00
|
|
|
ED_region_tag_redraw_no_rebuild(region);
|
2012-01-18 21:12:51 +00:00
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
ED_outliner_select_sync_from_outliner(C, space_outliner);
|
2019-08-07 22:27:07 -06:00
|
|
|
|
2012-01-18 21:12:51 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-09 14:00:49 -06:00
|
|
|
static int outliner_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|
|
|
|
{
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
|
2020-03-06 16:56:42 +01:00
|
|
|
ARegion *region = CTX_wm_region(C);
|
2019-08-09 14:00:49 -06:00
|
|
|
float view_mval[2];
|
|
|
|
|
const bool tweak = RNA_boolean_get(op->ptr, "tweak");
|
|
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
UI_view2d_region_to_view(
|
|
|
|
|
®ion->v2d, event->mval[0], event->mval[1], &view_mval[0], &view_mval[1]);
|
2019-08-09 14:00:49 -06:00
|
|
|
|
|
|
|
|
/* Find element clicked on */
|
2020-08-07 11:47:23 -06:00
|
|
|
TreeElement *te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_mval[1]);
|
2019-08-09 14:00:49 -06:00
|
|
|
|
|
|
|
|
/* Pass through if click is over name or icons, or not tweak event */
|
|
|
|
|
if (te && tweak && outliner_item_is_co_over_name_icons(te, view_mval[0])) {
|
|
|
|
|
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-10 17:21:11 -07:00
|
|
|
if (outliner_is_co_within_active_mode_column(C, space_outliner, view_mval)) {
|
2020-09-10 08:35:58 -06:00
|
|
|
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-09 14:00:49 -06:00
|
|
|
return WM_gesture_box_invoke(C, op, event);
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
void OUTLINER_OT_select_box(wmOperatorType *ot)
|
2012-01-18 21:12:51 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2018-10-05 10:27:04 +10:00
|
|
|
ot->name = "Box Select";
|
|
|
|
|
ot->idname = "OUTLINER_OT_select_box";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->description = "Use box selection to select tree elements";
|
2012-01-18 21:12:51 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2019-08-09 14:00:49 -06:00
|
|
|
ot->invoke = outliner_box_select_invoke;
|
2018-10-05 10:27:04 +10:00
|
|
|
ot->exec = outliner_box_select_exec;
|
|
|
|
|
ot->modal = WM_gesture_box_modal;
|
|
|
|
|
ot->cancel = WM_gesture_box_cancel;
|
2012-01-18 21:12:51 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = ED_operator_outliner_active;
|
2012-01-18 21:12:51 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2012-05-07 17:56:30 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2012-01-18 21:12:51 +00:00
|
|
|
|
2019-03-07 20:33:57 +11:00
|
|
|
/* properties */
|
2019-08-09 14:00:49 -06:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
|
|
|
|
prop = RNA_def_boolean(
|
|
|
|
|
ot->srna, "tweak", false, "Tweak", "Tweak gesture from empty space for box selection");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
|
|
2019-03-07 20:33:57 +11:00
|
|
|
WM_operator_properties_gesture_box(ot);
|
|
|
|
|
WM_operator_properties_select_operation_simple(ot);
|
2012-01-18 21:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ****************************************************** */
|
2019-08-08 22:00:57 -06:00
|
|
|
|
|
|
|
|
/* **************** Walk Select Tool ****************** */
|
|
|
|
|
|
|
|
|
|
/* Given a tree element return the rightmost child that is visible in the outliner */
|
2020-08-07 11:47:23 -06:00
|
|
|
static TreeElement *outliner_find_rightmost_visible_child(SpaceOutliner *space_outliner,
|
|
|
|
|
TreeElement *te)
|
2019-08-08 22:00:57 -06:00
|
|
|
{
|
|
|
|
|
while (te->subtree.last) {
|
2020-08-07 11:47:23 -06:00
|
|
|
if (TSELEM_OPEN(TREESTORE(te), space_outliner)) {
|
2019-08-08 22:00:57 -06:00
|
|
|
te = te->subtree.last;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return te;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find previous visible element in the tree */
|
2020-08-07 11:47:23 -06:00
|
|
|
static TreeElement *outliner_find_previous_element(SpaceOutliner *space_outliner, TreeElement *te)
|
2019-08-08 22:00:57 -06:00
|
|
|
{
|
2020-06-20 16:03:55 -06:00
|
|
|
if (te->prev) {
|
2020-08-07 11:47:23 -06:00
|
|
|
te = outliner_find_rightmost_visible_child(space_outliner, te->prev);
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
2020-06-20 16:03:55 -06:00
|
|
|
else if (te->parent) {
|
2019-08-08 22:00:57 -06:00
|
|
|
/* Use parent if at beginning of list */
|
2020-06-20 16:03:55 -06:00
|
|
|
te = te->parent;
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
|
2020-06-20 16:03:55 -06:00
|
|
|
return te;
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Recursively search up the tree until a successor to a given element is found */
|
|
|
|
|
static TreeElement *outliner_element_find_successor_in_parents(TreeElement *te)
|
|
|
|
|
{
|
|
|
|
|
TreeElement *successor = te;
|
|
|
|
|
while (successor->parent) {
|
|
|
|
|
if (successor->parent->next) {
|
|
|
|
|
te = successor->parent->next;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-07-03 17:20:22 +02:00
|
|
|
successor = successor->parent;
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return te;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Find next visible element in the tree */
|
2020-08-07 11:47:23 -06:00
|
|
|
static TreeElement *outliner_find_next_element(SpaceOutliner *space_outliner, TreeElement *te)
|
2019-08-08 22:00:57 -06:00
|
|
|
{
|
2020-06-20 16:03:55 -06:00
|
|
|
TreeStoreElem *tselem = TREESTORE(te);
|
2019-08-08 22:00:57 -06:00
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
if (TSELEM_OPEN(tselem, space_outliner) && te->subtree.first) {
|
2020-06-20 16:03:55 -06:00
|
|
|
te = te->subtree.first;
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
2020-06-20 16:03:55 -06:00
|
|
|
else if (te->next) {
|
|
|
|
|
te = te->next;
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
else {
|
2020-06-20 16:03:55 -06:00
|
|
|
te = outliner_element_find_successor_in_parents(te);
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
|
2020-06-20 16:03:55 -06:00
|
|
|
return te;
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
|
2020-08-26 10:58:23 -06:00
|
|
|
static TreeElement *outliner_walk_left(SpaceOutliner *space_outliner,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
bool toggle_all)
|
|
|
|
|
{
|
|
|
|
|
TreeStoreElem *tselem = TREESTORE(te);
|
|
|
|
|
|
|
|
|
|
if (TSELEM_OPEN(tselem, space_outliner)) {
|
2020-08-27 09:41:05 -06:00
|
|
|
outliner_item_openclose(space_outliner, te, false, toggle_all);
|
2020-08-26 10:58:23 -06:00
|
|
|
}
|
|
|
|
|
/* Only walk up a level if the element is closed and not toggling expand */
|
|
|
|
|
else if (!toggle_all && te->parent) {
|
|
|
|
|
te = te->parent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return te;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static TreeElement *outliner_walk_right(SpaceOutliner *space_outliner,
|
|
|
|
|
TreeElement *te,
|
|
|
|
|
bool toggle_all)
|
|
|
|
|
{
|
|
|
|
|
TreeStoreElem *tselem = TREESTORE(te);
|
|
|
|
|
|
|
|
|
|
/* Only walk down a level if the element is open and not toggling expand */
|
|
|
|
|
if (!toggle_all && TSELEM_OPEN(tselem, space_outliner) && !BLI_listbase_is_empty(&te->subtree)) {
|
|
|
|
|
te = te->subtree.first;
|
|
|
|
|
}
|
2020-08-27 09:41:05 -06:00
|
|
|
else {
|
|
|
|
|
outliner_item_openclose(space_outliner, te, true, toggle_all);
|
2020-08-26 10:58:23 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return te;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
static TreeElement *do_outliner_select_walk(SpaceOutliner *space_outliner,
|
2020-06-20 16:02:54 -06:00
|
|
|
TreeElement *te,
|
2019-08-08 22:00:57 -06:00
|
|
|
const int direction,
|
|
|
|
|
const bool extend,
|
|
|
|
|
const bool toggle_all)
|
|
|
|
|
{
|
2020-06-20 16:02:54 -06:00
|
|
|
TreeStoreElem *tselem = TREESTORE(te);
|
2019-08-08 22:00:57 -06:00
|
|
|
|
|
|
|
|
switch (direction) {
|
2020-03-02 16:05:59 +01:00
|
|
|
case UI_SELECT_WALK_UP:
|
2020-08-07 11:47:23 -06:00
|
|
|
te = outliner_find_previous_element(space_outliner, te);
|
2019-08-08 22:00:57 -06:00
|
|
|
break;
|
2020-03-02 16:05:59 +01:00
|
|
|
case UI_SELECT_WALK_DOWN:
|
2020-08-07 11:47:23 -06:00
|
|
|
te = outliner_find_next_element(space_outliner, te);
|
2019-08-08 22:00:57 -06:00
|
|
|
break;
|
2020-03-02 16:05:59 +01:00
|
|
|
case UI_SELECT_WALK_LEFT:
|
2020-08-26 10:58:23 -06:00
|
|
|
te = outliner_walk_left(space_outliner, te, toggle_all);
|
2019-08-08 22:00:57 -06:00
|
|
|
break;
|
2020-03-02 16:05:59 +01:00
|
|
|
case UI_SELECT_WALK_RIGHT:
|
2020-08-26 10:58:23 -06:00
|
|
|
te = outliner_walk_right(space_outliner, te, toggle_all);
|
2019-08-08 22:00:57 -06:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If new element is already selected, deselect the previous element */
|
2020-06-20 16:02:54 -06:00
|
|
|
TreeStoreElem *tselem_new = TREESTORE(te);
|
2019-08-08 22:00:57 -06:00
|
|
|
if (extend) {
|
|
|
|
|
tselem->flag = (tselem_new->flag & TSE_SELECTED) ? (tselem->flag & ~TSE_SELECTED) :
|
|
|
|
|
(tselem->flag | TSE_SELECTED);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-20 16:02:54 -06:00
|
|
|
return te;
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
|
2020-06-20 16:02:54 -06:00
|
|
|
/* Find the active element to walk from, or set one if none exists.
|
2020-06-30 20:54:31 +10:00
|
|
|
* Changed is set to true if the active element is found, or false if it was set */
|
2020-08-07 11:47:23 -06:00
|
|
|
static TreeElement *find_walk_select_start_element(SpaceOutliner *space_outliner, bool *changed)
|
2019-08-08 22:00:57 -06:00
|
|
|
{
|
2020-08-07 11:47:23 -06:00
|
|
|
TreeElement *active_te = outliner_find_element_with_flag(&space_outliner->tree, TSE_ACTIVE);
|
2019-08-08 22:00:57 -06:00
|
|
|
*changed = false;
|
|
|
|
|
|
2020-06-20 16:02:54 -06:00
|
|
|
/* If no active element exists, use the first element in the tree */
|
|
|
|
|
if (!active_te) {
|
2020-08-07 11:47:23 -06:00
|
|
|
active_te = space_outliner->tree.first;
|
2019-08-08 22:00:57 -06:00
|
|
|
*changed = true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-20 16:02:54 -06:00
|
|
|
/* If the active element is not visible, activate the first visible parent element */
|
|
|
|
|
if (!outliner_is_element_visible(active_te)) {
|
|
|
|
|
while (!outliner_is_element_visible(active_te)) {
|
|
|
|
|
active_te = active_te->parent;
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
*changed = true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-20 16:02:54 -06:00
|
|
|
return active_te;
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Scroll the outliner when the walk element reaches the top or bottom boundary */
|
2020-11-10 13:53:05 +01:00
|
|
|
static void outliner_walk_scroll(SpaceOutliner *space_outliner, ARegion *region, TreeElement *te)
|
2019-08-08 22:00:57 -06:00
|
|
|
{
|
|
|
|
|
/* Account for the header height */
|
2020-03-06 16:56:42 +01:00
|
|
|
int y_max = region->v2d.cur.ymax - UI_UNIT_Y;
|
|
|
|
|
int y_min = region->v2d.cur.ymin;
|
2019-08-08 22:00:57 -06:00
|
|
|
|
|
|
|
|
/* Scroll if walked position is beyond the border */
|
|
|
|
|
if (te->ys > y_max) {
|
2020-11-10 13:53:05 +01:00
|
|
|
outliner_scroll_view(space_outliner, region, te->ys - y_max);
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
else if (te->ys < y_min) {
|
2020-11-10 13:53:05 +01:00
|
|
|
outliner_scroll_view(space_outliner, region, -(y_min - te->ys));
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int outliner_walk_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
|
|
|
|
{
|
2020-08-07 11:47:23 -06:00
|
|
|
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
|
2020-03-06 16:56:42 +01:00
|
|
|
ARegion *region = CTX_wm_region(C);
|
2019-08-08 22:00:57 -06:00
|
|
|
|
|
|
|
|
const short direction = RNA_enum_get(op->ptr, "direction");
|
|
|
|
|
const bool extend = RNA_boolean_get(op->ptr, "extend");
|
|
|
|
|
const bool toggle_all = RNA_boolean_get(op->ptr, "toggle_all");
|
|
|
|
|
|
|
|
|
|
bool changed;
|
2020-08-07 11:47:23 -06:00
|
|
|
TreeElement *active_te = find_walk_select_start_element(space_outliner, &changed);
|
2019-08-08 22:00:57 -06:00
|
|
|
|
2020-06-20 16:02:54 -06:00
|
|
|
/* If finding the active element did not modify the selection, proceed to walk */
|
2019-08-08 22:00:57 -06:00
|
|
|
if (!changed) {
|
2020-08-07 11:47:23 -06:00
|
|
|
active_te = do_outliner_select_walk(space_outliner, active_te, direction, extend, toggle_all);
|
2019-08-08 22:00:57 -06:00
|
|
|
}
|
|
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
outliner_item_select(C,
|
|
|
|
|
space_outliner,
|
|
|
|
|
active_te,
|
|
|
|
|
OL_ITEM_SELECT | OL_ITEM_ACTIVATE | (extend ? OL_ITEM_EXTEND : 0));
|
2020-06-20 16:02:54 -06:00
|
|
|
|
2019-08-08 22:00:57 -06:00
|
|
|
/* Scroll outliner to focus on walk element */
|
2020-11-10 13:53:05 +01:00
|
|
|
outliner_walk_scroll(space_outliner, region, active_te);
|
2019-08-08 22:00:57 -06:00
|
|
|
|
2020-08-07 11:47:23 -06:00
|
|
|
ED_outliner_select_sync_from_outliner(C, space_outliner);
|
2020-08-20 20:17:00 +02:00
|
|
|
outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region);
|
2019-08-08 22:00:57 -06:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OUTLINER_OT_select_walk(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Walk Select";
|
|
|
|
|
ot->idname = "OUTLINER_OT_select_walk";
|
|
|
|
|
ot->description = "Use walk navigation to select tree elements";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->invoke = outliner_walk_select_invoke;
|
|
|
|
|
ot->poll = ED_operator_outliner_active;
|
|
|
|
|
|
2019-08-19 08:58:13 -06:00
|
|
|
ot->flag |= OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
|
|
2019-08-08 22:00:57 -06:00
|
|
|
/* properties */
|
|
|
|
|
PropertyRNA *prop;
|
2020-03-02 16:05:59 +01:00
|
|
|
WM_operator_properties_select_walk_direction(ot);
|
2019-08-08 22:00:57 -06:00
|
|
|
prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection on walk");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
|
prop = RNA_def_boolean(
|
|
|
|
|
ot->srna, "toggle_all", false, "Toggle All", "Toggle open/close hierarchy");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ****************************************************** */
|