GPv3: Display layer properties in animation channels #110991

Merged
Amélie Fondevilla merged 15 commits from amelief/blender:gpv3-dopesheet-draw-channels into main 2023-08-10 13:55:21 +02:00
6 changed files with 142 additions and 27 deletions

View File

@ -298,6 +298,8 @@ class Layer : public ::GreasePencilLayer {
bool is_empty() const;
bool is_selected() const;
bool use_onion_skinning() const;
/**
* Adds a new frame into the layer frames map.
* Fails if there already exists a frame at \a key that is not a null-frame.

View File

@ -600,6 +600,11 @@ bool Layer::is_selected() const
return ((this->base.flag & GP_LAYER_TREE_NODE_SELECT) != 0);
}
bool Layer::use_onion_skinning() const
{
return ((this->base.flag & GP_LAYER_TREE_NODE_USE_ONION_SKINNING) != 0);
}
Layer::SortedKeysIterator Layer::remove_leading_null_frames_in_range(
Layer::SortedKeysIterator begin, Layer::SortedKeysIterator end)
{

View File

@ -3557,7 +3557,7 @@ static bAnimChannelType ACF_GPL_LEGACY = {
/* Grease Pencil Layer ------------------------------------------- */
/* Name for grease pencil layer entries */
/* Name for grease pencil layer entries. */
static void acf_gpl_name(bAnimListElem *ale, char *name)
{
GreasePencilLayer *layer = (GreasePencilLayer *)ale->data;
@ -3567,7 +3567,7 @@ static void acf_gpl_name(bAnimListElem *ale, char *name)
}
}
/* Name property for grease pencil layer entries */
/* Name property for grease pencil layer entries. */
static bool acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *r_ptr, PropertyRNA **r_prop)
{
if (ale->data == nullptr) {
@ -3584,21 +3584,30 @@ static int acf_gpl_setting_flag(bAnimContext * /*ac*/, eAnimChannel_Settings set
{
*r_neg = false;
switch (setting) {
case ACHANNEL_SETTING_SELECT: /* selected */
case ACHANNEL_SETTING_SELECT: /* Layer selected. */
return GP_LAYER_TREE_NODE_SELECT;
default: /* unsupported */
case ACHANNEL_SETTING_MUTE: /* Animation muting. */
return GP_LAYER_TREE_NODE_MUTE;
case ACHANNEL_SETTING_VISIBLE: /* Visibility of the layers. */
*r_neg = true;
return GP_LAYER_TREE_NODE_HIDE;
case ACHANNEL_SETTING_PROTECT: /* Layer locked. */
return GP_LAYER_TREE_NODE_LOCKED;
default: /* Unsupported. */
return 0;
}
}
/* Get pointer to the setting */
/* Get pointer to the setting. */
static void *acf_gpl_setting_ptr(bAnimListElem *ale,
eAnimChannel_Settings /*setting*/,
short *r_type)
{
GreasePencilLayer *layer = (GreasePencilLayer *)ale->data;
/* All flags are just in gpl->flag for now... */
return GET_ACF_FLAG_PTR(layer->base.flag, r_type);
}
@ -4534,7 +4543,7 @@ void ANIM_channel_draw(
if (ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH) &&
(acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)) &&
!ELEM(ale->type, ANIMTYPE_GPLAYER, ANIMTYPE_DSGPENCIL))
!ELEM(ale->type, ANIMTYPE_GPLAYER, ANIMTYPE_DSGPENCIL, ANIMTYPE_GREASE_PENCIL_LAYER))
{
/* for F-Curves, draw color-preview of curve left to the visibility icon */
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
@ -4681,7 +4690,7 @@ void ANIM_channel_draw(
}
/* grease pencil visibility... */
if (ale->type == ANIMTYPE_GPLAYER) {
if (ELEM(ale->type, ANIMTYPE_GPLAYER, ANIMTYPE_GREASE_PENCIL_LAYER)) {
offset += ICON_WIDTH;
}
@ -4711,8 +4720,12 @@ void ANIM_channel_draw(
* - Slider should start before the toggles (if they're visible)
* to keep a clean line down the side.
*/
if ((draw_sliders) &&
ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE, ANIMTYPE_SHAPEKEY, ANIMTYPE_GPLAYER))
if ((draw_sliders) && ELEM(ale->type,
ANIMTYPE_FCURVE,
ANIMTYPE_NLACURVE,
ANIMTYPE_SHAPEKEY,
ANIMTYPE_GPLAYER,
ANIMTYPE_GREASE_PENCIL_LAYER))
{
/* adjust offset */
offset += SLIDER_WIDTH;
@ -5049,7 +5062,7 @@ static void draw_setting_widget(bAnimContext *ac,
if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
tooltip = TIP_("F-Curve visibility in Graph Editor");
}
else if (ale->type == ANIMTYPE_GPLAYER) {
else if (ELEM(ale->type, ANIMTYPE_GPLAYER, ANIMTYPE_GREASE_PENCIL_LAYER)) {
tooltip = TIP_("Grease Pencil layer is visible in the viewport");
}
else {
@ -5107,7 +5120,7 @@ static void draw_setting_widget(bAnimContext *ac,
tooltip = TIP_(
"Temporarily disable NLA stack evaluation (i.e. only the active action is evaluated)");
}
else if (ale->type == ANIMTYPE_GPLAYER) {
else if (ELEM(ale->type, ANIMTYPE_GPLAYER, ANIMTYPE_GREASE_PENCIL_LAYER)) {
tooltip = TIP_(
"Show all keyframes during animation playback and enable all frames for editing "
"(uncheck to use only the current keyframe during animation playback and editing)");
@ -5252,6 +5265,70 @@ static void draw_setting_widget(bAnimContext *ac,
}
}
static void draw_grease_pencil_layer_widgets(bAnimListElem *ale,
uiBlock *block,
const rctf *rect,
short &offset,
const short channel_height,
const int array_index)
{
using namespace blender::bke::greasepencil;
Layer *layer = static_cast<Layer *>(ale->data);
if (layer == nullptr) {
return;
}
/* Reset slider offset, in order to add special grease pencil icons. */
offset += SLIDER_WIDTH;
/* Create the RNA pointers. */
PointerRNA ptr, id_ptr;
RNA_pointer_create(ale->id, &RNA_GreasePencilLayer, ale->data, &ptr);
RNA_id_pointer_create(ale->id, &id_ptr);
/* Layer onion skinning switch. */
offset -= ICON_WIDTH;
UI_block_emboss_set(block, UI_EMBOSS_NONE);
PropertyRNA *onion_skinning_prop = RNA_struct_find_property(&ptr, "use_onion_skinning");
char *onion_skinning_rna_path = RNA_path_from_ID_to_property(&ptr, onion_skinning_prop);
if (RNA_path_resolve_property(&id_ptr, onion_skinning_rna_path, &ptr, &onion_skinning_prop)) {
const int icon = layer->use_onion_skinning() ? ICON_ONIONSKIN_ON : ICON_ONIONSKIN_OFF;
uiDefAutoButR(block,
&ptr,
onion_skinning_prop,
array_index,
"",
icon,
offset,
rect->ymin,
ICON_WIDTH,
channel_height);
}
MEM_freeN(onion_skinning_rna_path);
/* Layer opacity. */
const short width = SLIDER_WIDTH * 0.6;
offset -= width;
UI_block_emboss_set(block, UI_EMBOSS);
PropertyRNA *opacity_prop = RNA_struct_find_property(&ptr, "opacity");
char *opacity_rna_path = RNA_path_from_ID_to_property(&ptr, opacity_prop);
if (RNA_path_resolve_property(&id_ptr, opacity_rna_path, &ptr, &opacity_prop)) {
uiDefAutoButR(block,
&ptr,
opacity_prop,
array_index,
"",
ICON_NONE,
offset,
rect->ymin,
width,
channel_height);
}
MEM_freeN(opacity_rna_path);
}
void ANIM_channel_draw_widgets(const bContext *C,
bAnimContext *ac,
bAnimListElem *ale,
@ -5303,7 +5380,7 @@ void ANIM_channel_draw_widgets(const bContext *C,
if (ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH) &&
(acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)) &&
(ale->type != ANIMTYPE_GPLAYER))
!ELEM(ale->type, ANIMTYPE_GPLAYER, ANIMTYPE_GREASE_PENCIL_LAYER))
{
/* Pin toggle. */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)) {
@ -5418,7 +5495,7 @@ void ANIM_channel_draw_widgets(const bContext *C,
offset -= ICON_WIDTH;
draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_MUTE);
}
if (ale->type == ANIMTYPE_GPLAYER) {
if (ELEM(ale->type, ANIMTYPE_GPLAYER, ANIMTYPE_GREASE_PENCIL_LAYER)) {
/* Not technically "mute"
* (in terms of anim channels, but this sets layer visibility instead). */
offset -= ICON_WIDTH;
@ -5483,7 +5560,8 @@ void ANIM_channel_draw_widgets(const bContext *C,
ANIMTYPE_FCURVE,
ANIMTYPE_NLACURVE,
ANIMTYPE_SHAPEKEY,
ANIMTYPE_GPLAYER)) ||
ANIMTYPE_GPLAYER,
ANIMTYPE_GREASE_PENCIL_LAYER)) ||
ale->type == ANIMTYPE_SHAPEKEY)
{
/* adjust offset */
@ -5628,6 +5706,9 @@ void ANIM_channel_draw_widgets(const bContext *C,
MEM_freeN(gp_rna_path);
}
}
else if (ale->type == ANIMTYPE_GREASE_PENCIL_LAYER) {
draw_grease_pencil_layer_widgets(ale, block, rect, offset, channel_height, array_index);
}
/* Only if RNA-Path found. */
if (rna_path) {

View File

@ -12,6 +12,8 @@
#include "MEM_guardedalloc.h"
#include "BKE_grease_pencil.hh"
#include "BLI_dlrbTree.h"
#include "BLI_listbase.h"
#include "BLI_rect.h"
@ -726,7 +728,7 @@ void draw_grease_pencil_datablock_channel(AnimKeylistDrawList *draw_list,
}
void draw_grease_pencil_cels_channel(AnimKeylistDrawList *draw_list,
bDopeSheet * /*ads*/,
bDopeSheet *ads,
const GreasePencilLayer *layer,
const float ypos,
const float yscale_fac,
@ -734,7 +736,9 @@ void draw_grease_pencil_cels_channel(AnimKeylistDrawList *draw_list,
{
AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem(
draw_list, ANIM_KEYLIST_GREASE_PENCIL_CELS, ypos, yscale_fac, eSAction_Flag(saction_flag));
draw_elem->ads = ads;
draw_elem->grease_pencil_layer = layer;
draw_elem->channel_locked = layer->wrap().is_locked();
}
void draw_gpl_channel(AnimKeylistDrawList *draw_list,

View File

@ -295,18 +295,33 @@ static void draw_backdrops(bAnimContext *ac, ListBase &anim_data, View2D *v2d, u
else if (ac->datatype == ANIMCONT_GPENCIL) {
uchar *color;
uchar gpl_col[4];
if (ale->type == ANIMTYPE_SUMMARY) {
color = col_summary;
}
else if ((show_group_colors) && (ale->type == ANIMTYPE_GPLAYER)) {
bGPDlayer *gpl = (bGPDlayer *)ale->data;
rgb_float_to_uchar(gpl_col, gpl->color);
gpl_col[3] = col1[3];
switch (ale->type) {
case ANIMTYPE_SUMMARY:
color = col_summary;
break;
color = sel ? col1 : gpl_col;
}
else {
color = sel ? col1 : col2;
case ANIMTYPE_GPLAYER: {
if (show_group_colors) {
bGPDlayer *gpl = (bGPDlayer *)ale->data;
rgb_float_to_uchar(gpl_col, gpl->color);
gpl_col[3] = col1[3];
color = sel ? col1 : gpl_col;
}
else {
color = sel ? col1 : col2;
}
break;
}
case ANIMTYPE_GREASE_PENCIL_DATABLOCK:
color = col2b;
color[3] = sel ? col1[3] : col2b[3];
break;
default:
color = sel ? col1 : col2;
break;
}
/* Color overlay on frames between the start/end frames. */

View File

@ -214,6 +214,14 @@ static void rna_def_grease_pencil_layer(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, "GreasePencilLayer", "opacity");
RNA_def_property_ui_text(prop, "Opacity", "Layer Opacity");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
/* Onion Skinning. */
prop = RNA_def_property(srna, "use_onion_skinning", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, "GreasePencilLayerTreeNode", "flag", GP_LAYER_TREE_NODE_USE_ONION_SKINNING);
RNA_def_property_ui_text(
prop, "Onion Skinning", "Display onion skins before and after the current frame");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
}
static void rna_def_grease_pencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)