GPv3: Outliner support #111105
|
@ -55,11 +55,13 @@ set(SRC
|
|||
tree/tree_element_edit_bone.cc
|
||||
tree/tree_element_gpencil_effect.cc
|
||||
tree/tree_element_gpencil_layer.cc
|
||||
tree/tree_element_grease_pencil_node.cc
|
||||
tree/tree_element_id.cc
|
||||
tree/tree_element_id_armature.cc
|
||||
tree/tree_element_id_collection.cc
|
||||
tree/tree_element_id_curve.cc
|
||||
tree/tree_element_id_gpencil_legacy.cc
|
||||
tree/tree_element_id_grease_pencil.cc
|
||||
tree/tree_element_id_library.cc
|
||||
tree/tree_element_id_linestyle.cc
|
||||
tree/tree_element_id_mesh.cc
|
||||
|
@ -90,12 +92,14 @@ set(SRC
|
|||
tree/tree_element_driver.hh
|
||||
tree/tree_element_edit_bone.hh
|
||||
tree/tree_element_gpencil_layer.hh
|
||||
tree/tree_element_grease_pencil_node.hh
|
||||
tree/tree_element_id.hh
|
||||
tree/tree_element_id_armature.hh
|
||||
tree/tree_element_id_collection.hh
|
||||
tree/tree_element_id_curve.hh
|
||||
tree/tree_element_gpencil_effect.hh
|
||||
tree/tree_element_id_gpencil_legacy.hh
|
||||
tree/tree_element_id_grease_pencil.hh
|
||||
tree/tree_element_id_library.hh
|
||||
tree/tree_element_id_linestyle.hh
|
||||
tree/tree_element_id_mesh.hh
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "BKE_curve.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -69,6 +70,7 @@
|
|||
#include "outliner_intern.hh"
|
||||
#include "tree/tree_display.hh"
|
||||
#include "tree/tree_element.hh"
|
||||
#include "tree/tree_element_grease_pencil_node.hh"
|
||||
#include "tree/tree_element_id.hh"
|
||||
#include "tree/tree_element_overrides.hh"
|
||||
#include "tree/tree_element_rna.hh"
|
||||
|
@ -850,6 +852,26 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname)
|
|||
DEG_id_tag_update(tselem->id, ID_RECALC_COPY_ON_WRITE);
|
||||
break;
|
||||
}
|
||||
case TSE_GREASE_PENCIL_NODE: {
|
||||
GreasePencil &grease_pencil = *(GreasePencil *)tselem->id;
|
||||
bke::greasepencil::TreeNode &node =
|
||||
tree_element_cast<TreeElementGreasePencilNode>(te)->node();
|
||||
|
||||
/* The node already has the new name set. To properly rename the node, we need to first
|
||||
* store the new name, restore the old name in the node, and then call the rename
|
||||
* function. */
|
||||
std::string new_name(node.name);
|
||||
node.name = oldname;
|
||||
if (node.is_group()) {
|
||||
grease_pencil.rename_group(node.as_group_for_write(), new_name);
|
||||
}
|
||||
else if (node.is_layer()) {
|
||||
grease_pencil.rename_layer(node.as_layer_for_write(), new_name);
|
||||
}
|
||||
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_COPY_ON_WRITE);
|
||||
WM_event_add_notifier(C, NC_ID | NA_RENAME, nullptr);
|
||||
break;
|
||||
}
|
||||
case TSE_R_LAYER: {
|
||||
Scene *scene = (Scene *)tselem->id;
|
||||
ViewLayer *view_layer = static_cast<ViewLayer *>(te->directdata);
|
||||
|
@ -1489,6 +1511,43 @@ static void outliner_draw_restrictbuts(uiBlock *block,
|
|||
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
|
||||
}
|
||||
}
|
||||
else if (tselem->type == TSE_GREASE_PENCIL_NODE) {
|
||||
bke::greasepencil::TreeNode &node =
|
||||
tree_element_cast<TreeElementGreasePencilNode>(te)->node();
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *hide_prop;
|
||||
if (node.is_layer()) {
|
||||
RNA_pointer_create(tselem->id, &RNA_GreasePencilLayer, &node, &ptr);
|
||||
hide_prop = RNA_struct_type_find_property(&RNA_GreasePencilLayer, "hide");
|
||||
}
|
||||
else if (node.is_group()) {
|
||||
RNA_pointer_create(tselem->id, &RNA_GreasePencilLayerGroup, &node, &ptr);
|
||||
hide_prop = RNA_struct_type_find_property(&RNA_GreasePencilLayerGroup, "hide");
|
||||
}
|
||||
|
||||
if (space_outliner->show_restrict_flags & SO_RESTRICT_HIDE) {
|
||||
bt = uiDefIconButR_prop(block,
|
||||
UI_BTYPE_ICON_TOGGLE,
|
||||
0,
|
||||
0,
|
||||
int(region->v2d.cur.xmax - restrict_offsets.hide),
|
||||
te->ys,
|
||||
UI_UNIT_X,
|
||||
UI_UNIT_Y,
|
||||
&ptr,
|
||||
hide_prop,
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
-1,
|
||||
-1,
|
||||
nullptr);
|
||||
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
|
||||
if (!node.parent_group()->is_visible()) {
|
||||
UI_but_flag_enable(bt, UI_BUT_INACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (outliner_is_collection_tree_element(te)) {
|
||||
PointerRNA collection_ptr;
|
||||
PointerRNA layer_collection_ptr;
|
||||
|
@ -2468,6 +2527,7 @@ static BIFIconID tree_element_get_icon_from_id(const ID *id)
|
|||
}
|
||||
case ID_LS:
|
||||
return ICON_LINE_DATA;
|
||||
case ID_GP:
|
||||
case ID_GD_LEGACY:
|
||||
return ICON_OUTLINER_DATA_GREASEPENCIL;
|
||||
case ID_LP: {
|
||||
|
@ -2854,6 +2914,17 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
|
|||
data.icon = ICON_OUTLINER_DATA_GP_LAYER;
|
||||
break;
|
||||
}
|
||||
case TSE_GREASE_PENCIL_NODE: {
|
||||
bke::greasepencil::TreeNode &node =
|
||||
tree_element_cast<TreeElementGreasePencilNode>(te)->node();
|
||||
if (node.is_layer()) {
|
||||
data.icon = ICON_OUTLINER_DATA_GP_LAYER;
|
||||
}
|
||||
else if (node.is_group()) {
|
||||
data.icon = ICON_FILE_FOLDER;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSE_GPENCIL_EFFECT_BASE:
|
||||
case TSE_GPENCIL_EFFECT:
|
||||
data.drag_id = tselem->id;
|
||||
|
@ -3039,8 +3110,19 @@ int tree_element_id_type_to_index(TreeElement *te)
|
|||
{
|
||||
TreeStoreElem *tselem = TREESTORE(te);
|
||||
|
||||
const int id_index = (tselem->type == TSE_SOME_ID) ? BKE_idtype_idcode_to_index(te->idcode) :
|
||||
INDEX_ID_GR;
|
||||
int id_index = 0;
|
||||
if (tselem->type == TSE_SOME_ID) {
|
||||
id_index = BKE_idtype_idcode_to_index(te->idcode);
|
||||
}
|
||||
else if (tselem->type == TSE_GREASE_PENCIL_NODE) {
|
||||
/* Use the index of the grease pencil ID for the grease pencil tree nodes (which are not IDs).
|
||||
* All the Grease Pencil layer tree stats are stored in this index in #MergedIconRow. */
|
||||
id_index = INDEX_ID_GP;
|
||||
}
|
||||
else {
|
||||
id_index = INDEX_ID_GR;
|
||||
}
|
||||
|
||||
if (id_index < INDEX_ID_OB) {
|
||||
return id_index;
|
||||
}
|
||||
|
@ -3069,6 +3151,7 @@ static void outliner_draw_iconrow(bContext *C,
|
|||
int ys,
|
||||
float alpha_fac,
|
||||
bool in_bone_hierarchy,
|
||||
const bool is_grease_pencil_node_hierarchy,
|
||||
MergedIconRow *merged)
|
||||
{
|
||||
eOLDrawState active = OL_DRAWSEL_NONE;
|
||||
|
@ -3082,7 +3165,12 @@ static void outliner_draw_iconrow(bContext *C,
|
|||
* an they are at the root level of a collapsed subtree (e.g. not "hidden" in a collapsed
|
||||
* collection). */
|
||||
const bool is_bone = ELEM(tselem->type, TSE_BONE, TSE_EBONE, TSE_POSE_CHANNEL);
|
||||
/* The Grease Pencil layer tree is a hierarchy where we merge and count the total number of
|
||||
* layers in a node. We merge the counts for all the layers and skip counting nodes that are
|
||||
* layer groups (for less visual clutter in the outliner). */
|
||||
const bool is_grease_pencil_node = (tselem->type == TSE_GREASE_PENCIL_NODE);
|
||||
if ((level < 1) || ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) ||
|
||||
(is_grease_pencil_node_hierarchy && is_grease_pencil_node) ||
|
||||
(in_bone_hierarchy && is_bone))
|
||||
{
|
||||
/* active blocks get white circle */
|
||||
|
@ -3107,6 +3195,7 @@ static void outliner_draw_iconrow(bContext *C,
|
|||
TSE_LAYER_COLLECTION,
|
||||
TSE_R_LAYER,
|
||||
TSE_GP_LAYER,
|
||||
TSE_GREASE_PENCIL_NODE,
|
||||
TSE_LIBRARY_OVERRIDE_BASE,
|
||||
TSE_LIBRARY_OVERRIDE,
|
||||
TSE_LIBRARY_OVERRIDE_OPERATION,
|
||||
|
@ -3118,6 +3207,13 @@ static void outliner_draw_iconrow(bContext *C,
|
|||
{
|
||||
outliner_draw_iconrow_doit(block, te, xmax, offsx, ys, alpha_fac, active, 1);
|
||||
}
|
||||
else if (tselem->type == TSE_GREASE_PENCIL_NODE &&
|
||||
tree_element_cast<TreeElementGreasePencilNode>(te)->node().is_group())
|
||||
{
|
||||
/* Grease Pencil layer groups are tree nodes, but they shouldn't be counted. We only want
|
||||
* to keep track of the nodes that are layers and show the total number of layers in a
|
||||
* node. Adding the count of groups would add a lot of clutter. */
|
||||
}
|
||||
else {
|
||||
const int index = tree_element_id_type_to_index(te);
|
||||
merged->num_elements[index]++;
|
||||
|
@ -3129,12 +3225,17 @@ static void outliner_draw_iconrow(bContext *C,
|
|||
}
|
||||
|
||||
/* TSE_R_LAYER tree element always has same amount of branches, so don't draw. */
|
||||
/* Also only recurse into bone hierarchies if a direct child of the collapsed element to merge
|
||||
* into. */
|
||||
/* Also only recurse into bone hierarchies if a direct child of the collapsed element to
|
||||
* merge into. */
|
||||
const bool is_root_level_bone = is_bone && (level == 0);
|
||||
in_bone_hierarchy |= is_root_level_bone;
|
||||
/* Recurse into the grease pencil layer tree if we already are in the hierarchy or if we're at
|
||||
* the root level and find a grease pencil node. */
|
||||
const bool in_grease_pencil_node_hierarchy = is_grease_pencil_node_hierarchy ||
|
||||
(is_grease_pencil_node && level == 0);
|
||||
if (!ELEM(tselem->type, TSE_R_LAYER, TSE_BONE, TSE_EBONE, TSE_POSE_CHANNEL) ||
|
||||
in_bone_hierarchy) {
|
||||
in_bone_hierarchy || in_grease_pencil_node_hierarchy)
|
||||
{
|
||||
outliner_draw_iconrow(C,
|
||||
block,
|
||||
fstyle,
|
||||
|
@ -3147,6 +3248,7 @@ static void outliner_draw_iconrow(bContext *C,
|
|||
ys,
|
||||
alpha_fac,
|
||||
in_bone_hierarchy,
|
||||
in_grease_pencil_node_hierarchy,
|
||||
merged);
|
||||
}
|
||||
}
|
||||
|
@ -3217,6 +3319,16 @@ static bool element_should_draw_faded(const TreeViewContext *tvc,
|
|||
const bool is_excluded = layer_collection->flag & LAYER_COLLECTION_EXCLUDE;
|
||||
return !is_visible || is_excluded;
|
||||
}
|
||||
case TSE_GREASE_PENCIL_NODE: {
|
||||
bke::greasepencil::TreeNode &node =
|
||||
tree_element_cast<TreeElementGreasePencilNode>(te)->node();
|
||||
if (node.is_layer()) {
|
||||
return !node.as_layer().is_visible();
|
||||
}
|
||||
if (node.is_group()) {
|
||||
return !node.as_group().is_visible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (te->flag & TE_CHILD_NOT_IN_COLLECTION) {
|
||||
|
@ -3412,6 +3524,7 @@ static void outliner_draw_tree_element(bContext *C,
|
|||
*starty,
|
||||
alpha_fac,
|
||||
false,
|
||||
false,
|
||||
&merged);
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
|
@ -3517,6 +3630,14 @@ static void outliner_draw_hierarchy_lines_recursive(uint pos,
|
|||
y = *starty;
|
||||
}
|
||||
}
|
||||
else if (tselem->type == TSE_GREASE_PENCIL_NODE) {
|
||||
bke::greasepencil::TreeNode &node =
|
||||
tree_element_cast<TreeElementGreasePencilNode>(te)->node();
|
||||
if (node.is_group() && node.as_group().num_direct_nodes() > 0) {
|
||||
draw_hierarchy_line = true;
|
||||
y = *starty;
|
||||
}
|
||||
}
|
||||
|
||||
outliner_draw_hierarchy_lines_recursive(
|
||||
pos, space_outliner, &te->subtree, startx + UI_UNIT_X, col, draw_grayed_out, starty);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "BKE_deform.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_gpencil_modifier_legacy.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
|
@ -68,6 +69,7 @@
|
|||
|
||||
#include "outliner_intern.hh"
|
||||
#include "tree/tree_display.hh"
|
||||
#include "tree/tree_element_grease_pencil_node.hh"
|
||||
#include "tree/tree_element_seq.hh"
|
||||
#include "tree/tree_iterator.hh"
|
||||
|
||||
|
@ -484,6 +486,19 @@ static void tree_element_gplayer_activate(bContext *C, TreeElement *te, TreeStor
|
|||
}
|
||||
}
|
||||
|
||||
static void tree_element_grease_pencil_layer_activate(bContext *C,
|
||||
TreeElement *te,
|
||||
TreeStoreElem *tselem)
|
||||
{
|
||||
GreasePencil &grease_pencil = *(GreasePencil *)tselem->id;
|
||||
bke::greasepencil::TreeNode &node = tree_element_cast<TreeElementGreasePencilNode>(te)->node();
|
||||
if (node.is_layer()) {
|
||||
grease_pencil.set_active_layer(&node.as_layer());
|
||||
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, &grease_pencil);
|
||||
}
|
||||
}
|
||||
|
||||
static void tree_element_posegroup_activate(bContext *C, TreeElement *te, TreeStoreElem *tselem)
|
||||
{
|
||||
Object *ob = (Object *)tselem->id;
|
||||
|
@ -853,6 +868,9 @@ void tree_element_type_active_set(bContext *C,
|
|||
case TSE_GP_LAYER:
|
||||
tree_element_gplayer_activate(C, te, tselem);
|
||||
break;
|
||||
case TSE_GREASE_PENCIL_NODE:
|
||||
tree_element_grease_pencil_layer_activate(C, te, tselem);
|
||||
break;
|
||||
case TSE_VIEW_COLLECTION_BASE:
|
||||
tree_element_master_collection_activate(C);
|
||||
break;
|
||||
|
@ -1013,6 +1031,16 @@ static eOLDrawState tree_element_gplayer_state_get(const TreeElement *te)
|
|||
return OL_DRAWSEL_NONE;
|
||||
}
|
||||
|
||||
static eOLDrawState tree_element_grease_pencil_node_state_get(const TreeElement *te)
|
||||
{
|
||||
GreasePencil &grease_pencil = *(GreasePencil *)te->store_elem->id;
|
||||
bke::greasepencil::TreeNode &node = tree_element_cast<TreeElementGreasePencilNode>(te)->node();
|
||||
if (node.is_layer() && grease_pencil.is_layer_active(&node.as_layer())) {
|
||||
return OL_DRAWSEL_NORMAL;
|
||||
}
|
||||
return OL_DRAWSEL_NONE;
|
||||
}
|
||||
|
||||
static eOLDrawState tree_element_master_collection_state_get(const bContext *C)
|
||||
{
|
||||
const ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
@ -1156,6 +1184,8 @@ eOLDrawState tree_element_type_active_state_get(const bContext *C,
|
|||
return tree_element_sequence_dup_state_get(te);
|
||||
case TSE_GP_LAYER:
|
||||
return tree_element_gplayer_state_get(te);
|
||||
case TSE_GREASE_PENCIL_NODE:
|
||||
return tree_element_grease_pencil_node_state_get(te);
|
||||
case TSE_VIEW_COLLECTION_BASE:
|
||||
return tree_element_master_collection_state_get(C);
|
||||
case TSE_LAYER_COLLECTION:
|
||||
|
@ -1370,6 +1400,7 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE
|
|||
break;
|
||||
}
|
||||
case TSE_GP_LAYER:
|
||||
case TSE_GREASE_PENCIL_NODE:
|
||||
RNA_id_pointer_create(tselem->id, &ptr);
|
||||
context = BCONTEXT_DATA;
|
||||
break;
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "BKE_context.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -86,6 +87,7 @@
|
|||
#include "SEQ_sequencer.h"
|
||||
|
||||
#include "outliner_intern.hh"
|
||||
#include "tree/tree_element_grease_pencil_node.hh"
|
||||
#include "tree/tree_element_rna.hh"
|
||||
#include "tree/tree_element_seq.hh"
|
||||
#include "tree/tree_iterator.hh"
|
||||
|
@ -2207,6 +2209,27 @@ static void gpencil_layer_fn(int event,
|
|||
}
|
||||
}
|
||||
|
||||
static void grease_pencil_node_fn(int event,
|
||||
TreeElement *te,
|
||||
TreeStoreElem * /*tselem*/,
|
||||
void * /*arg*/)
|
||||
{
|
||||
bke::greasepencil::TreeNode &node = tree_element_cast<TreeElementGreasePencilNode>(te)->node();
|
||||
|
||||
if (event == OL_DOP_SELECT) {
|
||||
node.flag |= GP_LAYER_TREE_NODE_SELECT;
|
||||
}
|
||||
else if (event == OL_DOP_DESELECT) {
|
||||
node.flag &= ~GP_LAYER_TREE_NODE_SELECT;
|
||||
}
|
||||
else if (event == OL_DOP_HIDE) {
|
||||
node.flag |= GP_LAYER_TREE_NODE_HIDE;
|
||||
}
|
||||
else if (event == OL_DOP_UNHIDE) {
|
||||
node.flag &= ~GP_LAYER_TREE_NODE_HIDE;
|
||||
}
|
||||
}
|
||||
|
||||
static void data_select_linked_fn(int event,
|
||||
TreeElement *te,
|
||||
TreeStoreElem * /*tselem*/,
|
||||
|
@ -3529,6 +3552,12 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op)
|
|||
|
||||
break;
|
||||
}
|
||||
case TSE_GREASE_PENCIL_NODE: {
|
||||
outliner_do_data_operation(space_outliner, datalevel, event, grease_pencil_node_fn, nullptr);
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, nullptr);
|
||||
ED_undo_push(C, "Grease Pencil Node operation");
|
||||
break;
|
||||
}
|
||||
case TSE_RNA_STRUCT:
|
||||
if (event == OL_DOP_SELECT_LINKED) {
|
||||
outliner_do_data_operation(space_outliner, datalevel, event, data_select_linked_fn, C);
|
||||
|
|
|
@ -237,6 +237,10 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||
/* idv is the layer itself */
|
||||
id = TREESTORE(parent)->id;
|
||||
}
|
||||
else if (type == TSE_GREASE_PENCIL_NODE) {
|
||||
/* idv is the layer itself */
|
||||
id = TREESTORE(parent)->id;
|
||||
}
|
||||
else if (ELEM(type, TSE_GENERIC_LABEL)) {
|
||||
id = nullptr;
|
||||
}
|
||||
|
@ -310,7 +314,7 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||
else if (ELEM(type, TSE_ANIM_DATA, TSE_NLA, TSE_NLA_TRACK, TSE_DRIVER_BASE)) {
|
||||
/* pass */
|
||||
}
|
||||
else if (type == TSE_GP_LAYER) {
|
||||
else if (ELEM(type, TSE_GP_LAYER, TSE_GREASE_PENCIL_NODE)) {
|
||||
/* pass */
|
||||
}
|
||||
else if (ELEM(type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) {
|
||||
|
@ -399,7 +403,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||
TSE_POSEGRP,
|
||||
TSE_POSEGRP_BASE,
|
||||
TSE_R_LAYER,
|
||||
TSE_R_LAYER_BASE))
|
||||
TSE_R_LAYER_BASE,
|
||||
TSE_GREASE_PENCIL_NODE))
|
||||
{
|
||||
BLI_assert_msg(false, "Element type should already use new AbstractTreeElement design");
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "tree_element_edit_bone.hh"
|
||||
#include "tree_element_gpencil_effect.hh"
|
||||
#include "tree_element_gpencil_layer.hh"
|
||||
#include "tree_element_grease_pencil_node.hh"
|
||||
#include "tree_element_id.hh"
|
||||
#include "tree_element_label.hh"
|
||||
#include "tree_element_nla.hh"
|
||||
|
@ -80,6 +81,9 @@ std::unique_ptr<AbstractTreeElement> AbstractTreeElement::createFromType(const i
|
|||
return std::make_unique<TreeElementNLAAction>(legacy_te, *static_cast<bAction *>(idv));
|
||||
case TSE_GP_LAYER:
|
||||
return std::make_unique<TreeElementGPencilLayer>(legacy_te, *static_cast<bGPDlayer *>(idv));
|
||||
case TSE_GREASE_PENCIL_NODE:
|
||||
return std::make_unique<TreeElementGreasePencilNode>(
|
||||
legacy_te, *static_cast<bke::greasepencil::TreeNode *>(idv));
|
||||
case TSE_R_LAYER_BASE:
|
||||
return std::make_unique<TreeElementViewLayerBase>(legacy_te, *static_cast<Scene *>(idv));
|
||||
case TSE_R_LAYER: {
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup spoutliner
|
||||
*/
|
||||
|
||||
#include "BKE_grease_pencil.hh"
|
||||
|
||||
#include "DNA_outliner_types.h"
|
||||
|
||||
#include "../outliner_intern.hh"
|
||||
|
||||
#include "tree_element_grease_pencil_node.hh"
|
||||
|
||||
namespace blender::ed::outliner {
|
||||
|
||||
TreeElementGreasePencilNode::TreeElementGreasePencilNode(TreeElement &legacy_te,
|
||||
bke::greasepencil::TreeNode &node)
|
||||
: AbstractTreeElement(legacy_te), node_(node)
|
||||
{
|
||||
BLI_assert(legacy_te.store_elem->type == TSE_GREASE_PENCIL_NODE);
|
||||
legacy_te.name = node.name;
|
||||
}
|
||||
filedescriptor marked this conversation as resolved
Outdated
|
||||
|
||||
void TreeElementGreasePencilNode::expand(SpaceOutliner &space_outliner) const
|
||||
{
|
||||
if (!node_.is_group()) {
|
||||
return;
|
||||
}
|
||||
LISTBASE_FOREACH_BACKWARD (GreasePencilLayerTreeNode *, child, &node_.as_group().children) {
|
||||
outliner_add_element(
|
||||
&space_outliner, &legacy_te_.subtree, child, &legacy_te_, TSE_GREASE_PENCIL_NODE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
blender::bke::greasepencil::TreeNode &TreeElementGreasePencilNode::node() const
|
||||
{
|
||||
return node_;
|
||||
filedescriptor marked this conversation as resolved
Outdated
Julian Eisel
commented
I don't see a reason to use the I don't see a reason to use the `expand` option here. It exists because sometimes we just want to display some objects or collections, without expanding their entire hierarchy. It's mostly a performance workaround. Here there just isn't anything to expand, so the `expand()` function won't add elements anyway.
Falk David
commented
I tried setting this to I tried setting this to `false` but then I cannot expand groups with a single child. They show up as if they had no child at all.
Julian Eisel
commented
You don't need to set it at all, it has a default parameter value of You don't need to set it at all, it has a default parameter value of `true`.
Falk David
commented
Ah that explains it, ok. Ah that explains it, ok.
|
||||
}
|
||||
|
||||
} // namespace blender::ed::outliner
|
|
@ -0,0 +1,29 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup spoutliner
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tree_element.hh"
|
||||
|
||||
namespace blender::bke::greasepencil {
|
||||
class TreeNode;
|
||||
filedescriptor marked this conversation as resolved
Outdated
Julian Eisel
commented
Should be Should be `class`, otherwise MSVC won't build.
|
||||
} // namespace blender::bke::greasepencil
|
||||
|
||||
namespace blender::ed::outliner {
|
||||
|
||||
class TreeElementGreasePencilNode final : public AbstractTreeElement {
|
||||
blender::bke::greasepencil::TreeNode &node_;
|
||||
public:
|
||||
TreeElementGreasePencilNode(TreeElement &legacy_te, blender::bke::greasepencil::TreeNode &node);
|
||||
|
||||
void expand(SpaceOutliner &) const override;
|
||||
|
||||
blender::bke::greasepencil::TreeNode &node() const;
|
||||
};
|
||||
|
||||
} // namespace blender::ed::outliner
|
|
@ -25,6 +25,7 @@
|
|||
#include "tree_element_id_collection.hh"
|
||||
#include "tree_element_id_curve.hh"
|
||||
#include "tree_element_id_gpencil_legacy.hh"
|
||||
#include "tree_element_id_grease_pencil.hh"
|
||||
#include "tree_element_id_library.hh"
|
||||
#include "tree_element_id_linestyle.hh"
|
||||
#include "tree_element_id_mesh.hh"
|
||||
|
@ -61,6 +62,8 @@ std::unique_ptr<TreeElementID> TreeElementID::createFromID(TreeElement &legacy_t
|
|||
return std::make_unique<TreeElementIDLineStyle>(legacy_te, (FreestyleLineStyle &)id);
|
||||
case ID_GD_LEGACY:
|
||||
return std::make_unique<TreeElementIDGPLegacy>(legacy_te, (bGPdata &)id);
|
||||
case ID_GP:
|
||||
return std::make_unique<TreeElementIDGreasePencil>(legacy_te, (GreasePencil &)id);
|
||||
case ID_GR:
|
||||
return std::make_unique<TreeElementIDCollection>(legacy_te, (Collection &)id);
|
||||
case ID_AR:
|
||||
|
@ -94,7 +97,6 @@ std::unique_ptr<TreeElementID> TreeElementID::createFromID(TreeElement &legacy_t
|
|||
case ID_PAL:
|
||||
case ID_PC:
|
||||
case ID_CF:
|
||||
case ID_GP:
|
||||
return std::make_unique<TreeElementID>(legacy_te, id);
|
||||
case ID_IP:
|
||||
BLI_assert_unreachable();
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup spoutliner
|
||||
*/
|
||||
|
||||
#include "BKE_grease_pencil.hh"
|
||||
|
||||
#include "DNA_outliner_types.h"
|
||||
|
||||
#include "../outliner_intern.hh"
|
||||
|
||||
#include "tree_element_id_grease_pencil.hh"
|
||||
|
||||
namespace blender::ed::outliner {
|
||||
|
||||
TreeElementIDGreasePencil::TreeElementIDGreasePencil(TreeElement &legacy_te,
|
||||
GreasePencil &grease_pencil)
|
||||
: TreeElementID(legacy_te, grease_pencil.id), grease_pencil_(grease_pencil)
|
||||
{
|
||||
}
|
||||
|
||||
void TreeElementIDGreasePencil::expand(SpaceOutliner &space_outliner) const
|
||||
{
|
||||
expand_animation_data(space_outliner, grease_pencil_.adt);
|
||||
|
||||
expand_layer_tree(space_outliner);
|
||||
}
|
||||
|
||||
void TreeElementIDGreasePencil::expand_layer_tree(SpaceOutliner &space_outliner) const
|
||||
{
|
||||
LISTBASE_FOREACH_BACKWARD (
|
||||
GreasePencilLayerTreeNode *, child, &grease_pencil_.root_group().children)
|
||||
{
|
||||
outliner_add_element(
|
||||
&space_outliner, &legacy_te_.subtree, child, &legacy_te_, TSE_GREASE_PENCIL_NODE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::ed::outliner
|
|
@ -0,0 +1,29 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup spoutliner
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tree_element_id.hh"
|
||||
|
||||
struct GreasePencil;
|
||||
|
||||
namespace blender::ed::outliner {
|
||||
|
||||
class TreeElementIDGreasePencil final : public TreeElementID {
|
||||
GreasePencil &grease_pencil_;
|
||||
|
||||
public:
|
||||
TreeElementIDGreasePencil(TreeElement &legacy_te, GreasePencil &grease_pencil_);
|
||||
|
||||
void expand(SpaceOutliner &) const override;
|
||||
|
||||
private:
|
||||
void expand_layer_tree(SpaceOutliner &) const;
|
||||
};
|
||||
|
||||
} // namespace blender::ed::outliner
|
|
@ -117,6 +117,7 @@ typedef enum eTreeStoreElemType {
|
|||
TSE_LIBRARY_OVERRIDE = 45,
|
||||
TSE_LIBRARY_OVERRIDE_OPERATION = 46,
|
||||
TSE_GENERIC_LABEL = 47, /* No ID */
|
||||
TSE_GREASE_PENCIL_NODE = 48,
|
||||
filedescriptor marked this conversation as resolved
Outdated
Julian Eisel
commented
The comment says this is not an ID, but The comment says this is not an ID, but `TreeStoreElem.id` actually points to a valid ID. Checking above, it seems like the ID is needed, so the comment can be removed. Otherwise (if it wouldn't actually point to an ID), `TSE_IS_REAL_ID()` would have to be updated.
|
||||
} eTreeStoreElemType;
|
||||
|
||||
/** Check whether given #TreeStoreElem should have a real ID in #TreeStoreElem.id member. */
|
||||
|
|
Let's avoid usages of
directdata
. All necessary data can be stored directly withinTreeElementGreasePencilNode
. Code that needs access to it can usetree_element_cast()
to get this from theTreeElement
, and then use accessors to type-safely get the data.