GPv3: Add operator to add new layer group
This commit is contained in:
parent
8a39f438c3
commit
b61316c7ad
@ -2,7 +2,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
import bpy
|
||||
from bpy.types import Panel
|
||||
from bpy.types import Panel, Menu
|
||||
|
||||
|
||||
class DataButtonsPanel:
|
||||
@ -32,6 +32,15 @@ class DATA_PT_context_grease_pencil(DataButtonsPanel, Panel):
|
||||
layout.template_ID(space, "pin_id")
|
||||
|
||||
|
||||
class GREASE_PENCIL_MT_grease_pencil_add_layer_extra(Menu):
|
||||
bl_label = "Add Extra"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("grease_pencil.layer_group_add", text="Add Group")
|
||||
|
||||
|
||||
class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
|
||||
bl_label = "Layers"
|
||||
|
||||
@ -42,13 +51,17 @@ class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
|
||||
row.template_grease_pencil_layer_tree()
|
||||
|
||||
col = row.column()
|
||||
col.operator("grease_pencil.layer_add", icon='ADD', text="")
|
||||
sub = col.column(align=True)
|
||||
sub.operator("grease_pencil.layer_add", icon='ADD', text="")
|
||||
sub.menu("GREASE_PENCIL_MT_grease_pencil_add_layer_extra", icon='DOWNARROW_HLT', text="")
|
||||
|
||||
col.operator("grease_pencil.layer_remove", icon='REMOVE', text="")
|
||||
|
||||
|
||||
classes = (
|
||||
DATA_PT_context_grease_pencil,
|
||||
DATA_PT_grease_pencil_layers,
|
||||
GREASE_PENCIL_MT_grease_pencil_add_layer_extra,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
@ -207,6 +207,12 @@ class Layer : public ::GreasePencilLayer {
|
||||
*/
|
||||
LayerGroup &parent_group() const;
|
||||
|
||||
/**
|
||||
* \returns the layer as a `TreeNode`.
|
||||
*/
|
||||
const TreeNode &as_node() const;
|
||||
TreeNode &as_node();
|
||||
|
||||
/**
|
||||
* \returns the frames mapping.
|
||||
*/
|
||||
@ -287,6 +293,12 @@ class LayerGroup : public ::GreasePencilLayerTreeGroup {
|
||||
LayerGroup &add_group(LayerGroup *group);
|
||||
LayerGroup &add_group(StringRefNull name);
|
||||
|
||||
/**
|
||||
* Adds a layer group after \a link and returns it.
|
||||
*/
|
||||
LayerGroup &add_group_after(LayerGroup *group, TreeNode *link);
|
||||
LayerGroup &add_group_after(StringRefNull name, TreeNode *link);
|
||||
|
||||
/**
|
||||
* Adds a layer at the end of this group and returns it.
|
||||
*/
|
||||
@ -359,6 +371,15 @@ inline LayerGroup &Layer::parent_group() const
|
||||
return this->base.parent->wrap();
|
||||
}
|
||||
|
||||
inline const TreeNode &Layer::as_node() const
|
||||
{
|
||||
return *reinterpret_cast<const TreeNode *>(this);
|
||||
}
|
||||
inline TreeNode &Layer::as_node()
|
||||
{
|
||||
return *reinterpret_cast<TreeNode *>(this);
|
||||
}
|
||||
|
||||
namespace convert {
|
||||
|
||||
void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
|
@ -631,6 +631,23 @@ LayerGroup &LayerGroup::add_group(StringRefNull name)
|
||||
return this->add_group(new_group);
|
||||
}
|
||||
|
||||
LayerGroup &LayerGroup::add_group_after(LayerGroup *group, TreeNode *link)
|
||||
{
|
||||
BLI_assert(group != nullptr && link != nullptr);
|
||||
BLI_insertlinkafter(&this->children,
|
||||
reinterpret_cast<GreasePencilLayerTreeNode *>(link),
|
||||
reinterpret_cast<GreasePencilLayerTreeNode *>(group));
|
||||
group->base.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
|
||||
this->tag_nodes_cache_dirty();
|
||||
return *group;
|
||||
}
|
||||
|
||||
LayerGroup &LayerGroup::add_group_after(StringRefNull name, TreeNode *link)
|
||||
{
|
||||
LayerGroup *new_group = MEM_new<LayerGroup>(__func__, name);
|
||||
return this->add_group_after(new_group, link);
|
||||
}
|
||||
|
||||
Layer &LayerGroup::add_layer(Layer *layer)
|
||||
{
|
||||
BLI_assert(layer != nullptr);
|
||||
@ -1245,7 +1262,7 @@ static blender::VectorSet<blender::StringRefNull> get_node_names(GreasePencil &g
|
||||
return names;
|
||||
}
|
||||
|
||||
static bool check_unique_layer_cb(void *arg, const char *name)
|
||||
static bool check_unique_node_cb(void *arg, const char *name)
|
||||
{
|
||||
using namespace blender;
|
||||
VectorSet<StringRefNull> &names = *reinterpret_cast<VectorSet<StringRefNull> *>(arg);
|
||||
@ -1254,7 +1271,12 @@ static bool check_unique_layer_cb(void *arg, const char *name)
|
||||
|
||||
static bool unique_layer_name(VectorSet<blender::StringRefNull> &names, char *name)
|
||||
{
|
||||
return BLI_uniquename_cb(check_unique_layer_cb, &names, "GP_Layer", '.', name, MAX_NAME);
|
||||
return BLI_uniquename_cb(check_unique_node_cb, &names, "GP_Layer", '.', name, MAX_NAME);
|
||||
}
|
||||
|
||||
static bool unique_layer_group_name(VectorSet<blender::StringRefNull> &names, char *name)
|
||||
{
|
||||
return BLI_uniquename_cb(check_unique_node_cb, &names, "GP_Group", '.', name, MAX_NAME);
|
||||
}
|
||||
|
||||
blender::bke::greasepencil::Layer &GreasePencil::add_layer(
|
||||
@ -1284,6 +1306,34 @@ blender::bke::greasepencil::Layer &GreasePencil::add_layer(const blender::String
|
||||
return this->add_layer(this->root_group.wrap(), name);
|
||||
}
|
||||
|
||||
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group(
|
||||
blender::bke::greasepencil::LayerGroup &group, const blender::StringRefNull name)
|
||||
{
|
||||
using namespace blender;
|
||||
VectorSet<StringRefNull> names = get_node_names(*this);
|
||||
std::string unique_name(name.c_str());
|
||||
unique_layer_group_name(names, unique_name.data());
|
||||
return group.add_group(unique_name);
|
||||
}
|
||||
|
||||
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group_after(
|
||||
blender::bke::greasepencil::LayerGroup &group,
|
||||
blender::bke::greasepencil::TreeNode *node,
|
||||
const blender::StringRefNull name)
|
||||
{
|
||||
using namespace blender;
|
||||
VectorSet<StringRefNull> names = get_node_names(*this);
|
||||
std::string unique_name(name.c_str());
|
||||
unique_layer_group_name(names, unique_name.data());
|
||||
return group.add_group_after(unique_name, node);
|
||||
}
|
||||
|
||||
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group(
|
||||
const blender::StringRefNull name)
|
||||
{
|
||||
return this->add_layer_group(this->root_group.wrap(), name);
|
||||
}
|
||||
|
||||
const blender::bke::greasepencil::Layer *GreasePencil::find_layer_by_name(
|
||||
const blender::StringRefNull name) const
|
||||
{
|
||||
|
@ -179,6 +179,57 @@ static void GREASE_PENCIL_OT_layer_reorder(wmOperatorType *ot)
|
||||
ot->srna, "location", prop_layer_reorder_location, LAYER_REORDER_ABOVE, "Location", "");
|
||||
}
|
||||
|
||||
static int grease_pencil_layer_group_add_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
Object *object = CTX_data_active_object(C);
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
|
||||
|
||||
int new_layer_group_name_length;
|
||||
char *new_layer_group_name = RNA_string_get_alloc(
|
||||
op->ptr, "new_layer_group_name", nullptr, 0, &new_layer_group_name_length);
|
||||
|
||||
if (grease_pencil.has_active_layer()) {
|
||||
LayerGroup &active_group = grease_pencil.get_active_layer()->parent_group();
|
||||
grease_pencil.add_layer_group_after(active_group,
|
||||
&grease_pencil.get_active_layer_for_write()->as_node(),
|
||||
new_layer_group_name);
|
||||
}
|
||||
else {
|
||||
grease_pencil.add_layer_group(new_layer_group_name);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(new_layer_group_name);
|
||||
|
||||
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void GREASE_PENCIL_OT_layer_group_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Add New Layer Group";
|
||||
ot->idname = "GREASE_PENCIL_OT_layer_group_add";
|
||||
ot->description = "Add a new Grease Pencil layer group in the active object";
|
||||
|
||||
/* callbacks */
|
||||
ot->exec = grease_pencil_layer_group_add_exec;
|
||||
ot->poll = active_grease_pencil_poll;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
PropertyRNA *prop = RNA_def_string(ot->srna,
|
||||
"new_layer_group_name",
|
||||
"GP_Group",
|
||||
INT16_MAX,
|
||||
"Name",
|
||||
"Name of the new layer group");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
ot->prop = prop;
|
||||
}
|
||||
|
||||
} // namespace blender::ed::greasepencil
|
||||
|
||||
void ED_operatortypes_grease_pencil_layers(void)
|
||||
@ -187,4 +238,6 @@ void ED_operatortypes_grease_pencil_layers(void)
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_layer_add);
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_layer_remove);
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_layer_reorder);
|
||||
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_layer_group_add);
|
||||
}
|
||||
|
@ -450,6 +450,14 @@ typedef struct GreasePencil {
|
||||
blender::bke::greasepencil::Layer *layer,
|
||||
blender::StringRefNull name);
|
||||
|
||||
blender::bke::greasepencil::LayerGroup &add_layer_group(
|
||||
blender::bke::greasepencil::LayerGroup &group, blender::StringRefNull name);
|
||||
blender::bke::greasepencil::LayerGroup &add_layer_group(blender::StringRefNull name);
|
||||
blender::bke::greasepencil::LayerGroup &add_layer_group_after(
|
||||
blender::bke::greasepencil::LayerGroup &group,
|
||||
blender::bke::greasepencil::TreeNode *node,
|
||||
blender::StringRefNull name);
|
||||
|
||||
const blender::bke::greasepencil::Layer *find_layer_by_name(blender::StringRefNull name) const;
|
||||
blender::bke::greasepencil::Layer *find_layer_by_name(blender::StringRefNull name);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user